kernel: rtl8306: fix port link status
[openwrt/openwrt.git] / target / linux / generic / files / drivers / net / phy / rtl8306.c
index e280e9361a173555711cfc32825ae50e49c12ca9..7bbac40617bc8123d62e6aba2814516560199134 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rtl8306.c: RTL8306S switch driver
  *
- * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -592,7 +592,11 @@ rtl_get_port_link(struct switch_dev *dev, int port, struct switch_port_link *lin
        if (port >= RTL8306_NUM_PORTS)
                return -EINVAL;
 
+       /* in case the link changes from down to up, the register is only updated on read */
        link->link = rtl_get(dev, RTL_PORT_REG(port, LINK));
+       if (!link->link)
+               link->link = rtl_get(dev, RTL_PORT_REG(port, LINK));
+
        if (!link->link)
                return 0;
 
@@ -872,7 +876,7 @@ rtl8306_config_init(struct phy_device *pdev)
        int err;
 
        /* Only init the switch for the primary PHY */
-       if (pdev->addr != 0)
+       if (pdev->mdio.addr != 0)
                return 0;
 
        val.value.i = 1;
@@ -882,7 +886,7 @@ rtl8306_config_init(struct phy_device *pdev)
        priv->dev.ops = &rtl8306_ops;
        priv->do_cpu = 0;
        priv->page = -1;
-       priv->bus = pdev->bus;
+       priv->bus = pdev->mdio.bus;
 
        chipid = rtl_get(dev, RTL_REG_CHIPID);
        chipver = rtl_get(dev, RTL_REG_CHIPVER);
@@ -928,13 +932,13 @@ rtl8306_fixup(struct phy_device *pdev)
        u16 chipid;
 
        /* Attach to primary LAN port and WAN port */
-       if (pdev->addr != 0 && pdev->addr != 4)
+       if (pdev->mdio.addr != 0 && pdev->mdio.addr != 4)
                return 0;
 
        memset(&priv, 0, sizeof(priv));
        priv.fixup = true;
        priv.page = -1;
-       priv.bus = pdev->bus;
+       priv.bus = pdev->mdio.bus;
        chipid = rtl_get(&priv.dev, RTL_REG_CHIPID);
        if (chipid == 0x5988)
                pdev->phy_id = RTL8306_MAGIC;
@@ -952,14 +956,14 @@ rtl8306_probe(struct phy_device *pdev)
                 * share one rtl_priv instance between virtual phy
                 * devices on the same bus
                 */
-               if (priv->bus == pdev->bus)
+               if (priv->bus == pdev->mdio.bus)
                        goto found;
        }
        priv = kzalloc(sizeof(struct rtl_priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
-       priv->bus = pdev->bus;
+       priv->bus = pdev->mdio.bus;
 
 found:
        pdev->priv = priv;
@@ -980,7 +984,7 @@ rtl8306_config_aneg(struct phy_device *pdev)
        struct rtl_priv *priv = pdev->priv;
 
        /* Only for WAN */
-       if (pdev->addr == 0)
+       if (pdev->mdio.addr == 0)
                return 0;
 
        /* Restart autonegotiation */
@@ -996,7 +1000,7 @@ rtl8306_read_status(struct phy_device *pdev)
        struct rtl_priv *priv = pdev->priv;
        struct switch_dev *dev = &priv->dev;
 
-       if (pdev->addr == 4) {
+       if (pdev->mdio.addr == 4) {
                /* WAN */
                pdev->speed = rtl_get(dev, RTL_PORT_REG(4, SPEED)) ? SPEED_100 : SPEED_10;
                pdev->duplex = rtl_get(dev, RTL_PORT_REG(4, DUPLEX)) ? DUPLEX_FULL : DUPLEX_HALF;
@@ -1037,7 +1041,6 @@ static struct phy_driver rtl8306_driver = {
        .config_init    = &rtl8306_config_init,
        .config_aneg    = &rtl8306_config_aneg,
        .read_status    = &rtl8306_read_status,
-       .driver         = { .owner = THIS_MODULE,},
 };
 
 
@@ -1045,7 +1048,7 @@ static int __init
 rtl_init(void)
 {
        phy_register_fixup_for_id(PHY_ANY_ID, rtl8306_fixup);
-       return phy_driver_register(&rtl8306_driver);
+       return phy_driver_register(&rtl8306_driver, THIS_MODULE);
 }
 
 static void __exit