HI,
i am writing code to test Ethernet interface in u-boot with loopback method. i have taken the CCS code and made it compile in u-boot but the test id getting struct in waiting for link condition.
here i am attaching the code file.
//#include "stdio.h"
//#include "string.h"
#include <common.h>
typedef int STATUS;
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned int UINT32;
typedef char INT8;
typedef short INT16;
typedef int INT32;
#define SUCCESS 0
#define FAILED -1
#define TX_BUF 128
#define RX_BUF 128
/* ------------------------------------------------------------------------ *
* MDIO Controller *
* ------------------------------------------------------------------------ */
#define MDIO_BASE 0x4A100800
#define MDIO_CONTROL *( volatile UINT32* )( MDIO_BASE + 0x04 )
#define MDIO_ALIVE *( volatile UINT32* )( MDIO_BASE + 0x08 )
#define MDIO_LINK *( volatile UINT32* )( MDIO_BASE + 0x0c )
#define MDIO_LINKINTRAW *( volatile UINT32* )( MDIO_BASE + 0x10 )
#define MDIO_LINKINTMASKED *( volatile UINT32* )( MDIO_BASE + 0x14 )
#define MDIO_USERINTRAW *( volatile UINT32* )( MDIO_BASE + 0x20 )
#define MDIO_USERINTMASKED *( volatile UINT32* )( MDIO_BASE + 0x24 )
#define MDIO_USERINTMASKSET *( volatile UINT32* )( MDIO_BASE + 0x28 )
#define MDIO_USERINTMASKCLEAR *( volatile UINT32* )( MDIO_BASE + 0x2c )
#define MDIO_USERACCESS0 *( volatile UINT32* )( MDIO_BASE + 0x80 )
#define MDIO_USERPHYSEL0 *( volatile UINT32* )( MDIO_BASE + 0x84 )
#define MDIO_USERACCESS1 *( volatile UINT32* )( MDIO_BASE + 0x88 )
#define MDIO_USERPHYSEL1 *( volatile UINT32* )( MDIO_BASE + 0x8c )
#define GMII_SEL *( volatile UINT32* )(0x48140650)
/* ------------------------------------------------------------------------ *
* EMAC Modes *
* ------------------------------------------------------------------------ */
#define MII_MODE 1000
#define RMII_MODE 2000
/* ------------------------------------------------------------------------ *
* EMAC Descriptor *
* ------------------------------------------------------------------------ */
typedef struct _EMAC_Desc {
struct _EMAC_Desc *pNext; // Pointer to next descriptor
UINT8* pBuffer; // Pointer to data buffer
UINT32 BufOffLen; // Buffer Offset(MSW) and Length(LSW)
UINT32 PktFlgLen; // Packet Flags(MSW) and Length(LSW)
} EMAC_Desc;
extern void EMAC_isr
(
void
);
/* ------------------------------------------------------------------------ *
* EMAC Controller *
* ------------------------------------------------------------------------ */
#define EMAC_BASE 0x4A100000
#define EMAC_TXIDVER_BASE EMAC_BASE + 0x100
#define EMAC_RXIDVER_BASE EMAC_BASE + 0x110
#define EMAC_STATS_BASE EMAC_BASE + 0x400
#define EMAC_ALE_BASE EMAC_BASE + 0x600
#define EMAC_SWITCH_BASE EMAC_BASE + 0x900
#define EMAC0_SLIVER_CTRL *( volatile UINT32* )( EMAC_BASE + 0x704 ) // Per EMAC
#define EMAC1_SLIVER_CTRL *( volatile UINT32* )( EMAC_BASE + 0x744 ) // Per EMAC
#define EMAC_STAT_PORT_EN *( volatile UINT32* )( EMAC_BASE + 0x00C )
#define EMAC_P0_FLOW_THRESH *( volatile UINT32* )( EMAC_BASE + 0x01C )
#define EMAC0_MACSRCADDRLO *( volatile UINT32* )( EMAC_BASE + 0x02C )
#define EMAC0_MACSRCADDRHI *( volatile UINT32* )( EMAC_BASE + 0x030 )
#define EMAC1_MACSRCADDRLO *( volatile UINT32* )( EMAC_BASE + 0x04C )
#define EMAC1_MACSRCADDRHI *( volatile UINT32* )( EMAC_BASE + 0x050 )
#define EMAC_P2_MAX_BLKS *( volatile UINT32* )( EMAC_BASE + 0x054 )
#define EMAC_P2_TX_PRI_MAP *( volatile UINT32* )( EMAC_BASE + 0x064 )
#define EMAC0_MACCONTROL *( volatile UINT32* )( EMAC_BASE + 0x084 ) // Per EMAC
#define EMAC0_MACSTATUS *( volatile UINT32* )( EMAC_BASE + 0x088 ) // Per EMAC
#define EMAC1_MACCONTROL *( volatile UINT32* )( EMAC_BASE + 0x0C4 ) // Per EMAC
#define EMAC1_MACSTATUS *( volatile UINT32* )( EMAC_BASE + 0x0C8 ) // Per EMAC
#define EMAC_TXIDVER *( volatile UINT32* )( EMAC_TXIDVER_BASE )
#define EMAC_TXCONTROL *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x004 )
#define EMAC_TXTEARDOWN *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x008 )
#define EMAC_RXIDVER *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x010 )
#define EMAC_RXCONTROL *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x014 )
#define EMAC_RXTEARDOWN *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x018 )
#define EMAC_SOFTRESET *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x01C )
#define EMAC_DMACONTROL *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x024 )
#define EMAC_RXBUFFEROFFSET *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x028 )
#define EMAC_EMCONTROL *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x02C )
#define EMAC_TXINTSTATRAW *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x080 )
#define EMAC_TXINTSTATMASKED *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x084 )
#define EMAC_TXINTMASKSET *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x088 )
#define EMAC_TXINTMASKCLEAR *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x08c )
#define EMAC_MACEOIVECTOR *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x094 )
#define EMAC_RXINTSTATRAW *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0A0 )
#define EMAC_RXINTSTATMASKED *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0A4 )
#define EMAC_RXINTMASKSET *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0A8 )
#define EMAC_RXINTMASKCLEAR *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0Ac )
#define EMAC_MACINTSTATRAW *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0B0 )
#define EMAC_MACINTSTATMASKED *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0B4 )
#define EMAC_MACINTMASKSET *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0B8 )
#define EMAC_MACINTMASKCLEAR *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0Bc )
#define EMAC_RX0FREEBUFFER *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0E0 )
#define EMAC_RX1FREEBUFFER *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0E4 )
#define EMAC_RX2FREEBUFFER *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0E8 )
#define EMAC_RX3FREEBUFFER *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0Ec )
#define EMAC_RX4FREEBUFFER *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0F0 )
#define EMAC_RX5FREEBUFFER *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0F4 )
#define EMAC_RX6FREEBUFFER *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0F8 )
#define EMAC_RX7FREEBUFFER *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x0Fc )
#define EMAC_TX0HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x100 )
#define EMAC_TX1HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x104 )
#define EMAC_TX2HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x108 )
#define EMAC_TX3HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x10c )
#define EMAC_TX4HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x110 )
#define EMAC_TX5HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x114 )
#define EMAC_TX6HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x118 )
#define EMAC_TX7HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x11c )
#define EMAC_RX0HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x120 )
#define EMAC_RX1HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x124 )
#define EMAC_RX2HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x128 )
#define EMAC_RX3HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x12c )
#define EMAC_RX4HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x130 )
#define EMAC_RX5HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x134 )
#define EMAC_RX6HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x138 )
#define EMAC_RX7HDP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x13c )
#define EMAC_TX0CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x140 )
#define EMAC_TX1CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x144 )
#define EMAC_TX2CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x148 )
#define EMAC_TX3CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x14c )
#define EMAC_TX4CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x150 )
#define EMAC_TX5CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x154 )
#define EMAC_TX6CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x158 )
#define EMAC_TX7CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x15c )
#define EMAC_RX0CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x160 )
#define EMAC_RX1CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x164 )
#define EMAC_RX2CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x168 )
#define EMAC_RX3CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x16c )
#define EMAC_RX4CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x170 )
#define EMAC_RX5CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x174 )
#define EMAC_RX6CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x178 )
#define EMAC_RX7CP *( volatile UINT32* )( EMAC_TXIDVER_BASE + 0x17c )
#define EMAC_RXGOODFRAMES *( volatile UINT32* )( EMAC_STATS_BASE + 0x000 )
#define EMAC_RXBCASTFRAMES *( volatile UINT32* )( EMAC_STATS_BASE + 0x004 )
#define EMAC_RXMCASTFRAMES *( volatile UINT32* )( EMAC_STATS_BASE + 0x008 )
#define EMAC_RXPAUSEFRAMES *( volatile UINT32* )( EMAC_STATS_BASE + 0x00c )
#define EMAC_RXCRCERRORS *( volatile UINT32* )( EMAC_STATS_BASE + 0x010 )
#define EMAC_RXALIGNCODEERRORS *( volatile UINT32* )( EMAC_STATS_BASE + 0x014 )
#define EMAC_RXOVERSIZED *( volatile UINT32* )( EMAC_STATS_BASE + 0x018 )
#define EMAC_RXJABBER *( volatile UINT32* )( EMAC_STATS_BASE + 0x01c )
#define EMAC_RXUNDERSIZED *( volatile UINT32* )( EMAC_STATS_BASE + 0x020 )
#define EMAC_RXFRAGMENTS *( volatile UINT32* )( EMAC_STATS_BASE + 0x024 )
#define EMAC_RXFILTERED *( volatile UINT32* )( EMAC_STATS_BASE + 0x028 )
#define EMAC_RXQOSFILTERED *( volatile UINT32* )( EMAC_STATS_BASE + 0x02c )
#define EMAC_RXOCTETS *( volatile UINT32* )( EMAC_STATS_BASE + 0x030 )
#define EMAC_TXGOODFRAMES *( volatile UINT32* )( EMAC_STATS_BASE + 0x034 )
#define EMAC_TXBCASTFRAMES *( volatile UINT32* )( EMAC_STATS_BASE + 0x038 )
#define EMAC_TXMCASTFRAMES *( volatile UINT32* )( EMAC_STATS_BASE + 0x03c )
#define EMAC_TXPAUSEFRAMES *( volatile UINT32* )( EMAC_STATS_BASE + 0x040 )
#define EMAC_TXDEFERRED *( volatile UINT32* )( EMAC_STATS_BASE + 0x044 )
#define EMAC_TXCOLLISION *( volatile UINT32* )( EMAC_STATS_BASE + 0x048 )
#define EMAC_TXSINGLECOLL *( volatile UINT32* )( EMAC_STATS_BASE + 0x04c )
#define EMAC_TXMULTICOLL *( volatile UINT32* )( EMAC_STATS_BASE + 0x050 )
#define EMAC_TXEXCESSIVECOLL *( volatile UINT32* )( EMAC_STATS_BASE + 0x054 )
#define EMAC_TXLATECOLL *( volatile UINT32* )( EMAC_STATS_BASE + 0x058 )
#define EMAC_TXUNDERRUN *( volatile UINT32* )( EMAC_STATS_BASE + 0x05c )
#define EMAC_TXCARRIERSENSE *( volatile UINT32* )( EMAC_STATS_BASE + 0x060 )
#define EMAC_TXOCTETS *( volatile UINT32* )( EMAC_STATS_BASE + 0x064 )
#define EMAC_FRAME64 *( volatile UINT32* )( EMAC_STATS_BASE + 0x068 )
#define EMAC_FRAME65T127 *( volatile UINT32* )( EMAC_STATS_BASE + 0x06c )
#define EMAC_FRAME128T255 *( volatile UINT32* )( EMAC_STATS_BASE + 0x070 )
#define EMAC_FRAME256T511 *( volatile UINT32* )( EMAC_STATS_BASE + 0x074 )
#define EMAC_FRAME512T1023 *( volatile UINT32* )( EMAC_STATS_BASE + 0x078 )
#define EMAC_FRAME1024TUP *( volatile UINT32* )( EMAC_STATS_BASE + 0x07c )
#define EMAC_NETOCTETS *( volatile UINT32* )( EMAC_STATS_BASE + 0x080 )
#define EMAC_RXSOFOVERRUNS *( volatile UINT32* )( EMAC_STATS_BASE + 0x084 )
#define EMAC_RXMOFOVERRUNS *( volatile UINT32* )( EMAC_STATS_BASE + 0x088 )
#define EMAC_RXDMAOVERRUNS *( volatile UINT32* )( EMAC_STATS_BASE + 0x08c )
#define EMAC_ALE_IDVER *( volatile UINT32* )( EMAC_ALE_BASE )
#define EMAC_ALE_CONTROL *( volatile UINT32* )( EMAC_ALE_BASE + 0x08 )
#define EMAC_ALE_PRESCALE *( volatile UINT32* )( EMAC_ALE_BASE + 0x10 )
#define EMAC_ALE_UVLAN *( volatile UINT32* )( EMAC_ALE_BASE + 0x18 )
#define EMAC_ALE_TBLCTL *( volatile UINT32* )( EMAC_ALE_BASE + 0x20 )
#define EMAC_ALE_TBLWRD2 *( volatile UINT32* )( EMAC_ALE_BASE + 0x34 )
#define EMAC_ALE_TBLWRD1 *( volatile UINT32* )( EMAC_ALE_BASE + 0x38 )
#define EMAC_ALE_TBLWRD0 *( volatile UINT32* )( EMAC_ALE_BASE + 0x3C )
#define EMAC_ALE_PORTCTL0 *( volatile UINT32* )( EMAC_ALE_BASE + 0x40 )
#define EMAC_ALE_PORTCTL1 *( volatile UINT32* )( EMAC_ALE_BASE + 0x44 )
#define EMAC_ALE_PORTCTL2 *( volatile UINT32* )( EMAC_ALE_BASE + 0x48 )
/* EMAC Wrapper */
#define EMAC_EWSOFTRESET *( volatile UINT32* )( EMAC_SWITCH_BASE + 0x004 )
#define EMAC_EWEMCONTROL *( volatile UINT32* )( EMAC_SWITCH_BASE + 0x008 )
#define EMAC_EWRXEN *( volatile UINT32* )( EMAC_SWITCH_BASE + 0x014 )
#define EMAC_EWTXEN *( volatile UINT32* )( EMAC_SWITCH_BASE + 0x018 )
/* EMAC RAM */
#define EMAC_RAM_BASE 0x4A102000
#define EMAC_RAM_LEN 0x00002000
/* Packet Flags */
#define EMAC_DSC_FLAG_SOP 0x80000000
#define EMAC_DSC_FLAG_EOP 0x40000000
#define EMAC_DSC_FLAG_OWNER 0x20000000
#define EMAC_DSC_FLAG_EOQ 0x10000000
#define EMAC_DSC_FLAG_TDOWNCMPLT 0x08000000
#define EMAC_DSC_FLAG_PASSCRC 0x04000000
/* The following flags are RX only */
#define EMAC_DSC_FLAG_JABBER 0x02000000
#define EMAC_DSC_FLAG_OVERSIZE 0x01000000
#define EMAC_DSC_FLAG_FRAGMENT 0x00800000
#define EMAC_DSC_FLAG_UNDERSIZED 0x00400000
#define EMAC_DSC_FLAG_CONTROL 0x00200000
#define EMAC_DSC_FLAG_OVERRUN 0x00100000
#define EMAC_DSC_FLAG_CODEERROR 0x00080000
#define EMAC_DSC_FLAG_ALIGNERROR 0x00040000
#define EMAC_DSC_FLAG_CRCERROR 0x00020000
#define EMAC_DSC_FLAG_NOMATCH 0x00010000
#define EMAC_TO_PORT_ENABLE (1 << 20)
#define EMAC_TO_PORT (1 << 16)
/* Interrupts */
#define EMAC_MACINVECTOR_USERINT 0x01000000
#define EMAC_MACINVECTOR_LINKINT 0x02000000
#define EMAC_MACINVECTOR_HOSTPEND 0x00000002
#define EMAC_MACINVECTOR_STATPEND 0x00000001
#define EMAC_MACINVECTOR_RXPEND 0x000000FF
#define EMAC_MACINVECTOR_TXPEND 0x001F0000
static UINT8 packet_data[TX_BUF];
static UINT8 packet_buffer1[RX_BUF];
static UINT8 packet_buffer2[RX_BUF];
UINT16 gmii_phy_getReg( INT16 phynum, INT16 regnum );
/*
* We use pDescBase for a base address. Its easier this way
* because we can use indexing off the pointer.
*/
static EMAC_Desc* pDescBase = ( EMAC_Desc* )EMAC_RAM_BASE;
/*
* The following are used to allow the ISR to communicate with
* the application.
*/
volatile INT32 RxCount;
volatile INT32 TxCount;
volatile INT32 ErrCount;
volatile EMAC_Desc *pDescRx;
volatile EMAC_Desc *pDescTx;
/*
void DM814x_wait(UINT32 u32Delay )
{
volatile UINT32 u32LoopCntr;
for ( u32LoopCntr = 0 ; u32LoopCntr < u32Delay ; u32LoopCntr++ ){ };
}
void DM814x_usecDelay( UINT32 u32usec )
{
DM814x_wait( u32usec * 2 );
}
*/
/* ------------------------------------------------------------------------ *
* gmii_phy_detect( *phyaddr ) *
* ------------------------------------------------------------------------ */
UINT16 gmii_phy_detect( UINT16 *phyaddr )
{
UINT16 num = 0, i;
/* Reset Ethernet */
EMAC_SOFTRESET = 1;
while( EMAC_SOFTRESET != 0 );
DM814x_usecDelay( 100 );
MDIO_CONTROL = 0x40000020; // Enable MII interface ( MDIOCLK < 12.5MHz )
DM814x_usecDelay( 100000 );
/* Check for PHYs */
for(i=0;i<32;i++)
{
if((MDIO_ALIVE & (1 << i)) != 0)
{
printf(" PHY found at address %d\n", i);
*phyaddr++ = i;
}
}
return num;
}
/* ------------------------------------------------------------------------ *
* gmii_phy_getReg( phynum, regnum ) *
* ------------------------------------------------------------------------ */
UINT16 gmii_phy_getReg( INT16 phynum, INT16 regnum )
{
UINT16 value;
MDIO_USERACCESS0 = 0 // Read Phy Id 1
| ( 1 << 31 ) // [31] Go
| ( 0 << 30 ) // [30] Read
| ( 0 << 29 ) // [29] Ack
| ( regnum << 21 ) // [25-21] PHY register address
| ( phynum << 16 ) // [20-16] PHY address
| ( 0 << 0 ); // [15-0] Data
while( MDIO_USERACCESS0 & 0x80000000 ); // Wait for Results
value = MDIO_USERACCESS0;
return value;
}
/* ------------------------------------------------------------------------ *
* gmii_phy_setReg( phynum, regnum, data ) *
* ------------------------------------------------------------------------ */
void gmii_phy_setReg( INT16 phynum, INT16 regnum, UINT16 data )
{
MDIO_USERACCESS0 = 0 // Read Phy Id 1
| ( 1 << 31 ) // [31] Go
| ( 1 << 30 ) // [30] Write
| ( 0 << 29 ) // [29] Ack
| ( regnum << 21 ) // [25-21] PHY register address
| ( phynum << 16 ) // [20-16] PHY address
| ( data << 0 ); // [15-0] Data
while( MDIO_USERACCESS0 & 0x80000000 ); // Wait for Results
DM814x_usecDelay( 1000 );
}
/* ------------------------------------------------------------------------ *
* gmii_phy_dumpRegs( ) *
* ------------------------------------------------------------------------ */
void gmii_phy_dumpRegs( )
{
INT16 i;
for ( i = 0 ; i < 32 ; i++ )
printf( "PHY[%d] = %04x\n", i, gmii_phy_getReg( 1, i ) );
printf( "\n\n" );
}
/* ------------------------------------------------------------------------ *
* emac_gmii_init( phynum ) *
* ------------------------------------------------------------------------ */
INT16 emac_gmii_init( INT16 phynum )
{
INT16 i;
volatile UINT32* pReg;
INT16 readData = 0;
/*
* EMAC Boot code sets this offset to 0x21
* This initializes EMAC to work in all boot settings
*/
EMAC0_SLIVER_CTRL = 0x000000A1;
EMAC1_SLIVER_CTRL = 0x000000A1;
printf("\n emac_gmii_init phynum = %d \n",phynum);
/* Reset Ethernet */
EMAC_SOFTRESET = 1;
while( EMAC_SOFTRESET != 0 );
DM814x_usecDelay( 100 );
EMAC_ALE_CONTROL |= 0x80000000;
DM814x_usecDelay( 100000 );
EMAC_ALE_CONTROL |= 0x40000000;
DM814x_usecDelay( 100000 );
DM814x_usecDelay( 100000 );
EMAC_ALE_CONTROL |= 0x00000010;
DM814x_usecDelay( 100000 );
/* ---------------------------------------------------------------- *
* Init PHY / MDIO *
* ---------------------------------------------------------------- */
MDIO_CONTROL = 0x40000020; // Enable MII interface ( MDIOCLK < 12.5MHz )
DM814x_usecDelay( 100000 );
gmii_phy_setReg( phynum, 0x1D, 0x0b);
readData = gmii_phy_getReg( phynum, 0x1E );
readData &= ~(0x8000);
gmii_phy_setReg( phynum, 0x1D, 0x0b);
gmii_phy_setReg( phynum, 0x1E, readData);
gmii_phy_setReg( phynum, 0x1D, 0x11);
readData = gmii_phy_getReg( phynum, 0x1E );
readData |= 0x01;
gmii_phy_setReg( phynum, 0x1D, 0x11);
gmii_phy_setReg( phynum, 0x1E, readData);
gmii_phy_setReg( phynum, 0, 0x8140); // Enable external loopback with 1000; Full-Duplex
DM814x_usecDelay( 100000 );
readData = gmii_phy_getReg( phynum, 0 );
printf (" VIMAL read data = %x \n",readData);
if (readData == 0x3100)
printf (" MII 100 Mbps Link.\r\n");
else if (readData == 0x1140)
printf ("RGMII 1 Gbps Link.\r\n");
else if (readData == 0x1100)
printf ("MII 10 Mbps Link.\r\n");
//Setup GIG advertisement
if (readData == 0x1140)
{
readData = gmii_phy_getReg( phynum, 9 );
readData |= 0x200;
gmii_phy_setReg( phynum, 9, readData);
}
// setup the general advertisement
readData = gmii_phy_getReg( phynum, 4 );
readData |= 0x01E0;
gmii_phy_setReg( phynum, 4, readData);
DM814x_usecDelay( 100000 );
DM814x_usecDelay( 100000 );
printf( " In RGMII mode\n" );
MDIO_CONTROL = 0x40000020; // Enable MII interface ( MDIOCLK < 12.5MHz )
EMAC_STAT_PORT_EN = 0x7;
EMAC_P2_MAX_BLKS = 0x42;
/* Gigabit PHY external cable loopback */
gmii_phy_setReg( phynum, 19, 0x0080 ); // Enable cable loopback
gmii_phy_setReg( phynum, 0, 0x0140 ); // Force 1000mbps, full duplex
DM814x_usecDelay( 100000 );
/* Wait for link */
printf( " Waiting for link... phynum = %d \n",phynum );
while( ( gmii_phy_getReg( phynum, 1 ) & 0x04 ) == 0 );
printf( " Link Detected\n" );
printf ("Enabling the R-GMII interface on DM814X.\r\n");
GMII_SEL = 0x0000030a;
printf( " In R-GMII mode\n" );
EMAC_STAT_PORT_EN = 0x7;
EMAC_P2_MAX_BLKS = 0x104;
/* ---------------------------------------------------------------- *
* Init EMAC *
* ---------------------------------------------------------------- */
/* 1. Disable RX/TX interrupts */
EMAC_EWRXEN = 0x00000000;
EMAC_EWTXEN = 0x00000000;
/* 2. Clear the MAC control, receive control, & transmit control */
EMAC0_MACCONTROL = 0;
EMAC_RXCONTROL = 0;
EMAC_TXCONTROL = 0;
/* 3. Initialize all 16 header descriptor pointers RXnHDP & TXnHDP to zero */
EMAC_RX0HDP = 0;
EMAC_RX1HDP = 0;
EMAC_RX2HDP = 0;
EMAC_RX3HDP = 0;
EMAC_RX4HDP = 0;
EMAC_RX5HDP = 0;
EMAC_RX6HDP = 0;
EMAC_RX7HDP = 0;
EMAC_TX0HDP = 0;
EMAC_TX1HDP = 0;
EMAC_TX2HDP = 0;
EMAC_TX3HDP = 0;
EMAC_TX4HDP = 0;
EMAC_TX5HDP = 0;
EMAC_TX6HDP = 0;
EMAC_TX7HDP = 0;
/* 4. Clear all 36 statistics registers by writing 0 */
pReg = &EMAC_RXGOODFRAMES;
for ( i = 0 ; i < 36 ; i++ )
*(pReg+i) = *(pReg+i);
/* 8. Set RX buffer offset to 0. Valid data always begins on the 1st byte */
EMAC_RXBUFFEROFFSET = 0;
/* 11. Set the appropriate configuration bits in MACCONTROL (do not set the GMIIEN bit yet). */
EMAC0_MACCONTROL = 0
| ( 0 << 9 ) // Round robin
| ( 1 << 7 ) // Gigabit mode
| ( 0 << 6 ) // TX pacing disabled
| ( 0 << 5 ) // GMII RX & TX
| ( 0 << 4 ) // TX flow disabled
| ( 0 << 3 ) // RX flow disabled
| ( 0 << 1 ) // Loopback disabled
/*| ( 1 << 1 )*/ // Loopback enabled
| ( 1 << 0 ) // full duplex
| ( 1 << 22 ) // CEF
| ( 1 << 23 ); // CSF
#if 0
DM814x_usecDelay( 100000 );
ale_entry[2] = 0x80000000; /* */
ale_entry[1] = 0x10000000; /* Entry Type Unicast */
ale_entry[0] = 0x00000000;
ale_entry[1] |= 0xBB1300;
EMAC_ALE_TBLWRD2 = ale_entry[2];
EMAC_ALE_TBLWRD1 = ale_entry[1];
EMAC_ALE_TBLWRD0 = ale_entry[0];
#endif
EMAC_ALE_PORTCTL0 |= 0x13;
EMAC_ALE_PORTCTL1 |= 0x13;
EMAC_ALE_PORTCTL2 |= 0x13;
/* P2 TX Header Priority to Switch Priority Mapping */
EMAC_P2_TX_PRI_MAP = 0x00;
/* 12. Clear all unused channel interrupt bits */
EMAC_RXINTMASKCLEAR = 0xFF;
EMAC_TXINTMASKCLEAR = 0xFF;
/* 13. Enable the RX & TX channel interrupt bits. */
EMAC_RXINTMASKSET = 0xFF;
EMAC_TXINTMASKSET = 0xFF;
/* Enable Host Error and Statistics interrupts */
EMAC_MACINTMASKSET = 0
| ( 1 << 1 ) // Host Error interrupt mask
| ( 1 << 0 ); // Statistics interrupt mask
/* 14. Initialize the receive and transmit descriptor list queues. */
/* 15. Prepare receive by writing a pointer to the head of the receive buffer descriptor list to RXnHDP. */
EMAC0_MACSRCADDRLO = 0x03BB1300; /* bytes 0, 1 */
EMAC0_MACSRCADDRHI = 0xD967; /* bytes 2-5 - channel 0 ??? */
/* 16. Enable the RX & TX DMA controllers. Then set GMIIEN */
EMAC_RXCONTROL = 1;
EMAC_TXCONTROL = 1;
EMAC0_MACCONTROL |= ( 1 << 5 );
/* 17. Enable the device interrupt wrapper, emulation free mode */
EMAC_EWRXEN = 0x00000001; // Enable receive interrupts on channel 0
EMAC_EWTXEN = 0x00000001; // Enable transmit interrupts on channel 0
return 0;
}
/* ------------------------------------------------------------------------ *
* verify_packet *
* ------------------------------------------------------------------------ */
static INT16 verify_packet( EMAC_Desc* pDesc, UINT32 size, UINT32 flagCRC )
{
INT16 i;
UINT32 SizeCRC = ( flagCRC ) ? size + 4 : size;
UINT32 packet_flags = pDesc->PktFlgLen;
/* We must own this packet */
if ( packet_flags & EMAC_DSC_FLAG_OWNER )
return 1;
/* Must be SOP and EOP */
if ( ( packet_flags & ( EMAC_DSC_FLAG_SOP | EMAC_DSC_FLAG_EOP ) )
!= ( EMAC_DSC_FLAG_SOP | EMAC_DSC_FLAG_EOP ) )
return 2;
/* If flagCRC is set, it must have a CRC */
if ( flagCRC )
if ( ( packet_flags & EMAC_DSC_FLAG_PASSCRC ) != EMAC_DSC_FLAG_PASSCRC )
return 3;
/* Packet must be correct size */
if ( ( packet_flags & 0xFFFF ) != SizeCRC )
return 5;
/* Offset must be zero, packet size unchanged */
if ( pDesc->BufOffLen != SizeCRC )
return 6;
/* Validate the data */
for ( i = 0 ; i < size ; i++ )
if ( pDesc->pBuffer[i] != i )
return 7;
return 0;
}
/* ------------------------------------------------------------------------ *
* *
* test_gmii_packet( ) *
* EMAC tests to send data to external loopback cable. *
* *
* ------------------------------------------------------------------------ */
INT16 test_gmii_packet( )
{
INT32 i;
INT16 errors = 0;
UINT32 status;
EMAC_Desc* pDesc;
/* ---------------------------------------------------------------- *
* Setup EMAC for GMII mode *
* ---------------------------------------------------------------- */
//emac_gmii_init( );
memset( packet_buffer1, 0x00, 128 );
memset( packet_buffer2, 0x00, 128 );
/* ---------------------------------------------------------------- *
* *
* Setup RX packets *
* *
* ---------------------------------------------------------------- */
pDesc = pDescBase;
pDesc->pNext = pDescBase + 1;
pDesc->pBuffer = packet_buffer1;
pDesc->BufOffLen = RX_BUF;
pDesc->PktFlgLen = EMAC_DSC_FLAG_OWNER;
pDesc = pDescBase + 1;
pDesc->pNext = 0;
pDesc->pBuffer = packet_buffer2;
pDesc->BufOffLen = RX_BUF;
pDesc->PktFlgLen = EMAC_DSC_FLAG_OWNER;
/*
* Start RX receiving
*/
pDescRx = pDescBase;
EMAC_RX0HDP = ( UINT32 )pDescRx;
/* ---------------------------------------------------------------- *
* *
* Setup TX packets *
* Send 2 copies of the same packet using different sizes *
* *
* ---------------------------------------------------------------- */
for ( i = 0 ; i < TX_BUF ; i++ )
packet_data[i] = i;
pDesc = pDescBase + 10;
pDesc->pNext = pDescBase + 11;
pDesc->pBuffer = packet_data;
pDesc->BufOffLen = TX_BUF - 4; // 4 bytes for CRC
pDesc->PktFlgLen = EMAC_DSC_FLAG_OWNER
| EMAC_DSC_FLAG_SOP
| EMAC_DSC_FLAG_EOP
| (TX_BUF - 4);
pDesc = pDescBase + 11;
pDesc->pNext = 0;
pDesc->pBuffer = packet_data;
pDesc->BufOffLen = TX_BUF - 4; // 4 bytes for CRC
pDesc->PktFlgLen = EMAC_DSC_FLAG_OWNER
| EMAC_DSC_FLAG_SOP
| EMAC_DSC_FLAG_EOP
| (TX_BUF - 4);
/*
* Start TX sending
*/
TxCount = 0;
RxCount = 0;
pDescTx = pDescBase + 10;
EMAC_TX0HDP = ( UINT32 )pDescTx;
DM814x_usecDelay( 100000 );
/* ACK TX */
status = EMAC_TX0CP;
EMAC_TX0CP = status;
DM814x_usecDelay( 100000 );
/* ACK RX */
status = EMAC_RX0CP;
EMAC_RX0CP = status;
/* ---------------------------------------------------------------- *
* *
* Normally there would be a interrupt to service the EMAC RX/TX *
* transmission. Instead a short pause and manually call the ISR *
* Interrupt Service Routine to check on the status. *
* *
* You can later add in the ISR and the code to support. *
* *
* ---------------------------------------------------------------- */
/* Busy period */
DM814x_usecDelay( 100000 );
/* ---------------------------------------------------------------- *
* Check packet and results *
* ---------------------------------------------------------------- */
if ( verify_packet( pDescBase, TX_BUF - 4, 1 ) ) // Verify Size + Contents
errors++;
if ( verify_packet( pDescBase + 1, TX_BUF - 4, 1 ) ) // Verify Size + Contents
errors++;
#if 0
if ( ( status = EMAC_FRAME64 ) != 2 ) // Check # of 64 byte frames
errors++;
EMAC_FRAME64 = status;
if ( ( status = EMAC_FRAME128T255 ) != 2 ) // Check # of 128-255 byte frames
errors++;
EMAC_FRAME128T255 = status;
if ( ( status = EMAC_RXGOODFRAMES ) != 2 ) // Check # of Good RX frames
errors++;
EMAC_RXGOODFRAMES = status;
if ( ( status = EMAC_TXGOODFRAMES ) != 2 ) // Check # of Good TX frames
errors++;
EMAC_TXGOODFRAMES = status;
#endif
return errors;
}
/* ------------------------------------------------------------------------ *
* *
* emac_gmii_test( ) *
* *
* ------------------------------------------------------------------------ */
INT16 emac_rgmii_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
UINT16 phyaddr[32];
INT16 errors = 0, num, i;
/* Detect PHYs */
num = gmii_phy_detect( phyaddr );
num = num; /* for compiler warnings */
printf("PHY Detect Num = %d \n and phyaddr[0] = %d",num,phyaddr[0]);
/* Setup EMAC for GMII mode */
emac_gmii_init( phyaddr[0] ); // Lower address is on the Netra base board
/* Test EMAC in GMII mode */
for ( i = 0 ; i < 10 ; i++ )
errors += test_gmii_packet( );
if (!errors)
{
printf("Packet verification passed!!\n");
}
else
{
printf("Packet verification failed!!\n");
}
return errors;
}
U_BOOT_CMD(UU_ETH, 3, 0,emac_rgmii_test,"Ethernet TEST",0);
The output of this file while executing the test command is as below:
PHY found at address 0
PHY found at address 1
PHY Detect Num = 0
and phyaddr[0] = 0
emac_gmii_init phynum = 0
VIMAL read data = 140
In RGMII mode
Waiting for link... phynum = 0
kindly help me out to test it succesfully. testing it on 8148EVM kit.
Regards,
Vimal

