updating the size of tx and rx frames inside memset
[processor-sdk/pdk.git] / packages / ti / board / diag / enet_icssg / src / enet_icssg_test.c
1 /*
2  *  Copyright (c) Texas Instruments Incorporated 2021
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  */
33  /*!
34  * \file  enet_icssg_test.c
35  *
36  * \brief This file contains the implementation of the Enet lld with icssg example.
37  */
39 /* ========================================================================== */
40 /*                             Include Files                                  */
41 /* ========================================================================== */
43 #include "enet_icssg_test.h"
45 /* ========================================================================== */
46 /*                           Macros & Typedefs                                */
47 /* ========================================================================== */
50 /* ========================================================================== */
51 /*                         Structure Declarations                             */
52 /* ========================================================================== */
55 /* ========================================================================== */
56 /*                          Function Declarations                             */
57 /* ========================================================================== */
59 static int32_t EnetIg_init(void);
61 static void EnetIg_deinit(void);
63 static int32_t EnetIg_open(EnetIg_PerCtxt *perCtxts,
64                            uint32_t numPerCtxts);
66 static void EnetIg_close(EnetIg_PerCtxt *perCtxts,
67                          uint32_t numPerCtxts);
69 static int32_t EnetIg_openPort(EnetIg_PerCtxt *perCtxt);
71 static void EnetIg_closePort(EnetIg_PerCtxt *perCtxt);
73 static void EnetIg_printStats(EnetIg_PerCtxt *perCtxts,
74                               uint32_t numPerCtxts);
76 static void EnetIg_resetStats(EnetIg_PerCtxt *perCtxts, uint32_t numPerCtxts);
78 static int32_t EnetIg_waitForLinkUp(EnetIg_PerCtxt *perCtxt);
80 static void EnetIg_macMode2MacMii(emac_mode macMode,
81                                   EnetMacPort_Interface *mii);
83 static int32_t EnetIg_openDma(EnetIg_PerCtxt *perCtxt);
85 static void EnetIg_closeDma(EnetIg_PerCtxt *perCtxt);
87 static void EnetIg_initTxFreePktQ(void);
89 static void EnetIg_initRxReadyPktQ(EnetDma_RxChHandle hRxCh);
91 static uint32_t EnetIg_retrieveFreeTxPkts(EnetIg_PerCtxt *perCtxt);
93 static uint32_t BoardDiag_EnetIg_LpbkTxRx(void);
95 static uint32_t BoardDiag_EnetIg_Receive(EnetIg_PerCtxt *perCtxt);
97 static void BoardDiag_EnetIg_txIsrFxn(void *appData);
99 static void BoardDiag_EnetIg_rxIsrFxn(void *appData);
101 static int32_t BoardDiag_EnetIg_LpbckTest(EnetIg_PerCtxt *perCtxt, uint32_t numPerCtxts);
103 static void BoardDiag_printFrame(EthFrame *frame, uint32_t len);
105 static void BoardDiag_printMacAddr(uint8_t macAddr[]);
107 static uint32_t BoardDiag_EnetIg_Transmit(EnetIg_PerCtxt *txPerCtxt, EnetIg_PerCtxt *rxPerCtxt);
109 static void EnetIg_PortSelect(void);
111 /* ========================================================================== */
112 /*                            Global Variables                                */
113 /* ========================================================================== */
115 /* Enet Icssg Test Object */
116 EnetIg_Obj gEnetIg;
118 /* Statistics */
119 IcssgStats_MacPort gEnetIg_icssgStats;
120 IcssgStats_Pa gEnetIg_icssgPaStats;
122 bool printFrameEnable = false;
123 bool printStatsEnable = false;
125 static uint32_t gEnetLpbk_IterationCount;
127 /* Use this array to select the ports that will be used in the test */
128 const EnetIg_TestParams testParams[ENETIG_ICSSG_MAX_PORTS] =
130     /* ICSSG0 mode: DUALMAC */
131     { ENET_ICSSG_DUALMAC, 0U, { ENET_MAC_PORT_1 },                  1U, "icssg0-p1", },
132     { ENET_ICSSG_DUALMAC, 1U, { ENET_MAC_PORT_1 },                  1U, "icssg0-p2", },
133     /* ICSSG1 mode: DUALMAC */
134     { ENET_ICSSG_DUALMAC, 2U, { ENET_MAC_PORT_1 },                  1U, "icssg1-p1", },
135     { ENET_ICSSG_DUALMAC, 3U, { ENET_MAC_PORT_1 },                  1U, "icssg1-p2", },
136     /* ICSSG2 mode: DUALMAC */
137     { ENET_ICSSG_DUALMAC, 4U, { ENET_MAC_PORT_1 },                  1U, "icssg2-p1", },
138     { ENET_ICSSG_DUALMAC, 5U, { ENET_MAC_PORT_1 },                  1U, "icssg2-p2", },
139 };
141 /* ========================================================================== */
142 /*                          Function Definitions                              */
143 /* ========================================================================== */
145 int main(void)
147     int32_t status;
149     /* Board level initialization, UART might not be setup before this hence no prints yet */
150     status = EnetBoard_init();
151     if(status != ENET_SOK)
152     {
153         EnetAppUtils_print("\nBoard init failed with status: %d\n", status);
154         return status;
155     }
157     EnetIg_PortSelect();
159     for (gEnetIg.loopCnt = 0U; gEnetIg.loopCnt < gEnetLpbk_IterationCount; gEnetIg.loopCnt++)
160     {
161         EnetAppUtils_print("\n\n*******Iteration %d********\n", gEnetIg.loopCnt + 1);
163         /* Init driver */
164         status = EnetIg_init();
165         if (status != ENET_SOK)
166         {
167             EnetAppUtils_print("\nInitialization failed: %d\n", status);
168             return status;
169         }
171         /* Open all peripherals */
172         if (status == ENET_SOK)
173         {
174             status = EnetIg_open(gEnetIg.perCtxt, gEnetIg.numPerCtxts);
175             if (status != ENET_SOK)
176             {
177                 EnetAppUtils_print("\nFailed to open peripherals: %d\n", status);
178             }
179         }
181         if (status == ENET_SOK)
182         {
183             status = BoardDiag_EnetIg_LpbckTest(gEnetIg.perCtxt, gEnetIg.numPerCtxts);
184         }
186         if(status == ENET_SOK)
187         {
188             EnetAppUtils_print("\n\nTest Passed");
189         }
190         else
191         {
192             EnetAppUtils_print("\n\nTest Failed");
193         }
195         /* Close all peripherals */
196         EnetIg_close(gEnetIg.perCtxt, gEnetIg.numPerCtxts);
198         /* Deinit driver */
199         EnetIg_deinit();
200     }
202     /* Board level deinitialization */
203     EnetBoard_deinit();
205     return 0;
208 static void EnetIg_PortSelect(void)
210     uint8_t i;
211     uint8_t j;
212     uint8_t port[ENETIG_ICSSG_INSTANCE_MAX] = {0};
214 #if defined(am65xx_evm)
215     /* Select port 4 and port 5 */
216     port[0] = 4;
217     port[1] = 5;
218 #elif defined(am65xx_idk)
219     /* Can change this to 0 and 1, 4 and 5 for IDK */
220     /* Select port 2 and port 3 */
221     port[0] = 2;
222     port[1] = 3;
223 #else
224     EnetAppUtils_print("\nBoard not supported for this test");
225 #endif
227     /* Initialize test config */
228     memset(&gEnetIg, 0, sizeof(gEnetIg));
230     gEnetIg.numPerCtxts = ENETIG_ICSSG_INSTANCE_MAX;
232     for(i = 0; i < gEnetIg.numPerCtxts; i++)
233     {
234         gEnetIg.perCtxt[i].enetType = testParams[port[i]].enetType;
235         gEnetIg.perCtxt[i].instId   = testParams[port[i]].instId;
236         gEnetIg.perCtxt[i].name     = testParams[port[i]].name;
238         gEnetIg.perCtxt[i].macPortNum = testParams[port[i]].macPortNum;
239         for (j = 0; j < gEnetIg.perCtxt[port[i]].macPortNum; j++)
240         {
241             gEnetIg.perCtxt[i].macPort[j]  = testParams[port[i]].macPort[j];
242         }
243     }
244     EnetAppUtils_print("\nEnter number of iterations to test:");
245     gEnetLpbk_IterationCount = (uint32_t)EnetAppUtils_getNum();
248 static int32_t EnetIg_init(void)
250     EnetOsal_Cfg osalCfg;
251     EnetUtils_Cfg utilsCfg;
252     int32_t status = ENET_SOK;
254     /* Initialize Enet driver (use default OSAL and utils) */
255     EnetAppUtils_print("\nInit Enet's OSAL and utils to use defaults");
256     Enet_initOsalCfg(&osalCfg);
257     Enet_initUtilsCfg(&utilsCfg);
258     Enet_init(&osalCfg, &utilsCfg);
260     gEnetIg.coreId = EnetSoc_getCoreId();
262     /* Initialize memory */
263     EnetAppUtils_print("\nInit memory utils");
264     status = EnetMem_init();
265     if (status != ENET_SOK)
266     {
267         EnetAppUtils_print("\nFailed to initialize memory utils: %d\n", status);
268         EnetAppUtils_assert(false);
269     }
271     /* Initialize all queues */
272     EnetQueue_initQ(&gEnetIg.txFreePktInfoQ);
274     /* Open UDMA driver which is the same handle to be used for all peripherals */
275     if (status == ENET_SOK)
276     {
277         EnetAppUtils_print("\nOpen Main UDMA driver");
278         gEnetIg.hMainUdmaDrv = EnetAppUtils_udmaOpen(ENET_ICSSG_DUALMAC, NULL);
279         if (gEnetIg.hMainUdmaDrv == NULL)
280         {
281             EnetAppUtils_print("\nFailed to open Main UDMA driver: %d\n", status);
282             status = ENET_EALLOC;
283             EnetAppUtils_assert(false);
284         }
285     }
287     return status;
290 static void EnetIg_asyncIoctlCb(Enet_Event evt,
291                                 uint32_t evtNum,
292                                 void *evtCbArgs,
293                                 void *arg1,
294                                 void *arg2)
296     EnetIg_PerCtxt *perCtxt = (EnetIg_PerCtxt *)evtCbArgs;
298     EnetAppUtils_print("\n%s: Async IOCTL completed\n", perCtxt->name);
299     perCtxt->hAsyncIoctlSem = true;
302 static void EnetIg_txTsCb(Enet_Event evt,
303                           uint32_t evtNum,
304                           void *evtCbArgs,
305                           void *arg1,
306                           void *arg2)
308     EnetIg_PerCtxt *perCtxt = (EnetIg_PerCtxt *)evtCbArgs;
309     Icssg_TxTsEvtCbInfo *txTsInfo = (Icssg_TxTsEvtCbInfo *)arg1;
310     Enet_MacPort macPort = *(Enet_MacPort *)arg2;
311     uint32_t tsId = txTsInfo->txTsId;
312     uint64_t txTs = txTsInfo->ts;
313     uint64_t rxTs = perCtxt->rxTs[tsId % ENET_MEM_NUM_RX_PKTS];
314     uint64_t prevTs;
315     int64_t dt;
316     bool status = true;
318     dt = txTs - rxTs;
320     EnetAppUtils_print("\n%s: Port %u: RX-to-TX timestamp delta = %10lld (RX=%llu, TX=%llu)\n",
321                        perCtxt->name, ENET_MACPORT_ID(macPort), dt, rxTs, txTs);
323     /* Check correct timestamp delta */
324     if (dt < 0)
325     {
326         EnetAppUtils_print("\n%s: Port %u: ERROR: RX timestamp > TX timestamp: %llu > %llu\n",
327                            perCtxt->name, ENET_MACPORT_ID(macPort), rxTs, txTs);
328             status = false;
329     }
331     /* Check monotonicity of the TX and RX timestamps */
332     if (txTsInfo->txTsId > 0U)
333     {
334         prevTs = perCtxt->rxTs[(tsId - 1) % ENET_MEM_NUM_RX_PKTS];
335         if (prevTs > rxTs)
336         {
337             EnetAppUtils_print("\n%s: Port %u: ERROR: Non monotonic RX timestamp: %llu -> %llu\n",
338                                perCtxt->name, ENET_MACPORT_ID(macPort), prevTs, rxTs);
339             status = false;
340         }
342         prevTs = perCtxt->txTs[(tsId - 1) % ENET_MEM_NUM_RX_PKTS];
343         if (prevTs > txTs)
344         {
345             EnetAppUtils_print("\n%s: Port %u: ERROR: Non monotonic TX timestamp: %llu -> %llu\n",
346                                perCtxt->name, ENET_MACPORT_ID(macPort), prevTs, txTs);
347             status = false;
348         }
349     }
351     if (!status)
352     {
353         EnetAppUtils_print("\n");
354     }
356     /* Save current timestamp for future monotonicity checks */
357      perCtxt->txTs[txTsInfo->txTsId % ENET_MEM_NUM_RX_PKTS] = txTs;
359     perCtxt->hTxTsSem = true;
362 static void EnetIg_deinit(void)
364     /* Close UDMA driver if not closed */
365     EnetAppUtils_print("\nClose UDMA driver");
366     if(gEnetIg.hMainUdmaDrv != NULL)
367     {
368         EnetAppUtils_udmaclose(gEnetIg.hMainUdmaDrv);
369     }
371     if(gEnetIg.hMcuUdmaDrv != NULL)
372     {
373         EnetAppUtils_udmaclose(gEnetIg.hMcuUdmaDrv);
374     }
376     /* Deinitialize Enet driver (use default OSAL and utils) */
377     EnetAppUtils_print("\nDeinit Enet driver");
378     Enet_deinit();
380     /* Deinitialize memory */
381     EnetAppUtils_print("\nDeinit memory utils");
382     EnetMem_deInit();
384     EnetAppUtils_print("\nDeinit complete");
387 static int32_t EnetIg_open(EnetIg_PerCtxt *perCtxts,
388                            uint32_t numPerCtxts)
390     EnetUdma_Cfg *dmaCfg;
391     EnetRm_ResCfg *resCfg;
392     Enet_IoctlPrms prms;
393     EnetPer_AttachCoreOutArgs attachCoreOutArgs;
395     uint32_t i;
396     uint32_t j;
397     int32_t status = ENET_SOK;
399     /* Do peripheral dependent initalization */
400     EnetAppUtils_print("\nInit all peripheral clocks");
401     EnetAppUtils_print("\n----------------------------------------------\n");
402     for (i = 0U; i < numPerCtxts; i++)
403     {
404         EnetIg_PerCtxt *perCtxt = &perCtxts[i];
405         EnetAppUtils_enableClocks(perCtxt->enetType, perCtxt->instId);
407         /*Initialize aync IOCTL and TX timestamp flags*/
408         perCtxt->hAsyncIoctlSem = false;
409         perCtxt->hTxTsSem = false;
410     }
412     /* Prepare init configuration for all peripherals */
413     EnetAppUtils_print("\nInit all configs");
414     EnetAppUtils_print("\n----------------------------------------------");
415     for (i = 0U; i < numPerCtxts; i++)
416     {
417         EnetIg_PerCtxt *perCtxt = &perCtxts[i];
419         dmaCfg = &perCtxt->dmaCfg;
420         dmaCfg->rxChInitPrms.dmaPriority = UDMA_DEFAULT_RX_CH_DMA_PRIORITY;
422         EnetAppUtils_print("\n%s: init config", perCtxt->name);
424         Icssg_Cfg *icssgCfg = &perCtxt->icssgCfg;
426         Enet_initCfg(perCtxt->enetType, perCtxt->instId, icssgCfg, sizeof(*icssgCfg));
427         resCfg = &icssgCfg->resCfg;
429         /* Set DMA configuration */
430         dmaCfg->hUdmaDrv = gEnetIg.hMainUdmaDrv;
431         icssgCfg->dmaCfg = (void *)dmaCfg;
433         /* Initialize RM */
434         EnetAppUtils_initResourceConfig(perCtxt->enetType, EnetSoc_getCoreId(), resCfg);
436         /* We use software MAC address pool from apputils, but it will give same MAC address.
437          * Add port index to make them unique */
438         for (j = 0U; j < ENETIG_PORT_MAX; j++)
439         {
440             resCfg->macList.macAddress[j][ENET_MAC_ADDR_LEN - 1] += (i * ENETIG_PORT_MAX) + j;
441         }
442         resCfg->macList.numMacAddress = ENETIG_PORT_MAX;
443     }
445     /* Open Enet driver for all peripherals */
446     EnetAppUtils_print("\n\nOpen all peripherals");
447     EnetAppUtils_print("\n----------------------------------------------");
448     for (i = 0U; i < numPerCtxts; i++)
449     {
450         EnetIg_PerCtxt *perCtxt = &perCtxts[i];
451         EnetAppUtils_print("\n%s: Open enet", perCtxt->name);
453         Icssg_Cfg *icssgCfg = &perCtxt->icssgCfg;
454         perCtxt->hEnet = Enet_open(perCtxt->enetType, perCtxt->instId, icssgCfg, sizeof(*icssgCfg));
456         if (perCtxt->hEnet == NULL)
457         {
458             EnetAppUtils_print("\n%s: failed to open enet\n", perCtxt->name);
459             status = ENET_EFAIL;
460             break;
461         }
463         if (Enet_isIcssFamily(perCtxt->enetType))
464         {
465             EnetAppUtils_print("\n%s: Register async IOCTL callback", perCtxt->name);
466             Enet_registerEventCb(perCtxt->hEnet,
467                                 ENET_EVT_ASYNC_CMD_RESP,
468                                 0U,
469                                 EnetIg_asyncIoctlCb,
470                                 (void *)perCtxt);
472             EnetAppUtils_print("\n%s: Register TX timestamp callback", perCtxt->name);
473             perCtxt->txTsSeqId = 0U;
474             Enet_registerEventCb(perCtxt->hEnet,
475                                 ENET_EVT_TIMESTAMP_TX,
476                                 0U,
477                                 EnetIg_txTsCb,
478                                 (void *)perCtxt);
479         }
480     }
482     /* Attach the core with RM */
483     if (status == ENET_SOK)
484     {
485         EnetAppUtils_print("\n\nAttach core id %u on all peripherals", gEnetIg.coreId);
486         EnetAppUtils_print("\n----------------------------------------------");
487         for (i = 0U; i < numPerCtxts; i++)
488         {
489             EnetIg_PerCtxt *perCtxt = &perCtxts[i];
491             EnetAppUtils_print("\n%s: Attach core", perCtxt->name);
493             ENET_IOCTL_SET_INOUT_ARGS(&prms, &gEnetIg.coreId, &attachCoreOutArgs);
495             status = Enet_ioctl(perCtxt->hEnet, gEnetIg.coreId, ENET_PER_IOCTL_ATTACH_CORE, &prms);
496             if (status != ENET_SOK)
497             {
498                 EnetAppUtils_print("\n%s: failed to attach: %d", perCtxt->name, status);
499             }
500             else
501             {
502                 gEnetIg.coreKey = attachCoreOutArgs.coreKey;
503             }
504         }
505     }
507     return status;
510 static void EnetIg_close(EnetIg_PerCtxt *perCtxts,
511                          uint32_t numPerCtxts)
513     Enet_IoctlPrms prms;
514     uint32_t i;
515     int32_t status;
517     EnetAppUtils_print("\n\nClose DMA for all peripherals");
518     EnetAppUtils_print("\n----------------------------------------------");
519     for (i = 0U; i < numPerCtxts; i++)
520     {
521         EnetIg_PerCtxt *perCtxt = &perCtxts[i];
523         EnetAppUtils_print("\n%s: Close DMA", perCtxt->name);
525         EnetIg_closePort(perCtxt);
526         EnetIg_closeDma(perCtxt);
527     }
529     /* Detach core */
530     EnetAppUtils_print("\nDetach core from all peripherals");
531     EnetAppUtils_print("\n----------------------------------------------");
532     for (i = 0U; i < numPerCtxts; i++)
533     {
534         EnetIg_PerCtxt *perCtxt = &perCtxts[i];
536         EnetAppUtils_print("\n%s: Detach core", perCtxt->name);
538         ENET_IOCTL_SET_IN_ARGS(&prms, &gEnetIg.coreKey);
539         status = Enet_ioctl(perCtxt->hEnet, gEnetIg.coreId, ENET_PER_IOCTL_DETACH_CORE, &prms);
540         if (status != ENET_SOK)
541         {
542             EnetAppUtils_print("\n%s: Failed to detach: %d\n", perCtxt->name);
543         }
544     }
546     /* Close opened Enet drivers if any peripheral failed */
547     EnetAppUtils_print("\n\nClose all peripherals");
548     EnetAppUtils_print("\n----------------------------------------------");
549     for (i = 0U; i < numPerCtxts; i++)
550     {
551         EnetIg_PerCtxt *perCtxt = &perCtxts[i];
553         EnetAppUtils_print("\n%s: Close enet", perCtxt->name);
555         if (Enet_isIcssFamily(perCtxt->enetType))
556         {
557             EnetAppUtils_print("\n%s: Unregister async IOCTL callback", perCtxt->name);
558             Enet_unregisterEventCb(perCtxt->hEnet,
559                                    ENET_EVT_ASYNC_CMD_RESP,
560                                    0U);
562             EnetAppUtils_print("\n%s: Unregister TX timestamp callback", perCtxt->name);
563             Enet_unregisterEventCb(perCtxt->hEnet,
564                                    ENET_EVT_TIMESTAMP_TX,
565                                    0U);
566         }
568         Enet_close(perCtxt->hEnet);
569         perCtxt->hEnet = NULL;
570     }
572     /* Do peripheral dependent initalization */
573     EnetAppUtils_print("\n\nDeinit all peripheral clocks");
574     EnetAppUtils_print("\n----------------------------------------------\n");
575     for (i = 0U; i < numPerCtxts; i++)
576     {
577         EnetIg_PerCtxt *perCtxt = &perCtxts[i];
578         EnetAppUtils_disableClocks(perCtxt->enetType, perCtxt->instId);
579     }
581     /* Delete the semaphores */
582     EnetAppUtils_print("\nDeleting all the semaphores");
583     for (i = 0U; i < numPerCtxts; i++)
584     {
585         EnetIg_PerCtxt *perCtxt = &perCtxts[i];
586         if(perCtxt->hRxSem != NULL)
587         {
588             SemaphoreP_delete(perCtxt->hRxSem);
589         }
591         if(perCtxt->hTxSem != NULL)
592         {
593             SemaphoreP_delete(perCtxt->hTxSem);
594         }
595     }
598 static void EnetIg_printStats(EnetIg_PerCtxt *perCtxts,
599                               uint32_t numPerCtxts)
601     Enet_IoctlPrms prms;
602     Enet_MacPort macPort;
603     uint32_t i;
604     uint32_t j;
605     int32_t status;
607     EnetAppUtils_print("\nPrint statistics\n");
608     EnetAppUtils_print("----------------------------------------------\n");
609     for (i = 0U; i < numPerCtxts; i++)
610     {
611         EnetIg_PerCtxt *perCtxt = &gEnetIg.perCtxt[i];
613         if (Enet_isIcssFamily(perCtxt->enetType))
614         {
615             EnetAppUtils_print("\n%s - PA statistics\n", perCtxt->name);
616             EnetAppUtils_print("--------------------------------\n");
617             ENET_IOCTL_SET_OUT_ARGS(&prms, &gEnetIg_icssgPaStats);
618             status = Enet_ioctl(perCtxt->hEnet, gEnetIg.coreId, ENET_STATS_IOCTL_GET_HOSTPORT_STATS, &prms);
619             if (status != ENET_SOK)
620             {
621                 EnetAppUtils_print("\n%s: Failed to get PA stats\n", perCtxt->name);
622             }
624             EnetAppUtils_printIcssgPaStats(&gEnetIg_icssgPaStats);
625             EnetAppUtils_print("\n");
626         }
628         for (j = 0U; j < perCtxt->macPortNum; j++)
629         {
630             macPort = perCtxt->macPort[j];
632             EnetAppUtils_print("\n%s - Port %u statistics\n", perCtxt->name, ENET_MACPORT_ID(macPort));
633             EnetAppUtils_print("--------------------------------\n");
635             ENET_IOCTL_SET_INOUT_ARGS(&prms, &macPort, &gEnetIg_icssgStats);
637             status = Enet_ioctl(perCtxt->hEnet, gEnetIg.coreId, ENET_STATS_IOCTL_GET_MACPORT_STATS, &prms);
638             if (status != ENET_SOK)
639             {
640                 EnetAppUtils_print("\n%s: Failed to get port %u stats\n", perCtxt->name, ENET_MACPORT_ID(macPort));
641                 continue;
642             }
644             EnetAppUtils_printIcssgMacPortStats(&gEnetIg_icssgStats, false);
645             EnetAppUtils_print("\n");
646         }
647     }
650 static void EnetIg_resetStats(EnetIg_PerCtxt *perCtxts,
651                               uint32_t numPerCtxts)
653     Enet_IoctlPrms prms;
654     Enet_MacPort macPort;
655     uint32_t i;
656     uint32_t j;
657     int32_t status;
659     EnetAppUtils_print("\nReset statistics\n");
660     EnetAppUtils_print("----------------------------------------------\n");
661     for (i = 0U; i < numPerCtxts; i++)
662     {
663         EnetIg_PerCtxt *perCtxt = &gEnetIg.perCtxt[i];
665         EnetAppUtils_print("\n%s: Reset statistics", perCtxt->name);
667         for (j = 0U; j < perCtxt->macPortNum; j++)
668         {
669             macPort = perCtxt->macPort[j];
671             ENET_IOCTL_SET_IN_ARGS(&prms, &macPort);
672             status = Enet_ioctl(perCtxt->hEnet, gEnetIg.coreId, ENET_STATS_IOCTL_RESET_MACPORT_STATS, &prms);
673             if (status != ENET_SOK)
674             {
675                 EnetAppUtils_print("\n%s: Failed to reset port %u stats", perCtxt->name, ENET_MACPORT_ID(macPort));
676                 continue;
677             }
678         }
679     }
682 static int32_t EnetIg_openPort(EnetIg_PerCtxt *perCtxt)
684     Enet_IoctlPrms prms;
685     EnetBoard_EthPort ethPort;
686     const EnetBoard_PhyCfg *boardPhyCfg;
687     EnetPer_PortLinkCfg portLinkCfg;
689     IcssgMacPort_Cfg icssgMacCfg;
690     EnetMacPort_LinkCfg *linkCfg = &portLinkCfg.linkCfg;
691     EnetMacPort_Interface *mii = &portLinkCfg.mii;
692     EnetPhy_Cfg *phyCfg = &portLinkCfg.phyCfg;
693     Enet_MacPort macPort;
694     uint32_t i;
695     int32_t status = ENET_SOK;
697     EnetAppUtils_print("\n\nOpen ports");
698     EnetAppUtils_print("\n----------------------------------------------");
700     for (i = 0U; i < perCtxt->macPortNum; i++)
701     {
702         macPort = perCtxt->macPort[i];
704         EnetAppUtils_print("\n%s: Open port %u", perCtxt->name, ENET_MACPORT_ID(macPort));
706         /* Setup board for requested Ethernet port */
707         ethPort.enetType = perCtxt->enetType;
708         ethPort.instId   = perCtxt->instId;
709         ethPort.macPort  = macPort;
710         ethPort.boardId  = ENETBOARD_CPB_ID;
711         EnetIg_macMode2MacMii(RGMII, &ethPort.mii);
713         status = EnetBoard_setupPorts(&ethPort, 1U);
714         if (status != ENET_SOK)
715         {
716             EnetAppUtils_print("\n%s: Failed to setup MAC port %u\n", perCtxt->name, ENET_MACPORT_ID(macPort));
717             EnetAppUtils_assert(false);
718         }
720         IcssgMacPort_initCfg(&icssgMacCfg);
721         portLinkCfg.macCfg = &icssgMacCfg;
723         /* Set port link params */
724         portLinkCfg.macPort = macPort;
726         mii->layerType     = ethPort.mii.layerType;
727         mii->sublayerType  = ethPort.mii.sublayerType;
728         mii->variantType   = ENET_MAC_VARIANT_FORCED;
730         linkCfg->speed     = ENET_SPEED_AUTO;
731         linkCfg->duplexity = ENET_DUPLEX_AUTO;
733         boardPhyCfg = EnetBoard_getPhyCfg(&ethPort);
734         if (boardPhyCfg != NULL)
735         {
736             EnetPhy_initCfg(phyCfg);
737             phyCfg->phyAddr     = boardPhyCfg->phyAddr;
738             phyCfg->isStrapped  = boardPhyCfg->isStrapped;
739             phyCfg->loopbackEn  = false;
740             phyCfg->skipExtendedCfg = boardPhyCfg->skipExtendedCfg;
741             phyCfg->extendedCfgSize = boardPhyCfg->extendedCfgSize;
742             memcpy(phyCfg->extendedCfg, boardPhyCfg->extendedCfg, phyCfg->extendedCfgSize);
743         }
744         else
745         {
746             EnetAppUtils_print("%s: No PHY configuration found\n", perCtxt->name);
747             EnetAppUtils_assert(false);
748         }
750         /* Open port link */
751         if (status == ENET_SOK)
752         {
753             ENET_IOCTL_SET_IN_ARGS(&prms, &portLinkCfg);
755             EnetAppUtils_print("\n%s: Open port %u link", perCtxt->name, ENET_MACPORT_ID(macPort));
756             status = Enet_ioctl(perCtxt->hEnet, gEnetIg.coreId, ENET_PER_IOCTL_OPEN_PORT_LINK, &prms);
757             if (status != ENET_SOK)
758             {
759                 EnetAppUtils_print("\n%s: Failed to open port link: %d\n", perCtxt->name, status);
760             }
761         }
762     }
764     return status;
767 static void EnetIg_closePort(EnetIg_PerCtxt *perCtxt)
769     Enet_IoctlPrms prms;
770     Enet_MacPort macPort;
771     uint32_t i;
772     int32_t status;
774     for (i = 0U; i < perCtxt->macPortNum; i++)
775     {
776         macPort = perCtxt->macPort[i];
778         EnetAppUtils_print("\n%s: Close port %u", perCtxt->name, ENET_MACPORT_ID(macPort));
780         /* Close port link */
781         ENET_IOCTL_SET_IN_ARGS(&prms, &macPort);
783         EnetAppUtils_print("\n%s: Close port %u link", perCtxt->name, ENET_MACPORT_ID(macPort));
784         status = Enet_ioctl(perCtxt->hEnet, gEnetIg.coreId, ENET_PER_IOCTL_CLOSE_PORT_LINK, &prms);
785         if (status != ENET_SOK)
786         {
787             EnetAppUtils_print("\n%s: Failed to close port link: %d\n", perCtxt->name, status);
788         }
789     }
792 static int32_t EnetIg_waitForLinkUp(EnetIg_PerCtxt *perCtxt)
794     Enet_IoctlPrms prms;
795     Enet_MacPort macPort;
796     IcssgMacPort_SetPortStateInArgs setPortStateInArgs;
797     bool linked;
799     uint32_t i;
800     uint32_t linkCheckTime = 0;
801     int32_t status = ENET_SOK;
803     EnetAppUtils_print("\n%s: Waiting for link up...\n", perCtxt->name);
805     for (i = 0U; i < perCtxt->macPortNum; i++)
806     {
807         macPort = perCtxt->macPort[i];
808         linked = false;
809         ENET_IOCTL_SET_INOUT_ARGS(&prms, &macPort, &linked);
811         while (!linked)
812         {
813             status = Enet_ioctl(perCtxt->hEnet, gEnetIg.coreId, ENET_PER_IOCTL_IS_PORT_LINK_UP, &prms);
814             if (status != ENET_SOK)
815             {
816                 EnetAppUtils_print("\n%s: Failed to get port %u link status: %d\n",
817                                    perCtxt->name, ENET_MACPORT_ID(macPort), status);
818                 linked = false;
819                 break;
820             }
822             if (!linked)
823             {
824                 Enet_periodicTick(perCtxt->hEnet);
825                 EnetUtils_delay(10U);
826             }
828             linkCheckTime++;
829             if(linkCheckTime > BOARD_DIAG_ICSSG_LINKUP_TIMEOUT)
830             {
831                 status = ENET_ETIMEOUT;
832                 EnetAppUtils_print("\n%s: Port %u link up timed out\n",
833                                     perCtxt->name, ENET_MACPORT_ID(macPort));
834                 break;
835             }
836         }
838         EnetAppUtils_print("\n%s: Port %u link is %s",
839                         perCtxt->name, ENET_MACPORT_ID(macPort), linked ? "up" : "down");
841         /* Set port to 'Forward' state */
842         if (status == ENET_SOK)
843         {
844             EnetAppUtils_print("\n%s: Set port state to 'Forward'", perCtxt->name);
846             setPortStateInArgs.macPort   = macPort;
847             setPortStateInArgs.portState = ICSSG_PORT_STATE_FORWARD;
848             ENET_IOCTL_SET_IN_ARGS(&prms, &setPortStateInArgs);
850             status = Enet_ioctl(perCtxt->hEnet, gEnetIg.coreId, ICSSG_PER_IOCTL_SET_PORT_STATE, &prms);
851             if (status == ENET_SINPROGRESS)
852             {
853                 /* Wait for asyc ioctl to complete */
854                 while(perCtxt->hAsyncIoctlSem != true)
855                 {
856                     Enet_poll(perCtxt->hEnet, ENET_EVT_ASYNC_CMD_RESP, NULL, 0U);
857                 }
858                 perCtxt->hAsyncIoctlSem = false;
860                 status = ENET_SOK;
861             }
862             else
863             {
864                 EnetAppUtils_print("\n%s: Failed to set port state: %d\n", perCtxt->name, status);
865             }
866         }
867     }
869     return status;
872 static void EnetIg_macMode2MacMii(emac_mode macMode,
873                                   EnetMacPort_Interface *mii)
875     switch (macMode)
876     {
877 #if defined(SOC_AM65XX) || defined(SOC_J7200) || defined(SOC_J721E) || defined(SOC_TPR12) || defined(SOC_AWR294X)
878         case RMII:
879             mii->layerType    = ENET_MAC_LAYER_MII;
880             mii->sublayerType = ENET_MAC_SUBLAYER_REDUCED;
881             mii->variantType  = ENET_MAC_VARIANT_NONE;
882             break;
884         case RGMII:
885             mii->layerType    = ENET_MAC_LAYER_GMII;
886             mii->sublayerType = ENET_MAC_SUBLAYER_REDUCED;
887             mii->variantType  = ENET_MAC_VARIANT_FORCED;
888             break;
889 #endif
890 #if defined(SOC_J7200) || defined(SOC_J721E)
891         case GMII:
892             mii->layerType    = ENET_MAC_LAYER_GMII;
893             mii->sublayerType = ENET_MAC_SUBLAYER_STANDARD;
894             mii->variantType  = ENET_MAC_VARIANT_NONE;
895             break;
897         case SGMII:
898             mii->layerType    = ENET_MAC_LAYER_GMII;
899             mii->sublayerType = ENET_MAC_SUBLAYER_SERIAL;
900             mii->variantType  = ENET_MAC_VARIANT_NONE;
901             break;
903         case QSGMII:
904             mii->layerType    = ENET_MAC_LAYER_GMII;
905             mii->sublayerType = ENET_MAC_SUBLAYER_QUAD_SERIAL_MAIN;
906             mii->variantType  = ENET_MAC_VARIANT_NONE;
907             break;
909         case QSGMII_SUB:
910             mii->layerType    = ENET_MAC_LAYER_GMII;
911             mii->sublayerType = ENET_MAC_SUBLAYER_QUAD_SERIAL_SUB;
912             mii->variantType  = ENET_MAC_VARIANT_NONE;
913             break;
915         case XFI:
916             mii->layerType    = ENET_MAC_LAYER_XGMII;
917             mii->sublayerType = ENET_MAC_SUBLAYER_STANDARD;
918             mii->variantType  = ENET_MAC_VARIANT_NONE;
919             break;
920 #endif
921         default:
922             EnetAppUtils_print("\nInvalid MAC mode: %u\n", macMode);
923             EnetAppUtils_assert(false);
924             break;
925     }
928 static void BoardDiag_EnetIg_rxIsrFxn(void *appData)
930     EnetIg_PerCtxt *perCtxt = (EnetIg_PerCtxt *)appData;
932     SemaphoreP_post(perCtxt->hRxSem);
935 static void BoardDiag_EnetIg_txIsrFxn(void *appData)
937     EnetIg_PerCtxt *perCtxt = (EnetIg_PerCtxt *)appData;
939     SemaphoreP_post(perCtxt->hTxSem);
942 static int32_t EnetIg_openDma(EnetIg_PerCtxt *perCtxt)
944     EnetUdma_OpenRxFlowPrms rxChCfg;
945     EnetUdma_OpenTxChPrms txChCfg;
946     int32_t status = ENET_SOK;
948     /* Open the TX channel */
949     EnetDma_initTxChParams(&txChCfg);
951     txChCfg.hUdmaDrv = (perCtxt->enetType == ENET_CPSW_2G) ? gEnetIg.hMcuUdmaDrv : gEnetIg.hMainUdmaDrv;
952     txChCfg.cbArg    = perCtxt;
953     txChCfg.notifyCb = BoardDiag_EnetIg_txIsrFxn;
954     txChCfg.useGlobalEvt = true;
956     EnetAppUtils_setCommonTxChPrms(&txChCfg);
958     EnetAppUtils_openTxCh(perCtxt->hEnet,
959                           gEnetIg.coreKey,
960                           gEnetIg.coreId,
961                           &perCtxt->txChNum,
962                           &perCtxt->hTxCh,
963                           &txChCfg);
964     if (perCtxt->hTxCh == NULL)
965     {
966 #if FIX_RM
967         /* Free the channel number if open Tx channel failed */
968         EnetAppUtils_freeTxCh(gEnetIg.hEnet,
969                               gEnetIg.coreKey,
970                               gEnetIg.coreId,
971                               gEnetIg.txChNum);
972 #endif
973         EnetAppUtils_print("\nEnetIg_openDma() failed to open TX channel");
974         status = ENET_EFAIL;
975         EnetAppUtils_assert(perCtxt->hTxCh != NULL);
976     }
978     /* Allocate TX packets and keep them locally enqueued */
979     if (status == ENET_SOK)
980     {
981         EnetIg_initTxFreePktQ();
982     }
984     /* Open the RX flow */
985     if (status == ENET_SOK)
986     {
987         EnetDma_initRxChParams(&rxChCfg);
989         rxChCfg.hUdmaDrv = (perCtxt->enetType == ENET_CPSW_2G) ? gEnetIg.hMcuUdmaDrv : gEnetIg.hMainUdmaDrv;
990         rxChCfg.notifyCb = BoardDiag_EnetIg_rxIsrFxn;
991         rxChCfg.cbArg    = perCtxt;
992         rxChCfg.useGlobalEvt = true;
993         rxChCfg.flowPrms.sizeThreshEn = 0U;
995         EnetAppUtils_setCommonRxFlowPrms(&rxChCfg);
996         EnetAppUtils_openRxFlow(perCtxt->enetType,
997                                 perCtxt->hEnet,
998                                 gEnetIg.coreKey,
999                                 gEnetIg.coreId,
1000                                 true,
1001                                 &perCtxt->rxStartFlowIdx,
1002                                 &perCtxt->rxFlowIdx,
1003                                 &perCtxt->macAddr[0U],
1004                                 &perCtxt->hRxCh,
1005                                 &rxChCfg);
1007         if (perCtxt->hRxCh == NULL)
1008         {
1009             EnetAppUtils_print("\nEnetIg_openRxCh() failed to open RX flow");
1010             status = ENET_EFAIL;
1011             EnetAppUtils_assert(perCtxt->hRxCh != NULL);
1012         }
1013     }
1015     /* Submit all ready RX buffers to DMA */
1016     if (status == ENET_SOK)
1017     {
1018         EnetIg_initRxReadyPktQ(perCtxt->hRxCh);
1019     }
1021     return status;
1024 static void EnetIg_closeDma(EnetIg_PerCtxt *perCtxt)
1026     EnetDma_PktQ fqPktInfoQ;
1027     EnetDma_PktQ cqPktInfoQ;
1029     EnetQueue_initQ(&fqPktInfoQ);
1030     EnetQueue_initQ(&cqPktInfoQ);
1032     /* Close RX channel */
1033     EnetAppUtils_closeRxFlow(perCtxt->enetType,
1034                             perCtxt->hEnet,
1035                             gEnetIg.coreKey,
1036                             gEnetIg.coreId,
1037                             true,
1038                             &fqPktInfoQ,
1039                             &cqPktInfoQ,
1040                             perCtxt->rxStartFlowIdx,
1041                             perCtxt->rxFlowIdx,
1042                             perCtxt->macAddr,
1043                             perCtxt->hRxCh);
1045     EnetAppUtils_freePktInfoQ(&fqPktInfoQ);
1046     EnetAppUtils_freePktInfoQ(&cqPktInfoQ);
1048     /* Close TX channel */
1049     EnetQueue_initQ(&fqPktInfoQ);
1050     EnetQueue_initQ(&cqPktInfoQ);
1052     /* Retrieve any pending TX packets from driver */
1053     EnetIg_retrieveFreeTxPkts(perCtxt);
1055     EnetAppUtils_closeTxCh(perCtxt->hEnet,
1056                            gEnetIg.coreKey,
1057                            gEnetIg.coreId,
1058                            &fqPktInfoQ,
1059                            &cqPktInfoQ,
1060                            perCtxt->hTxCh,
1061                            perCtxt->txChNum);
1063     EnetAppUtils_freePktInfoQ(&fqPktInfoQ);
1064     EnetAppUtils_freePktInfoQ(&cqPktInfoQ);
1065     EnetAppUtils_freePktInfoQ(&gEnetIg.txFreePktInfoQ);
1068 static void EnetIg_initTxFreePktQ(void)
1070     EnetDma_Pkt *pPktInfo;
1071     uint32_t i;
1073     /* Initialize TX EthPkts and queue them to txFreePktInfoQ */
1074     for (i = 0U; i < ENET_MEM_NUM_TX_PKTS; i++)
1075     {
1076         pPktInfo = EnetMem_allocEthPkt(&gEnetIg,
1077                                        ENET_MEM_LARGE_POOL_PKT_SIZE,
1078                                        ENETDMA_CACHELINE_ALIGNMENT);
1079         EnetAppUtils_assert(pPktInfo != NULL);
1080         ENET_UTILS_SET_PKT_APP_STATE(&pPktInfo->pktState, ENET_PKTSTATE_APP_WITH_FREEQ);
1082         EnetQueue_enq(&gEnetIg.txFreePktInfoQ, &pPktInfo->node);
1083     }
1085     EnetAppUtils_print("\ninitQs() txFreePktInfoQ initialized with %d pkts",
1086                        EnetQueue_getQCount(&gEnetIg.txFreePktInfoQ));
1089 static void EnetIg_initRxReadyPktQ(EnetDma_RxChHandle hRxCh)
1091     EnetDma_PktQ rxReadyQ;
1092     EnetDma_PktQ rxFreeQ;
1093     EnetDma_Pkt *pPktInfo;
1094     uint32_t i;
1095     int32_t status;
1097     EnetQueue_initQ(&rxFreeQ);
1099     for (i = 0U; i < ENET_MEM_NUM_RX_PKTS; i++)
1100     {
1101         pPktInfo = EnetMem_allocEthPkt(&gEnetIg,
1102                                        ENET_MEM_LARGE_POOL_PKT_SIZE,
1103                                        ENETDMA_CACHELINE_ALIGNMENT);
1104         EnetAppUtils_assert(pPktInfo != NULL);
1106         ENET_UTILS_SET_PKT_APP_STATE(&pPktInfo->pktState, ENET_PKTSTATE_APP_WITH_FREEQ);
1108         EnetQueue_enq(&rxFreeQ, &pPktInfo->node);
1109     }
1111     /* Retrieve any packets which are ready */
1112     EnetQueue_initQ(&rxReadyQ);
1113     status = EnetDma_retrieveRxPktQ(hRxCh, &rxReadyQ);
1114     EnetAppUtils_assert(status == ENET_SOK);
1116     /* There should not be any packet with DMA during init */
1117     EnetAppUtils_assert(EnetQueue_getQCount(&rxReadyQ) == 0U);
1119     EnetDma_submitRxPktQ(hRxCh, &rxFreeQ);
1121     /* Assert here, as during init, the number of DMA descriptors should be equal to
1122      * the number of free Ethernet buffers available with app */
1123     EnetAppUtils_assert(EnetQueue_getQCount(&rxFreeQ) == 0U);
1126 static uint32_t EnetIg_retrieveFreeTxPkts(EnetIg_PerCtxt *perCtxt)
1128     EnetDma_PktQ txFreeQ;
1129     EnetDma_Pkt *pktInfo;
1130     uint32_t txFreeQCnt = 0U;
1131     int32_t status;
1133     EnetQueue_initQ(&txFreeQ);
1135     /* Retrieve any packets that may be free now */
1136     status = EnetDma_retrieveTxPktQ(perCtxt->hTxCh, &txFreeQ);
1137     if (status == ENET_SOK)
1138     {
1139         txFreeQCnt = EnetQueue_getQCount(&txFreeQ);
1141         pktInfo = (EnetDma_Pkt *)EnetQueue_deq(&txFreeQ);
1142         while (NULL != pktInfo)
1143         {
1144             EnetDma_checkPktState(&pktInfo->pktState,
1145                                     ENET_PKTSTATE_MODULE_APP,
1146                                     ENET_PKTSTATE_APP_WITH_DRIVER,
1147                                     ENET_PKTSTATE_APP_WITH_FREEQ);
1149             EnetQueue_enq(&gEnetIg.txFreePktInfoQ, &pktInfo->node);
1150             pktInfo = (EnetDma_Pkt *)EnetQueue_deq(&txFreeQ);
1151         }
1152     }
1153     else
1154     {
1155         EnetAppUtils_print("\nretrieveFreeTxPkts() failed to retrieve pkts: %d", status);
1156     }
1158     return txFreeQCnt;
1161 static int32_t BoardDiag_EnetIg_LpbckTest(EnetIg_PerCtxt *perCtxts, uint32_t numPerCtxts)
1163     uint32_t i;
1164     int32_t status = ENET_SOK;
1165     Enet_IoctlPrms prms;
1166     SemaphoreP_Params semParams;
1168     for (i = 0U; i < numPerCtxts; i++)
1169     {
1170         EnetIg_PerCtxt *perCtxt = &perCtxts[i];
1172         SemaphoreP_Params_init(&semParams);
1173         semParams.mode = SemaphoreP_Mode_BINARY;
1175         perCtxt->hRxSem = SemaphoreP_create(0, &semParams);
1176         EnetAppUtils_assert(perCtxt->hRxSem != NULL);
1178         perCtxt->hTxSem = SemaphoreP_create(0, &semParams);
1179         EnetAppUtils_assert(perCtxt->hTxSem != NULL);
1181         status = EnetIg_openPort(perCtxt);
1182         if (status != ENET_SOK)
1183         {
1184             EnetAppUtils_print("\n%s: Failed to open port link: %d\n", perCtxt->name, status);
1185         }
1187         status = EnetIg_waitForLinkUp(perCtxt);
1188         if (status != ENET_SOK)
1189         {
1190             EnetAppUtils_print("\n%s: Failed to wait for link up: %d\n", perCtxt->name, status);
1191         }
1193         /* Open DMA for peripheral/port */
1194         if (status == ENET_SOK)
1195         {
1196             EnetAppUtils_print("\n%s: Open DMA", perCtxt->name);
1198             status = EnetIg_openDma(perCtxt);
1199             if (status != ENET_SOK)
1200             {
1201                 EnetAppUtils_print("\n%s: failed to open DMA: %d\n", perCtxt->name, status);
1202             }
1203         }
1205         /* Add port MAC entry */
1206         if ((status == ENET_SOK) && (Enet_isIcssFamily(perCtxt->enetType)))
1207         {
1208             EnetAppUtils_print("\n%s: Set MAC addr: ", perCtxt->name);
1209             EnetAppUtils_printMacAddr(&perCtxt->macAddr[0U]);
1211             if (perCtxt->enetType == ENET_ICSSG_DUALMAC)
1212             {
1213                 IcssgMacPort_SetMacAddressInArgs inArgs;
1215                 memset(&inArgs, 0, sizeof(inArgs));
1216                 inArgs.macPort = perCtxt->macPort[0U];
1217                 EnetUtils_copyMacAddr(&inArgs.macAddr[0U], &perCtxt->macAddr[0U]);
1218                 ENET_IOCTL_SET_IN_ARGS(&prms, &inArgs);
1220                 status = Enet_ioctl(perCtxt->hEnet, gEnetIg.coreId, ICSSG_MACPORT_IOCTL_SET_MACADDR, &prms);
1221             }
1222             else
1223             {
1224                 Icssg_MacAddr addr; // FIXME Icssg_MacAddr type
1226                 /* Set host port's MAC address */
1227                 EnetUtils_copyMacAddr(&addr.macAddr[0U], &perCtxt->macAddr[0U]);
1228                 ENET_IOCTL_SET_IN_ARGS(&prms, &addr);
1230                 status = Enet_ioctl(perCtxt->hEnet, gEnetIg.coreId, ICSSG_HOSTPORT_IOCTL_SET_MACADDR, &prms);
1231             }
1233             if (status != ENET_SOK)
1234             {
1235                 EnetAppUtils_print("\n%s: Failed to set MAC address entry: %d\n", perCtxt->name, status);
1236             }
1237         }
1238     }
1240     if(status == ENET_SOK)
1241     {
1242         status = BoardDiag_EnetIg_LpbkTxRx();
1243     }
1244     return status;
1247 static uint32_t BoardDiag_EnetIg_Receive(EnetIg_PerCtxt *perCtxt)
1249     EnetDma_PktQ rxReadyQ;
1250     EnetDma_PktQ rxFreeQ;
1251     EnetDma_Pkt *rxPktInfo;
1253     uint32_t rxReadyCnt = 0U;
1254     int32_t status;
1256     EnetQueue_initQ(&rxReadyQ);
1257     EnetQueue_initQ(&rxFreeQ);
1259     /* Get the packets received so far */
1260     status = EnetDma_retrieveRxPktQ(perCtxt->hRxCh, &rxReadyQ);
1261     if (status != ENET_SOK)
1262     {
1263         EnetAppUtils_print("\nreceivePkts() failed to retrieve pkts: %d\n", status);
1264     }
1265     else
1266     {
1267         rxReadyCnt = EnetQueue_getQCount(&rxReadyQ);
1269         /* Consume the received packets */
1270         rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rxReadyQ);
1272         while(rxPktInfo != NULL)
1273         {
1274             EnetDma_checkPktState(&rxPktInfo->pktState,
1275                                     ENET_PKTSTATE_MODULE_APP,
1276                                     ENET_PKTSTATE_APP_WITH_DRIVER,
1277                                     ENET_PKTSTATE_APP_WITH_READYQ);
1279             gEnetIg.rxFrame = (EthFrame *)rxPktInfo->bufPtr;
1281             EnetDma_checkPktState(&rxPktInfo->pktState,
1282                                 ENET_PKTSTATE_MODULE_APP,
1283                                 ENET_PKTSTATE_APP_WITH_READYQ,
1284                                 ENET_PKTSTATE_APP_WITH_FREEQ);
1286             /* Release the received packet */
1287             EnetQueue_enq(&rxFreeQ, &rxPktInfo->node);
1288             rxPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&rxReadyQ);
1289         }
1291         EnetAppUtils_validatePacketState(&rxFreeQ,
1292                                     ENET_PKTSTATE_APP_WITH_FREEQ,
1293                                     ENET_PKTSTATE_APP_WITH_DRIVER);
1295         /* Submit now processed buffers */
1296         EnetDma_submitRxPktQ(perCtxt->hRxCh, &rxFreeQ);
1297     }
1299     return rxReadyCnt;
1302 static uint32_t BoardDiag_EnetIg_Transmit(EnetIg_PerCtxt *txPerCtxt, EnetIg_PerCtxt *rxPerCtxt)
1304     EnetDma_PktQ txSubmitQ;
1305     EnetDma_Pkt *txPktInfo;
1307     int32_t status = ENET_SOK;
1308     uint8_t bcastAddr[ENET_MAC_ADDR_LEN] =
1309             {0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU};
1311     uint32_t pktCnt = 0;
1312     uint32_t txRetrievePktCnt = 0;
1313     uint32_t loopTxPktCnt = 0;
1314     uint32_t loopRxPktCnt = 0;
1315     uint32_t rxReadyCnt = 0;
1316     uint32_t txCnt = 0;
1317     SemaphoreP_Status semStatus;
1319     while (pktCnt < BOARD_DIAG_ENETLPBK_TEST_PKT_NUM)
1320     {
1321         loopRxPktCnt = loopTxPktCnt = 0U;
1323         /* Retrieve TX packets from driver and recycle them */
1324         EnetIg_retrieveFreeTxPkts(txPerCtxt);
1326         /* Transmit a single packet */
1327         EnetQueue_initQ(&txSubmitQ);
1329         /* Dequeue one free TX Eth packet */
1330         txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&gEnetIg.txFreePktInfoQ);
1332         memset(gEnetIg.txFrame, 0, BOARD_DIAG_ENETLPBK_TEST_PKT_LEN + sizeof(EthFrameHeader));
1333         memset(gEnetIg.rxFrame, 0, BOARD_DIAG_ENETLPBK_TEST_PKT_LEN + sizeof(EthFrameHeader));
1335         while (NULL != txPktInfo)
1336         {
1337             pktCnt++;
1338             /* Fill the TX Eth frame with test content */
1339             gEnetIg.txFrame = (EthFrame *)txPktInfo->bufPtr;
1340             memcpy(gEnetIg.txFrame->hdr.dstMac, &bcastAddr[0U], ENET_MAC_ADDR_LEN);
1341             memcpy(gEnetIg.txFrame->hdr.srcMac, &txPerCtxt->macAddr[0U], ENET_MAC_ADDR_LEN);
1343             gEnetIg.txFrame->hdr.etherType = Enet_htons(0x0800);
1345             memset(&gEnetIg.txFrame->payload[0U], (uint8_t)(0xA5 + pktCnt),
1346                     BOARD_DIAG_ENETLPBK_TEST_PKT_LEN);
1348             txPktInfo->userBufLen = BOARD_DIAG_ENETLPBK_TEST_PKT_LEN +
1349                                   sizeof(EthFrameHeader);
1351             txPktInfo->appPriv = &gEnetIg;
1352             txPktInfo->tsInfo.enableHostTxTs = false;
1354             /* Enqueue the packet for later transmission */
1355             EnetQueue_enq(&txSubmitQ, &txPktInfo->node);
1357             if (pktCnt >= BOARD_DIAG_ENETLPBK_TEST_PKT_NUM)
1358             {
1359                 break;
1360             }
1362             /* Dequeue one free TX Eth packet */
1363             txPktInfo = (EnetDma_Pkt *)EnetQueue_deq(&gEnetIg.txFreePktInfoQ);
1364         }
1366         loopTxPktCnt = EnetQueue_getQCount(&txSubmitQ);
1367         while (0U != EnetQueue_getQCount(&txSubmitQ))
1368         {
1369             txCnt = EnetQueue_getQCount(&txSubmitQ);
1370             status = EnetDma_submitTxPktQ(txPerCtxt->hTxCh, &txSubmitQ);
1372             semStatus = SemaphoreP_pend(txPerCtxt->hTxSem, BOARD_DIAG_ENETLPBK_TIMEOUT);
1374             if(semStatus == SemaphoreP_TIMEOUT)
1375             {
1376                 status = ENET_ETIMEOUT;
1377                 EnetAppUtils_print("\n\nTrasmit timeout at packet %d", loopTxPktCnt);
1378                 break;
1379             }
1382             /* Retrieve TX free packets */
1383             if (status == ENET_SOK)
1384             {
1385                 txCnt            = txCnt - EnetQueue_getQCount(&txSubmitQ);
1386                 txRetrievePktCnt = 0U;
1387                 while (txRetrievePktCnt != txCnt)
1388                 {
1389                     /* TODO this is not failure as HW is busy sending
1390                      * packets, we need to wait and again call retrieve
1391                      * packets */
1392                     Osal_delay(10);
1393                     txRetrievePktCnt += EnetIg_retrieveFreeTxPkts(txPerCtxt);
1394                 }
1395             }
1396             else
1397             {
1398                 break;
1399             }
1400         }
1402         if(status == ENET_SOK)
1403         {
1404             /* wait to receive the packet */
1405             do
1406             {
1407                 semStatus = SemaphoreP_pend(rxPerCtxt->hRxSem, BOARD_DIAG_ENETLPBK_TIMEOUT);
1409                 if(semStatus == SemaphoreP_TIMEOUT)
1410                 {
1411                     status = ENET_ETIMEOUT;
1412                     EnetAppUtils_print("\n\nReceive timeout at packet %d", loopRxPktCnt);
1413                     break;
1414                 }
1416                 rxReadyCnt = 0;
1418                 if(status == ENET_SOK)
1419                 {
1420                     rxReadyCnt = BoardDiag_EnetIg_Receive(rxPerCtxt);
1421                     loopRxPktCnt += rxReadyCnt;
1423                     status = memcmp(&gEnetIg.txFrame->payload[0], &gEnetIg.rxFrame->payload[0], rxReadyCnt);
1424                     if(status != ENET_SOK)
1425                     {
1426                         EnetAppUtils_print("\n\nPacket mismatch error at packet %d", pktCnt);
1427                         EnetAppUtils_print("\n\nRx Byte Count = %d", rxReadyCnt);
1428                         if(printFrameEnable == true)
1429                         {
1430                             EnetAppUtils_print("\n\nTransmitted Packets: ", pktCnt);
1431                             BoardDiag_printFrame(gEnetIg.rxFrame, rxReadyCnt);
1432                         }
1433                     }
1434                 }
1435                 else
1436                 {
1437                     break;
1438                 }
1440             }while(loopRxPktCnt < loopTxPktCnt);
1442             gEnetIg.totalRxCnt += loopTxPktCnt;
1443         }
1444     }
1446     gEnetIg.totalTxCnt += pktCnt;
1448     EnetAppUtils_print("\n\nTransmitted - %d packets\nReceived - %d packets\n",
1449                         loopTxPktCnt, loopRxPktCnt);
1451     return status;
1454 uint32_t BoardDiag_EnetIg_LpbkTxRx(void)
1456     int32_t status = ENET_SOK;
1458     gEnetIg.totalTxCnt = 0U;
1459     gEnetIg.totalRxCnt = 0U;
1461     EnetAppUtils_print("\n\nPort %d to Port %d", gEnetIg.perCtxt[0].instId, gEnetIg.perCtxt[1].instId);
1463     status |= BoardDiag_EnetIg_Transmit(&gEnetIg.perCtxt[0], &gEnetIg.perCtxt[1]);
1464     Osal_delay(100);
1466     EnetAppUtils_print("\n\nPort %d to Port %d", gEnetIg.perCtxt[1].instId, gEnetIg.perCtxt[0].instId);
1468     status |= BoardDiag_EnetIg_Transmit(&gEnetIg.perCtxt[1], &gEnetIg.perCtxt[0]);
1469     Osal_delay(100);
1471     if(status == ENET_SOK)
1472     {
1473         if(gEnetIg.totalTxCnt != gEnetIg.totalRxCnt)
1474         {
1475             EnetAppUtils_print("\n\nPacket Loss, Test Failed");
1476             EnetAppUtils_print("\n\nTest Iteration %d failed", gEnetIg.loopCnt+1);
1477             gEnetIg.failIterations++;
1478             printStatsEnable = true;
1479         }
1480         else
1481         {
1482             EnetAppUtils_print("\n\nTest Iteration %d passed", gEnetIg.loopCnt+1);
1483             gEnetIg.passIterations++;
1484         }
1485     }
1486     else
1487     {
1488         gEnetIg.failIterations++;
1489         printStatsEnable = true;
1490         EnetAppUtils_print("\n\nFailed to transmit/receive packets");
1491     }
1493     EnetAppUtils_print("\n\nNo. of tests passed: %d", gEnetIg.passIterations);
1494     EnetAppUtils_print("\n\nNo. of tests failed: %d", gEnetIg.failIterations);
1495     if(printStatsEnable == true)
1496     {
1497         /* Print statistics */
1498         EnetIg_printStats(gEnetIg.perCtxt, gEnetIg.numPerCtxts);
1500         EnetIg_resetStats(gEnetIg.perCtxt, gEnetIg.numPerCtxts);
1502         printStatsEnable = false;
1503     }
1505     return status;
1508 /**
1509  * \brief   This function is used to display Mac address
1510  *
1511  * \param   EthFrame EthFrame[] frame to be displayed
1512  *          uint32_t len        length of the frame
1513  * \return  NULL
1514  *
1515  */
1516 static void BoardDiag_printFrame(EthFrame *frame, uint32_t len)
1518     uint8_t *payload;
1519     uint32_t i;
1521     EnetAppUtils_print("\nDst addr : ");
1522     BoardDiag_printMacAddr(&frame->hdr.dstMac[0]);
1524     EnetAppUtils_print("\nSrc addr : ");
1525     BoardDiag_printMacAddr(&frame->hdr.srcMac[0]);
1528     EnetAppUtils_print("\nEtherType: 0x%04x",
1529                 Enet_ntohs(frame->hdr.etherType) & 0xFFFFU);
1530     payload = frame->payload;
1532     EnetAppUtils_print("\nPayload  : ");
1533     for (i = 0; i < len; i++)
1534     {
1535         EnetAppUtils_print("0x%02x ", payload[i]);
1536         if (i && (((i + 1) % OCTETS_PER_ROW) == 0))
1537         {
1538             EnetAppUtils_print("\n           ");
1539         }
1540     }
1542     if (len && ((len % OCTETS_PER_ROW) != 0))
1543     {
1544         EnetAppUtils_print("\n");
1545     }
1547     EnetAppUtils_print("\n");
1550 /**
1551  * \brief   This function is used to display Mac address
1552  *
1553  * \param   uint8_t macAddr[] MAC Address
1554  *
1555  * \return   NULL
1556  *
1557  */
1558 static void BoardDiag_printMacAddr(uint8_t macAddr[])
1560     EnetAppUtils_print("%02x:%02x:%02x:%02x:%02x:%02x\n",
1561                        macAddr[0] & 0xFF,
1562                        macAddr[1] & 0xFF,
1563                        macAddr[2] & 0xFF,
1564                        macAddr[3] & 0xFF,
1565                        macAddr[4] & 0xFF,
1566                        macAddr[5] & 0xFF);