NET: mvgbe: add phylib support
authorSebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Tue, 4 Dec 2012 08:32:00 +0000 (09:32 +0100)
committerJoe Hershberger <joe.hershberger@ni.com>
Tue, 25 Jun 2013 00:10:14 +0000 (19:10 -0500)
This add phylib support to the Marvell GBE driver.

Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
drivers/net/mvgbe.c

index 47bf27c8ba3981d0d060ad090aacad4e41ef85e8..4b588235a5e0ca9e1a775979e845920ccc2f44ad 100644 (file)
@@ -52,7 +52,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #define MV_PHY_ADR_REQUEST 0xee
 #define MVGBE_SMI_REG (((struct mvgbe_registers *)MVGBE0_BASE)->smi)
 
-#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+#if defined(CONFIG_PHYLIB) || defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
 /*
  * smi_reg_read - miiphy_read callback function.
  *
@@ -184,6 +184,25 @@ static int smi_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
 }
 #endif
 
+#if defined(CONFIG_PHYLIB)
+int mvgbe_phy_read(struct mii_dev *bus, int phy_addr, int dev_addr,
+                  int reg_addr)
+{
+       u16 data;
+       int ret;
+       ret = smi_reg_read(bus->name, phy_addr, reg_addr, &data);
+       if (ret)
+               return ret;
+       return data;
+}
+
+int mvgbe_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
+                   int reg_addr, u16 data)
+{
+       return smi_reg_write(bus->name, phy_addr, reg_addr, data);
+}
+#endif
+
 /* Stop and checks all queues */
 static void stop_queue(u32 * qreg)
 {
@@ -467,8 +486,9 @@ static int mvgbe_init(struct eth_device *dev)
        /* Enable port Rx. */
        MVGBE_REG_WR(regs->rqc, (1 << RXUQ));
 
-#if (defined (CONFIG_MII) || defined (CONFIG_CMD_MII)) \
-        && defined (CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
+#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
+       !defined(CONFIG_PHYLIB) && \
+       defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
        /* Wait up to 5s for the link status */
        for (i = 0; i < 5; i++) {
                u16 phyadr;
@@ -647,6 +667,45 @@ static int mvgbe_recv(struct eth_device *dev)
        return 0;
 }
 
+#if defined(CONFIG_PHYLIB)
+int mvgbe_phylib_init(struct eth_device *dev, int phyid)
+{
+       struct mii_dev *bus;
+       struct phy_device *phydev;
+       int ret;
+
+       bus = mdio_alloc();
+       if (!bus) {
+               printf("mdio_alloc failed\n");
+               return -ENOMEM;
+       }
+       bus->read = mvgbe_phy_read;
+       bus->write = mvgbe_phy_write;
+       sprintf(bus->name, dev->name);
+
+       ret = mdio_register(bus);
+       if (ret) {
+               printf("mdio_register failed\n");
+               free(bus);
+               return -ENOMEM;
+       }
+
+       /* Set phy address of the port */
+       mvgbe_phy_write(bus, MV_PHY_ADR_REQUEST, 0, MV_PHY_ADR_REQUEST, phyid);
+
+       phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RGMII);
+       if (!phydev) {
+               printf("phy_connect failed\n");
+               return -ENODEV;
+       }
+
+       phy_config(phydev);
+       phy_startup(phydev);
+
+       return 0;
+}
+#endif
+
 int mvgbe_initialize(bd_t *bis)
 {
        struct mvgbe_device *dmvgbe;
@@ -729,7 +788,9 @@ error1:
 
                eth_register(dev);
 
-#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+#if defined(CONFIG_PHYLIB)
+               mvgbe_phylib_init(dev, PHY_BASE_ADR + devnum);
+#elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
                miiphy_register(dev->name, smi_reg_read, smi_reg_write);
                /* Set phy address of the port */
                miiphy_write(dev->name, MV_PHY_ADR_REQUEST,