embeddedsw/XilinxProcessorIPLib/drivers/axiethernet/examples/xaxiethernet_example_util.c
Jagannadha Sutradharudu Teki 2c8f92039d embeddesw: Add initial code support
Added initial support Xilinx Embedded Software.

Signed-off-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
2014-06-24 16:45:01 +05:30

789 lines
21 KiB
C
Executable file

/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/**
*
* @file xaxiethernet_example_util.c
*
* This file implements the utility functions for the Axi Ethernet example code.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a asa 6/30/10 First release based on the ll temac driver
* 3.01a srt 02/03/13 Added support for SGMII mode (CR 676793).
* 02/14/13 Added support for Zynq (CR 681136).
* 3.02a srt 04/24/13 Modified parameter *_SGMII_PHYADDR to *_PHYADDR, the
* config parameter C_PHYADDR applies to SGMII/1000BaseX
* modes of operation and added support for 1000BaseX mode
* (CR 704195). Added function *_ConfigureInternalPhy()
* for this purpose.
* 04/24/13 Added support for RGMII mode.
* 3.02a srt 08/06/13 Fixed CR 717949:
* Configures external Marvel 88E1111 PHY based on the
* axi ethernet physical interface type and allows to
* operate in specific interface mode without changing
* jumpers on the Microblaze board.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xaxiethernet_example.h"
#if !defined (__MICROBLAZE__) && !defined(__PPC__)
#include "sleep.h"
#endif
/************************** Variable Definitions ****************************/
/*
* Local MAC address
*/
char AxiEthernetMAC[6] = { 0x00, 0x0A, 0x35, 0x01, 0x02, 0x03 };
/******************************************************************************/
/**
*
* Set the MAC addresses in the frame.
*
* @param FramePtr is the pointer to the frame.
* @param DestAddr is the Destination MAC address.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetUtilFrameHdrFormatMAC(EthernetFrame *FramePtr, char *DestAddr)
{
char *Frame = (char *) FramePtr;
char *SourceAddress = AxiEthernetMAC;
int Index;
/*
* Destination address
*/
for (Index = 0; Index < XAE_MAC_ADDR_SIZE; Index++) {
*Frame++ = *DestAddr++;
}
/*
* Source address
*/
for (Index = 0; Index < XAE_MAC_ADDR_SIZE; Index++) {
*Frame++ = *SourceAddress++;
}
}
/******************************************************************************/
/**
*
* Set the frame type for the specified frame.
*
* @param FramePtr is the pointer to the frame.
* @param FrameType is the Type to set in frame.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetUtilFrameHdrFormatType(EthernetFrame *FramePtr, u16 FrameType)
{
char *Frame = (char *) FramePtr;
/*
* Increment to type field
*/
Frame = Frame + 12;
FrameType = Xil_Htons(FrameType);
/*
* Set the type
*/
*(u16 *) Frame = FrameType;
}
/******************************************************************************/
/**
* This function places a pattern in the payload section of a frame. The pattern
* is a 8 bit incrementing series of numbers starting with 0.
* Once the pattern reaches 256, then the pattern changes to a 16 bit
* incrementing pattern:
* <pre>
* 0, 1, 2, ... 254, 255, 00, 00, 00, 01, 00, 02, ...
* </pre>
*
* @param FramePtr is a pointer to the frame to change.
* @param PayloadSize is the number of bytes in the payload that will be
* set.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetUtilFrameSetPayloadData(EthernetFrame *FramePtr,
int PayloadSize)
{
unsigned BytesLeft = PayloadSize;
u8 *Frame;
u16 Counter = 0;
/*
* Set the frame pointer to the start of the payload area
*/
Frame = (u8 *) FramePtr + XAE_HDR_SIZE;
/*
* Insert 8 bit incrementing pattern
*/
while (BytesLeft && (Counter < 256)) {
*Frame++ = (u8) Counter++;
BytesLeft--;
}
/*
* Switch to 16 bit incrementing pattern
*/
while (BytesLeft) {
*Frame++ = (u8) (Counter >> 8); /* high */
BytesLeft--;
if (!BytesLeft)
break;
*Frame++ = (u8) Counter++; /* low */
BytesLeft--;
}
}
/******************************************************************************/
/**
*
* Set the frame VLAN info for the specified frame.
*
* @param FramePtr is the pointer to the frame.
* @param VlanNumber is the VlanValue insertion position to set in frame.
* @param Vid is the 4 bytes Vlan value (TPID, Priority, CFI, VID)
* to be set in frame.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetUtilFrameHdrVlanFormatVid(EthernetFrame *FramePtr,
u32 VlanNumber, u32 Vid)
{
char *Frame = (char *) FramePtr;
/*
* Increment to type field
*/
Frame = Frame + 12 + (VlanNumber * 4);
Vid = Xil_Htonl(Vid);
/*
* Set the type
*/
*(u32 *) Frame = Vid;
}
/******************************************************************************/
/**
*
* Set the frame type for the specified frame.
*
* @param FramePtr is the pointer to the frame.
* @param FrameType is the Type to set in frame.
* @param VlanNumber is the VLAN friendly adjusted insertion position to
* set in frame.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetUtilFrameHdrVlanFormatType(EthernetFrame *FramePtr,
u16 FrameType, u32 VlanNumber)
{
char *Frame = (char *) FramePtr;
/*
* Increment to type field
*/
Frame = Frame + 12 + (VlanNumber * 4);
FrameType = Xil_Htons(FrameType);
/*
* Set the type
*/
*(u16 *) Frame = FrameType;
}
/******************************************************************************/
/**
* This function places a pattern in the payload section of a frame. The pattern
* is a 8 bit incrementing series of numbers starting with 0.
* Once the pattern reaches 256, then the pattern changes to a 16 bit
* incrementing pattern:
* <pre>
* 0, 1, 2, ... 254, 255, 00, 00, 00, 01, 00, 02, ...
* </pre>
*
* @param FramePtr is a pointer to the frame to change.
* @param PayloadSize is the number of bytes in the payload that will be set.
* @param VlanNumber is the VLAN friendly adjusted insertion position to
* set in frame.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetUtilFrameSetVlanPayloadData(EthernetFrame *FramePtr,
int PayloadSize, u32 VlanNumber)
{
unsigned BytesLeft = PayloadSize;
u8 *Frame;
u16 Counter = 0;
/*
* Set the frame pointer to the start of the payload area
*/
Frame = (u8 *) FramePtr + XAE_HDR_SIZE + (VlanNumber * 4);
/*
* Insert 8 bit incrementing pattern
*/
while (BytesLeft && (Counter < 256)) {
*Frame++ = (u8) Counter++;
BytesLeft--;
}
/*
* Switch to 16 bit incrementing pattern
*/
while (BytesLeft) {
*Frame++ = (u8) (Counter >> 8); /* high */
BytesLeft--;
if (!BytesLeft)
break;
*Frame++ = (u8) Counter++; /* low */
BytesLeft--;
}
}
/******************************************************************************/
/**
* This function verifies the frame data against a CheckFrame.
*
* Validation occurs by comparing the ActualFrame to the header of the
* CheckFrame. If the headers match, then the payload of ActualFrame is
* verified for the same pattern Util_FrameSetPayloadData() generates.
*
* @param CheckFrame is a pointer to a frame containing the 14 byte header
* that should be present in the ActualFrame parameter.
* @param ActualFrame is a pointer to a frame to validate.
*
* @return - XST_SUCCESS if successful.
* - XST_FAILURE in case of failure.
*
* @note None.
*
******************************************************************************/
int AxiEthernetUtilFrameVerify(EthernetFrame * CheckFrame,
EthernetFrame * ActualFrame)
{
unsigned char *CheckPtr = (unsigned char *) CheckFrame;
unsigned char *ActualPtr = (unsigned char *) ActualFrame;
u16 BytesLeft;
u16 Counter;
int Index;
/*
* Compare the headers
*/
for (Index = 0; Index < XAE_HDR_SIZE; Index++) {
if (CheckPtr[Index] != ActualPtr[Index]) {
return XST_FAILURE;
}
}
Index = 0;
BytesLeft = *(u16 *) &ActualPtr[12];
BytesLeft = Xil_Ntohs(BytesLeft);
/*
* Get the length of the payload, do not use VLAN TPID here.
* TPID needs to be verified.
*/
while ((0x8100 == BytesLeft) || (0x88A8 == BytesLeft) ||
(0x9100 == BytesLeft) || (0x9200 == BytesLeft)) {
Index++;
BytesLeft = *(u16 *) &ActualPtr[12+(4*Index)];
BytesLeft = Xil_Ntohs(BytesLeft);
}
/*
* Validate the payload
*/
Counter = 0;
ActualPtr = &ActualPtr[14+(4*Index)];
/*
* Check 8 bit incrementing pattern
*/
while (BytesLeft && (Counter < 256)) {
if (*ActualPtr++ != (u8) Counter++) {
return XST_FAILURE;
}
BytesLeft--;
}
/*
* Check 16 bit incrementing pattern
*/
while (BytesLeft) {
if (*ActualPtr++ != (u8) (Counter >> 8)) { /* high */
return XST_FAILURE;
}
BytesLeft--;
if (!BytesLeft)
break;
if (*ActualPtr++ != (u8) Counter++) { /* low */
return XST_FAILURE;
}
BytesLeft--;
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
* This function sets all bytes of a frame to 0.
*
* @param FramePtr is a pointer to the frame itself.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetUtilFrameMemClear(EthernetFrame * FramePtr)
{
u32 *Data32Ptr = (u32 *) FramePtr;
u32 WordsLeft = sizeof(EthernetFrame) / sizeof(u32);
/*
* Frame should be an integral number of words
*/
while (WordsLeft--) {
*Data32Ptr++ = 0;
}
}
/******************************************************************************/
/**
*
* This function detects the PHY address by looking for successful MII status
* register contents (PHY register 1). It looks for a PHY that supports
* auto-negotiation and 10Mbps full-duplex and half-duplex. So, this code
* won't work for PHYs that don't support those features, but it's a bit more
* general purpose than matching a specific PHY manufacturer ID.
*
* Note also that on some (older) Xilinx ML4xx boards, PHY address 0 does not
* properly respond to this query. But, since the default is 0 and asssuming
* no other address responds, then it seems to work OK.
*
* @param The Axi Ethernet driver instance
*
* @return The address of the PHY (defaults to 0 if none detected)
*
* @note None.
*
******************************************************************************/
/* Use MII register 1 (MII status register) to detect PHY */
#define PHY_DETECT_REG 1
/* Mask used to verify certain PHY features (or register contents)
* in the register above:
* 0x1000: 10Mbps full duplex support
* 0x0800: 10Mbps half duplex support
* 0x0008: Auto-negotiation support
*/
#define PHY_DETECT_MASK 0x1808
u32 AxiEthernetDetectPHY(XAxiEthernet * AxiEthernetInstancePtr)
{
u16 PhyReg;
int PhyAddr;
for (PhyAddr = 31; PhyAddr >= 0; PhyAddr--) {
XAxiEthernet_PhyRead(AxiEthernetInstancePtr, PhyAddr,
PHY_DETECT_REG, &PhyReg);
if ((PhyReg != 0xFFFF) &&
((PhyReg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
/* Found a valid PHY address */
return PhyAddr;
}
}
return 0; /* Default to zero */
}
/******************************************************************************/
/**
* Set PHY to loopback mode. This works with the marvell PHY common on ML40x
* evaluation boards
*
* @param Speed is the loopback speed 10, 100, or 1000 Mbit
*
******************************************************************************/
/* IEEE PHY Specific definitions */
#define PHY_R0_CTRL_REG 0
#define PHY_R3_PHY_IDENT_REG 3
#define PHY_R0_RESET 0x8000
#define PHY_R0_LOOPBACK 0x4000
#define PHY_R0_ANEG_ENABLE 0x1000
#define PHY_R0_DFT_SPD_MASK 0x2040
#define PHY_R0_DFT_SPD_10 0x0000
#define PHY_R0_DFT_SPD_100 0x2000
#define PHY_R0_DFT_SPD_1000 0x0040
#define PHY_R0_ISOLATE 0x0400
/* Marvel PHY 88E1111 Specific definitions */
#define PHY_R20_EXTND_CTRL_REG 20
#define PHY_R27_EXTND_STS_REG 27
#define PHY_R20_DFT_SPD_10 0x20
#define PHY_R20_DFT_SPD_100 0x50
#define PHY_R20_DFT_SPD_1000 0x60
#define PHY_R20_RX_DLY 0x80
#define PHY_R27_MAC_CONFIG_GMII 0x000F
#define PHY_R27_MAC_CONFIG_MII 0x000F
#define PHY_R27_MAC_CONFIG_RGMII 0x000B
#define PHY_R27_MAC_CONFIG_SGMII 0x0004
/* Marvel PHY 88E1116R Specific definitions */
#define PHY_R22_PAGE_ADDR_REG 22
#define PHY_PG2_R21_CTRL_REG 21
#define PHY_REG21_10 0x0030
#define PHY_REG21_100 0x2030
#define PHY_REG21_1000 0x0070
/* Marvel PHY flags */
#define MARVEL_PHY_88E1111_MODEL 0xC0
#define MARVEL_PHY_88E1116R_MODEL 0x240
#define PHY_MODEL_NUM_MASK 0x3F0
/******************************************************************************/
/**
*
* This function sets the PHY to loopback mode. This works with the marvell PHY
* common on ML40x evaluation boards.
*
* @param AxiEthernetInstancePtr is a pointer to the instance of the
* AxiEthernet component.
* @param Speed is the loopback speed 10, 100, or 1000 Mbit.
*
* @return - XST_SUCCESS if successful.
* - XST_FAILURE, in case of failure..
*
* @note None.
*
******************************************************************************/
int AxiEthernetUtilEnterLoopback(XAxiEthernet *AxiEthernetInstancePtr,
int Speed)
{
u16 PhyReg0;
signed int PhyAddr;
u8 PhyType;
u16 PhyModel;
u16 PhyReg20; /* Extended PHY specific Register (Reg 20)
of Marvell 88E1111 PHY */
u16 PhyReg21; /* Control Register MAC (Reg 21)
of Marvell 88E1116R PHY */
/* Get the Phy Interface */
PhyType = XAxiEthernet_GetPhysicalInterface(AxiEthernetInstancePtr);
/* Detect the PHY address */
if (PhyType != XAE_PHY_TYPE_1000BASE_X) {
PhyAddr = AxiEthernetDetectPHY(AxiEthernetInstancePtr);
} else {
PhyAddr = XPAR_AXIETHERNET_0_PHYADDR;
}
XAxiEthernet_PhyRead(AxiEthernetInstancePtr, PhyAddr,
PHY_R3_PHY_IDENT_REG, &PhyModel);
PhyModel = PhyModel & PHY_MODEL_NUM_MASK;
/* Clear the PHY of any existing bits by zeroing this out */
PhyReg0 = PhyReg20 = PhyReg21 = 0;
switch (Speed) {
case XAE_SPEED_10_MBPS:
PhyReg0 |= PHY_R0_DFT_SPD_10;
PhyReg20 |= PHY_R20_DFT_SPD_10;
PhyReg21 |= PHY_REG21_10;
break;
case XAE_SPEED_100_MBPS:
PhyReg0 |= PHY_R0_DFT_SPD_100;
PhyReg20 |= PHY_R20_DFT_SPD_100;
PhyReg21 |= PHY_REG21_100;
break;
case XAE_SPEED_1000_MBPS:
PhyReg0 |= PHY_R0_DFT_SPD_1000;
PhyReg20 |= PHY_R20_DFT_SPD_1000;
PhyReg21 |= PHY_REG21_1000;
break;
default:
AxiEthernetUtilErrorTrap("Intg_LinkSpeed not 10, 100, or 1000 mbps");
return XST_FAILURE;
}
/* RGMII mode Phy specific registers initialization */
if ((PhyType == XAE_PHY_TYPE_RGMII_2_0) ||
(PhyType == XAE_PHY_TYPE_RGMII_1_3)) {
if (PhyModel == MARVEL_PHY_88E1111_MODEL) {
PhyReg20 |= PHY_R20_RX_DLY;
/*
* Adding Rx delay. Configuring loopback speed.
*/
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr,
PhyAddr, PHY_R20_EXTND_CTRL_REG,
PhyReg20);
} else if (PhyModel == MARVEL_PHY_88E1116R_MODEL) {
/*
* Switching to PAGE2
*/
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr,
PhyAddr,
PHY_R22_PAGE_ADDR_REG, 2);
/*
* Adding Tx and Rx delay. Configuring loopback speed.
*/
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr,
PhyAddr,
PHY_PG2_R21_CTRL_REG, PhyReg21);
/*
* Switching to PAGE0
*/
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr,
PhyAddr,
PHY_R22_PAGE_ADDR_REG, 0);
}
PhyReg0 &= (~PHY_R0_ANEG_ENABLE);
}
/* Configure interface modes */
if (PhyModel == MARVEL_PHY_88E1111_MODEL) {
if ((PhyType == XAE_PHY_TYPE_RGMII_2_0) ||
(PhyType == XAE_PHY_TYPE_RGMII_1_3)) {
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr,
PhyAddr, PHY_R27_EXTND_STS_REG,
PHY_R27_MAC_CONFIG_RGMII);
} else if (PhyType == XAE_PHY_TYPE_SGMII) {
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr,
PhyAddr, PHY_R27_EXTND_STS_REG,
PHY_R27_MAC_CONFIG_SGMII);
} else if ((PhyType == XAE_PHY_TYPE_GMII) ||
(PhyType == XAE_PHY_TYPE_MII)) {
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr,
PhyAddr, PHY_R27_EXTND_STS_REG,
PHY_R27_MAC_CONFIG_GMII );
}
}
/* Set the speed and put the PHY in reset, then put the PHY in loopback */
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr, PhyAddr,
PHY_R0_CTRL_REG,
PhyReg0 | PHY_R0_RESET);
AxiEthernetUtilPhyDelay(AXIETHERNET_PHY_DELAY_SEC);
XAxiEthernet_PhyRead(AxiEthernetInstancePtr,PhyAddr,
PHY_R0_CTRL_REG, &PhyReg0);
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr, PhyAddr,
PHY_R0_CTRL_REG,
PhyReg0 | PHY_R0_LOOPBACK);
if ((PhyType == XAE_PHY_TYPE_SGMII) ||
(PhyType == XAE_PHY_TYPE_1000BASE_X)) {
AxiEthernetUtilConfigureInternalPhy(AxiEthernetInstancePtr, Speed);
}
AxiEthernetUtilPhyDelay(1);
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function is called by example code when an error is detected. It
* can be set as a breakpoint with a debugger or it can be used to print out the
* given message if there is a UART or STDIO device.
*
* @param Message is the text explaining the error
*
* @return None
*
* @note None
*
******************************************************************************/
void AxiEthernetUtilErrorTrap(char *Message)
{
static int Count = 0;
Count++;
#ifdef STDOUT_BASEADDRESS
xil_printf("%s\r\n", Message);
#endif
}
/******************************************************************************/
/**
*
* For Microblaze we use an assembly loop that is roughly the same regardless of
* optimization level, although caches and memory access time can make the delay
* vary. Just keep in mind that after resetting or updating the PHY modes,
* the PHY typically needs time to recover.
*
* @return None
*
* @note None
*
******************************************************************************/
void AxiEthernetUtilPhyDelay(unsigned int Seconds)
{
#if defined (__MICROBLAZE__) || defined(__PPC__)
static int WarningFlag = 0;
/* If MB caches are disabled or do not exist, this delay loop could
* take minutes instead of seconds (e.g., 30x longer). Print a warning
* message for the user (once). If only MB had a built-in timer!
*/
if (((mfmsr() & 0x20) == 0) && (!WarningFlag)) {
WarningFlag = 1;
}
#define ITERS_PER_SEC (XPAR_CPU_CORE_CLOCK_FREQ_HZ / 6)
asm volatile ("\n"
"1: \n\t"
"addik r7, r0, %0 \n\t"
"2: \n\t"
"addik r7, r7, -1 \n\t"
"bneid r7, 2b \n\t"
"or r0, r0, r0 \n\t"
"bneid %1, 1b \n\t"
"addik %1, %1, -1 \n\t"
:: "i"(ITERS_PER_SEC), "d" (Seconds));
#else
sleep(Seconds);
#endif
}
/******************************************************************************/
/**
*
* This function configures the internal phy for SGMII and 1000baseX modes.
* *
* @param AxiEthernetInstancePtr is a pointer to the instance of the
* AxiEthernet component.
* @param Speed is the loopback speed 10, 100, or 1000 Mbit.
*
* @return - XST_SUCCESS if successful.
* - XST_FAILURE, in case of failure..
*
* @note None.
*
******************************************************************************/
int AxiEthernetUtilConfigureInternalPhy(XAxiEthernet *AxiEthernetInstancePtr,
int Speed)
{
u16 PhyReg0;
signed int PhyAddr;
PhyAddr = XPAR_AXIETHERNET_0_PHYADDR;
/* Clear the PHY of any existing bits by zeroing this out */
PhyReg0 = 0;
XAxiEthernet_PhyRead(AxiEthernetInstancePtr, PhyAddr,
PHY_R0_CTRL_REG, &PhyReg0);
PhyReg0 &= (~PHY_R0_ANEG_ENABLE);
PhyReg0 &= (~PHY_R0_ISOLATE);
switch (Speed) {
case XAE_SPEED_10_MBPS:
PhyReg0 |= PHY_R0_DFT_SPD_10;
break;
case XAE_SPEED_100_MBPS:
PhyReg0 |= PHY_R0_DFT_SPD_100;
break;
case XAE_SPEED_1000_MBPS:
PhyReg0 |= PHY_R0_DFT_SPD_1000;
break;
default:
AxiEthernetUtilErrorTrap(
"Intg_LinkSpeed not 10, 100, or 1000 mbps\n\r");
return XST_FAILURE;
}
AxiEthernetUtilPhyDelay(1);
XAxiEthernet_PhyWrite(AxiEthernetInstancePtr, PhyAddr,
PHY_R0_CTRL_REG, PhyReg0);
return XST_SUCCESS;
}