diff --git a/source/portable/NetworkInterface/Zynq/README.txt b/source/portable/NetworkInterface/Zynq/README.txt index a1185c104..24541c737 100644 --- a/source/portable/NetworkInterface/Zynq/README.txt +++ b/source/portable/NetworkInterface/Zynq/README.txt @@ -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 diff --git a/source/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c b/source/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c index 6ea17fe92..ac9dcfcf0 100644 --- a/source/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c +++ b/source/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c @@ -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; @@ -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 ) = @@ -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 } } @@ -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 } } @@ -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 ) {