Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions source/portable/NetworkInterface/Zynq/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,11 @@ It is obligatory to define:

#define ipconfigZERO_COPY_RX_DRIVER 1
#define ipconfigZERO_COPY_TX_DRIVER 1

If using SDT drivers, it may be necessary to define certain link speed divisor values.
This is to work around a driver issue where certain link speeds will not transmit any data
without defining the values. These macros can be defined in the FreeRTOSIPConfig.h
For example, it may be necessary to define:

#define XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0 8
#define XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV1 5
81 changes: 44 additions & 37 deletions source/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,19 +500,12 @@ unsigned configure_IEEE_phy_speed( XEmacPs * xemacpsp,
return 0;
}

static void SetUpSLCRDivisors( int mac_baseaddr,
int speed )
static void WriteSLCRDivisors( int mac_baseaddr,
u32 SlcrDiv0,
u32 SlcrDiv1 )
{
volatile u32 slcrBaseAddress;

#ifndef PEEP
u32 SlcrDiv0 = 0;
u32 SlcrDiv1 = 0;
u32 SlcrTxClkCntrl;
#endif

*( volatile unsigned int * ) ( SLCR_UNLOCK_ADDR ) = SLCR_UNLOCK_KEY_VALUE;

if( ( unsigned long ) mac_baseaddr == EMAC0_BASE_ADDRESS )
{
slcrBaseAddress = SLCR_GEM0_CLK_CTRL_ADDR;
Expand All @@ -522,7 +515,30 @@ static void SetUpSLCRDivisors( int mac_baseaddr,
slcrBaseAddress = SLCR_GEM1_CLK_CTRL_ADDR;
}

u32 SlcrTxClkCntrl = *( volatile unsigned int * ) ( slcrBaseAddress );
SlcrTxClkCntrl &= EMACPS_SLCR_DIV_MASK;
SlcrTxClkCntrl |= ( SlcrDiv1 << 20 );
SlcrTxClkCntrl |= ( SlcrDiv0 << 8 );
*( volatile unsigned int * ) ( slcrBaseAddress ) = SlcrTxClkCntrl;
}

static void SetUpSLCRDivisors( int mac_baseaddr,
int speed )
{
*( volatile unsigned int * ) ( SLCR_UNLOCK_ADDR ) = SLCR_UNLOCK_KEY_VALUE;

#ifdef PEEP
volatile u32 slcrBaseAddress;

if( ( unsigned long ) mac_baseaddr == EMAC0_BASE_ADDRESS )
{
slcrBaseAddress = SLCR_GEM0_CLK_CTRL_ADDR;
}
else
{
slcrBaseAddress = SLCR_GEM1_CLK_CTRL_ADDR;
}

if( speed == 1000 )
{
*( volatile unsigned int * ) ( slcrBaseAddress ) =
Expand All @@ -544,15 +560,17 @@ static void SetUpSLCRDivisors( int mac_baseaddr,
if( ( unsigned long ) mac_baseaddr == EMAC0_BASE_ADDRESS )
{
#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0
SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0;
SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV1;
u32 SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0;
u32 SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV1;
WriteSLCRDivisors( mac_baseaddr, SlcrDiv0, SlcrDiv1 );
#endif
}
else
{
#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0
SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0;
SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV1;
u32 SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0;
u32 SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV1;
WriteSLCRDivisors( mac_baseaddr, SlcrDiv0, SlcrDiv1 );
#endif
}
}
Expand All @@ -561,15 +579,17 @@ static void SetUpSLCRDivisors( int mac_baseaddr,
if( ( unsigned long ) mac_baseaddr == EMAC0_BASE_ADDRESS )
{
#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0
SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0;
SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV1;
u32 SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0;
u32 SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV1;
WriteSLCRDivisors( mac_baseaddr, SlcrDiv0, SlcrDiv1 );
#endif
}
else
{
#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0
SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0;
SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV1;
u32 SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0;
u32 SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV1;
WriteSLCRDivisors( mac_baseaddr, SlcrDiv0, SlcrDiv1 );
#endif
}
}
Expand All @@ -578,37 +598,24 @@ static void SetUpSLCRDivisors( int mac_baseaddr,
if( ( unsigned long ) mac_baseaddr == EMAC0_BASE_ADDRESS )
{
#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0
SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0;
SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV1;
u32 SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0;
u32 SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV1;
WriteSLCRDivisors( mac_baseaddr, SlcrDiv0, SlcrDiv1 );
#endif
}
else
{
#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0
SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0;
SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV1;
u32 SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0;
u32 SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV1;
WriteSLCRDivisors( mac_baseaddr, SlcrDiv0, SlcrDiv1 );
#endif
}
}

/* SDT drivers should not write to the register */
#ifndef SDT
SlcrTxClkCntrl = *( volatile unsigned int * ) ( slcrBaseAddress );
SlcrTxClkCntrl &= EMACPS_SLCR_DIV_MASK;
SlcrTxClkCntrl |= ( SlcrDiv1 << 20 );
SlcrTxClkCntrl |= ( SlcrDiv0 << 8 );
*( volatile unsigned int * ) ( slcrBaseAddress ) = SlcrTxClkCntrl;
#else
( void ) SlcrTxClkCntrl;
( void ) SlcrDiv0;
( void ) SlcrDiv1;
( void ) slcrBaseAddress;
#endif
#endif /* ifdef PEEP */
*( volatile unsigned int * ) ( SLCR_LOCK_ADDR ) = SLCR_LOCK_KEY_VALUE;
}


unsigned link_speed;
unsigned Phy_Setup( XEmacPs * xemacpsp )
{
Expand Down