]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - psdk_cust/pdk_k2g_1_0_1_2_eng/packages/ti/board/diag/gmac/src/gmac_main.c
PASDK-319:Update PDK eng to 1.0.1.2.
[processor-sdk/performance-audio-sr.git] / psdk_cust / pdk_k2g_1_0_1_2_eng / packages / ti / board / diag / gmac / src / gmac_main.c
1 /**
2  *  \file   cpsw_test.c
3  *
4  *  \brief
5  *
6  *
7  */
9 /* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
10  * ALL RIGHTS RESERVED
11  */
12 #include <stdint.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <ti/csl/cslr.h>
16 #include <ti/csl/tistdtypes.h>
17 #include <ti/csl/cslr_device.h>
18 #include <ti/csl/cslr_cpgmac_sl.h>
19 #include <ti/csl/src/ip/cpgmac/V2/cslr_cpgmac_sl.h>
20 #include <ti/csl/csl_cpgmac_sl.h>
21 #include <ti/csl/src/ip/emac/V2/csl_cpgmac_sl.h>
22 #include <ti/csl/csl_cpgmac_slAux.h>
23 #include <ti/csl/src/ip/emac/V2/csl_cpgmac_slAux.h>
24 #include <ti/csl/cslr_cpsw.h>
25 #include <ti/csl/src/ip/cpsw/V3/cslr_cpsw_3g.h>
26 #include <ti/csl/src/ip/cpsw/V3/cslr_wr.h>
27 #include <ti/csl/src/ip/cpdma/V0/cslr_cpdma.h>
28 #include <ti/csl/csl_cpsw.h>
29 #include <ti/csl/csl_cpswAux.h>
30 #include <ti/csl/src/ip/cpsw/V3/csl_cpswAux.h>
31 #include <ti/csl/cslr_mdio.h>
32 #include <ti/csl/src/ip/mdio/V2/cslr_mdio.h>
33 #include <ti/csl/csl_mdio.h>
34 #include <ti/csl/src/ip/mdio/V2/csl_mdio.h>
35 #include <ti/csl/csl_mdioAux.h>
36 #include <ti/csl/src/ip/mdio/V2/csl_mdioAux.h>
38 #include "hw_types.h"
39 #include <ti/csl/csl_armGicAux.h>
40 #include <ti/csl/soc.h>
41 #include "gmac_test.h"
42 #include <ti/board/board.h>
44 /* Example/Board Header files */
45 #if defined (IDK_AM572X)
46 #include <ti/board/src/idkAM572x/include/board_cfg.h>
47 #include <ti/board/src/idkAM572x/device/enet_phy.h>
48 #endif
49 #if defined (IDK_AM571X)
50 #include <ti/board/src/idkAM571x/include/board_cfg.h>
51 #include <ti/board/src/idkAM571x/device/enet_phy.h>
52 #endif
53 #if defined (EVM_AM572X)
54 #include <ti/board/src/evmAM572x/include/board_cfg.h>
55 #include <ti/board/src/evmAM572x/device/enet_phy.h>
56 #endif
58 /* UART Header files */
59 #include <ti/drv/uart/UART.h>
60 #include <ti/drv/uart/UART_stdio.h>
63 #define REG_IDX_SHIFT           (0x05)
64 #define REG_BIT_MASK            (0x1F)
65 #define NUM_BYTES_REG           4
67 #define MPU_XBAR_INSTANCE_GMAC_SW_IRQ_RX_PULSE  87
68 #define MPU_XBAR_INSTANCE_GMAC_SW_IRQ_TX_PULSE  88
70 #define GMAC_SW_IRQ_RX_PULSE_INT_NUM  92
71 #define GMAC_SW_IRQ_TX_PULSE_INT_NUM  93
73 /* Enable the below macro to have prints on the IO Console */
74 //#define IO_CONSOLE
76 #ifndef IO_CONSOLE
77 #define GMAC_log                UART_printf
78 #else
79 #define GMAC_log                printf
80 #endif
82 #define CPSW_INT_PACING_C0_RX_PULSE  (0x01 << CSL_WR_INT_CONTROL_INT_PACE_EN_SHIFT)
83 #define CPSW_INT_PACING_C0_TX_PULSE  (0x02 << CSL_WR_INT_CONTROL_INT_PACE_EN_SHIFT)
85 //*****************************************************************************
86 //  global variables
87 //*****************************************************************************
88 extern void Entry(void);
89 extern void UndefInstHandler(void);
90 extern void SVC_Handler(void);
91 extern void PrefetchAbortHandler(void);
92 extern void AbortHandler(void);
93 extern void ResvHandler(void);
94 extern void IRQHandler(void);
95 extern void FIQHandler(void);
97 static Uint32 const vecTbl[14]=
98 {
99     0xE59FF018,    /* Opcode for loading PC with the contents of [PC + 0x18] */
100     0xE59FF018,    /* Opcode for loading PC with the contents of [PC + 0x18] */
101     0xE59FF018,    /* Opcode for loading PC with the contents of [PC + 0x18] */
102     0xE59FF018,    /* Opcode for loading PC with the contents of [PC + 0x18] */
103     0xE59FF014,    /* Opcode for loading PC with the contents of [PC + 0x14] */
104     0xE24FF008,    /* Opcode for loading PC with (PC - 8) (eq. to while(1)) */
105     0xE59FF010,    /* Opcode for loading PC with the contents of [PC + 0x10] */
106     0xE59FF010,    /* Opcode for loading PC with the contents of [PC + 0x10] */
107     (Uint32)Entry,
108     (Uint32)UndefInstHandler,
109     (Uint32)SVC_Handler,
110     (Uint32)AbortHandler,
111     (Uint32)IRQHandler,
112     (Uint32)FIQHandler
113 };
115 Uint32 CpswBase =               (GMAC_BASEADDRESS);
116 Uint32 MdioBase =               (GMAC_BASEADDRESS + 0x1000);
117 Uint32 CpswWrBase =             (GMAC_BASEADDRESS + 0x1200);
118 Uint32 CpswCpdmaBase =          (GMAC_BASEADDRESS + 0x0800);
119 Uint32 CpswAleBase =            (GMAC_BASEADDRESS + 0x0D00);
120 Uint32 CpswStatBase =           (GMAC_BASEADDRESS + 0x0900);
121 Uint32 CpswStateBase =          (GMAC_BASEADDRESS + 0x0A00);
122 Uint32 CpswCptsBase =           (GMAC_BASEADDRESS + 0x0C00);
123 Uint32 CpswPort0Base =          (GMAC_BASEADDRESS + 0x0100);
124 Uint32 CpswPort1Base =          (GMAC_BASEADDRESS + 0x0200);
125 Uint32 CpswSl1Base =            (GMAC_BASEADDRESS + 0x0D80);
126 Uint32 CpswPort2Base =          (GMAC_BASEADDRESS + 0x0300);
127 Uint32 CpswSl2Base =            (GMAC_BASEADDRESS + 0x0DC0);
128 Uint32 CpswCppiRamBase =        (GMAC_BASEADDRESS + 0x2000);
130 Desc    *RxHead[8], *RxTail[8];
131 Desc    *TxHead[8], *TxTail[8];
132 Desc    *TxFreeHead, *TxFreeTail;
133 volatile Uint32  RxQueueCnt[8], TxQueueCnt[8], TxFreeCnt;
134 volatile Uint32  RxPackets[8]={0,0,0,0,0,0,0,0}, TxPackets[8]={0,0,0,0,0,0,0,0};
135 volatile Uint32  RxMisqueue[8]={0,0,0,0,0,0,0,0}, TxMisqueue[8]={0,0,0,0,0,0,0,0};
136 volatile Uint32  TxActive[8]={0,0,0,0,0,0,0,0};
138 volatile Uint32  fPacing=FALSE, fBlastTransmit=FALSE, fTxP=FALSE, fTxP2=FALSE;
139 Uint32  fExtRmiiClk=TRUE, fRMII=FALSE, fMII=FALSE, fRGMII=FALSE, fGig=FALSE;
140 Uint32  BoardType, Phy1Type, Phy2Type, Phy1Addr, Phy2Addr;
142 CSL_ArmGicIntrParams_t gRxIntrParams;
143 CSL_ArmGicIntrParams_t gTxIntrParams;
145 extern CSL_ArmGicDistIntrf distrIntrf;
147 extern CSL_ArmGicCpuIntrf gCpuIntrf;
149 /* ========================================================================== */
150 /*                          Function Definitions                              */
151 /* ========================================================================== */
153 static void copyVectorTable(void)
155     Uint32 vectorBase = 0x40300000U;
156     Uint32 ocmcRamSize = 512U * 1024U;
158     vectorBase = vectorBase + ocmcRamSize - 0x400U;
160     Uint32 *dest = (Uint32 *)vectorBase;
161     Uint32 *src =  (Uint32 *)vecTbl;
162     Uint32 count;
164     CSL_a15SetVectorTable(vectorBase);
166     for(count = 0; count < sizeof(vecTbl)/sizeof(vecTbl[0]); count++)
167     {
168         dest[count] = src[count];
169     }
172 void startup(void)
174     gCpuIntrf.gicDist = &distrIntrf;
175     gCpuIntrf.cpuIntfBasePtr = (void *)0x48212000U;
176     distrIntrf.distBasePtr = (void *)0x48211000U;
177     gCpuIntrf.initStatus = FALSE;
178     gCpuIntrf.gicDist->initStatus = FALSE;
179     gCpuIntrf.pDefaultIntrHandlers = NULL;
180     gCpuIntrf.pDefaultUserParameter = NULL;
182     CSL_armGicInit(&gCpuIntrf);
185 void Delay(Uint32 delay)
187     volatile Uint32 delay1 = delay;
188     while (delay1--) asm("nop\n");
191 /**
192  * \brief   Enables pacing of interrupts.
193  *
194  * \param   baseAddr    Base address of the CPSW Wrapper Module
195  * \param   pacFlag     The interrpupts for which pacing to be enabled
196  *    'pacFlag' can take any combination of the below values. \n
197  *         CPSW_INT_PACING_C0_RX_PULSE  - Core 0 RX pulse interrupt pacing \n
198  *         CPSW_INT_PACING_C0_TX_PULSE  - Core 0 TX pulse interrupt pacing \n
199  *         CPSW_INT_PACING_C1_RX_PULSE  - Core 1 RX pulse interrupt pacing \n
200  *         CPSW_INT_PACING_C1_TX_PULSE  - Core 1 TX pulse interrupt pacing \n
201  *         CPSW_INT_PACING_C2_RX_PULSE  - Core 2 RX pulse interrupt pacing \n
202  *         CPSW_INT_PACING_C2_TX_PULSE  - Core 2 TX pulse interrupt pacing \n
203  *
204  * \return  None
205  **/
206 void CPSWWrIntPacingEnable(unsigned int baseAddr, unsigned int pacFlag)
208     HWREG(baseAddr + CSL_WR_INT_CONTROL) &= ~CSL_WR_INT_CONTROL_INT_PACE_EN_MASK;
209     HWREG(baseAddr + CSL_WR_INT_CONTROL) |= pacFlag;
212 /**
213  * \brief   Sets the number of transmit interrupts per millisecond.
214  *
215  * \param   baseAddr    Base address of the CPSW Wrapper Module
216  * \param   core        Core number
217  * \param   txIntPerMs  The number of tx interrupts per millisecond
218  *    The maximum value for 'txIntPerMs' is 0x3F.
219  *
220  * \return  None
221  **/
222 void CPSWWrIntTxPerMsSet(unsigned int baseAddr, unsigned int core,
223                          unsigned int txIntPerMs)
225     HWREG(baseAddr + CSL_WR_TX_IMAX(core)) = txIntPerMs;
228 /**
229  * \brief   Sets the number of receive interrupts per millisecond.
230  *
231  * \param   baseAddr    Base address of the CPSW Wrapper Module
232  * \param   core        Core number
233  * \param   rxIntPerMs  The number of rx interrupts per millisecond
234  *    The maximum value for 'rxIntPerMs' is 0x3F.
235  *
236  * \return  None
237  **/
238 void CPSWWrIntRxPerMsSet(unsigned int baseAddr, unsigned int core,
239                          unsigned int rxIntPerMs)
241     HWREG(baseAddr + CSL_WR_RX_IMAX(core)) = rxIntPerMs;
244 /**
245  * \brief   Disables pacing of interrupts
246  *
247  * \param   baseAddr    Base address of the CPSW Wrapper Module
248  * \param   pacFlag     The interrpupts for which pacing to be disabled
249  *    'pacFlag' can take any combination of the below values. \n
250  *         CPSW_INT_PACING_C0_RX_PULSE  - Core 0 RX pulse interrupt pacing \n
251  *         CPSW_INT_PACING_C0_TX_PULSE  - Core 0 TX pulse interrupt pacing \n
252  *         CPSW_INT_PACING_C1_RX_PULSE  - Core 1 RX pulse interrupt pacing \n
253  *         CPSW_INT_PACING_C1_TX_PULSE  - Core 1 TX pulse interrupt pacing \n
254  *         CPSW_INT_PACING_C2_RX_PULSE  - Core 2 RX pulse interrupt pacing \n
255  *         CPSW_INT_PACING_C2_TX_PULSE  - Core 2 TX pulse interrupt pacing \n
256  *
257  * \return  None
258  **/
259 void CPSWWrIntPacingDisable(unsigned int baseAddr, unsigned int pacFlag)
261    HWREG(baseAddr + CSL_WR_INT_CONTROL) &= ~(pacFlag);
264 //-------------------------------------------------------------------------
265 // CPSW Interrupt init
266 //-------------------------------------------------------------------------
267 void CpswInterruptInit(void)
269   CSL_xbarMpuIrqConfigure(CSL_XBAR_INST_MPU_IRQ_92, CSL_XBAR_GMAC_SW_IRQ_RX_PULSE);
271   CSL_xbarMpuIrqConfigure(CSL_XBAR_INST_MPU_IRQ_93, CSL_XBAR_GMAC_SW_IRQ_TX_PULSE);
273     /* Do the interrupt related configurations */
274     gRxIntrParams.triggerType = CSL_ARM_GIC_TRIG_TYPE_HIGH_LEVEL;
275     gRxIntrParams.priority = 0x20U;
277     /*
278      * Assign the ISR to the function pointer to invoke when the
279      * interrupt is raised.
280      */
281     gRxIntrParams.pFnIntrHandler = &ServiceRx;
282     gRxIntrParams.pUserParam = NULL;
284     /* Configure the interrupt Controller */
285     CSL_armGicConfigIntr(&gCpuIntrf, (GMAC_SW_IRQ_RX_PULSE_INT_NUM + 32),
286                          &gRxIntrParams);
288   CpswIntEnable(RX);
290     /* Do the interrupt related configurations */
291     gTxIntrParams.triggerType = CSL_ARM_GIC_TRIG_TYPE_HIGH_LEVEL;
292     gTxIntrParams.priority = 0x20U;
294     /*
295      * Assign the ISR to the function pointer to invoke when the
296      * interrupt is raised.
297      */
298     gTxIntrParams.pFnIntrHandler = &ServiceTx;
299     gTxIntrParams.pUserParam = NULL;
301     /* Configure the interrupt Controller */
302     CSL_armGicConfigIntr(&gCpuIntrf, (GMAC_SW_IRQ_TX_PULSE_INT_NUM + 32),
303                          &gTxIntrParams);
305   CpswIntEnable(TX);
310 //-------------------------------------------------------------------------
311 // Link setup
312 //-------------------------------------------------------------------------
313 Uint32 LinkSetup(Uint32 port, Uint32 speed)
315     Uint32 val, retries;
316     Uint32 phy_addr=0, SlBase=0;
317     Uint32 val16, debug_data;
318     Uint32 speed_duplex=0, speed_detected=100, loopback=0;
319     CSL_CPSW_ALE_PORTCONTROL pPortControlInfo;
320     ENETPHY_DEVICE phyDev;
322     phyDev.miibase = MdioBase;
323     if(port==1)
324     {
325         phy_addr=Phy1Addr;
326         SlBase=CpswSl1Base;
327     }
328     else if(port==2)
329     {
330         phy_addr=Phy2Addr;
331         SlBase=CpswSl2Base;
332     }
333     else
334     {
335         GMAC_log("                                ");
336         return 1;
337     }
339     //put port into a disabled state in ale and mac_sl
340     CSL_CPSW_getAlePortControlReg((CSL_cpswHandle) CpswBase, port, &pPortControlInfo);
341     pPortControlInfo.portState = 0x00U;
342     CSL_CPSW_setAlePortControlReg((CSL_cpswHandle) CpswBase, port, &pPortControlInfo);
344     CSL_CPGMAC_SL_disableGMII((CSL_cpgmacSlHandle) SlBase);
346     //set the mac to non-gig mode to start with incase we error out later
347     switch(speed)
348     {
349         case SPEED_10H:
350             CSL_CPGMAC_SL_disableGigabit((CSL_cpgmacSlHandle) SlBase);
351             CSL_CPGMAC_SL_disableFullDuplex((CSL_cpgmacSlHandle) SlBase);
352             CSL_CPGMAC_SL_disableTxFlowControl((CSL_cpgmacSlHandle) SlBase);
353             CSL_CPGMAC_SL_disableRxFlowControl((CSL_cpgmacSlHandle) SlBase);
354             if(fRMII)
355                 CSL_CPGMAC_SL_disableIFCTLA((CSL_cpgmacSlHandle) SlBase);
356             if(fRGMII)
357                 CSL_CPGMAC_SL_enableExtControl((CSL_cpgmacSlHandle) SlBase);
358             break;
359         case SPEED_100H:
360             CSL_CPGMAC_SL_disableGigabit((CSL_cpgmacSlHandle) SlBase);
361             CSL_CPGMAC_SL_disableFullDuplex((CSL_cpgmacSlHandle) SlBase);
362             CSL_CPGMAC_SL_disableTxFlowControl((CSL_cpgmacSlHandle) SlBase);
363             CSL_CPGMAC_SL_disableRxFlowControl((CSL_cpgmacSlHandle) SlBase);
364             if(fRMII)
365                 CSL_CPGMAC_SL_enableIFCTLA((CSL_cpgmacSlHandle) SlBase);
366             if(fRGMII)
367                 CSL_CPGMAC_SL_disableExtControl((CSL_cpgmacSlHandle) SlBase);
368             break;
369         case SPEED_10F:
370             CSL_CPGMAC_SL_disableGigabit((CSL_cpgmacSlHandle) SlBase);
371             CSL_CPGMAC_SL_enableFullDuplex((CSL_cpgmacSlHandle) SlBase);
372             CSL_CPGMAC_SL_enableTxFlowControl((CSL_cpgmacSlHandle) SlBase);
373             CSL_CPGMAC_SL_enableRxFlowControl((CSL_cpgmacSlHandle) SlBase);
374             if(fRMII)
375                 CSL_CPGMAC_SL_disableIFCTLA((CSL_cpgmacSlHandle) SlBase);
376             if(fRGMII)
377                 CSL_CPGMAC_SL_enableExtControl((CSL_cpgmacSlHandle) SlBase);
378             break;
379         case SPEED_100F:    
380             CSL_CPGMAC_SL_disableGigabit((CSL_cpgmacSlHandle) SlBase);
381             CSL_CPGMAC_SL_enableFullDuplex((CSL_cpgmacSlHandle) SlBase);
382             CSL_CPGMAC_SL_enableTxFlowControl((CSL_cpgmacSlHandle) SlBase);
383             CSL_CPGMAC_SL_enableRxFlowControl((CSL_cpgmacSlHandle) SlBase);
384             if(fRMII)
385                 CSL_CPGMAC_SL_enableIFCTLA((CSL_cpgmacSlHandle) SlBase);
386             if(fRGMII)
387                 CSL_CPGMAC_SL_disableExtControl((CSL_cpgmacSlHandle) SlBase);
388             break;
389         case SPEED_1000F:
390         case SPEED_LB:
391             CSL_CPGMAC_SL_enableGigabit((CSL_cpgmacSlHandle) SlBase);
392             CSL_CPGMAC_SL_enableFullDuplex((CSL_cpgmacSlHandle) SlBase);
393             if(fRGMII)
394                 CSL_CPGMAC_SL_disableExtControl((CSL_cpgmacSlHandle) SlBase);
395             break;
396     }
397   
398     Delay(100000);
400     //check phy is alive
401     if(!CSL_MDIO_isPhyAlive((CSL_mdioHandle) MdioBase, phy_addr))
402     {
403         GMAC_log("                                ");
404         return 2;
405     }
407     //reset phy
408     _ENETPHY_UserAccessWrite((ENETPHY_Handle) &phyDev, ENETPHY_BCR, phy_addr, 0x8000);
409     do
410     {
411         _ENETPHY_UserAccessRead((ENETPHY_Handle) &phyDev, ENETPHY_BCR, phy_addr, &val16);
412     } while(val16>>15);
415     //force phy into desired mode
416     _ENETPHY_UserAccessRead((ENETPHY_Handle) &phyDev, ENETPHY_BCR, phy_addr, &val16);
417     val16 &= ~(1<<12);        //disable auto-negotiate
418     val16 &= ~(1<<14);        //disable loopback
420     switch(speed)
421     {
422         case SPEED_10H:
423             val16 &= ~(1<<13);    //clear speed LSB
424             val16 &= ~(1<<6);     //clear speed MSB
425             val16 &= ~(1<<8);     //clear duplex bit
426             break;
427         case SPEED_100H:
428             val16 |= (1<<13);     //set speed LSB
429             val16 &= ~(1<<6);     //clear speed MSB
430             val16 &= ~(1<<8);     //clear duplex bit
431             break;
432         case SPEED_10F:
433             val16 &= ~(1<<13);     //clear speed LSB
434             val16 &= ~(1<<6);     //clear speed MSB
435             val16 |= (1<<8);      //set duplex bit
436             break;
437         case SPEED_100F:
438             val16 |= (1<<13);     //set speed LSB
439             val16 &= ~(1<<6);     //clear speed MSB
440             val16 |= (1<<8);      //set duplex bit
441             break;
442         case SPEED_1000F:
443             val16 &= ~(1<<13);    //clear speed LSB
444             val16 |= (1<<6);      //set speed MSB
445             val16 |= (1<<8);      //set duplex bit
446             break;
447         case SPEED_LB:
448             //val16 |= (1<<13);     //set speed LSB
449             //val16 &= ~(1<<6);     //clear speed MSB
450             //val16 |= (1<<8);      //set duplex bit
451             val16 &= ~(1<<13);    //clear speed LSB
452             val16 |= (1<<6);      //set speed MSB
453             val16 |= (1<<8);      //set duplex bit
455             val16 |= (1<<14);     //set loopback
456             break;
457     }
458     _ENETPHY_UserAccessWrite((ENETPHY_Handle) &phyDev, ENETPHY_BCR, phy_addr, val16);
460     //special phy setup for external loopback
462     if(speed==SPEED_LB)  //PHY_MICREL_KSZ9031RNX: for 1000M Loopback mode
463     {
464         _ENETPHY_UserAccessRead((ENETPHY_Handle) &phyDev, ENETPHY_1000BT_CONTROL, phy_addr, &debug_data);
465         debug_data |= (1<<12);     //Enable master-slave manual configuration
466         debug_data &= ~(1<<11);     //select slave configuration(required for loopback mode)
467         _ENETPHY_UserAccessWrite((ENETPHY_Handle) &phyDev, ENETPHY_1000BT_CONTROL, phy_addr, debug_data);
468     }
469     else
470     {
471         _ENETPHY_UserAccessRead((ENETPHY_Handle) &phyDev, ENETPHY_1000BT_CONTROL, phy_addr, &debug_data);
472         debug_data &= ~(1<<12);     //Disable master-slave manual configuration  
473         _ENETPHY_UserAccessWrite((ENETPHY_Handle) &phyDev, ENETPHY_1000BT_CONTROL, phy_addr, debug_data);
474     }
476     Delay(100000);
478     //make sure link is up
479     val = 0;
480     retries = 2000;
481     while (retries)
482     {
483         /* First read the BSR of the PHY */
484         _ENETPHY_UserAccessRead((ENETPHY_Handle) &phyDev, ENETPHY_BSR, phy_addr, &val16);
486         if(val16 & ENETPHY_LINK_STATUS)
487         {
488             val = 1;
489         }
491         retries--;
492     }
494     GMAC_log("%s    ", val?"Up":"Down                        " );
495     if(!val)
496     {
497         mdioDump();
498         return 3;
499     }
501     //determine if in loopback
502     Delay(100000);
503     _ENETPHY_UserAccessRead((ENETPHY_Handle) &phyDev, ENETPHY_BCR, phy_addr, &val16);
504     if(val16&(1<<14))
505     {
506         loopback=1;
507     }
509     //use phy specific registers to detect link status
510     // speed_duplex = (speed1, speed0, duplex) where speed 00 = 10mpbs, speed 01 = 100mbps, speed 10 = 1000mbps
511     //PHY_MICREL_KSZ9031RNX:
512     _ENETPHY_UserAccessRead((ENETPHY_Handle) &phyDev, 0x1F, phy_addr, &val16);
514     speed_duplex=(val16>>3)&1 ;         //duplex bit
515     speed_duplex|=((val16>>5)&1)<<1;    //speed[0] bit
516     speed_duplex|=((val16>>6)&1)<<2;    //speed[1] bit
518     switch(speed_duplex)
519     {
520         case 0:
521             GMAC_log("10Mbps Half duplex      ");
522             speed_detected=SPEED_10H;
523             break;
524         case 1:
525             GMAC_log("10Mbps Full duplex      ");
526             speed_detected=SPEED_10F;
527             break;
528         case 2:
529             GMAC_log("100Mbps Half duplex     ");
530             speed_detected=SPEED_100H;
531             break;
532         case 3:
533             if(loopback)
534             {
535                 GMAC_log("Phy Loopback            ");
536                 speed_detected=SPEED_LB;
537             }
538             else
539             {
540                 GMAC_log("100Mbps Full duplex     ");
541                 speed_detected=SPEED_100F;
542             }
543             break;
544         case 5:
545             if(loopback)
546             {
547                 GMAC_log("Phy Loopback            ");
548                 speed_detected=SPEED_LB;
549             }
550             else
551             {
552                 GMAC_log("1000Mbps Full duplex    ");
553                 speed_detected=SPEED_1000F;
554             }
555             break;
556         default:
557             GMAC_log("Unknown                 ");
558             speed_detected=100;
559             break;
560     }
562     // check speed requested vs detected
563     if(speed!=speed_detected)
564         return 4;
566     //if we made it this far successfully, we can enable mac and ale port now
567     CSL_CPSW_getAlePortControlReg((CSL_cpswHandle) CpswBase, port, &pPortControlInfo);
568     pPortControlInfo.portState = 0x03U;
569     CSL_CPSW_setAlePortControlReg((CSL_cpswHandle) CpswBase, port, &pPortControlInfo);
571     CSL_CPGMAC_SL_enableGMII((CSL_cpgmacSlHandle) SlBase);
573     return 0;
576 //-------------------------------------------------------------------------
577 // ALE Dump table
578 //-------------------------------------------------------------------------
579 void CPSWAleDumpTable(void)
581   Uint32  entry;
582   Uint32  word2, word1, word0;
583   Uint32  fIsEmpty=TRUE;
585   GMAC_log("CPSW3G ALE Table:  \n");
586   GMAC_log("Entry:          Word2:          Word1:          Word0:          \n");
587   GMAC_log("----------      ----------      ----------      ----------      \n");
589   for(entry=0;entry<1024;entry++)
590   {
591     CSL_CPSW_getAleTableEntry((CSL_cpswHandle) CpswBase, entry, &word0, &word1, &word2);
592     if ( word2 || word1 || word0 )
593       if( !(word2==0x7f && word1==0xffffffff && word0==0xffffffff) )
594       {
595         fIsEmpty=FALSE;
596         GMAC_log("%10d      0x%08x      0x%08x      0x%08x\n", entry, word2, word1, word0 );
597       }
598   }
599   if ( fIsEmpty )
600     GMAC_log("ALE table is empty.\n");
603 // dump switch stats
604 void CPSWStatsDump(void)
606   GMAC_log("CPSW3G Stats:  \n");
607   GMAC_log("Stat:                               \n");
608   GMAC_log("---------------------     ----------\n");
609   GMAC_log("RxGoodFrames              %10u      \n",   HWREG(CpswStatBase+0x00));
610   GMAC_log("RxBroadcastFrames         %10u      \n",   HWREG(CpswStatBase+0x04));
611   GMAC_log("RxMulticastFrames         %10u      \n",   HWREG(CpswStatBase+0x08));
612   GMAC_log("RxPauseFrames             %10u      \n",   HWREG(CpswStatBase+0x0c));
613   GMAC_log("RxCRCErrors               %10u      \n",   HWREG(CpswStatBase+0x10));
614   GMAC_log("RxAlignCodeErrors         %10u      \n",   HWREG(CpswStatBase+0x14));
615   GMAC_log("RxOversizedFrames         %10u      \n",   HWREG(CpswStatBase+0x18));
616   GMAC_log("RxJabberFrames            %10u      \n",   HWREG(CpswStatBase+0x1c));
617   GMAC_log("RxUndersizedFrames        %10u      \n",   HWREG(CpswStatBase+0x20));
618   GMAC_log("RxFragments               %10u      \n",   HWREG(CpswStatBase+0x24));
619   GMAC_log("RxOctets                  %10u      \n",   HWREG(CpswStatBase+0x30));
620   GMAC_log("TxGoodFrames              %10u      \n",   HWREG(CpswStatBase+0x34));
621   GMAC_log("TxBroadcastFrames         %10u      \n",   HWREG(CpswStatBase+0x38));
622   GMAC_log("TxMulticastFrames         %10u      \n",   HWREG(CpswStatBase+0x3c));
623   GMAC_log("TxPauseFrames             %10u      \n",   HWREG(CpswStatBase+0x40));
624   GMAC_log("TxDeferredFrames          %10u      \n",   HWREG(CpswStatBase+0x44));
625   GMAC_log("TxCollisionFrames         %10u      \n",   HWREG(CpswStatBase+0x48));
626   GMAC_log("TxSingleCollFrames        %10u      \n",   HWREG(CpswStatBase+0x4c));
627   GMAC_log("TxMultCollFrames          %10u      \n",   HWREG(CpswStatBase+0x50));
628   GMAC_log("TxExcessiveCollisions     %10u      \n",   HWREG(CpswStatBase+0x54));
629   GMAC_log("TxLateCollisions          %10u      \n",   HWREG(CpswStatBase+0x58));
630   GMAC_log("TxUnderrun                %10u      \n",   HWREG(CpswStatBase+0x5c));
631   GMAC_log("TxCarrierSenseErrors      %10u      \n",   HWREG(CpswStatBase+0x60));
632   GMAC_log("TxOctets                  %10u      \n",   HWREG(CpswStatBase+0x64));
633   GMAC_log("64octetFrames             %10u      \n",   HWREG(CpswStatBase+0x68));
634   GMAC_log("65t127octetFrames         %10u      \n",   HWREG(CpswStatBase+0x6c));
635   GMAC_log("128t255octetFrames        %10u      \n",   HWREG(CpswStatBase+0x70));
636   GMAC_log("256t511octetFrames        %10u      \n",   HWREG(CpswStatBase+0x74));
637   GMAC_log("512t1023octetFrames       %10u      \n",   HWREG(CpswStatBase+0x78));
638   GMAC_log("1024UPoctetFrames         %10u      \n",   HWREG(CpswStatBase+0x7c));
639   GMAC_log("NetOctets                 %10u      \n",   HWREG(CpswStatBase+0x80));
640   GMAC_log("SOF Overrun               %10u      \n",   HWREG(CpswStatBase+0x84));
641   GMAC_log("MOF Overrun               %10u      \n",   HWREG(CpswStatBase+0x88));
642   GMAC_log("DMA Overrun               %10u      \n",   HWREG(CpswStatBase+0x8c));
645 // clear switch stats
646 void CPSWStatsClear(void)
648   //GMAC_log("Clearing CPSW_3G stats....");
649   HWREG(CpswStatBase+0x00) = 0xffffffff;
650   HWREG(CpswStatBase+0x04) = 0xffffffff;
651   HWREG(CpswStatBase+0x08) = 0xffffffff;
652   HWREG(CpswStatBase+0x0c) = 0xffffffff;
653   HWREG(CpswStatBase+0x10) = 0xffffffff;
654   HWREG(CpswStatBase+0x14) = 0xffffffff;
655   HWREG(CpswStatBase+0x18) = 0xffffffff;
656   HWREG(CpswStatBase+0x1c) = 0xffffffff;
657   HWREG(CpswStatBase+0x20) = 0xffffffff;
658   HWREG(CpswStatBase+0x24) = 0xffffffff;
659   HWREG(CpswStatBase+0x30) = 0xffffffff;
660   HWREG(CpswStatBase+0x34) = 0xffffffff;
661   HWREG(CpswStatBase+0x38) = 0xffffffff;
662   HWREG(CpswStatBase+0x3c) = 0xffffffff;
663   HWREG(CpswStatBase+0x40) = 0xffffffff;
664   HWREG(CpswStatBase+0x44) = 0xffffffff;
665   HWREG(CpswStatBase+0x48) = 0xffffffff;
666   HWREG(CpswStatBase+0x4c) = 0xffffffff;
667   HWREG(CpswStatBase+0x50) = 0xffffffff;
668   HWREG(CpswStatBase+0x54) = 0xffffffff;
669   HWREG(CpswStatBase+0x58) = 0xffffffff;
670   HWREG(CpswStatBase+0x5c) = 0xffffffff;
671   HWREG(CpswStatBase+0x60) = 0xffffffff;
672   HWREG(CpswStatBase+0x64) = 0xffffffff;
673   HWREG(CpswStatBase+0x68) = 0xffffffff;
674   HWREG(CpswStatBase+0x6c) = 0xffffffff;
675   HWREG(CpswStatBase+0x70) = 0xffffffff;
676   HWREG(CpswStatBase+0x74) = 0xffffffff;
677   HWREG(CpswStatBase+0x78) = 0xffffffff;
678   HWREG(CpswStatBase+0x7c) = 0xffffffff;
679   HWREG(CpswStatBase+0x80) = 0xffffffff;
680   HWREG(CpswStatBase+0x84) = 0xffffffff;
681   HWREG(CpswStatBase+0x88) = 0xffffffff;
682   HWREG(CpswStatBase+0x8c) = 0xffffffff;
683   //GMAC_log("done\n");
686 // CPSW init
687 void CpswInit(Uint32 base)
689   CSL_CPSW_PORTSTAT       portStatsCfg;
690   Uint32 pPortTxPriMap = 0x0U;
692   portStatsCfg.p0StatEnable   =   1;
693   portStatsCfg.p1StatEnable   =   1;
694   portStatsCfg.p2StatEnable   =   1;
696   //enable stats
697   CSL_CPSW_setPortStatsEnableReg ((CSL_cpswHandle) base, &portStatsCfg);
699   //configure rx->cpdma channel mapping
700   //  port 1, pri 0 ---> cpdma channel 0
701   //  port 1, pri 1 ---> cpdma channel 1
702   //  port 1, pri 2 ---> cpdma channel 2
703   //  port 1, pri 3 ---> cpdma channel 3
704   //  port 2, pri 0 ---> cpdma channel 4
705   //  port 2, pri 1 ---> cpdma channel 5
706   //  port 2, pri 2 ---> cpdma channel 6
707   //  port 2, pri 3 ---> cpdma channel 7
708   HWREG(CpswPort0Base + CSL_CPSW_3G_P0_CPDMA_RX_CH_MAP) = 0x00000000;
709   CSL_CPSW_setPortTxPriMapReg((CSL_cpswHandle) CpswBase, 0, &pPortTxPriMap);
712 // ALE init
713 void AleInit(Uint32 base)
715   CSL_CPSW_ALE_PORTCONTROL pPortControlInfo;
716   //init
717   CSL_CPSW_clearAleTable((CSL_cpswHandle) base);
719   //enable learning
720   CSL_CPSW_getAlePortControlReg((CSL_cpswHandle) base, 0, &pPortControlInfo);
721   pPortControlInfo.noLearnModeEnable = 0x1;
722   CSL_CPSW_setAlePortControlReg((CSL_cpswHandle) base, 0, &pPortControlInfo);
723   CSL_CPSW_getAlePortControlReg((CSL_cpswHandle) base, 1, &pPortControlInfo);
724   pPortControlInfo.noLearnModeEnable = 0x1;
725   CSL_CPSW_setAlePortControlReg((CSL_cpswHandle) base, 1, &pPortControlInfo);
726   CSL_CPSW_getAlePortControlReg((CSL_cpswHandle) base, 2, &pPortControlInfo);
727   pPortControlInfo.noLearnModeEnable = 0x1;
728   CSL_CPSW_setAlePortControlReg((CSL_cpswHandle) base, 2, &pPortControlInfo);
729   //add ale entries for port 0,1,2
730   CSL_CPSW_setAleTableEntry((CSL_cpswHandle) base, 0, 0xadbeef00, 0xd00000de, 0x0);
731   CSL_CPSW_setAleTableEntry((CSL_cpswHandle) base, 1, 0xadbeef01, 0xd00000de, 0x4);
732   CSL_CPSW_setAleTableEntry((CSL_cpswHandle) base, 2, 0xadbeef02, 0xd00000de, 0x8);
734   CSL_CPSW_enableAle((CSL_cpswHandle) base);
735   //port into forwarding mode
736   CSL_CPSW_getAlePortControlReg((CSL_cpswHandle) base, 0, &pPortControlInfo);
737   pPortControlInfo.portState = 0x03U;
738   CSL_CPSW_setAlePortControlReg((CSL_cpswHandle) base, 0, &pPortControlInfo);
741 void AlePortDisable(Uint32 base)
743   CSL_CPSW_ALE_PORTCONTROL pPortControlInfo;
744   CSL_CPSW_disableAle((CSL_cpswHandle) base);
745   CSL_CPSW_clearAleTable((CSL_cpswHandle) base);
746   //port into forwarding mode
747   CSL_CPSW_getAlePortControlReg((CSL_cpswHandle) base, 0, &pPortControlInfo);
748   pPortControlInfo.portState = 0x00U;
749   CSL_CPSW_setAlePortControlReg((CSL_cpswHandle) base, 0, &pPortControlInfo);
750   CSL_CPSW_getAlePortControlReg((CSL_cpswHandle) base, 1, &pPortControlInfo);
751   pPortControlInfo.portState = 0x00U;
752   CSL_CPSW_setAlePortControlReg((CSL_cpswHandle) base, 1, &pPortControlInfo);
753   CSL_CPSW_getAlePortControlReg((CSL_cpswHandle) base, 2, &pPortControlInfo);
754   pPortControlInfo.portState = 0x00U;
755   CSL_CPSW_setAlePortControlReg((CSL_cpswHandle) base, 2, &pPortControlInfo);
758 // CPDMA init
759 void CpswCpdmaInit(Uint32 base)
761   Uint32 chan;
763   // clear interrupts to start clean
764   CSL_CPSW_setCpdmaTxEndOfIntVector((CSL_cpdmaHandle) base);
765   CSL_CPSW_setCpdmaRxEndOfIntVector((CSL_cpdmaHandle) base);
767   CSL_CPSW_setCpdmaRxBufOffset((CSL_cpdmaHandle) base, 0x0);
769   // enable rx and tx
770   CSL_CPSW_enableCpdmaTx((CSL_cpdmaHandle) base);
771   CSL_CPSW_enableCpdmaRx((CSL_cpdmaHandle) base);
773   // enable rx and tx interrupts for all channels
774   for(chan=0;chan<8;chan++)
775   {
776         CSL_CPSW_enableCpdmaTxInt((CSL_cpdmaHandle) base, chan);
777         CSL_CPSW_enableCpdmaRxInt((CSL_cpdmaHandle) base, chan);
778   }
781 // Cpsw wrapper init
782 void CpswWrInit(Uint32 base)
784   // set prescaler and interrupts per ms
785   HWREG(base + CSL_WR_INT_CONTROL) = 500;
786   CPSWWrIntRxPerMsSet(base, 0, 2);
787   CPSWWrIntTxPerMsSet(base, 0, 2);
788   //enable interrupt pacing
789   if(fPacing)
790     CPSWWrIntPacingEnable(base, CPSW_INT_PACING_C0_RX_PULSE | CPSW_INT_PACING_C0_TX_PULSE );
793 // Enable cpsw level interrupts
794 void CpswIntEnable(Uint32 dir)
796   Uint32 chan;
798   if(dir==RX)
799     for(chan=0;chan<8;chan++)
800           CSL_CPSW_enableWrRxInt((CSL_wrHandle) CpswWrBase, 0, chan);
801   else
802     for(chan=0;chan<8;chan++)
803           CSL_CPSW_enableWrTxInt((CSL_wrHandle) CpswWrBase, 0, chan);
806 // Disable cpsw level interrupts
807 int CpswIntDisable(Uint32 dir)
809   Uint32 chan, ret_val=0;
811   if(dir==RX)
812   {
813     if( HWREG(CpswWrBase + CSL_WR_RX_EN(0)) )
814       ret_val=1;
815     for(chan=0;chan<8;chan++)
816           CSL_CPSW_disableWrRxInt((CSL_wrHandle) CpswWrBase, 0, chan);
817   }
818   else
819   {
820     if( HWREG(CpswWrBase + CSL_WR_TX_EN(0)) )
821       ret_val=1;
822     for(chan=0;chan<8;chan++)
823           CSL_CPSW_disableWrRxInt((CSL_wrHandle) CpswWrBase, 0, chan);
824   }
825   return ret_val;
828 // Descriptor init
829 void DescInit(void)
831   Uint32 num_desc, i;
832   Uint32 chan;
833   Desc *rd;
834   Desc *td;
835   Uint32 tmp;
837   //RX descriptor init
838   //GMAC_log("Initializing RX descriptors\n");
839   num_desc=RX_NUM_DESC;
840   rd=(Desc *)CpswCppiRamBase;
841   //for(chan=0;chan<8;chan++)
842   for(chan=0;chan<1;chan++)
843   {
844     RxHead[chan]=rd;
845     for(i=0;i<num_desc;i++)
846     {
847       if(i!=(num_desc-1))
848         rd->NextDesc    = (Uint32)rd+sizeof(*rd);
849       else
850         rd->NextDesc    = 0;
851       rd->BufPtr        = BUFFER_BASE + ((chan*num_desc)+i)*0x800;
852       rd->Off_BufLen    = BUFFER_SIZE;
853       rd->Flags_PktLen  = OWNERSHIP_BIT;
854       rd->OrigQueue     = chan;
856       RxTail[chan]=rd;
857       tmp=(Uint32)rd+sizeof(*rd);
858       rd=(Desc*)tmp;
859     }
860   //GMAC_log("RxHead[%d]:  0x%08x    RxTail[%d]:  0x%08x\n", chan, RxHead[chan], chan, RxTail[chan]);
861   RxQueueCnt[chan]=RX_NUM_DESC;
862   CSL_CPSW_setCpdmaRxHdrDescPtr((CSL_cpdmaHandle) CpswCpdmaBase, (Uint32)RxHead[chan], chan);
863   }
865   //TX descriptor init
866   num_desc=TX_NUM_DESC;
867   //GMAC_log("Initializing free TX descriptors\n");
868   td=(Desc*)rd;
869   TxFreeHead=td;
870   for(i=0;i<num_desc;i++)
871   {
872     if(i!=(num_desc-1))
873       td->NextDesc    = (Uint32)td+sizeof(*td);
874     else
875       td->NextDesc    = 0;
876     td->BufPtr        = BUFFER_BASE + ((chan*num_desc)+i)*0x800;
877     td->Off_BufLen    = BUFFER_SIZE;
878     td->Flags_PktLen  = SOF_AND_EOF_BIT;
879     td->OrigQueue     = 8;
881     TxFreeTail=td;
882     tmp=(Uint32)td+sizeof(*td);
883     td=(Desc*)tmp;
884   }
885   TxFreeCnt=TX_NUM_DESC;
886   //GMAC_log("TxFreeHead:  0x%08x    TxFreeTail:  0x%08x\n", TxFreeHead, TxFreeTail);
889 // build and transmit packet
890 int TransmitPacket(Uint32 pkt_len, Uint32 port)
892   Uint32 data_len;
893   Desc *pDesc;
894   ETH_PKT *pPkt;
895   Uint8 *data;
896   int i, ret_val=0;
898   fTxP=TRUE;
900   //get descriptor
901   pDesc=TxFreeHead;
902   if(pDesc!=NULL)
903   {
904     TxFreeCnt--;
905     TxFreeHead=(Desc *)pDesc->NextDesc;
906     if(TxFreeHead==NULL)
907       TxFreeTail=NULL;
909     fTxP=FALSE;
911     pPkt = (ETH_PKT *)(pDesc->BufPtr);
912     pkt_len = pkt_len-4;
913     data_len = pkt_len-sizeof(ETH_HEADER);
915     //Update descriptor for transmit
916     pDesc->NextDesc = 0;
917     pDesc->Flags_PktLen = SOF_AND_EOF_BIT | OWNERSHIP_BIT | pkt_len;
919     //Build actual packet data
920     if(port==1)
921     {
922       pPkt->Eth.UpperDstMac = 0xde00;
923       pPkt->Eth.LowerDstMac = 0x01efbead;
924     }
925     else
926     {
927       pPkt->Eth.UpperDstMac = 0xde00;
928       pPkt->Eth.LowerDstMac = 0x02efbead;
929     }
930     pPkt->Eth.UpperSrcMac = 0xde00;
931     pPkt->Eth.LowerSrcMac = 0x00efbead;
932     pPkt->Eth.Type = 0x0008;
934     data=(Uint8 *)&pPkt->Data;
935     for(i=0;i<data_len;i++)
936     {
937       *data=i&0xff;
938       data++;
939     }
941     TxPacket(pDesc);
942   }
943   else
944   {
945     fTxP=FALSE;
946     ret_val = 1;
947   }
949   return ret_val;
952 // Service Rx completion queue
953 void ServiceRx(void *arg) 
955   Uint32 chan=0, serviced=0, pend_int;
956   Desc *curr,*next,*last,*processed;
958   //disable switch and clear system interrupt
959   CpswIntDisable(RX);
960   CSL_CPSW_setCpdmaRxEndOfIntVector((CSL_cpdmaHandle) CpswCpdmaBase);
961   pend_int=CSL_CPSW_getCpdmaRxIntStatMasked((CSL_cpdmaHandle) CpswCpdmaBase);
962   while(pend_int && serviced<=NUM_RX_SERVICE)
963   {
964     for(chan=0;chan<8;chan++)
965     {
966       //update pending interrupts
967       if((pend_int>>chan)&1)
968       {
969         CSL_a15InvDataCache(RxHead[chan], sizeof(Desc));
970         CSL_a15InvDataCache(RxTail[chan], sizeof(Desc));
971         curr=RxHead[chan];
972         last=RxTail[chan];
973         CSL_a15InvDataCache(curr->BufPtr, BUFFER_SIZE);
974         if(curr!=NULL)
975         {
976           while( (curr->Flags_PktLen & OWNERSHIP_BIT)==0 )
977           {
978             if( (curr->Flags_PktLen & SOF_AND_EOF_BIT)==0 )
979             {
980               GMAC_log("ERROR, SOF and EOF not set\n");
981               break;
982             }
983             processed=curr;
984             RxPackets[chan]++;
985             serviced++;
987             //reset queue head
988             next = (Desc*)curr->NextDesc;
989             RxHead[chan] = next;
991             //detect misqueue
992             if( (curr->Flags_PktLen & EOQ_BIT) )
993               if(next!=NULL)
994               {
995                 CSL_CPSW_setCpdmaRxHdrDescPtr((CSL_cpdmaHandle) CpswCpdmaBase, (Uint32)RxHead[chan], chan);
996                 RxMisqueue[chan]++;
997               }
999             //reset queue tail
1000             last->NextDesc = (Uint32)curr;
1001             RxTail[chan] = curr;
1003             //reset descriptor for recycling
1004             curr->NextDesc      = 0;
1005             curr->Off_BufLen    = BUFFER_SIZE;
1006             curr->Flags_PktLen  = OWNERSHIP_BIT;
1008             // update curr and last to repeat loop
1009             if(next!=NULL)
1010             {
1011               curr=RxHead[chan];
1012               last=RxTail[chan];
1013             }
1014             else
1015             {
1016               RxTail[chan]=NULL;
1017               break;
1018             }
1019           }
1020           // write last processed descriptor
1021           CSL_CPSW_setCpdmaRxCp((CSL_cpdmaHandle) CpswCpdmaBase, chan, (Uint32)processed);
1022         }
1023       }
1024           pend_int=CSL_CPSW_getCpdmaRxIntStatMasked((CSL_cpdmaHandle) CpswCpdmaBase);
1025     }
1026   }
1027   // re-enable switch interrupt
1028   CpswIntEnable(RX);
1031 // Service TX completion queue
1032 void ServiceTx(void *arg) 
1034   Uint32 pend_int, chan, orig_queue, serviced=0;
1035   Desc *curr,*next,*last,*processed;
1036   Uint32 fMisQ=FALSE;
1037   Uint32 last_process;
1039   pend_int=CSL_CPSW_getCpdmaTxIntStatMasked((CSL_cpdmaHandle) CpswCpdmaBase);
1041   //disable switch and clear system interrupt
1042   CpswIntDisable(TX);
1043   CSL_CPSW_setCpdmaTxEndOfIntVector((CSL_cpdmaHandle) CpswCpdmaBase);
1045   //begin processing
1046   while(pend_int && serviced<=NUM_TX_SERVICE)
1047   {
1048     for(chan=0;chan<8;chan++)
1049     {
1050       fMisQ=FALSE;
1051       if((pend_int>>chan)&1)
1052       {
1053         processed=TxHead[chan];
1054         serviced++;
1055         if(processed!=NULL)
1056         {
1057           //Normal processing
1058           while( (processed->Flags_PktLen & OWNERSHIP_BIT)==0 && !fMisQ)
1059           {
1060             TxPackets[chan]++;
1061             //serviced++;
1062             TxQueueCnt[chan]--;
1064             //reset queue head
1065             next=(Desc*)processed->NextDesc;
1066             TxHead[chan] = next;
1068             if( (processed->Flags_PktLen & EOQ_BIT) )
1069               if(next!=NULL)
1070               {
1071                 CSL_CPSW_setCpdmaTxHdrDescPtr((CSL_cpdmaHandle) CpswCpdmaBase, (Uint32)TxHead[chan], chan);
1072                 fMisQ=TRUE;
1073                 TxMisqueue[chan]++;
1074               }
1076             orig_queue = processed->OrigQueue;
1077             //original packet came from RX
1078             if(orig_queue<8)
1079             {
1080               //update descriptor for recycling
1081               processed->NextDesc      = 0;
1082               processed->Off_BufLen    = BUFFER_SIZE;
1083               processed->Flags_PktLen  = OWNERSHIP_BIT;
1085               curr=RxHead[orig_queue];
1086               last=RxTail[orig_queue];
1087               if(curr!=NULL && last!=NULL)
1088                 last->NextDesc = (Uint32)processed;
1089               else
1090               {
1091                 RxHead[orig_queue]=processed;
1092                 CSL_CPSW_setCpdmaRxHdrDescPtr((CSL_cpdmaHandle) CpswCpdmaBase, (Uint32)RxHead[orig_queue], orig_queue);
1093               }
1094               //update queue tail
1095               RxTail[orig_queue] = processed;
1096               RxQueueCnt[orig_queue]++;
1097             }
1098             //original packet came from TX
1099             else
1100             {
1101               //if((Uint32)processed<0x4a103400)
1102               //  GMAC_log("service tx: orig_queue error, processed: 0x%08x, orig_queue: %d\n", processed, orig_queue);
1103               processed->NextDesc      = 0;
1104               processed->Off_BufLen    = BUFFER_SIZE;
1105               processed->Flags_PktLen  = SOF_AND_EOF_BIT;
1106               //processed->OrigQueue     = 8;
1108               curr=TxFreeHead;
1109               last=TxFreeTail;
1110               if(curr!=NULL && last!=NULL)
1111                 last->NextDesc = (Uint32)processed;
1112               else
1113                 TxFreeHead=processed;
1114               TxFreeTail=processed;
1115               TxFreeCnt++;
1116             }
1117             last_process=(Uint32)processed;
1119             //advance to next descriptor or exit if there is none
1120             if(next!=NULL)
1121               processed=next;
1122             else
1123             {
1124               TxTail[chan]=NULL;
1125               break;
1126             }
1127           }
1128           //write last processed descriptor
1129           CSL_CPSW_setCpdmaTxCp((CSL_cpdmaHandle) CpswCpdmaBase, chan, last_process);
1130         }
1131       }
1132       //update pending interrupts
1133       pend_int=CSL_CPSW_getCpdmaTxIntStatMasked((CSL_cpdmaHandle) CpswCpdmaBase);
1134     }
1135   }
1136   //re-enable switch interrupt
1137   CpswIntEnable(TX);
1140 //TxPacket
1141 //  Packet is transmitted based on orig queue
1142 //  Orig queue is channel packet was received on or tx free queue descriptor was popped off
1143 void TxPacket(Desc *TxDesc)
1145   Uint32 chan, flags;
1146   Desc *curr, *last;
1148   fTxP2=TRUE;
1150   chan = TxDesc->OrigQueue;
1151   if(chan>=8)
1152     chan-=8;
1154   curr=TxHead[chan];
1155   last=TxTail[chan];
1157   __sync_synchronize();
1158   CSL_a15WbDataCache(TxDesc, sizeof(Desc));
1159   CSL_a15WbDataCache(TxDesc->BufPtr, BUFFER_SIZE);
1161   if(curr==NULL)
1162   {
1163     TxHead[chan]=TxDesc;
1164     TxTail[chan]=TxDesc;
1165     TxQueueCnt[chan]++;
1166     CSL_CPSW_setCpdmaTxHdrDescPtr((CSL_cpdmaHandle) CpswCpdmaBase, (Uint32)TxDesc, chan);
1167   }
1168   else
1169   {
1170     TxQueueCnt[chan]++;
1171     last->NextDesc = (Uint32)TxDesc;
1172     TxTail[chan]=TxDesc;
1174     flags=last->Flags_PktLen;
1175     if( (flags & EOQ_BIT) )
1176     {
1177       CSL_CPSW_setCpdmaTxHdrDescPtr((CSL_cpdmaHandle) CpswCpdmaBase, (Uint32)TxDesc, chan);
1178       TxMisqueue[chan]++;
1179       flags&=~EOQ_BIT;
1180       last->Flags_PktLen=flags;
1181     }
1182   }
1184   fTxP2=FALSE;
1187 // Dump host port stats
1188 void HostStats(void)
1190   Uint32 chan;
1192   GMAC_log("Channel      RxPackets       TxPackets       RxMisqueue      TxMisqueue      \n");
1193   GMAC_log("-------      ----------      ----------      ----------      ----------      \n");
1195   for(chan=0;chan<8;chan++)
1196     GMAC_log("%7d      %10d      %10d      %10d      %10d      \n", chan, RxPackets[chan], TxPackets[chan], RxMisqueue[chan], TxMisqueue[chan]);
1200 // dump some internal stats
1201 void DebugStats(void)
1203   Uint32 chan;
1205   GMAC_log("Channel      RxHead          RxTail          RxQueueCnt      RxHDP           TxHead          TxTail          TxQueueCnt      TxHDP           \n");
1206   GMAC_log("-------      ----------      ----------      ----------      ----------      ----------      ----------      ----------      ----------      \n");
1208   for(chan=0;chan<8;chan++)
1209     GMAC_log("%7d      0x%08x      0x%08x      0x%08x      0x%08x      0x%08x      0x%08x      0x%08x      0x%08x      \n",
1210                 chan,
1211                 RxHead[chan],
1212                 RxTail[chan],
1213                 RxQueueCnt[chan],
1214                 HWREG(CpswCpdmaBase + CSL_CPDMA_RX_HDP(chan)),
1215                 TxHead[chan],
1216                 TxTail[chan],
1217                 TxQueueCnt[chan],
1218                 HWREG(CpswCpdmaBase + CSL_CPDMA_TX_HDP(chan)) );
1219   GMAC_log(" TxFree      N/A             N/A             N/A             N/A             0x%08x      0x%08x      0x%08x      N/A             \n", TxFreeHead, TxFreeTail, TxFreeCnt );
1222 // dump queue chain
1223 void DumpQueue(Uint32 channel)
1225   Uint32 cnt=0;
1226   Desc *pd;
1228   GMAC_log("dump queue %d\n", channel);
1229   GMAC_log("\nChannel      Descriptor      NextDesc        BufPtr          Off_BufLen      Flags_Pkt       Orig_Queue      \n");
1230   GMAC_log(  "-------      ----------      ----------      ----------      ----------      ----------      ----------      \n");
1231   if(channel<8)
1232     pd=RxHead[channel];
1233   else
1234     pd=TxFreeHead;
1235   while(pd!=NULL)
1236   {
1237     GMAC_log("%7d      0x%08x      0x%08x      0x%08x      0x%08x      0x%08x      0x%08x      \n", channel, pd, pd->NextDesc, pd->BufPtr, pd->Off_BufLen, pd->Flags_PktLen, pd->OrigQueue );
1238     pd=(Desc *)pd->NextDesc;
1239     cnt++;
1240   }
1241   GMAC_log("Channel %d queue cnt: %d\n", channel, cnt);
1244 //*****************************************************************************
1245 //  mdioDump
1246 //****************************************************************************/
1247 void mdioDump(void)
1249   unsigned int i, phy_addr1, phy_addr2;
1250   Uint32 val16, val16_b;
1251   ENETPHY_DEVICE phyDev;
1253   phyDev.miibase = MdioBase;
1255   phy_addr1=Phy1Addr;
1256   phy_addr2=Phy2Addr;
1258   GMAC_log("MDIO register dump\n");
1259   GMAC_log("Reg:     Port 1:     Port 2:     \n");
1260   for(i=0; i<32; i++)
1261   {
1262     _ENETPHY_UserAccessRead((ENETPHY_Handle) &phyDev, i+0, phy_addr1, &val16);
1263     _ENETPHY_UserAccessRead((ENETPHY_Handle) &phyDev, i+0, phy_addr2, &val16_b);
1264     GMAC_log("0x%02x     0x%04x      0x%04x\n",  i+0, val16, val16_b);
1265   }
1268 Uint32 CheckStats(Uint32 speed)
1270     int timeout=0;
1272     if(speed==SPEED_10H || speed==SPEED_100H)
1273     {
1274         while(1)
1275         {
1276             //if tx_exc_coll =TEST_NUM_PACKETS and rx_frag=512 and tx_coll=512, we're done
1277             if( HWREG(CpswStatBase+0x54)==TEST_NUM_PACKETS )
1278             {
1279                 if( HWREG(CpswStatBase+0x48)==(TEST_NUM_PACKETS*16) )
1280                     return 0;
1281             }
1283             //if any rx errors or good we're done with error
1284             if( HWREG(CpswStatBase+0x10) ||
1285                 HWREG(CpswStatBase+0x14) ||
1286                 HWREG(CpswStatBase+0x18) ||
1287                 HWREG(CpswStatBase+0x1c) ||
1288                 HWREG(CpswStatBase+0x20) ||
1289                 HWREG(CpswStatBase+0x00)
1290                 )
1291                 return 6;
1293             //if any tx good or errors we're done with error
1294             if( HWREG(CpswStatBase+0x34) ||
1295                 HWREG(CpswStatBase+0x5c) ||
1296                 HWREG(CpswStatBase+0x60)
1297                 )
1298                 return 5;
1300             Delay(1000000);
1301             timeout++;
1302             if(timeout==50)
1303                 return 8;
1304         }
1305     }
1306     else
1307     {
1308         while(1)
1309         {
1310         //if tx good and rx good, we're done
1311         if( HWREG(CpswStatBase+0x34)==TEST_NUM_PACKETS )
1312         {
1313             if( HWREG(CpswStatBase+0x00)==TEST_NUM_PACKETS )
1314                 return 0;
1315         }
1317         //if any rx errors we're done with error
1318         if( HWREG(CpswStatBase+0x10) ||
1319             HWREG(CpswStatBase+0x14) ||
1320             HWREG(CpswStatBase+0x18) ||
1321             HWREG(CpswStatBase+0x1c) ||
1322             HWREG(CpswStatBase+0x20) ||
1323             HWREG(CpswStatBase+0x24)
1324             )
1325             return 6;
1327         //if any tx collisions or errors we're done with error
1328         if( HWREG(CpswStatBase+0x44) ||
1329             HWREG(CpswStatBase+0x48) ||
1330             HWREG(CpswStatBase+0x4c) ||
1331             HWREG(CpswStatBase+0x50) ||
1332             HWREG(CpswStatBase+0x54) ||
1333             HWREG(CpswStatBase+0x58) ||
1334             HWREG(CpswStatBase+0x5c) ||
1335             HWREG(CpswStatBase+0x60)
1336             )
1337             return 5;
1339             Delay(1000000);
1340             timeout++;
1341             if(timeout==50)
1342                 return 8;
1343         }
1344     }
1347 //*****************************************************************************
1348 //  Main
1349 //****************************************************************************/
1350 int main(void)
1352     Uint32 size, port=1, i, speed;
1353     Uint32 ret_val=0, error_code=0;
1354     Uint32 num_ports=2, phy_type;
1355     Uint32 fDone=FALSE;
1356     Uint32 timeout=0;
1357     Board_initCfg boardCfg;
1359     /* Copy the vector table to desired location.  */
1360     copyVectorTable();
1362     /* Configure system */
1363     startup();
1365     /* Call board init functions */
1366     boardCfg = BOARD_INIT_UART_STDIO;
1367     Board_init(boardCfg);
1369     //Phy_clk_gen_config(0D
1370     fRGMII=TRUE;
1371     fGig=TRUE;
1372     fRMII=TRUE;
1374     Phy1Addr=GMAC_PORT1_ETHERNET_PHY_ADRESS;
1375     Phy2Addr=GMAC_PORT2_ETHERNET_PHY_ADRESS;
1377     UART_printf("\n*********************************************\n"); 
1378     UART_printf  ("*                 GMAC Test                 *\n");
1379     UART_printf  ("*********************************************\n");
1381     //basic clock, pin mux setup
1383     /* Select RGMII 2 ports GMIIx_SEL = 2 for RGMII*/ 
1384     CSL_FINS (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->CONTROL_IO_1,
1385       CONTROL_CORE_CONTROL_IO_1_GMII1_SEL, 2U);
1386     CSL_FINS (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->CONTROL_IO_1,
1387       CONTROL_CORE_CONTROL_IO_1_GMII2_SEL, 2U);
1389     /*GMAC RESET ISOLATION Enable*/
1390     CSL_FINS (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->CONTROL_IO_2,
1391       CONTROL_CORE_CONTROL_IO_2_GMAC_RESET_ISOLATION_ENABLE, 0U);
1392     CSL_FINS (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->CONTROL_IO_2,
1393       CONTROL_CORE_CONTROL_IO_2_GMAC_RESET_ISOLATION_ENABLE, 1U);
1395     //using the arm cycle counter for a sort of pseudo-random number generator
1396     CycleCountEnable();
1398     //test
1399     GMAC_log("Test                    Port    Link    Link-Speed              Status    Error\n");
1400     GMAC_log("--------------------    ----    ----    --------------------    ------    ---------------------------\n");
1401     for(port=1;port<=num_ports;port++)
1402     {
1403         phy_type=PHY_MICREL_KSZ9031RNX;
1405         speed=SPEED_LB;
1406         //speed=SPEED_1000F;
1407         fDone=FALSE;
1408         do
1409         {
1410             CSL_CPSW_reset((CSL_cpswHandle) CpswBase);
1411             while (FALSE == CSL_CPSW_isResetDone((CSL_cpswHandle) CpswBase));
1413             CSL_CPSW_resetWr((CSL_wrHandle) CpswWrBase);
1414             while (FALSE == CSL_CPSW_isWrResetDone((CSL_wrHandle) CpswWrBase));
1416             CSL_CPGMAC_SL_resetMac((CSL_cpgmacSlHandle) CpswSl1Base);
1417             while (FALSE == CSL_CPGMAC_SL_isMACResetDone((CSL_cpgmacSlHandle) CpswSl1Base));
1419             if(num_ports>1)
1420             {
1421                 CSL_CPGMAC_SL_resetMac((CSL_cpgmacSlHandle) CpswSl2Base);
1422                 while (FALSE == CSL_CPGMAC_SL_isMACResetDone((CSL_cpgmacSlHandle) CpswSl2Base));
1423             }
1425             CSL_CPSW_resetCpdma((CSL_cpdmaHandle) CpswCpdmaBase);
1426             while (FALSE == CSL_CPSW_isCpdmaResetDone((CSL_cpdmaHandle) CpswCpdmaBase));
1429             //enable mdio
1430             CSL_MDIO_setClkDivVal((CSL_mdioHandle) MdioBase, (MDIO_FREQ_INPUT/MDIO_FREQ_OUTPUT - 1));
1431             CSL_MDIO_enableFaultDetect((CSL_mdioHandle) MdioBase);
1432             CSL_MDIO_disablePreamble((CSL_mdioHandle) MdioBase);
1433             CSL_MDIO_enableStateMachine((CSL_mdioHandle) MdioBase);
1435             Delay(100000);
1437             AlePortDisable(CpswBase);
1439             //main switch init
1440             CpswInit(CpswBase);
1441             AleInit(CpswBase);
1442             CpswCpdmaInit(CpswCpdmaBase);
1443             CpswWrInit(CpswWrBase);
1445             DescInit();
1446             CpswInterruptInit();
1448                 switch(speed)
1449                 {
1450                     case SPEED_10H:
1451                         GMAC_log("10Mbps Half-Duplex      %4d    ", port);
1452                         break;
1453                     case SPEED_100H:
1454                         GMAC_log("100Mbps Half-Duplex     %4d    ", port);
1455                         break;
1456                     case SPEED_10F:
1457                         GMAC_log("10Mbps Full-Duplex      %4d    ", port);
1458                         break;
1459                     case SPEED_100F:
1460                         GMAC_log("100Mbps Full-Duplex     %4d    ", port);
1461                         break;
1462                     case SPEED_1000F:
1463                         GMAC_log("1000Mbps Full-Duplex    %4d    ", port);
1464                         break;
1465                     case SPEED_LB:
1466                         GMAC_log("Phy Loopback            %4d    ", port);
1467                         break;
1468                 }
1470                 error_code=LinkSetup(port, speed);
1471                 if(!error_code)
1472                 {
1473                     //send packets
1474                     //  if we're sending more than 10, make sure we hit some min, max, and random; else all random
1475                     if(TEST_NUM_PACKETS>10)
1476                     {
1477                         for(i=0;i<5;i++)
1478                         {
1479                             TransmitPacket(64, port);
1480                             Delay(100000);
1481                         }
1482                         for(i=0;i<5;i++)
1483                         {
1484                             TransmitPacket(1518, port);
1485                             Delay(100000);
1486                         }
1488                         for(i=0;i<(TEST_NUM_PACKETS-10);i++)
1489                         {
1490                             size=((CycleCounterRegRead()>>1)%1455)+64;
1491                             TransmitPacket(size, port);
1492                             Delay(100000);
1493                         }
1494                     }
1495                     else
1496                     {
1497                         for(i=0;i<(TEST_NUM_PACKETS);i++)
1498                         {
1499                             size=((CycleCounterRegRead()>>1)%1455)+64;
1500                             TransmitPacket(size, port);
1501                             Delay(100000);
1502                         }
1503                     }
1505                     timeout=0;
1506                     while((TxPackets[0]!=TEST_NUM_PACKETS) &&(timeout!=10)) // && !IsTimeout());//FIXME
1507                     {
1508                         Delay(10000000);
1509                         timeout++;
1510                     }
1512                     if(timeout==10)
1513                     {
1514                         error_code=8;
1515                         timeout=0;
1516                     }
1517                     else
1518                         //check for errors
1519                         error_code=CheckStats(speed);
1520                 }
1522                 //print results from test
1523                 if(!error_code)
1524                 {
1525                     GMAC_log("PASS\n");
1526                 }
1527                 else
1528                 {
1529                     ret_val=1;
1530                     GMAC_log("FAIL      ");
1531                     switch(error_code)
1532                     {
1533                         case 1:
1534                             GMAC_log("Invalid port number\n");
1535                             break;
1536                         case 2:
1537                             GMAC_log("Phy not alive\n");
1538                             break;
1539                         case 3:
1540                             GMAC_log("Link down\n");
1541                             break;
1542                         case 4:
1543                             GMAC_log("Detected speed mismatch\n");
1544                             break;
1545                         case 5:
1546                             GMAC_log("Transmit errors (see stats)\n");
1547                             HostStats();
1548                             DebugStats();
1549                             CPSWStatsDump();
1550                             CPSWAleDumpTable();
1551                             break;
1552                         case 6:
1553                             GMAC_log("Receive errors (see stats)\n");
1554                             HostStats();
1555                             DebugStats();
1556                             CPSWStatsDump();
1557                             CPSWAleDumpTable();
1558                             break;
1559                         case 7:
1560                             GMAC_log("User abort\n");
1561                             HostStats();
1562                             DebugStats();
1563                             CPSWStatsDump();
1564                             CPSWAleDumpTable();
1565                             break;
1566                         case 8:
1567                             GMAC_log("Test timeout\n");
1568                             HostStats();
1569                             DebugStats();
1570                             CPSWStatsDump();
1571                             CPSWAleDumpTable();
1572                             break;
1573                     }
1574                 }
1576                 //reset stats and transmitted stats for next run
1577                 error_code=0;
1578                 CPSWStatsClear();
1579                 TxPackets[0]=0;
1581                 //change speed
1582                 if(speed==SPEED_LB)
1583                 {
1584                     speed=SPEED_10H;
1585                     if(phy_type==PHY_MICREL_KSZ9031RNX) //10H is failing now
1586                         speed=SPEED_10F;
1587                 }
1588                 else if(speed==SPEED_10H)
1589                 {
1590                     speed=SPEED_10F;
1591                 }
1592                 else if(speed==SPEED_10F)
1593                 {
1594                     speed=SPEED_100H;
1595                 }
1596                 else if(speed==SPEED_100H)
1597                     speed=SPEED_100F;
1598                 else if(speed==SPEED_100F)
1599                 {
1600                     if(fGig && (phy_type!=PHY_MICREL_KSZ9031RNX))
1601                         speed=SPEED_1000F;
1602                 else
1603                     fDone=TRUE;
1604                 }
1605                 else if(speed==SPEED_1000F)
1606                     fDone=TRUE;
1607             AlePortDisable(CpswBase);
1608         } while(!fDone);
1609     }
1611     /* disable interrupts */
1612     CSL_armGicDisableIntr(&gCpuIntrf, (GMAC_SW_IRQ_RX_PULSE_INT_NUM + 32));
1613     CSL_armGicDisableIntr(&gCpuIntrf, (GMAC_SW_IRQ_TX_PULSE_INT_NUM + 32));
1615     /* Disconnect the XBar */
1616     CSL_xbarMpuIrqConfigure(CSL_XBAR_INST_MPU_IRQ_92, 0U);
1617     CSL_xbarMpuIrqConfigure(CSL_XBAR_INST_MPU_IRQ_93, 0U);
1619     GMAC_log("Exiting\n");
1620     return ret_val;