]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/net/ax88180.c
net: sh-eth: Add support Gigabit of SH7734
[karo-tx-uboot.git] / drivers / net / ax88180.c
index d843397f343b91b3f27aa6c18fdd77f942766cda..f5017682d496c0f4cf004ca9893ad509515c4f2e 100644 (file)
@@ -41,6 +41,7 @@
 #include <command.h>
 #include <net.h>
 #include <malloc.h>
+#include <linux/mii.h>
 #include "ax88180.h"
 
 /*
@@ -50,9 +51,9 @@
  */
 static void ax88180_rx_handler (struct eth_device *dev);
 static int ax88180_phy_initial (struct eth_device *dev);
-static void ax88180_meidia_config (struct eth_device *dev);
-static unsigned long get_CicadaPHY_meida_mode (struct eth_device *dev);
-static unsigned long get_MarvellPHY_meida_mode (struct eth_device *dev);
+static void ax88180_media_config (struct eth_device *dev);
+static unsigned long get_CicadaPHY_media_mode (struct eth_device *dev);
+static unsigned long get_MarvellPHY_media_mode (struct eth_device *dev);
 static unsigned short ax88180_mdio_read (struct eth_device *dev,
                                         unsigned long regaddr);
 static void ax88180_mdio_write (struct eth_device *dev,
@@ -112,10 +113,10 @@ static int ax88180_phy_reset (struct eth_device *dev)
 {
        unsigned short delay_cnt = 500;
 
-       ax88180_mdio_write (dev, BMCR, (PHY_RESET | AUTONEG_EN));
+       ax88180_mdio_write (dev, MII_BMCR, (BMCR_RESET | BMCR_ANENABLE));
 
        /* Wait for the reset to complete, or time out (500 ms) */
-       while (ax88180_mdio_read (dev, BMCR) & PHY_RESET) {
+       while (ax88180_mdio_read (dev, MII_BMCR) & BMCR_RESET) {
                udelay (1000);
                if (--delay_cnt == 0) {
                        printf ("Failed to reset PHY!\n");
@@ -255,52 +256,78 @@ static int ax88180_phy_initial (struct eth_device *dev)
 {
        struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
        unsigned long tmp_regval;
+       unsigned short phyaddr;
 
-       /* Check avaliable PHY chipset  */
-       priv->PhyAddr = MARVELL_88E1111_PHYADDR;
-       priv->PhyID0 = ax88180_mdio_read (dev, PHYIDR0);
-
-       if (priv->PhyID0 == MARVELL_88E1111_PHYIDR0) {
-
-               debug ("ax88180: Found Marvell 88E1111 PHY."
-                      " (PHY Addr=0x%x)\n", priv->PhyAddr);
-
-               tmp_regval = ax88180_mdio_read (dev, M88_EXT_SSR);
-               if ((tmp_regval & HWCFG_MODE_MASK) == RGMII_COPPER_MODE) {
+       /* Search for first avaliable PHY chipset */
+#ifdef CONFIG_PHY_ADDR
+       phyaddr = CONFIG_PHY_ADDR;
+#else
+       for (phyaddr = 0; phyaddr < 32; ++phyaddr)
+#endif
+       {
+               priv->PhyAddr = phyaddr;
+               priv->PhyID0 = ax88180_mdio_read(dev, MII_PHYSID1);
+               priv->PhyID1 = ax88180_mdio_read(dev, MII_PHYSID2);
+
+               switch (priv->PhyID0) {
+               case MARVELL_ALASKA_PHYSID0:
+                       debug("ax88180: Found Marvell Alaska PHY family."
+                             " (PHY Addr=0x%x)\n", priv->PhyAddr);
+
+                       switch (priv->PhyID1) {
+                       case MARVELL_88E1118_PHYSID1:
+                               ax88180_mdio_write(dev, M88E1118_PAGE_SEL, 2);
+                               ax88180_mdio_write(dev, M88E1118_CR,
+                                       M88E1118_CR_DEFAULT);
+                               ax88180_mdio_write(dev, M88E1118_PAGE_SEL, 3);
+                               ax88180_mdio_write(dev, M88E1118_LEDCTL,
+                                       M88E1118_LEDCTL_DEFAULT);
+                               ax88180_mdio_write(dev, M88E1118_LEDMIX,
+                                       M88E1118_LEDMIX_LED050 | M88E1118_LEDMIX_LED150 | 0x15);
+                               ax88180_mdio_write(dev, M88E1118_PAGE_SEL, 0);
+                       default: /* Default to 88E1111 Phy */
+                               tmp_regval = ax88180_mdio_read(dev, M88E1111_EXT_SSR);
+                               if ((tmp_regval & HWCFG_MODE_MASK) != RGMII_COPPER_MODE)
+                                       ax88180_mdio_write(dev, M88E1111_EXT_SCR,
+                                               DEFAULT_EXT_SCR);
+                       }
 
-                       ax88180_mdio_write (dev, M88_EXT_SCR, DEFAULT_EXT_SCR);
-                       if (ax88180_phy_reset (dev) < 0)
+                       if (ax88180_phy_reset(dev) < 0)
                                return 0;
-                       ax88180_mdio_write (dev, M88_IER, LINK_CHANGE_INT);
-               }
-       } else {
+                       ax88180_mdio_write(dev, M88_IER, LINK_CHANGE_INT);
 
-               priv->PhyAddr = CICADA_CIS8201_PHYADDR;
-               priv->PhyID0 = ax88180_mdio_read (dev, PHYIDR0);
+                       return 1;
 
-               if (priv->PhyID0 == CICADA_CIS8201_PHYIDR0) {
+               case CICADA_CIS8201_PHYSID0:
+                       debug("ax88180: Found CICADA CIS8201 PHY"
+                             " chipset. (PHY Addr=0x%x)\n", priv->PhyAddr);
 
-                       debug ("ax88180: Found CICADA CIS8201 PHY"
-                              " chipset. (PHY Addr=0x%x)\n", priv->PhyAddr);
-                       ax88180_mdio_write (dev, CIS_IMR,
+                       ax88180_mdio_write(dev, CIS_IMR,
                                            (CIS_INT_ENABLE | LINK_CHANGE_INT));
 
                        /* Set CIS_SMI_PRIORITY bit before force the media mode */
-                       tmp_regval =
-                           ax88180_mdio_read (dev, CIS_AUX_CTRL_STATUS);
+                       tmp_regval = ax88180_mdio_read(dev, CIS_AUX_CTRL_STATUS);
                        tmp_regval &= ~CIS_SMI_PRIORITY;
-                       ax88180_mdio_write (dev, CIS_AUX_CTRL_STATUS,
-                                           tmp_regval);
-               } else {
-                       printf ("ax88180: Unknown PHY chipset!!\n");
-                       return 0;
+                       ax88180_mdio_write(dev, CIS_AUX_CTRL_STATUS, tmp_regval);
+
+                       return 1;
+
+               case 0xffff:
+                       /* No PHY at this addr */
+                       break;
+
+               default:
+                       printf("ax88180: Unknown PHY chipset %#x at addr %#x\n",
+                              priv->PhyID0, priv->PhyAddr);
+                       break;
                }
        }
 
-       return 1;
+       printf("ax88180: Unknown PHY chipset!!\n");
+       return 0;
 }
 
-static void ax88180_meidia_config (struct eth_device *dev)
+static void ax88180_media_config (struct eth_device *dev)
 {
        struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
        unsigned long bmcr_val, bmsr_val;
@@ -310,20 +337,20 @@ static void ax88180_meidia_config (struct eth_device *dev)
 
        /* Waiting 2 seconds for PHY link stable */
        for (i = 0; i < 20000; i++) {
-               bmsr_val = ax88180_mdio_read (dev, BMSR);
-               if (bmsr_val & LINKOK) {
+               bmsr_val = ax88180_mdio_read (dev, MII_BMSR);
+               if (bmsr_val & BMSR_LSTATUS) {
                        break;
                }
                udelay (100);
        }
 
-       bmsr_val = ax88180_mdio_read (dev, BMSR);
+       bmsr_val = ax88180_mdio_read (dev, MII_BMSR);
        debug ("ax88180: BMSR=0x%04x\n", (unsigned int)bmsr_val);
 
-       if (bmsr_val & LINKOK) {
-               bmcr_val = ax88180_mdio_read (dev, BMCR);
+       if (bmsr_val & BMSR_LSTATUS) {
+               bmcr_val = ax88180_mdio_read (dev, MII_BMCR);
 
-               if (bmcr_val & AUTONEG_EN) {
+               if (bmcr_val & BMCR_ANENABLE) {
 
                        /*
                         * Waiting for Auto-negotiation completion, this may
@@ -332,8 +359,8 @@ static void ax88180_meidia_config (struct eth_device *dev)
                        debug ("ax88180: Auto-negotiation is "
                               "enabled. Waiting for NWay completion..\n");
                        for (i = 0; i < 50000; i++) {
-                               bmsr_val = ax88180_mdio_read (dev, BMSR);
-                               if (bmsr_val & AUTONEG_COMPLETE) {
+                               bmsr_val = ax88180_mdio_read (dev, MII_BMSR);
+                               if (bmsr_val & BMSR_ANEGCOMPLETE) {
                                        break;
                                }
                                udelay (100);
@@ -345,12 +372,16 @@ static void ax88180_meidia_config (struct eth_device *dev)
                       (unsigned int)bmcr_val, (unsigned int)bmsr_val);
 
                /* Get real media mode here */
-               if (priv->PhyID0 == MARVELL_88E1111_PHYIDR0) {
-                       RealMediaMode = get_MarvellPHY_meida_mode (dev);
-               } else if (priv->PhyID0 == CICADA_CIS8201_PHYIDR0) {
-                       RealMediaMode = get_CicadaPHY_meida_mode (dev);
-               } else {
+               switch (priv->PhyID0) {
+               case MARVELL_ALASKA_PHYSID0:
+                       RealMediaMode = get_MarvellPHY_media_mode(dev);
+                       break;
+               case CICADA_CIS8201_PHYSID0:
+                       RealMediaMode = get_CicadaPHY_media_mode(dev);
+                       break;
+               default:
                        RealMediaMode = MEDIA_1000FULL;
+                       break;
                }
 
                priv->LinkState = INS_LINK_UP;
@@ -424,7 +455,7 @@ static void ax88180_meidia_config (struct eth_device *dev)
        return;
 }
 
-static unsigned long get_MarvellPHY_meida_mode (struct eth_device *dev)
+static unsigned long get_MarvellPHY_media_mode (struct eth_device *dev)
 {
        unsigned long m88_ssr;
        unsigned long MediaMode;
@@ -457,7 +488,7 @@ static unsigned long get_MarvellPHY_meida_mode (struct eth_device *dev)
        return MediaMode;
 }
 
-static unsigned long get_CicadaPHY_meida_mode (struct eth_device *dev)
+static unsigned long get_CicadaPHY_media_mode (struct eth_device *dev)
 {
        unsigned long tmp_regval;
        unsigned long MediaMode;
@@ -522,7 +553,7 @@ static int ax88180_init (struct eth_device *dev, bd_t * bd)
            dev->enetaddr[4] | (((unsigned short)dev->enetaddr[5]) << 8);
        OUTW (dev, tmp_regval, MACID2);
 
-       ax88180_meidia_config (dev);
+       ax88180_media_config (dev);
 
        OUTW (dev, DEFAULT_RXFILTER, RXFILTER);
 
@@ -558,7 +589,7 @@ static int ax88180_recv (struct eth_device *dev)
                if (ISR_Status & ISR_PHY) {
                        /* Read ISR register once to clear PHY interrupt bit */
                        tmp_regval = ax88180_mdio_read (dev, M88_ISR);
-                       ax88180_meidia_config (dev);
+                       ax88180_media_config (dev);
                }
 
                if ((ISR_Status & ISR_RX) || (ISR_Status & ISR_RXBUFFOVR)) {
@@ -573,8 +604,7 @@ static int ax88180_recv (struct eth_device *dev)
 }
 
 /* Send a data block via Ethernet. */
-static int
-ax88180_send (struct eth_device *dev, volatile void *packet, int length)
+static int ax88180_send(struct eth_device *dev, void *packet, int length)
 {
        struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
        unsigned short TXDES_addr;