]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/drv/emac/test/EmacLoopbackTest/test_utils.c
emac-lld: add to PDK
[processor-sdk/pdk.git] / packages / ti / drv / emac / test / EmacLoopbackTest / test_utils.c
1 /* =============================================================================
2  *   Copyright (c) Texas Instruments Incorporated 2015
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions
6  *  are met:
7  *
8  *    Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  *    Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the
14  *    distribution.
15  *
16  *    Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
34 /**
35  *  \file     test_utils.c
36  *
37  *  \brief    This file contains common utility functions used by the emac loopback unit 
38  *             test applications.
39  *
40  */
42 #include <string.h>
44 #include <xdc/std.h>
45 #include <ti/sysbios/BIOS.h>
46 #include <ti/sysbios/knl/Task.h>
48 #include <ti/csl/csl_chip.h>
49 /* EMAC Driver Header File. */
50 #include <ti/drv/emac/emac_drv.h>
52 /* SOC Include Files. */
53 #include <ti/drv/emac/soc/emac_soc_v4.h>
55 /* Test application local header file */
56 #include "test_loc.h"
58 #include <ti/drv/uart/UART.h>
59 #include <ti/drv/uart/UART_stdio.h>
60 #include <ti/board/board.h>
62 extern EMAC_MAC_ADDR_T macAddr1;
63 extern EMAC_OPEN_CONFIG_INFO_T open_cfg;
64 extern uint32_t linkStatus;
65 extern void Osal_enterSingleCoreCriticalSection(Uint32      port_num);
66 extern void Osal_exitSingleCoreCriticalSection(Uint32      port_num);
68 extern void Osal_beginMemAccess(void*   addr, Uint32  size);
69 extern void Osal_endMemAccess(void*   addr, Uint32  size);
70 /**********************************************************************
71  ************************** Global Variables **************************
72  **********************************************************************/
73 #ifdef _TMS320C6X
74 /* Memory allocated for the packet buffer. This is 128 bytes aligned. */
75 uint8_t   app_pkt_buffer[APP_TOTAL_PKTBUF_SIZE];
76 #pragma DATA_ALIGN(app_pkt_buffer, 64)
78 /* Memory allocated for the application control block */
79 #else
80 uint8_t   app_pkt_buffer[APP_TOTAL_PKTBUF_SIZE] __attribute__ ((aligned (64)));
81 #endif
83 APP_EMAC_MCB_T   app_mcb;
85 static uint32_t pkt_rcv_count = 0;
86 static uint32_t pkt_received = 0;
89 /**********************************************************************
90  ****************** Test Configuration Variables **********************
91  **********************************************************************/
92 #define PKT_SEND_COUNT  100
94 /* DO NOT CHANGE test_pkt UNLESS TEST_PKT_SIZE IS UPDATED */
95 #define TEST_PKT_SIZE       64
97 static const uint8_t test_pkt[64] = {
98     0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
99     0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
100     0x08, 0x06, 0x00, 0x01,
101     0x08, 0x00, 0x06, 0x04,
102     0x00,0x01,0x01, 0xbb,
103     0xcc, 0xdd, 0xee, 0xff,
104     0xc0, 0xa8, 0x01, 0x16,
105     0x00, 0x00, 0x00, 0x00,
106     0xc0, 0xa8,0x01, 0x02,
107     0x01,0x02,0x03,0x04,
108     0x01,0x02,0x03,0x04,
109     0x01,0x02,0x03,0x04,
110     0x01,0x02,0x03,0x04,
111     0x01,0x02,0x03,0x04,
112     0xfe,0xfe, 0x00, 0x00
113 };
115 /**********************************************************************
116  ************************ EMAC TEST FUNCTIONS *************************
117  **********************************************************************/
119 /**
120  *  @b app_queue_pop
121  *  @n
122  *      Dequeues a packet descriptor from an app queue.
123  *
124  *  @param[in]  pq
125  *      Packet queue of type APP_PKT_QUEUE_T .
126  *
127  *  @retval
128  *      EMAC_Pkt popped from the queue.
129  */
130 EMAC_PKT_DESC_T*
131 app_queue_pop
133     Uint32              port_num,
134     APP_PKT_QUEUE_T*    pq
137     EMAC_PKT_DESC_T*    pPktHdr;
139     if (!pq->Count)
140     {
141         return 0;
142     }
144     Osal_enterSingleCoreCriticalSection(port_num);
145     pPktHdr = pq->pHead;
146     if( pPktHdr )
147     {
148         pq->pHead = pPktHdr->pNext;
149         pq->Count--;
150         pPktHdr->pPrev = pPktHdr->pNext = 0;
151     }
152     Osal_exitSingleCoreCriticalSection(port_num);
154     return( pPktHdr );
157 /**
158  *  @b app_queue_push
159  *  @n
160  *      Enqueues a packet in EMAC_Pkt queue.
161  *
162  *  @param[in]  pq
163  *      Packet queue of type EMAC_PKT_QUEUE_T .
164  *  @param[in]  pPktHdr
165  *      EMAC_PKT_DESC_T type packet to push.
166  *
167  *  @retval
168  *      void
169  */
170 void
171 app_queue_push
173     Uint32              port_num,
174     APP_PKT_QUEUE_T*    pq,
175     EMAC_PKT_DESC_T*    pPktHdr
178         Osal_enterSingleCoreCriticalSection(port_num);
179     pPktHdr->pNext = 0;
181     if( !pq->pHead )
182     {
183         /* Queue is empty - Initialize it with this one packet */
184         pq->pHead = pPktHdr;
185         pq->pTail = pPktHdr;
186     }
187     else
188     {
189         /* Queue is not empty - Push onto end */
190         pq->pTail->pNext = pPktHdr;
191         pq->pTail        = pPktHdr;
192     }
193     pq->Count++;
194     Osal_exitSingleCoreCriticalSection(port_num);
198 uint32_t allocFailed = 0;
199 #ifndef EMAC_TEST_ALLOC_FAIL
200 /**
201  *  @b Description
202  *  @n
203  *      Call back function provided by application for EMAC driver
204  *      to allocate a packet descriptor.
205  *
206  *  @retval
207  *      pointer to the allocated packet descriptor.
208  */
209  EMAC_PKT_DESC_T*
210 app_alloc_pkt
212     Uint32              port_num,
213     Uint32              pkt_size
216     EMAC_PKT_DESC_T*    p_pkt_desc = NULL;
217     if (pkt_size < APP_EMAC_MAX_PKT_SIZE)
218     {
219         /* Get a packet descriptor from the free queue */
220         p_pkt_desc              = app_queue_pop(port_num, &app_mcb.emac_pcb[port_num].freeQueue);
221         p_pkt_desc->AppPrivate  = (Uint32)p_pkt_desc;
222         p_pkt_desc->BufferLen   = APP_EMAC_MAX_PKT_SIZE;
223         p_pkt_desc->DataOffset  = 0;
224         p_pkt_desc->pPrev = NULL;
225         p_pkt_desc->pNext = NULL;
226     }
227     else
228     {
229         UART_printf ("app_alloc_pkt on port %d failed, packet size %d is too big\n", port_num, pkt_size);
230         return NULL;
231     }
232     return p_pkt_desc;
234 #else
235 /**
236  *  @b Description
237  *  @n
238  *      Call back function provided by application for EMAC driver
239  *      to allocate a packet descriptor.
240  *
241  *  @retval
242  *      pointer to the allocated packet descriptor.
243  */
244  EMAC_PKT_DESC_T*
245 app_alloc_pkt
247     Uint32              port_num,
248     Uint32              pkt_size
251     EMAC_PKT_DESC_T*    p_pkt_desc = NULL;
252     static uint32_t allocFailCount = 0;
253     static uint32_t entryCount = 0;
255     /* testing pkt allocation failure for idkAM437x */
256     if (entryCount++ > 64)
257     {
258         if ((++allocFailCount % 50) == 0 )
259         {
260             allocFailed++;
261             return NULL;
262         }
263     }
265     if (pkt_size < APP_EMAC_MAX_PKT_SIZE)
266     {
267         /* Get a packet descriptor from the free queue */
268         p_pkt_desc              = app_queue_pop(port_num, &app_mcb.emac_pcb[port_num].freeQueue);
269         p_pkt_desc->AppPrivate  = (Uint32)p_pkt_desc;
270         p_pkt_desc->BufferLen   = APP_EMAC_MAX_PKT_SIZE;
271         p_pkt_desc->DataOffset  = 0;
272         p_pkt_desc->pPrev = NULL;
273         p_pkt_desc->pNext = NULL;
274     }
275     else
276     {
277         UART_printf ("app_alloc_pkt on port %d failed, packet size %d is too big\n", port_num, pkt_size);
278         return NULL;
279     }
280     return p_pkt_desc;
282 #endif
283 /**
284  *  @b Description
285  *  @n
286  *      Call back function provided by application for EMAC driver
287  *      to free a packet descriptor.
288  *
289  *  @retval
290  *      None.
291  */
292 void
293 app_free_pkt
295     Uint32              port_num,
296     EMAC_PKT_DESC_T*    p_pkt_desc
299     /* Free a packet descriptor to the free queue */
300     app_queue_push(port_num, &app_mcb.emac_pcb[port_num].freeQueue,
301                    (EMAC_PKT_DESC_T *)p_pkt_desc->AppPrivate);
305 /**
306 *  @b Description
307 *  @n
308 *      Intialize the application control block, free/rx packet queue.
310 *  @retval
311 *      None.
312 */
313 void
314 app_init(void)
316     Uint32              i, j;
317     EMAC_PKT_DESC_T*    p_pkt_desc;
318     Uint8*              pktbuf_ptr;
320     UART_printf ("EMAC loopback test application initialization\n");
322     /* Reset application control block */
323     memset(&app_mcb, 0, sizeof (APP_EMAC_MCB_T));
325 #ifdef _TMS320C6X
326     app_mcb.core_num = CSL_chipReadReg (CSL_CHIP_DNUM);
327 #else
328     app_mcb.core_num = 0;
329 #endif
330     pktbuf_ptr = (Uint8 *) ((Uint32) app_pkt_buffer);
332     /* Initialize the free packet queue */
333     for (i=0; i<MAX_NUM_EMAC_PORTS; i++)
334     {
336         for (j=0; j<APP_MAX_PKTS; j++)
337         {
338             p_pkt_desc               = &app_mcb.emac_pcb[i].pkt_desc[j];
339             p_pkt_desc->pDataBuffer  = pktbuf_ptr;
340             p_pkt_desc->BufferLen    = APP_EMAC_MAX_PKT_SIZE;
341             app_queue_push( i, &app_mcb.emac_pcb[i].freeQueue, p_pkt_desc );
342             pktbuf_ptr += APP_EMAC_MAX_PKT_SIZE;
343         }
344     }
348 /******************************************************************************
349  * Function: EMAC RX packet call back function
350  ******************************************************************************/
351 /**
352  *  @brief  This function is used to call back the network application when a
353  *          packet is received.
354  */
355 void app_test_rx_pkt_cb(Uint32               port_num, EMAC_PKT_DESC_T*     p_desc)
357     EMAC_STATISTICS_T stats;
358     pkt_rcv_count++;
359     if (memcmp(p_desc->pDataBuffer, &test_pkt[0], TEST_PKT_SIZE) == 0)
360     {
361         if (pkt_rcv_count <=PKT_SEND_COUNT)
362          UART_printf("received packet: %d\n", pkt_rcv_count);
364         if ((pkt_rcv_count + allocFailed) ==  PKT_SEND_COUNT)
365         {
366 #ifdef EMAC_TEST_ALLOC_FAIL
367             UART_printf("Test case to validate burst packet RX at host which could could result in buffer allocation failure\n");
368             UART_printf("Expected alloc failed to be >0 in logs\n");
369 #endif
370             UART_printf("packet received; %d, alloc failed: %d\n", pkt_rcv_count, allocFailed);
371             UART_printStatus("All tests have passed\n");
372             memset(&stats, 0, sizeof(EMAC_STATISTICS_T));
373             emac_get_statistics(0,&stats);
374             UART_printf("stats: rx: 0x%d, tx: 0x%d, RxOctets: %d\n", stats.RxGoodFrames, stats.TxGoodFrames, stats.RxOctets);
375             emac_close(0);
376         }
377     }
378     else
379     {
380         if ((pkt_rcv_count  + allocFailed) <=PKT_SEND_COUNT)
381             UART_printStatus("packet match failed\n");
382     }
383     if (p_desc->AppPrivate != NULL)
384         app_free_pkt(port_num,  (EMAC_PKT_DESC_T*) p_desc->AppPrivate);
385     pkt_received = 1;
388 void app_test_task_poll_pkt (UArg arg0, UArg arg1)
390     while(linkStatus == 0)
391     {
392         Task_sleep(100);
393     }
394     while(1)
395     {
396         emac_poll_pkt(0);
397          Task_sleep(10);
398     }
402 #if defined (SOC_AM571x)  || defined (SOC_DRA72x)| defined (SOC_DRA75x) || defined (SOC_DRA78x)
404 void app_test_task_send_pkts(UArg arg0, UArg arg1)
406     uint32_t i;
407     uint32_t port_num = 0;
408     int32_t fail_count = 0;
409     EMAC_PKT_DESC_T *p_pkt_desc;
410     EMAC_DRV_ERR_E ret;
412     while(linkStatus == 0)
413     {
414         Task_sleep(1000);
415     }
416     for (i = 0; i < PKT_SEND_COUNT/2; i++)
417     {
418         p_pkt_desc = app_alloc_pkt(0, TEST_PKT_SIZE);
419         memcpy (p_pkt_desc->pDataBuffer, &test_pkt[0], TEST_PKT_SIZE);
420         p_pkt_desc->AppPrivate = (uint32_t)p_pkt_desc;
421         p_pkt_desc->Flags        = EMAC_PKT_FLAG_SOP | EMAC_PKT_FLAG_EOP;
422         p_pkt_desc->ValidLen     = TEST_PKT_SIZE;
423         p_pkt_desc->DataOffset   = 0;
425         p_pkt_desc->PktLength    = TEST_PKT_SIZE;
426         p_pkt_desc->PktFrags     = 1;
427         p_pkt_desc->pNext = NULL;
428         p_pkt_desc->pPrev = NULL;
429         p_pkt_desc->PktChannel     = 0;
430         p_pkt_desc->PktLength      = TEST_PKT_SIZE;
432         UART_printf("sending packet: %d\n", i+1);
433         emac_send(port_num, p_pkt_desc);
435         while(pkt_received == 0)
436         {
437            Task_sleep(100);
438             fail_count++;
439             if(fail_count == 5)
440             {
441                 fail_count = 0;
442                 break;
443             }
444         }
445        
446         pkt_received = 0;
447     }
449       if ((ret = emac_close(0)) == EMAC_DRV_RESULT_OPEN_PORT_ERR)
450      {
451          UART_printf("main: emac_close failure: %d\n", ret);
452      }
453      else
454          UART_printf("main: emac_close sucess\n");
456      if ((ret = emac_open(0, &open_cfg)) == EMAC_DRV_RESULT_OPEN_PORT_ERR)
457     {
458         UART_printf("main: emac_open failure: %d\n", ret);
459     }
460     else
461         UART_printf("main: emac_open1 sucess\n");
463    Task_sleep(50);
466     while(linkStatus == 0)
467     {
468         Task_sleep(100);
469     }
471     for (i = 0; i < PKT_SEND_COUNT/2; i++)
472     {
473         p_pkt_desc = app_alloc_pkt(0, TEST_PKT_SIZE);
474         memcpy (p_pkt_desc->pDataBuffer, &test_pkt[0], TEST_PKT_SIZE);
475         p_pkt_desc->AppPrivate = (uint32_t)p_pkt_desc;
476         p_pkt_desc->Flags        = EMAC_PKT_FLAG_SOP | EMAC_PKT_FLAG_EOP;
477         p_pkt_desc->ValidLen     = TEST_PKT_SIZE;
478         p_pkt_desc->DataOffset   = 0;
480         p_pkt_desc->PktLength    = TEST_PKT_SIZE;
481         p_pkt_desc->PktFrags     = 1;
482         p_pkt_desc->pNext = NULL;
483         p_pkt_desc->pPrev = NULL;
484         p_pkt_desc->PktChannel     = 0;
485         p_pkt_desc->PktLength      = TEST_PKT_SIZE;
487         UART_printf("sending packet: %d\n", i+1);
488         emac_send(port_num, p_pkt_desc);
489                 while(pkt_received == 0)
490                 {
491                     Task_sleep(100);
492                      fail_count++;
493                      if(fail_count == 5)
494                      {
495                          fail_count = 0;
496                          break;
497                      }
498                 
499                 }
500          
501         pkt_received = 0;
502     }
504 #else
505 void app_test_task_send_pkts(UArg arg0, UArg arg1)
507     uint32_t i;
508     uint32_t port_num = 0;
509     static uint32_t pkt_send_count =0;
510     uint32_t fail_count = 0;
511     EMAC_PKT_DESC_T *p_pkt_desc;
512     while(linkStatus == 0)
513     {
514         Task_sleep(1000);
515     }
516     Task_sleep(1000);
517     for (i = 0; i < PKT_SEND_COUNT; i++)
518     {
519         p_pkt_desc = app_alloc_pkt(0, TEST_PKT_SIZE);
520         /* app_alloc_pkt can return NULL because of logic added test allocation failure when app_alloc_pkt is called from the driver to replenish
521            packet descriptor during packet receive, just alloc again and it will pass */
522         if (p_pkt_desc == NULL)
523         {
524             p_pkt_desc = app_alloc_pkt(0, TEST_PKT_SIZE);
525         }
526         memcpy (p_pkt_desc->pDataBuffer, &test_pkt[0], TEST_PKT_SIZE);
527         p_pkt_desc->AppPrivate = (uint32_t)p_pkt_desc;
528         p_pkt_desc->Flags        = EMAC_PKT_FLAG_SOP | EMAC_PKT_FLAG_EOP;
529         p_pkt_desc->ValidLen     = TEST_PKT_SIZE;
530         p_pkt_desc->DataOffset   = 0;
532         p_pkt_desc->PktLength    = TEST_PKT_SIZE;
533         p_pkt_desc->PktFrags     = 1;
534         p_pkt_desc->pNext = NULL;
535         p_pkt_desc->pPrev = NULL;
536         p_pkt_desc->PktChannel     = 0;
537         p_pkt_desc->PktLength      = TEST_PKT_SIZE;
539         
540         emac_send(port_num, p_pkt_desc);
542         fail_count = 0;
543         while(pkt_received == 0)
544         {
545             Task_sleep(100);
546              fail_count++;
547              if(fail_count == 5)
548              {
549                  fail_count = 0;
550                  break;
551              }
552         }
553         pkt_received = 0;
554         pkt_send_count++;
555     }
558 #endif
560 /*
561  *  ======== Delay function ========
562  */
563 void app_delay(int32_t delayValue)
565     volatile int32_t delay = delayValue*100;
566     while (delay--);