]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2822 1d2547de-c912-0410...
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / portable / NetworkInterface / Zynq / x_emacpsif_physpeed.c
index 742ff8b96665c9797e7fc4d6625c0728d48d7e30..12b8c60c8b9da9b4ccf0fe20cb0ef6fc31352b14 100644 (file)
-/*
- * Copyright (c) 2007-2008, Advanced Micro Devices, Inc.
- *               All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in
- *      the documentation and/or other materials provided with the
- *      distribution.
- *    * Neither the name of Advanced Micro Devices, Inc. nor the names
- *      of its contributors may be used to endorse or promote products
- *      derived from this software without specific prior written
- *      permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Some portions copyright (c) 2010-2013 Xilinx, Inc.  All rights reserved.
- *
- * Xilinx, Inc.
- * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
- * COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
- * ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
- * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
- * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
- * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
- * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
- * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
- * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
- * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "Zynq/x_emacpsif.h"
-//#include "lwipopts.h"
-#include "xparameters_ps.h"
-#include "xparameters.h"
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-///* FreeRTOS+TCP includes. */
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-
-int phy_detected = 0;
-
-/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
- *** to run it on a PEEP board
- ***/
-
-/* Advertisement control register. */
-#define ADVERTISE_10HALF               0x0020  /* Try for 10mbps half-duplex  */
-#define ADVERTISE_10FULL               0x0040  /* Try for 10mbps full-duplex  */
-#define ADVERTISE_100HALF              0x0080  /* Try for 100mbps half-duplex */
-#define ADVERTISE_100FULL              0x0100  /* Try for 100mbps full-duplex */
-
-#define ADVERTISE_100_AND_10   (ADVERTISE_10FULL | ADVERTISE_100FULL | \
-                                                               ADVERTISE_10HALF | ADVERTISE_100HALF)
-#define ADVERTISE_100                  (ADVERTISE_100FULL | ADVERTISE_100HALF)
-#define ADVERTISE_10                   (ADVERTISE_10FULL | ADVERTISE_10HALF)
-
-#define ADVERTISE_1000                 0x0300
-
-
-//#define PHY_REG_00_BMCR            0x00 // Basic mode control register
-//#define PHY_REG_01_BMSR            0x01 // Basic mode status register
-//#define PHY_REG_02_PHYSID1         0x02 // PHYS ID 1
-//#define PHY_REG_03_PHYSID2         0x03 // PHYS ID 2
-//#define PHY_REG_04_ADVERTISE       0x04 // Advertisement control reg
-
-#define IEEE_CONTROL_REG_OFFSET                                0
-#define IEEE_STATUS_REG_OFFSET                         1
-#define IEEE_AUTONEGO_ADVERTISE_REG                    4
-#define IEEE_PARTNER_ABILITIES_1_REG_OFFSET    5
-#define IEEE_1000_ADVERTISE_REG_OFFSET         9
-#define IEEE_PARTNER_ABILITIES_3_REG_OFFSET    10
-#define IEEE_COPPER_SPECIFIC_CONTROL_REG       16
-#define IEEE_SPECIFIC_STATUS_REG                       17
-#define IEEE_COPPER_SPECIFIC_STATUS_REG_2      19
-#define IEEE_CONTROL_REG_MAC                           21
-#define IEEE_PAGE_ADDRESS_REGISTER                     22
-
-
-#define IEEE_CTRL_1GBPS_LINKSPEED_MASK         0x2040
-#define IEEE_CTRL_LINKSPEED_MASK                       0x0040
-#define IEEE_CTRL_LINKSPEED_1000M                      0x0040
-#define IEEE_CTRL_LINKSPEED_100M                       0x2000
-#define IEEE_CTRL_LINKSPEED_10M                                0x0000
-#define IEEE_CTRL_RESET_MASK                           0x8000
-#define IEEE_CTRL_AUTONEGOTIATE_ENABLE         0x1000
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-#define IEEE_CTRL_RESET                         0x9140
-#define IEEE_CTRL_ISOLATE_DISABLE               0xFBFF
-#endif
-#define IEEE_STAT_AUTONEGOTIATE_CAPABLE                0x0008
-#define IEEE_STAT_AUTONEGOTIATE_COMPLETE       0x0020
-#define IEEE_STAT_AUTONEGOTIATE_RESTART                0x0200
-#define IEEE_STAT_1GBPS_EXTENSIONS                     0x0100
-#define IEEE_AN1_ABILITY_MASK                          0x1FE0
-#define IEEE_AN3_ABILITY_MASK_1GBPS                    0x0C00
-#define IEEE_AN1_ABILITY_MASK_100MBPS          0x0380
-#define IEEE_AN1_ABILITY_MASK_10MBPS           0x0060
-#define IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK     0x0030
-
-#define IEEE_ASYMMETRIC_PAUSE_MASK                     0x0800
-#define IEEE_PAUSE_MASK                                                0x0400
-#define IEEE_AUTONEG_ERROR_MASK                                0x8000
-
-#define PHY_DETECT_REG  1
-#define PHY_DETECT_MASK 0x1808
-
-#define XEMACPS_GMII2RGMII_SPEED1000_FD                0x140
-#define XEMACPS_GMII2RGMII_SPEED100_FD         0x2100
-#define XEMACPS_GMII2RGMII_SPEED10_FD          0x100
-#define XEMACPS_GMII2RGMII_REG_NUM                     0x10
-
-/* Frequency setting */
-#define SLCR_LOCK_ADDR                 (XPS_SYS_CTRL_BASEADDR + 0x4)
-#define SLCR_UNLOCK_ADDR               (XPS_SYS_CTRL_BASEADDR + 0x8)
-#define SLCR_GEM0_CLK_CTRL_ADDR        (XPS_SYS_CTRL_BASEADDR + 0x140)
-#define SLCR_GEM1_CLK_CTRL_ADDR        (XPS_SYS_CTRL_BASEADDR + 0x144)
-#ifdef PEEP
-#define SLCR_GEM_10M_CLK_CTRL_VALUE            0x00103031
-#define SLCR_GEM_100M_CLK_CTRL_VALUE   0x00103001
-#define SLCR_GEM_1G_CLK_CTRL_VALUE             0x00103011
-#endif
-#define SLCR_LOCK_KEY_VALUE                    0x767B
-#define SLCR_UNLOCK_KEY_VALUE                  0xDF0D
-#define SLCR_ADDR_GEM_RST_CTRL                 (XPS_SYS_CTRL_BASEADDR + 0x214)
-#define EMACPS_SLCR_DIV_MASK                   0xFC0FC0FF
-
-#define EMAC0_BASE_ADDRESS                             0xE000B000
-#define EMAC1_BASE_ADDRESS                             0xE000C000
-
-static int detect_phy(XEmacPs *xemacpsp)
-{
-       u16 phy_reg;
-       u32 phy_addr;
-
-       for (phy_addr = 31; phy_addr > 0; phy_addr--) {
-               XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_DETECT_REG,
-                                                       &phy_reg);
-
-               if ((phy_reg != 0xFFFF) &&
-                       ((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
-                       /* Found a valid PHY address */
-                       FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected at address %d.\r\n",
-                                                                                                                                       phy_addr));
-                       FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected.\n" ) );
-                       phy_detected = phy_addr;
-                       return phy_addr;
-               }
-       }
-
-       FreeRTOS_printf( ("XEmacPs detect_phy: No PHY detected.  Assuming a PHY at address 0\n" ) );
-
-        /* default to zero */
-       return 0;
-}
-
-#ifdef PEEP
-unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
-{
-
-       u16 control;
-       u16 status;
-       u16 partner_capabilities;
-       u16 partner_capabilities_1000;
-       u16 phylinkspeed;
-       u32 phy_addr = detect_phy(xemacpsp);
-
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
-                                                                                                                       ADVERTISE_1000);
-       /* Advertise PHY speed of 100 and 10 Mbps */
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
-                                                                                                       ADVERTISE_100_AND_10);
-
-       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,
-                                                                                                                               &control);
-       control |= (IEEE_CTRL_AUTONEGOTIATE_ENABLE |
-                                       IEEE_STAT_AUTONEGOTIATE_RESTART);
-
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
-
-       /* Read PHY control and status registers is successful. */
-       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
-       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
-
-       if ((control & IEEE_CTRL_AUTONEGOTIATE_ENABLE) && (status &
-                                       IEEE_STAT_AUTONEGOTIATE_CAPABLE)) {
-
-               while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
-                       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
-                                                                                                                               &status);
-               }
-
-               XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_1_REG_OFFSET,
-                                                                                                                       &partner_capabilities);
-
-               if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
-                       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_3_REG_OFFSET,
-                                                                                                               &partner_capabilities_1000);
-                       if (partner_capabilities_1000 & IEEE_AN3_ABILITY_MASK_1GBPS)
-                               return 1000;
-               }
-
-               if (partner_capabilities & IEEE_AN1_ABILITY_MASK_100MBPS)
-                       return 100;
-               if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)
-                       return 10;
-
-               xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",
-                               __FUNCTION__);
-               return 10;
-
-       } else {
-
-               /* Update TEMAC speed accordingly */
-               if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
-                       /* Get commanded link speed */
-                       phylinkspeed = control & IEEE_CTRL_1GBPS_LINKSPEED_MASK;
-
-                       switch (phylinkspeed) {
-                               case (IEEE_CTRL_LINKSPEED_1000M):
-                                       return 1000;
-                               case (IEEE_CTRL_LINKSPEED_100M):
-                                       return 100;
-                               case (IEEE_CTRL_LINKSPEED_10M):
-                                       return 10;
-                               default:
-                                       xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",
-                                                       __FUNCTION__, phylinkspeed);
-                                       return 10;
-                       }
-
-               } else {
-
-                       return (control & IEEE_CTRL_LINKSPEED_MASK) ? 100 : 10;
-
-               }
-       }
-}
-
-#else /* Zynq */
-unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
-{
-       u16 temp;
-       u16 control;
-       u16 status;
-       u16 partner_capabilities;
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-       u32 phy_addr = XPAR_PCSPMA_SGMII_PHYADDR;
-#else
-       u32 phy_addr = detect_phy(xemacpsp);
-#endif
-       xil_printf("Start PHY autonegotiation \r\n");
-
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-#else
-       XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
-       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
-       control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);
-
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
-
-       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
-       control |= IEEE_ASYMMETRIC_PAUSE_MASK;
-       control |= IEEE_PAUSE_MASK;
-       control |= ADVERTISE_100;
-       control |= ADVERTISE_10;
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
-
-       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
-                                                                                                                                       &control);
-       control |= ADVERTISE_1000;
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
-                                                                                                                                       control);
-
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
-       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
-                                                                                                                               &control);
-       control |= (7 << 12);   /* max number of gigabit attempts */
-       control |= (1 << 11);   /* enable downshift */
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
-                                                                                                                               control);
-#endif
-       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
-       control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
-       control |= IEEE_STAT_AUTONEGOTIATE_RESTART;
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-    control &= IEEE_CTRL_ISOLATE_DISABLE;
-#endif
-
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
-
-
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-#else
-       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
-       control |= IEEE_CTRL_RESET_MASK;
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
-
-       while (1) {
-               XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
-               if (control & IEEE_CTRL_RESET_MASK)
-                       continue;
-               else
-                       break;
-       }
-#endif
-       xil_printf("Waiting for PHY to complete autonegotiation.\r\n");
-
-       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
-       while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
-               sleep(1);
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-#else
-               XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,
-                                                                                                                                       &temp);
-               if (temp & IEEE_AUTONEG_ERROR_MASK) {
-                       xil_printf("Auto negotiation error \r\n");
-               }
-#endif
-               XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
-                                                                                                                               &status);
-               }
-
-       xil_printf("autonegotiation complete \r\n");
-
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-#else
-       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_SPECIFIC_STATUS_REG, &partner_capabilities);
-#endif
-
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-       xil_printf("Waiting for Link to be up; Polling for SGMII core Reg \r\n");
-       XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
-       while(!(temp & 0x8000)) {
-               XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
-       }
-       if((temp & 0x0C00) == 0x0800) {
-               XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
-               return 1000;
-       }
-       else if((temp & 0x0C00) == 0x0400) {
-               XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
-               return 100;
-       }
-       else if((temp & 0x0C00) == 0x0000) {
-               XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
-               return 10;
-       } else {
-               xil_printf("get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\r\n");
-               XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
-               XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);
-               return 10;
-       }
-#else
-       if ( ((partner_capabilities >> 14) & 3) == 2)/* 1000Mbps */
-               return 1000;
-       else if ( ((partner_capabilities >> 14) & 3) == 1)/* 100Mbps */
-               return 100;
-       else                                    /* 10Mbps */
-               return 10;
-#endif
-}
-#endif
-
-unsigned configure_IEEE_phy_speed(XEmacPs *xemacpsp, unsigned speed)
-{
-       u16 control;
-       u32 phy_addr = detect_phy(xemacpsp);
-
-       XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
-       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
-       control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);
-
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
-
-       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
-       control |= IEEE_ASYMMETRIC_PAUSE_MASK;
-       control |= IEEE_PAUSE_MASK;
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
-
-       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
-       control &= ~IEEE_CTRL_LINKSPEED_1000M;
-       control &= ~IEEE_CTRL_LINKSPEED_100M;
-       control &= ~IEEE_CTRL_LINKSPEED_10M;
-
-       if (speed == 1000) {
-               control |= IEEE_CTRL_LINKSPEED_1000M;
-       }
-
-       else if (speed == 100) {
-               control |= IEEE_CTRL_LINKSPEED_100M;
-               /* Dont advertise PHY speed of 1000 Mbps */
-               XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, 0);
-               /* Dont advertise PHY speed of 10 Mbps */
-               XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
-                                                                                                                               ADVERTISE_100);
-       }
-
-       else if (speed == 10) {
-               control |= IEEE_CTRL_LINKSPEED_10M;
-               /* Dont advertise PHY speed of 1000 Mbps */
-               XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
-                                                                                                                                                       0);
-               /* Dont advertise PHY speed of 100 Mbps */
-               XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
-                                                                                                                               ADVERTISE_10);
-       }
-
-       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,
-                                                                                       control | IEEE_CTRL_RESET_MASK);
-       {
-               volatile int wait;
-               for (wait=0; wait < 100000; wait++);
-       }
-       return 0;
-}
-
-static void SetUpSLCRDivisors(int mac_baseaddr, int speed)
-{
-       volatile u32 slcrBaseAddress;
-#ifndef PEEP
-       u32 SlcrDiv0;
-       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;
-       } else {
-               slcrBaseAddress = SLCR_GEM1_CLK_CTRL_ADDR;
-       }
-#ifdef PEEP
-       if (speed == 1000) {
-               *(volatile unsigned int *)(slcrBaseAddress) =
-                                                                                       SLCR_GEM_1G_CLK_CTRL_VALUE;
-       } else if (speed == 100) {
-               *(volatile unsigned int *)(slcrBaseAddress) =
-                                                                                       SLCR_GEM_100M_CLK_CTRL_VALUE;
-       } else {
-               *(volatile unsigned int *)(slcrBaseAddress) =
-                                                                                       SLCR_GEM_10M_CLK_CTRL_VALUE;
-       }
-#else
-       if (speed == 1000) {
-               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;
-#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;
-#endif
-               }
-       } else if (speed == 100) {
-               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;
-#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;
-#endif
-               }
-       } else {
-               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;
-#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;
-#endif
-               }
-       }
-       SlcrTxClkCntrl = *(volatile unsigned int *)(slcrBaseAddress);
-       SlcrTxClkCntrl &= EMACPS_SLCR_DIV_MASK;
-       SlcrTxClkCntrl |= (SlcrDiv1 << 20);
-       SlcrTxClkCntrl |= (SlcrDiv0 << 8);
-       *(volatile unsigned int *)(slcrBaseAddress) = SlcrTxClkCntrl;
-#endif
-       *(volatile unsigned int *)(SLCR_LOCK_ADDR) = SLCR_LOCK_KEY_VALUE;
-       return;
-}
-
-
-unsigned link_speed;
-unsigned Phy_Setup (XEmacPs *xemacpsp)
-{
-       unsigned long conv_present = 0;
-       unsigned long convspeeddupsetting = 0;
-       unsigned long convphyaddr = 0;
-
-#ifdef XPAR_GMII2RGMIICON_0N_ETH0_ADDR
-       convphyaddr = XPAR_GMII2RGMIICON_0N_ETH0_ADDR;
-       conv_present = 1;
-#else
-#ifdef XPAR_GMII2RGMIICON_0N_ETH1_ADDR
-       convphyaddr = XPAR_GMII2RGMIICON_0N_ETH1_ADDR;
-       conv_present = 1;
-#endif
-#endif
-
-#ifdef  ipconfigNIC_LINKSPEED_AUTODETECT
-       link_speed = get_IEEE_phy_speed(xemacpsp);
-       if (link_speed == 1000) {
-               SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);
-               convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
-       } else if (link_speed == 100) {
-               SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
-               convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
-       } else {
-               SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
-               convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
-       }
-#elif  defined(ipconfigNIC_LINKSPEED1000)
-       SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);
-       link_speed = 1000;
-       configure_IEEE_phy_speed(xemacpsp, link_speed);
-       convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
-       sleep(1);
-#elif  defined(ipconfigNIC_LINKSPEED100)
-       SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
-       link_speed = 100;
-       configure_IEEE_phy_speed(xemacpsp, link_speed);
-       convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
-       sleep(1);
-#elif  defined(ipconfigNIC_LINKSPEED10)
-       SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
-       link_speed = 10;
-       configure_IEEE_phy_speed(xemacpsp, link_speed);
-       convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
-       sleep(1);
-#endif
-       if (conv_present) {
-               XEmacPs_PhyWrite(xemacpsp, convphyaddr,
-               XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
-       }
-
-       xil_printf("link speed: %d\r\n", link_speed);
-       return link_speed;
-}
-
+/*\r
+ * Copyright (c) 2007-2008, Advanced Micro Devices, Inc.\r
+ *               All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    * Redistributions of source code must retain the above copyright\r
+ *      notice, this list of conditions and the following disclaimer.\r
+ *    * Redistributions in binary form must reproduce the above copyright\r
+ *      notice, this list of conditions and the following disclaimer in\r
+ *      the documentation and/or other materials provided with the\r
+ *      distribution.\r
+ *    * Neither the name of Advanced Micro Devices, Inc. nor the names\r
+ *      of its contributors may be used to endorse or promote products\r
+ *      derived from this software without specific prior written\r
+ *      permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+/*\r
+ * Some portions copyright (c) 2010-2013 Xilinx, Inc.  All rights reserved.\r
+ *\r
+ * Xilinx, Inc.\r
+ * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A\r
+ * COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS\r
+ * ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR\r
+ * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION\r
+ * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE\r
+ * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.\r
+ * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO\r
+ * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO\r
+ * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE\r
+ * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ */\r
+\r
+/* Standard includes. */\r
+#include <stdint.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+\r
+#include "Zynq/x_emacpsif.h"\r
+//#include "lwipopts.h"\r
+#include "xparameters_ps.h"\r
+#include "xparameters.h"\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+#include "semphr.h"\r
+\r
+///* FreeRTOS+TCP includes. */\r
+/* FreeRTOS+TCP includes. */\r
+#include "FreeRTOS_IP.h"\r
+#include "FreeRTOS_Sockets.h"\r
+#include "FreeRTOS_IP_Private.h"\r
+#include "NetworkBufferManagement.h"\r
+\r
+int phy_detected = 0;\r
+\r
+/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c\r
+ *** to run it on a PEEP board\r
+ ***/\r
+\r
+/* Advertisement control register. */\r
+#define ADVERTISE_10HALF               0x0020  /* Try for 10mbps half-duplex  */\r
+#define ADVERTISE_10FULL               0x0040  /* Try for 10mbps full-duplex  */\r
+#define ADVERTISE_100HALF              0x0080  /* Try for 100mbps half-duplex */\r
+#define ADVERTISE_100FULL              0x0100  /* Try for 100mbps full-duplex */\r
+\r
+#define ADVERTISE_100_AND_10   (ADVERTISE_10FULL | ADVERTISE_100FULL | \\r
+                                                               ADVERTISE_10HALF | ADVERTISE_100HALF)\r
+#define ADVERTISE_100                  (ADVERTISE_100FULL | ADVERTISE_100HALF)\r
+#define ADVERTISE_10                   (ADVERTISE_10FULL | ADVERTISE_10HALF)\r
+\r
+#define ADVERTISE_1000                 0x0300\r
+\r
+\r
+//#define PHY_REG_00_BMCR            0x00 // Basic mode control register\r
+//#define PHY_REG_01_BMSR            0x01 // Basic mode status register\r
+//#define PHY_REG_02_PHYSID1         0x02 // PHYS ID 1\r
+//#define PHY_REG_03_PHYSID2         0x03 // PHYS ID 2\r
+//#define PHY_REG_04_ADVERTISE       0x04 // Advertisement control reg\r
+\r
+#define IEEE_CONTROL_REG_OFFSET                                0\r
+#define IEEE_STATUS_REG_OFFSET                         1\r
+#define IEEE_AUTONEGO_ADVERTISE_REG                    4\r
+#define IEEE_PARTNER_ABILITIES_1_REG_OFFSET    5\r
+#define IEEE_1000_ADVERTISE_REG_OFFSET         9\r
+#define IEEE_PARTNER_ABILITIES_3_REG_OFFSET    10\r
+#define IEEE_COPPER_SPECIFIC_CONTROL_REG       16\r
+#define IEEE_SPECIFIC_STATUS_REG                       17\r
+#define IEEE_COPPER_SPECIFIC_STATUS_REG_2      19\r
+#define IEEE_CONTROL_REG_MAC                           21\r
+#define IEEE_PAGE_ADDRESS_REGISTER                     22\r
+\r
+\r
+#define IEEE_CTRL_1GBPS_LINKSPEED_MASK         0x2040\r
+#define IEEE_CTRL_LINKSPEED_MASK                       0x0040\r
+#define IEEE_CTRL_LINKSPEED_1000M                      0x0040\r
+#define IEEE_CTRL_LINKSPEED_100M                       0x2000\r
+#define IEEE_CTRL_LINKSPEED_10M                                0x0000\r
+#define IEEE_CTRL_RESET_MASK                           0x8000\r
+#define IEEE_CTRL_AUTONEGOTIATE_ENABLE         0x1000\r
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1\r
+#define IEEE_CTRL_RESET                         0x9140\r
+#define IEEE_CTRL_ISOLATE_DISABLE               0xFBFF\r
+#endif\r
+#define IEEE_STAT_AUTONEGOTIATE_CAPABLE                0x0008\r
+#define IEEE_STAT_AUTONEGOTIATE_COMPLETE       0x0020\r
+#define IEEE_STAT_AUTONEGOTIATE_RESTART                0x0200\r
+#define IEEE_STAT_1GBPS_EXTENSIONS                     0x0100\r
+#define IEEE_AN1_ABILITY_MASK                          0x1FE0\r
+#define IEEE_AN3_ABILITY_MASK_1GBPS                    0x0C00\r
+#define IEEE_AN1_ABILITY_MASK_100MBPS          0x0380\r
+#define IEEE_AN1_ABILITY_MASK_10MBPS           0x0060\r
+#define IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK     0x0030\r
+\r
+#define IEEE_ASYMMETRIC_PAUSE_MASK                     0x0800\r
+#define IEEE_PAUSE_MASK                                                0x0400\r
+#define IEEE_AUTONEG_ERROR_MASK                                0x8000\r
+\r
+#define PHY_DETECT_REG  1\r
+#define PHY_DETECT_MASK 0x1808\r
+\r
+#define XEMACPS_GMII2RGMII_SPEED1000_FD                0x140\r
+#define XEMACPS_GMII2RGMII_SPEED100_FD         0x2100\r
+#define XEMACPS_GMII2RGMII_SPEED10_FD          0x100\r
+#define XEMACPS_GMII2RGMII_REG_NUM                     0x10\r
+\r
+/* Frequency setting */\r
+#define SLCR_LOCK_ADDR                 (XPS_SYS_CTRL_BASEADDR + 0x4)\r
+#define SLCR_UNLOCK_ADDR               (XPS_SYS_CTRL_BASEADDR + 0x8)\r
+#define SLCR_GEM0_CLK_CTRL_ADDR        (XPS_SYS_CTRL_BASEADDR + 0x140)\r
+#define SLCR_GEM1_CLK_CTRL_ADDR        (XPS_SYS_CTRL_BASEADDR + 0x144)\r
+#ifdef PEEP\r
+#define SLCR_GEM_10M_CLK_CTRL_VALUE            0x00103031\r
+#define SLCR_GEM_100M_CLK_CTRL_VALUE   0x00103001\r
+#define SLCR_GEM_1G_CLK_CTRL_VALUE             0x00103011\r
+#endif\r
+#define SLCR_LOCK_KEY_VALUE                    0x767B\r
+#define SLCR_UNLOCK_KEY_VALUE                  0xDF0D\r
+#define SLCR_ADDR_GEM_RST_CTRL                 (XPS_SYS_CTRL_BASEADDR + 0x214)\r
+#define EMACPS_SLCR_DIV_MASK                   0xFC0FC0FF\r
+\r
+#define EMAC0_BASE_ADDRESS                             0xE000B000\r
+#define EMAC1_BASE_ADDRESS                             0xE000C000\r
+\r
+static int detect_phy(XEmacPs *xemacpsp)\r
+{\r
+       u16 phy_reg;\r
+       u32 phy_addr;\r
+\r
+       for (phy_addr = 31; phy_addr > 0; phy_addr--) {\r
+               XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_DETECT_REG,\r
+                                                       &phy_reg);\r
+\r
+               if ((phy_reg != 0xFFFF) &&\r
+                       ((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {\r
+                       /* Found a valid PHY address */\r
+                       FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected at address %d.\r\n",\r
+                                                                                                                                       phy_addr));\r
+                       FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected.\n" ) );\r
+                       phy_detected = phy_addr;\r
+                       return phy_addr;\r
+               }\r
+       }\r
+\r
+       FreeRTOS_printf( ("XEmacPs detect_phy: No PHY detected.  Assuming a PHY at address 0\n" ) );\r
+\r
+        /* default to zero */\r
+       return 0;\r
+}\r
+\r
+#ifdef PEEP\r
+unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)\r
+{\r
+\r
+       u16 control;\r
+       u16 status;\r
+       u16 partner_capabilities;\r
+       u16 partner_capabilities_1000;\r
+       u16 phylinkspeed;\r
+       u32 phy_addr = detect_phy(xemacpsp);\r
+\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,\r
+                                                                                                                       ADVERTISE_1000);\r
+       /* Advertise PHY speed of 100 and 10 Mbps */\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,\r
+                                                                                                       ADVERTISE_100_AND_10);\r
+\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,\r
+                                                                                                                               &control);\r
+       control |= (IEEE_CTRL_AUTONEGOTIATE_ENABLE |\r
+                                       IEEE_STAT_AUTONEGOTIATE_RESTART);\r
+\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);\r
+\r
+       /* Read PHY control and status registers is successful. */\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);\r
+\r
+       if ((control & IEEE_CTRL_AUTONEGOTIATE_ENABLE) && (status &\r
+                                       IEEE_STAT_AUTONEGOTIATE_CAPABLE)) {\r
+\r
+               while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {\r
+                       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,\r
+                                                                                                                               &status);\r
+               }\r
+\r
+               XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_1_REG_OFFSET,\r
+                                                                                                                       &partner_capabilities);\r
+\r
+               if (status & IEEE_STAT_1GBPS_EXTENSIONS) {\r
+                       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_3_REG_OFFSET,\r
+                                                                                                               &partner_capabilities_1000);\r
+                       if (partner_capabilities_1000 & IEEE_AN3_ABILITY_MASK_1GBPS)\r
+                               return 1000;\r
+               }\r
+\r
+               if (partner_capabilities & IEEE_AN1_ABILITY_MASK_100MBPS)\r
+                       return 100;\r
+               if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)\r
+                       return 10;\r
+\r
+               xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",\r
+                               __FUNCTION__);\r
+               return 10;\r
+\r
+       } else {\r
+\r
+               /* Update TEMAC speed accordingly */\r
+               if (status & IEEE_STAT_1GBPS_EXTENSIONS) {\r
+                       /* Get commanded link speed */\r
+                       phylinkspeed = control & IEEE_CTRL_1GBPS_LINKSPEED_MASK;\r
+\r
+                       switch (phylinkspeed) {\r
+                               case (IEEE_CTRL_LINKSPEED_1000M):\r
+                                       return 1000;\r
+                               case (IEEE_CTRL_LINKSPEED_100M):\r
+                                       return 100;\r
+                               case (IEEE_CTRL_LINKSPEED_10M):\r
+                                       return 10;\r
+                               default:\r
+                                       xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",\r
+                                                       __FUNCTION__, phylinkspeed);\r
+                                       return 10;\r
+                       }\r
+\r
+               } else {\r
+\r
+                       return (control & IEEE_CTRL_LINKSPEED_MASK) ? 100 : 10;\r
+\r
+               }\r
+       }\r
+}\r
+\r
+#else /* Zynq */\r
+unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)\r
+{\r
+       u16 temp;\r
+       u16 control;\r
+       u16 status;\r
+       u16 partner_capabilities;\r
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1\r
+       u32 phy_addr = XPAR_PCSPMA_SGMII_PHYADDR;\r
+#else\r
+       u32 phy_addr = detect_phy(xemacpsp);\r
+#endif\r
+       xil_printf("Start PHY autonegotiation \r\n");\r
+\r
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1\r
+#else\r
+       XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);\r
+       control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);\r
+\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);\r
+\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);\r
+       control |= IEEE_ASYMMETRIC_PAUSE_MASK;\r
+       control |= IEEE_PAUSE_MASK;\r
+       control |= ADVERTISE_100;\r
+       control |= ADVERTISE_10;\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);\r
+\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,\r
+                                                                                                                                       &control);\r
+       control |= ADVERTISE_1000;\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,\r
+                                                                                                                                       control);\r
+\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,\r
+                                                                                                                               &control);\r
+       control |= (7 << 12);   /* max number of gigabit attempts */\r
+       control |= (1 << 11);   /* enable downshift */\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,\r
+                                                                                                                               control);\r
+#endif\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);\r
+       control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;\r
+       control |= IEEE_STAT_AUTONEGOTIATE_RESTART;\r
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1\r
+    control &= IEEE_CTRL_ISOLATE_DISABLE;\r
+#endif\r
+\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);\r
+\r
+\r
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1\r
+#else\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);\r
+       control |= IEEE_CTRL_RESET_MASK;\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);\r
+\r
+       while (1) {\r
+               XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);\r
+               if (control & IEEE_CTRL_RESET_MASK)\r
+                       continue;\r
+               else\r
+                       break;\r
+       }\r
+#endif\r
+       xil_printf("Waiting for PHY to complete autonegotiation.\r\n");\r
+\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);\r
+       while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {\r
+               sleep(1);\r
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1\r
+#else\r
+               XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,\r
+                                                                                                                                       &temp);\r
+               if (temp & IEEE_AUTONEG_ERROR_MASK) {\r
+                       xil_printf("Auto negotiation error \r\n");\r
+               }\r
+#endif\r
+               XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,\r
+                                                                                                                               &status);\r
+               }\r
+\r
+       xil_printf("autonegotiation complete \r\n");\r
+\r
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1\r
+#else\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_SPECIFIC_STATUS_REG, &partner_capabilities);\r
+#endif\r
+\r
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1\r
+       xil_printf("Waiting for Link to be up; Polling for SGMII core Reg \r\n");\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);\r
+       while(!(temp & 0x8000)) {\r
+               XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);\r
+       }\r
+       if((temp & 0x0C00) == 0x0800) {\r
+               XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);\r
+               return 1000;\r
+       }\r
+       else if((temp & 0x0C00) == 0x0400) {\r
+               XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);\r
+               return 100;\r
+       }\r
+       else if((temp & 0x0C00) == 0x0000) {\r
+               XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);\r
+               return 10;\r
+       } else {\r
+               xil_printf("get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\r\n");\r
+               XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);\r
+               XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);\r
+               return 10;\r
+       }\r
+#else\r
+       if ( ((partner_capabilities >> 14) & 3) == 2)/* 1000Mbps */\r
+               return 1000;\r
+       else if ( ((partner_capabilities >> 14) & 3) == 1)/* 100Mbps */\r
+               return 100;\r
+       else                                    /* 10Mbps */\r
+               return 10;\r
+#endif\r
+}\r
+#endif\r
+\r
+unsigned configure_IEEE_phy_speed(XEmacPs *xemacpsp, unsigned speed)\r
+{\r
+       u16 control;\r
+       u32 phy_addr = detect_phy(xemacpsp);\r
+\r
+       XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);\r
+       control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);\r
+\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);\r
+\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);\r
+       control |= IEEE_ASYMMETRIC_PAUSE_MASK;\r
+       control |= IEEE_PAUSE_MASK;\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);\r
+\r
+       XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);\r
+       control &= ~IEEE_CTRL_LINKSPEED_1000M;\r
+       control &= ~IEEE_CTRL_LINKSPEED_100M;\r
+       control &= ~IEEE_CTRL_LINKSPEED_10M;\r
+\r
+       if (speed == 1000) {\r
+               control |= IEEE_CTRL_LINKSPEED_1000M;\r
+       }\r
+\r
+       else if (speed == 100) {\r
+               control |= IEEE_CTRL_LINKSPEED_100M;\r
+               /* Dont advertise PHY speed of 1000 Mbps */\r
+               XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, 0);\r
+               /* Dont advertise PHY speed of 10 Mbps */\r
+               XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,\r
+                                                                                                                               ADVERTISE_100);\r
+       }\r
+\r
+       else if (speed == 10) {\r
+               control |= IEEE_CTRL_LINKSPEED_10M;\r
+               /* Dont advertise PHY speed of 1000 Mbps */\r
+               XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,\r
+                                                                                                                                                       0);\r
+               /* Dont advertise PHY speed of 100 Mbps */\r
+               XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,\r
+                                                                                                                               ADVERTISE_10);\r
+       }\r
+\r
+       XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,\r
+                                                                                       control | IEEE_CTRL_RESET_MASK);\r
+       {\r
+               volatile int wait;\r
+               for (wait=0; wait < 100000; wait++);\r
+       }\r
+       return 0;\r
+}\r
+\r
+static void SetUpSLCRDivisors(int mac_baseaddr, int speed)\r
+{\r
+       volatile u32 slcrBaseAddress;\r
+#ifndef PEEP\r
+       u32 SlcrDiv0;\r
+       u32 SlcrDiv1=0;\r
+       u32 SlcrTxClkCntrl;\r
+#endif\r
+\r
+       *(volatile unsigned int *)(SLCR_UNLOCK_ADDR) = SLCR_UNLOCK_KEY_VALUE;\r
+\r
+       if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {\r
+               slcrBaseAddress = SLCR_GEM0_CLK_CTRL_ADDR;\r
+       } else {\r
+               slcrBaseAddress = SLCR_GEM1_CLK_CTRL_ADDR;\r
+       }\r
+#ifdef PEEP\r
+       if (speed == 1000) {\r
+               *(volatile unsigned int *)(slcrBaseAddress) =\r
+                                                                                       SLCR_GEM_1G_CLK_CTRL_VALUE;\r
+       } else if (speed == 100) {\r
+               *(volatile unsigned int *)(slcrBaseAddress) =\r
+                                                                                       SLCR_GEM_100M_CLK_CTRL_VALUE;\r
+       } else {\r
+               *(volatile unsigned int *)(slcrBaseAddress) =\r
+                                                                                       SLCR_GEM_10M_CLK_CTRL_VALUE;\r
+       }\r
+#else\r
+       if (speed == 1000) {\r
+               if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {\r
+#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0\r
+                       SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0;\r
+                       SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV1;\r
+#endif\r
+               } else {\r
+#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0\r
+                       SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0;\r
+                       SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV1;\r
+#endif\r
+               }\r
+       } else if (speed == 100) {\r
+               if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {\r
+#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0\r
+                       SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0;\r
+                       SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV1;\r
+#endif\r
+               } else {\r
+#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0\r
+                       SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0;\r
+                       SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV1;\r
+#endif\r
+               }\r
+       } else {\r
+               if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {\r
+#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0\r
+                       SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0;\r
+                       SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV1;\r
+#endif\r
+               } else {\r
+#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0\r
+                       SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0;\r
+                       SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV1;\r
+#endif\r
+               }\r
+       }\r
+       SlcrTxClkCntrl = *(volatile unsigned int *)(slcrBaseAddress);\r
+       SlcrTxClkCntrl &= EMACPS_SLCR_DIV_MASK;\r
+       SlcrTxClkCntrl |= (SlcrDiv1 << 20);\r
+       SlcrTxClkCntrl |= (SlcrDiv0 << 8);\r
+       *(volatile unsigned int *)(slcrBaseAddress) = SlcrTxClkCntrl;\r
+#endif\r
+       *(volatile unsigned int *)(SLCR_LOCK_ADDR) = SLCR_LOCK_KEY_VALUE;\r
+       return;\r
+}\r
+\r
+\r
+unsigned link_speed;\r
+unsigned Phy_Setup (XEmacPs *xemacpsp)\r
+{\r
+       unsigned long conv_present = 0;\r
+       unsigned long convspeeddupsetting = 0;\r
+       unsigned long convphyaddr = 0;\r
+\r
+#ifdef XPAR_GMII2RGMIICON_0N_ETH0_ADDR\r
+       convphyaddr = XPAR_GMII2RGMIICON_0N_ETH0_ADDR;\r
+       conv_present = 1;\r
+#else\r
+#ifdef XPAR_GMII2RGMIICON_0N_ETH1_ADDR\r
+       convphyaddr = XPAR_GMII2RGMIICON_0N_ETH1_ADDR;\r
+       conv_present = 1;\r
+#endif\r
+#endif\r
+\r
+#ifdef  ipconfigNIC_LINKSPEED_AUTODETECT\r
+       link_speed = get_IEEE_phy_speed(xemacpsp);\r
+       if (link_speed == 1000) {\r
+               SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);\r
+               convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;\r
+       } else if (link_speed == 100) {\r
+               SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);\r
+               convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;\r
+       } else {\r
+               SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);\r
+               convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;\r
+       }\r
+#elif  defined(ipconfigNIC_LINKSPEED1000)\r
+       SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);\r
+       link_speed = 1000;\r
+       configure_IEEE_phy_speed(xemacpsp, link_speed);\r
+       convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;\r
+       sleep(1);\r
+#elif  defined(ipconfigNIC_LINKSPEED100)\r
+       SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);\r
+       link_speed = 100;\r
+       configure_IEEE_phy_speed(xemacpsp, link_speed);\r
+       convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;\r
+       sleep(1);\r
+#elif  defined(ipconfigNIC_LINKSPEED10)\r
+       SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);\r
+       link_speed = 10;\r
+       configure_IEEE_phy_speed(xemacpsp, link_speed);\r
+       convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;\r
+       sleep(1);\r
+#endif\r
+       if (conv_present) {\r
+               XEmacPs_PhyWrite(xemacpsp, convphyaddr,\r
+               XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);\r
+       }\r
+\r
+       xil_printf("link speed: %d\r\n", link_speed);\r
+       return link_speed;\r
+}\r
+\r