drivers/net : move net drivers to drivers/net
[oweals/u-boot.git] / drivers / ns7520_eth.c
diff --git a/drivers/ns7520_eth.c b/drivers/ns7520_eth.c
deleted file mode 100644 (file)
index a5a20df..0000000
+++ /dev/null
@@ -1,859 +0,0 @@
-/***********************************************************************
- *
- * Copyright (C) 2005 by Videon Central, Inc.
- *
- * $Id$
- * @Author: Arthur Shipkowski
- * @Descr: Ethernet driver for the NS7520. Uses polled Ethernet, like
- *     the older netarmeth driver.  Note that attempting to filter
- *     broadcast and multicast out in the SAFR register will cause
- *     bad things due to released errata.
- * @References: [1] NS7520 Hardware Reference, December 2003
- *             [2] Intel LXT971 Datasheet #249414 Rev. 02
- *
- ***********************************************************************/
-
-#include <common.h>
-
-#if defined(CONFIG_DRIVER_NS7520_ETHERNET)
-
-#include <net.h>               /* NetSendPacket */
-#include <asm/arch/netarm_registers.h>
-#include <asm/arch/netarm_dma_module.h>
-
-#include "ns7520_eth.h"                /* for Ethernet and PHY */
-
-/**
- * Send an error message to the terminal.
- */
-#define ERROR(x) \
-do { \
-       char *__foo = strrchr(__FILE__, '/'); \
-       \
-       printf("%s: %d: %s(): ", (__foo == NULL ? __FILE__ : (__foo + 1)), \
-                       __LINE__, __FUNCTION__); \
-       printf x; printf("\n"); \
-} while (0);
-
-/* some definition to make transistion to linux easier */
-
-#define NS7520_DRIVER_NAME     "eth"
-#define KERN_WARNING           "Warning:"
-#define KERN_ERR               "Error:"
-#define KERN_INFO              "Info:"
-
-#if 1
-# define DEBUG
-#endif
-
-#ifdef DEBUG
-# define printk                        printf
-
-# define DEBUG_INIT            0x0001
-# define DEBUG_MINOR           0x0002
-# define DEBUG_RX              0x0004
-# define DEBUG_TX              0x0008
-# define DEBUG_INT             0x0010
-# define DEBUG_POLL            0x0020
-# define DEBUG_LINK            0x0040
-# define DEBUG_MII             0x0100
-# define DEBUG_MII_LOW         0x0200
-# define DEBUG_MEM             0x0400
-# define DEBUG_ERROR           0x4000
-# define DEBUG_ERROR_CRIT      0x8000
-
-static int nDebugLvl = DEBUG_ERROR_CRIT;
-
-# define DEBUG_ARGS0( FLG, a0 ) if( ( nDebugLvl & (FLG) ) == (FLG) ) \
-               printf("%s: " a0, __FUNCTION__, 0, 0, 0, 0, 0, 0 )
-# define DEBUG_ARGS1( FLG, a0, a1 ) if( ( nDebugLvl & (FLG) ) == (FLG)) \
-               printf("%s: " a0, __FUNCTION__, (int)(a1), 0, 0, 0, 0, 0 )
-# define DEBUG_ARGS2( FLG, a0, a1, a2 ) if( (nDebugLvl & (FLG)) ==(FLG))\
-               printf("%s: " a0, __FUNCTION__, (int)(a1), (int)(a2), 0, 0,0,0 )
-# define DEBUG_ARGS3( FLG, a0, a1, a2, a3 ) if((nDebugLvl &(FLG))==(FLG))\
-               printf("%s: "a0,__FUNCTION__,(int)(a1),(int)(a2),(int)(a3),0,0,0)
-# define DEBUG_FN( FLG ) if( (nDebugLvl & (FLG)) == (FLG) ) \
-               printf("\r%s:line %d\n", (int)__FUNCTION__, __LINE__, 0,0,0,0);
-# define ASSERT( expr, func ) if( !( expr ) ) { \
-               printf( "Assertion failed! %s:line %d %s\n", \
-               (int)__FUNCTION__,__LINE__,(int)(#expr),0,0,0); \
-               func }
-#else                          /* DEBUG */
-# define printk(...)
-# define DEBUG_ARGS0( FLG, a0 )
-# define DEBUG_ARGS1( FLG, a0, a1 )
-# define DEBUG_ARGS2( FLG, a0, a1, a2 )
-# define DEBUG_ARGS3( FLG, a0, a1, a2, a3 )
-# define DEBUG_FN( n )
-# define ASSERT(expr, func)
-#endif                         /* DEBUG */
-
-#define NS7520_MII_NEG_DELAY           (5*CFG_HZ)      /* in s */
-#define TX_TIMEOUT                     (5*CFG_HZ)      /* in s */
-#define RX_STALL_WORKAROUND_CNT 100
-
-static int ns7520_eth_reset(void);
-
-static void ns7520_link_auto_negotiate(void);
-static void ns7520_link_update_egcr(void);
-static void ns7520_link_print_changed(void);
-
-/* the PHY stuff */
-
-static char ns7520_mii_identify_phy(void);
-static unsigned short ns7520_mii_read(unsigned short uiRegister);
-static void ns7520_mii_write(unsigned short uiRegister,
-                            unsigned short uiData);
-static unsigned int ns7520_mii_get_clock_divisor(unsigned int
-                                                unMaxMDIOClk);
-static unsigned int ns7520_mii_poll_busy(void);
-
-static unsigned int nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
-static unsigned int uiLastLinkStatus;
-static PhyType phyDetected = PHY_NONE;
-
-/***********************************************************************
- * @Function: eth_init
- * @Return: -1 on failure otherwise 0
- * @Descr: Initializes the ethernet engine and uses either FS Forth's default
- *        MAC addr or the one in environment
- ***********************************************************************/
-
-int eth_init(bd_t * pbis)
-{
-       unsigned char aucMACAddr[6];
-       char *pcTmp = getenv("ethaddr");
-       char *pcEnd;
-       int i;
-
-       DEBUG_FN(DEBUG_INIT);
-
-       /* no need to check for hardware */
-
-       if (!ns7520_eth_reset())
-               return -1;
-
-       if (NULL == pcTmp)
-               return -1;
-
-       for (i = 0; i < 6; i++) {
-               aucMACAddr[i] =
-                   pcTmp ? simple_strtoul(pcTmp, &pcEnd, 16) : 0;
-               pcTmp = (*pcTmp) ? pcEnd + 1 : pcEnd;
-       }
-
-       /* configure ethernet address */
-
-       *get_eth_reg_addr(NS7520_ETH_SA1) =
-           aucMACAddr[5] << 8 | aucMACAddr[4];
-       *get_eth_reg_addr(NS7520_ETH_SA2) =
-           aucMACAddr[3] << 8 | aucMACAddr[2];
-       *get_eth_reg_addr(NS7520_ETH_SA3) =
-           aucMACAddr[1] << 8 | aucMACAddr[0];
-
-       /* enable hardware */
-
-       *get_eth_reg_addr(NS7520_ETH_MAC1) = NS7520_ETH_MAC1_RXEN;
-       *get_eth_reg_addr(NS7520_ETH_SUPP) = NS7520_ETH_SUPP_JABBER;
-       *get_eth_reg_addr(NS7520_ETH_MAC1) = NS7520_ETH_MAC1_RXEN;
-
-       /* the linux kernel may give packets < 60 bytes, for example arp */
-       *get_eth_reg_addr(NS7520_ETH_MAC2) = NS7520_ETH_MAC2_CRCEN |
-           NS7520_ETH_MAC2_PADEN | NS7520_ETH_MAC2_HUGE;
-
-       /* Broadcast/multicast allowed; if you don't set this even unicast chokes */
-       /* Based on NS7520 errata documentation */
-       *get_eth_reg_addr(NS7520_ETH_SAFR) =
-           NS7520_ETH_SAFR_BROAD | NS7520_ETH_SAFR_PRM;
-
-       /* enable receive and transmit FIFO, use 10/100 Mbps MII */
-       *get_eth_reg_addr(NS7520_ETH_EGCR) |=
-           NS7520_ETH_EGCR_ETXWM_75 |
-           NS7520_ETH_EGCR_ERX |
-           NS7520_ETH_EGCR_ERXREG |
-           NS7520_ETH_EGCR_ERXBR | NS7520_ETH_EGCR_ETX;
-
-       return 0;
-}
-
-/***********************************************************************
- * @Function: eth_send
- * @Return: -1 on timeout otherwise 1
- * @Descr: sends one frame by DMA
- ***********************************************************************/
-
-int eth_send(volatile void *pPacket, int nLen)
-{
-       int i, length32, retval = 1;
-       char *pa;
-       unsigned int *pa32, lastp = 0, rest;
-       unsigned int status;
-
-       pa = (char *) pPacket;
-       pa32 = (unsigned int *) pPacket;
-       length32 = nLen / 4;
-       rest = nLen % 4;
-
-       /* make sure there's no garbage in the last word */
-       switch (rest) {
-       case 0:
-               lastp = pa32[length32 - 1];
-               length32--;
-               break;
-       case 1:
-               lastp = pa32[length32] & 0x000000ff;
-               break;
-       case 2:
-               lastp = pa32[length32] & 0x0000ffff;
-               break;
-       case 3:
-               lastp = pa32[length32] & 0x00ffffff;
-               break;
-       }
-
-       while (((*get_eth_reg_addr(NS7520_ETH_EGSR)) &
-               NS7520_ETH_EGSR_TXREGE)
-              == 0) {
-       }
-
-       /* write to the fifo */
-       for (i = 0; i < length32; i++)
-               *get_eth_reg_addr(NS7520_ETH_FIFO) = pa32[i];
-
-       /* the last word is written to an extra register, this
-          starts the transmission */
-       *get_eth_reg_addr(NS7520_ETH_FIFOL) = lastp;
-
-       /* Wait for it to be done */
-       while ((*get_eth_reg_addr(NS7520_ETH_EGSR) & NS7520_ETH_EGSR_TXBC)
-              == 0) {
-       }
-       status = (*get_eth_reg_addr(NS7520_ETH_ETSR));
-       *get_eth_reg_addr(NS7520_ETH_EGSR) = NS7520_ETH_EGSR_TXBC;      /* Clear it now */
-
-       if (status & NS7520_ETH_ETSR_TXOK) {
-               retval = 0;     /* We're OK! */
-       } else if (status & NS7520_ETH_ETSR_TXDEF) {
-               printf("Deferred, we'll see.\n");
-               retval = 0;
-       } else if (status & NS7520_ETH_ETSR_TXAL) {
-               printf("Late collision error, %d collisions.\n",
-                      (*get_eth_reg_addr(NS7520_ETH_ETSR)) &
-                      NS7520_ETH_ETSR_TXCOLC);
-       } else if (status & NS7520_ETH_ETSR_TXAEC) {
-               printf("Excessive collisions: %d\n",
-                      (*get_eth_reg_addr(NS7520_ETH_ETSR)) &
-                      NS7520_ETH_ETSR_TXCOLC);
-       } else if (status & NS7520_ETH_ETSR_TXAED) {
-               printf("Excessive deferral on xmit.\n");
-       } else if (status & NS7520_ETH_ETSR_TXAUR) {
-               printf("Packet underrun.\n");
-       } else if (status & NS7520_ETH_ETSR_TXAJ) {
-               printf("Jumbo packet error.\n");
-       } else {
-               printf("Error: Should never get here.\n");
-       }
-
-       return (retval);
-}
-
-/***********************************************************************
- * @Function: eth_rx
- * @Return: size of last frame in bytes or 0 if no frame available
- * @Descr: gives one frame to U-Boot which has been copied by DMA engine already
- *        to NetRxPackets[ 0 ].
- ***********************************************************************/
-
-int eth_rx(void)
-{
-       int i;
-       unsigned short rxlen;
-       unsigned short totrxlen = 0;
-       unsigned int *addr;
-       unsigned int rxstatus, lastrxlen;
-       char *pa;
-
-       /* If RXBR is 1, data block was received */
-       while (((*get_eth_reg_addr(NS7520_ETH_EGSR)) &
-               NS7520_ETH_EGSR_RXBR) == NS7520_ETH_EGSR_RXBR) {
-
-               /* get status register and the length of received block */
-               rxstatus = *get_eth_reg_addr(NS7520_ETH_ERSR);
-               rxlen = (rxstatus & NS7520_ETH_ERSR_RXSIZE) >> 16;
-
-               /* clear RXBR to make fifo available */
-               *get_eth_reg_addr(NS7520_ETH_EGSR) = NS7520_ETH_EGSR_RXBR;
-
-               if (rxstatus & NS7520_ETH_ERSR_ROVER) {
-                       printf("Receive overrun, resetting FIFO.\n");
-                       *get_eth_reg_addr(NS7520_ETH_EGCR) &=
-                           ~NS7520_ETH_EGCR_ERX;
-                       udelay(20);
-                       *get_eth_reg_addr(NS7520_ETH_EGCR) |=
-                           NS7520_ETH_EGCR_ERX;
-               }
-               if (rxlen == 0) {
-                       printf("Nothing.\n");
-                       return 0;
-               }
-
-               addr = (unsigned int *) NetRxPackets[0];
-               pa = (char *) NetRxPackets[0];
-
-               /* read the fifo */
-               for (i = 0; i < rxlen / 4; i++) {
-                       *addr = *get_eth_reg_addr(NS7520_ETH_FIFO);
-                       addr++;
-               }
-
-               if ((*get_eth_reg_addr(NS7520_ETH_EGSR)) &
-                   NS7520_ETH_EGSR_RXREGR) {
-                       /* RXFDB indicates wether the last word is 1,2,3 or 4 bytes long */
-                       lastrxlen =
-                           ((*get_eth_reg_addr(NS7520_ETH_EGSR)) &
-                            NS7520_ETH_EGSR_RXFDB_MA) >> 28;
-                       *addr = *get_eth_reg_addr(NS7520_ETH_FIFO);
-                       switch (lastrxlen) {
-                       case 1:
-                               *addr &= 0xff000000;
-                               break;
-                       case 2:
-                               *addr &= 0xffff0000;
-                               break;
-                       case 3:
-                               *addr &= 0xffffff00;
-                               break;
-                       }
-               }
-
-               /* Pass the packet up to the protocol layers. */
-               NetReceive(NetRxPackets[0], rxlen - 4);
-               totrxlen += rxlen - 4;
-       }
-
-       return totrxlen;
-}
-
-/***********************************************************************
- * @Function: eth_halt
- * @Return: n/a
- * @Descr: stops the ethernet engine
- ***********************************************************************/
-
-void eth_halt(void)
-{
-       DEBUG_FN(DEBUG_INIT);
-
-       *get_eth_reg_addr(NS7520_ETH_MAC1) &= ~NS7520_ETH_MAC1_RXEN;
-       *get_eth_reg_addr(NS7520_ETH_EGCR) &= ~(NS7520_ETH_EGCR_ERX |
-                                               NS7520_ETH_EGCR_ERXDMA |
-                                               NS7520_ETH_EGCR_ERXREG |
-                                               NS7520_ETH_EGCR_ERXBR |
-                                               NS7520_ETH_EGCR_ETX |
-                                               NS7520_ETH_EGCR_ETXDMA);
-}
-
-/***********************************************************************
- * @Function: ns7520_eth_reset
- * @Return: 0 on failure otherwise 1
- * @Descr: resets the ethernet interface and the PHY,
- *        performs auto negotiation or fixed modes
- ***********************************************************************/
-
-static int ns7520_eth_reset(void)
-{
-       DEBUG_FN(DEBUG_MINOR);
-
-       /* Reset important registers */
-       *get_eth_reg_addr(NS7520_ETH_EGCR) = 0; /* Null it out! */
-       *get_eth_reg_addr(NS7520_ETH_MAC1) &= NS7520_ETH_MAC1_SRST;
-       *get_eth_reg_addr(NS7520_ETH_MAC2) = 0;
-       /* Reset MAC */
-       *get_eth_reg_addr(NS7520_ETH_EGCR) |= NS7520_ETH_EGCR_MAC_RES;
-       udelay(5);
-       *get_eth_reg_addr(NS7520_ETH_EGCR) &= ~NS7520_ETH_EGCR_MAC_RES;
-
-       /* reset and initialize PHY */
-
-       *get_eth_reg_addr(NS7520_ETH_MAC1) &= ~NS7520_ETH_MAC1_SRST;
-
-       /* we don't support hot plugging of PHY, therefore we don't reset
-          phyDetected and nPhyMaxMdioClock here. The risk is if the setting is
-          incorrect the first open
-          may detect the PHY correctly but succeding will fail
-          For reseting the PHY and identifying we have to use the standard
-          MDIO CLOCK value 2.5 MHz only after hardware reset
-          After having identified the PHY we will do faster */
-
-       *get_eth_reg_addr(NS7520_ETH_MCFG) =
-           ns7520_mii_get_clock_divisor(nPhyMaxMdioClock);
-
-       /* reset PHY */
-       ns7520_mii_write(PHY_COMMON_CTRL, PHY_COMMON_CTRL_RESET);
-       ns7520_mii_write(PHY_COMMON_CTRL, 0);
-
-       udelay(3000);           /* [2] p.70 says at least 300us reset recovery time. */
-
-       /* MII clock has been setup to default, ns7520_mii_identify_phy should
-          work for all */
-
-       if (!ns7520_mii_identify_phy()) {
-               printk(KERN_ERR NS7520_DRIVER_NAME
-                      ": Unsupported PHY, aborting\n");
-               return 0;
-       }
-
-       /* now take the highest MDIO clock possible after detection */
-       *get_eth_reg_addr(NS7520_ETH_MCFG) =
-           ns7520_mii_get_clock_divisor(nPhyMaxMdioClock);
-
-       /* PHY has been detected, so there can be no abort reason and we can
-          finish initializing ethernet */
-
-       uiLastLinkStatus = 0xff;        /* undefined */
-
-       ns7520_link_auto_negotiate();
-
-       if (phyDetected == PHY_LXT971A)
-               /* set LED2 to link mode */
-               ns7520_mii_write(PHY_LXT971_LED_CFG,
-                                (PHY_LXT971_LED_CFG_LINK_ACT <<
-                                 PHY_LXT971_LED_CFG_SHIFT_LED2) |
-                                (PHY_LXT971_LED_CFG_TRANSMIT <<
-                                 PHY_LXT971_LED_CFG_SHIFT_LED1));
-
-       return 1;
-}
-
-/***********************************************************************
- * @Function: ns7520_link_auto_negotiate
- * @Return: void
- * @Descr: performs auto-negotation of link.
- ***********************************************************************/
-
-static void ns7520_link_auto_negotiate(void)
-{
-       unsigned long ulStartJiffies;
-       unsigned short uiStatus;
-
-       DEBUG_FN(DEBUG_LINK);
-
-       /* run auto-negotation */
-       /* define what we are capable of */
-       ns7520_mii_write(PHY_COMMON_AUTO_ADV,
-                        PHY_COMMON_AUTO_ADV_100BTXFD |
-                        PHY_COMMON_AUTO_ADV_100BTX |
-                        PHY_COMMON_AUTO_ADV_10BTFD |
-                        PHY_COMMON_AUTO_ADV_10BT |
-                        PHY_COMMON_AUTO_ADV_802_3);
-       /* start auto-negotiation */
-       ns7520_mii_write(PHY_COMMON_CTRL,
-                        PHY_COMMON_CTRL_AUTO_NEG |
-                        PHY_COMMON_CTRL_RES_AUTO);
-
-       /* wait for completion */
-
-       ulStartJiffies = get_timer(0);
-       while (get_timer(0) < ulStartJiffies + NS7520_MII_NEG_DELAY) {
-               uiStatus = ns7520_mii_read(PHY_COMMON_STAT);
-               if ((uiStatus &
-                    (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT))
-                   ==
-                   (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) {
-                       /* lucky we are, auto-negotiation succeeded */
-                       ns7520_link_print_changed();
-                       ns7520_link_update_egcr();
-                       return;
-               }
-       }
-
-       DEBUG_ARGS0(DEBUG_LINK, "auto-negotiation timed out\n");
-       /* ignore invalid link settings */
-}
-
-/***********************************************************************
- * @Function: ns7520_link_update_egcr
- * @Return: void
- * @Descr: updates the EGCR and MAC2 link status after mode change or
- *        auto-negotation
- ***********************************************************************/
-
-static void ns7520_link_update_egcr(void)
-{
-       unsigned int unEGCR;
-       unsigned int unMAC2;
-       unsigned int unIPGT;
-
-       DEBUG_FN(DEBUG_LINK);
-
-       unEGCR = *get_eth_reg_addr(NS7520_ETH_EGCR);
-       unMAC2 = *get_eth_reg_addr(NS7520_ETH_MAC2);
-       unIPGT =
-           *get_eth_reg_addr(NS7520_ETH_IPGT) & ~NS7520_ETH_IPGT_IPGT;
-
-       unEGCR &= ~NS7520_ETH_EGCR_EFULLD;
-       unMAC2 &= ~NS7520_ETH_MAC2_FULLD;
-       if ((uiLastLinkStatus & PHY_LXT971_STAT2_DUPLEX_MODE)
-           == PHY_LXT971_STAT2_DUPLEX_MODE) {
-               unEGCR |= NS7520_ETH_EGCR_EFULLD;
-               unMAC2 |= NS7520_ETH_MAC2_FULLD;
-               unIPGT |= 0x15; /* see [1] p. 167 */
-       } else
-               unIPGT |= 0x12; /* see [1] p. 167 */
-
-       *get_eth_reg_addr(NS7520_ETH_MAC2) = unMAC2;
-       *get_eth_reg_addr(NS7520_ETH_EGCR) = unEGCR;
-       *get_eth_reg_addr(NS7520_ETH_IPGT) = unIPGT;
-}
-
-/***********************************************************************
- * @Function: ns7520_link_print_changed
- * @Return: void
- * @Descr: checks whether the link status has changed and if so prints
- *        the new mode
- ***********************************************************************/
-
-static void ns7520_link_print_changed(void)
-{
-       unsigned short uiStatus;
-       unsigned short uiControl;
-
-       DEBUG_FN(DEBUG_LINK);
-
-       uiControl = ns7520_mii_read(PHY_COMMON_CTRL);
-
-       if ((uiControl & PHY_COMMON_CTRL_AUTO_NEG) ==
-           PHY_COMMON_CTRL_AUTO_NEG) {
-               /* PHY_COMMON_STAT_LNK_STAT is only set on autonegotiation */
-               uiStatus = ns7520_mii_read(PHY_COMMON_STAT);
-
-               if (!(uiStatus & PHY_COMMON_STAT_LNK_STAT)) {
-                       printk(KERN_WARNING NS7520_DRIVER_NAME
-                              ": link down\n");
-                       /* @TODO Linux: carrier_off */
-               } else {
-                       /* @TODO Linux: carrier_on */
-                       if (phyDetected == PHY_LXT971A) {
-                               uiStatus =
-                                   ns7520_mii_read(PHY_LXT971_STAT2);
-                               uiStatus &=
-                                   (PHY_LXT971_STAT2_100BTX |
-                                    PHY_LXT971_STAT2_DUPLEX_MODE |
-                                    PHY_LXT971_STAT2_AUTO_NEG);
-
-                               /* mask out all uninteresting parts */
-                       }
-                       /* other PHYs must store there link information in
-                          uiStatus as PHY_LXT971 */
-               }
-       } else {
-               /* mode has been forced, so uiStatus should be the same as the
-                  last link status, enforce printing */
-               uiStatus = uiLastLinkStatus;
-               uiLastLinkStatus = 0xff;
-       }
-
-       if (uiStatus != uiLastLinkStatus) {
-               /* save current link status */
-               uiLastLinkStatus = uiStatus;
-
-               /* print new link status */
-
-               printk(KERN_INFO NS7520_DRIVER_NAME
-                      ": link mode %i Mbps %s duplex %s\n",
-                      (uiStatus & PHY_LXT971_STAT2_100BTX) ? 100 : 10,
-                      (uiStatus & PHY_LXT971_STAT2_DUPLEX_MODE) ? "full" :
-                      "half",
-                      (uiStatus & PHY_LXT971_STAT2_AUTO_NEG) ? "(auto)" :
-                      "");
-       }
-}
-
-/***********************************************************************
- * the MII low level stuff
- ***********************************************************************/
-
-/***********************************************************************
- * @Function: ns7520_mii_identify_phy
- * @Return: 1 if supported PHY has been detected otherwise 0
- * @Descr: checks for supported PHY and prints the IDs.
- ***********************************************************************/
-
-static char ns7520_mii_identify_phy(void)
-{
-       unsigned short uiID1;
-       unsigned short uiID2;
-       unsigned char *szName;
-       char cRes = 0;
-
-       DEBUG_FN(DEBUG_MII);
-
-       phyDetected = (PhyType) uiID1 = ns7520_mii_read(PHY_COMMON_ID1);
-
-       switch (phyDetected) {
-       case PHY_LXT971A:
-               szName = "LXT971A";
-               uiID2 = ns7520_mii_read(PHY_COMMON_ID2);
-               nPhyMaxMdioClock = PHY_LXT971_MDIO_MAX_CLK;
-               cRes = 1;
-               break;
-       case PHY_NONE:
-       default:
-               /* in case uiID1 == 0 && uiID2 == 0 we may have the wrong
-                  address or reset sets the wrong NS7520_ETH_MCFG_CLKS */
-
-               uiID2 = 0;
-               szName = "unknown";
-               nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
-               phyDetected = PHY_NONE;
-       }
-
-       printk(KERN_INFO NS7520_DRIVER_NAME
-              ": PHY (0x%x, 0x%x) = %s detected\n", uiID1, uiID2, szName);
-
-       return cRes;
-}
-
-/***********************************************************************
- * @Function: ns7520_mii_read
- * @Return: the data read from PHY register uiRegister
- * @Descr: the data read may be invalid if timed out. If so, a message
- *        is printed but the invalid data is returned.
- *        The fixed device address is being used.
- ***********************************************************************/
-
-static unsigned short ns7520_mii_read(unsigned short uiRegister)
-{
-       DEBUG_FN(DEBUG_MII_LOW);
-
-       /* write MII register to be read */
-       *get_eth_reg_addr(NS7520_ETH_MADR) =
-           CONFIG_PHY_ADDR << 8 | uiRegister;
-
-       *get_eth_reg_addr(NS7520_ETH_MCMD) = NS7520_ETH_MCMD_READ;
-
-       if (!ns7520_mii_poll_busy())
-               printk(KERN_WARNING NS7520_DRIVER_NAME
-                      ": MII still busy in read\n");
-       /* continue to read */
-
-       *get_eth_reg_addr(NS7520_ETH_MCMD) = 0;
-
-       return (unsigned short) (*get_eth_reg_addr(NS7520_ETH_MRDD));
-}
-
-/***********************************************************************
- * @Function: ns7520_mii_write
- * @Return: nothing
- * @Descr: writes the data to the PHY register. In case of a timeout,
- *        no special handling is performed but a message printed
- *        The fixed device address is being used.
- ***********************************************************************/
-
-static void ns7520_mii_write(unsigned short uiRegister,
-                            unsigned short uiData)
-{
-       DEBUG_FN(DEBUG_MII_LOW);
-
-       /* write MII register to be written */
-       *get_eth_reg_addr(NS7520_ETH_MADR) =
-           CONFIG_PHY_ADDR << 8 | uiRegister;
-
-       *get_eth_reg_addr(NS7520_ETH_MWTD) = uiData;
-
-       if (!ns7520_mii_poll_busy()) {
-               printf(KERN_WARNING NS7520_DRIVER_NAME
-                      ": MII still busy in write\n");
-       }
-}
-
-/***********************************************************************
- * @Function: ns7520_mii_get_clock_divisor
- * @Return: the clock divisor that should be used in NS7520_ETH_MCFG_CLKS
- * @Descr: if no clock divisor can be calculated for the
- *        current SYSCLK and the maximum MDIO Clock, a warning is printed
- *        and the greatest divisor is taken
- ***********************************************************************/
-
-static unsigned int ns7520_mii_get_clock_divisor(unsigned int unMaxMDIOClk)
-{
-       struct {
-               unsigned int unSysClkDivisor;
-               unsigned int unClks;    /* field for NS7520_ETH_MCFG_CLKS */
-       } PHYClockDivisors[] = {
-               {
-               4, NS7520_ETH_MCFG_CLKS_4}, {
-               6, NS7520_ETH_MCFG_CLKS_6}, {
-               8, NS7520_ETH_MCFG_CLKS_8}, {
-               10, NS7520_ETH_MCFG_CLKS_10}, {
-               14, NS7520_ETH_MCFG_CLKS_14}, {
-               20, NS7520_ETH_MCFG_CLKS_20}, {
-               28, NS7520_ETH_MCFG_CLKS_28}
-       };
-
-       int nIndexSysClkDiv;
-       int nArraySize =
-           sizeof(PHYClockDivisors) / sizeof(PHYClockDivisors[0]);
-       unsigned int unClks = NS7520_ETH_MCFG_CLKS_28;  /* defaults to
-                                                          greatest div */
-
-       DEBUG_FN(DEBUG_INIT);
-
-       for (nIndexSysClkDiv = 0; nIndexSysClkDiv < nArraySize;
-            nIndexSysClkDiv++) {
-               /* find first sysclock divisor that isn't higher than 2.5 MHz
-                  clock */
-               if (NETARM_XTAL_FREQ /
-                   PHYClockDivisors[nIndexSysClkDiv].unSysClkDivisor <=
-                   unMaxMDIOClk) {
-                       unClks = PHYClockDivisors[nIndexSysClkDiv].unClks;
-                       break;
-               }
-       }
-
-       DEBUG_ARGS2(DEBUG_INIT,
-                   "Taking MDIO Clock bit mask 0x%0x for max clock %i\n",
-                   unClks, unMaxMDIOClk);
-
-       /* return greatest divisor */
-       return unClks;
-}
-
-/***********************************************************************
- * @Function: ns7520_mii_poll_busy
- * @Return: 0 if timed out otherwise the remaing timeout
- * @Descr: waits until the MII has completed a command or it times out
- *        code may be interrupted by hard interrupts.
- *        It is not checked what happens on multiple actions when
- *        the first is still being busy and we timeout.
- ***********************************************************************/
-
-static unsigned int ns7520_mii_poll_busy(void)
-{
-       unsigned int unTimeout = 1000;
-
-       DEBUG_FN(DEBUG_MII_LOW);
-
-       while (((*get_eth_reg_addr(NS7520_ETH_MIND) & NS7520_ETH_MIND_BUSY)
-               == NS7520_ETH_MIND_BUSY) && unTimeout)
-               unTimeout--;
-
-       return unTimeout;
-}
-
-/* ----------------------------------------------------------------------------
- * Net+ARM ethernet MII functionality.
- */
-#if defined(CONFIG_MII)
-
-/**
- * Maximum MII address we support
- */
-#define MII_ADDRESS_MAX                        (31)
-
-/**
- * Maximum MII register address we support
- */
-#define MII_REGISTER_MAX               (31)
-
-/**
- * Ethernet MII interface return values for public functions.
- */
-enum mii_status {
-       MII_STATUS_SUCCESS = 0,
-       MII_STATUS_FAILURE = 1,
-};
-
-/**
- * Read a 16-bit value from an MII register.
- */
-extern int ns7520_miiphy_read(char *devname, unsigned char const addr,
-               unsigned char const reg, unsigned short *const value)
-{
-       int ret = MII_STATUS_FAILURE;
-
-       /* Parameter checks */
-       if (addr > MII_ADDRESS_MAX) {
-               ERROR(("invalid addr, 0x%02X", addr));
-               goto miiphy_read_failed_0;
-       }
-
-       if (reg > MII_REGISTER_MAX) {
-               ERROR(("invalid reg, 0x%02X", reg));
-               goto miiphy_read_failed_0;
-       }
-
-       if (value == NULL) {
-               ERROR(("NULL value"));
-               goto miiphy_read_failed_0;
-       }
-
-       DEBUG_FN(DEBUG_MII_LOW);
-
-       /* write MII register to be read */
-       *get_eth_reg_addr(NS7520_ETH_MADR) = (addr << 8) | reg;
-
-       *get_eth_reg_addr(NS7520_ETH_MCMD) = NS7520_ETH_MCMD_READ;
-
-       if (!ns7520_mii_poll_busy())
-               printk(KERN_WARNING NS7520_DRIVER_NAME
-                      ": MII still busy in read\n");
-       /* continue to read */
-
-       *get_eth_reg_addr(NS7520_ETH_MCMD) = 0;
-
-       *value = (*get_eth_reg_addr(NS7520_ETH_MRDD));
-       ret = MII_STATUS_SUCCESS;
-       /* Fall through */
-
-      miiphy_read_failed_0:
-       return (ret);
-}
-
-/**
- * Write a 16-bit value to an MII register.
- */
-extern int ns7520_miiphy_write(char *devname, unsigned char const addr,
-               unsigned char const reg, unsigned short const value)
-{
-       int ret = MII_STATUS_FAILURE;
-
-       /* Parameter checks */
-       if (addr > MII_ADDRESS_MAX) {
-               ERROR(("invalid addr, 0x%02X", addr));
-               goto miiphy_write_failed_0;
-       }
-
-       if (reg > MII_REGISTER_MAX) {
-               ERROR(("invalid reg, 0x%02X", reg));
-               goto miiphy_write_failed_0;
-       }
-
-       /* write MII register to be written */
-       *get_eth_reg_addr(NS7520_ETH_MADR) = (addr << 8) | reg;
-
-       *get_eth_reg_addr(NS7520_ETH_MWTD) = value;
-
-       if (!ns7520_mii_poll_busy()) {
-               printf(KERN_WARNING NS7520_DRIVER_NAME
-                      ": MII still busy in write\n");
-       }
-
-       ret = MII_STATUS_SUCCESS;
-       /* Fall through */
-
-      miiphy_write_failed_0:
-       return (ret);
-}
-#endif                         /* defined(CONFIG_MII) */
-#endif                         /* CONFIG_DRIVER_NS7520_ETHERNET */
-
-int ns7520_miiphy_initialize(bd_t *bis)
-{
-#if defined(CONFIG_DRIVER_NS7520_ETHERNET)
-#if defined(CONFIG_MII)
-       miiphy_register("ns7520phy", ns7520_miiphy_read, ns7520_miiphy_write);
-#endif
-#endif
-       return 0;
-}