generic: ar8216: drop duplicated include
[openwrt/openwrt.git] / target / linux / generic / files / drivers / net / phy / ar8216.c
index 7512ee1b43d5a549b5d0fafe0e60e18899c91953..fa33c2032b59e60f459a202cec702f3ff3dc194c 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/switch.h>
 #include <linux/delay.h>
 #include <linux/phy.h>
-#include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/lockdep.h>
 #include <linux/ar8216_platform.h>
@@ -295,6 +294,17 @@ ar8xxx_rmw(struct ar8xxx_priv *priv, int reg, u32 mask, u32 val)
 
        return ret;
 }
+void
+ar8xxx_phy_dbg_read(struct ar8xxx_priv *priv, int phy_addr,
+           u16 dbg_addr, u16 *dbg_data)
+{
+       struct mii_bus *bus = priv->mii_bus;
+
+       mutex_lock(&bus->mdio_lock);
+       bus->write(bus, phy_addr, MII_ATH_DBG_ADDR, dbg_addr);
+       *dbg_data = bus->read(bus, phy_addr, MII_ATH_DBG_DATA);
+       mutex_unlock(&bus->mdio_lock);
+}
 
 void
 ar8xxx_phy_dbg_write(struct ar8xxx_priv *priv, int phy_addr,
@@ -749,7 +759,6 @@ static void ar8216_get_arl_entry(struct ar8xxx_priv *priv,
        u16 r2, page;
        u16 r1_func0, r1_func1, r1_func2;
        u32 t, val0, val1, val2;
-       int i;
 
        split_addr(AR8216_REG_ATU_FUNC0, &r1_func0, &r2, &page);
        r2 |= 0x10;
@@ -785,12 +794,7 @@ static void ar8216_get_arl_entry(struct ar8xxx_priv *priv,
                if (!*status)
                        break;
 
-               i = 0;
-               t = AR8216_ATU_PORT0;
-               while (!(val2 & t) && ++i < priv->dev.ports)
-                       t <<= 1;
-
-               a->port = i;
+               a->portmap = (val2 & AR8216_ATU_PORTS) >> AR8216_ATU_PORTS_S;
                a->mac[0] = (val0 & AR8216_ATU_ADDR5) >> AR8216_ATU_ADDR5_S;
                a->mac[1] = (val0 & AR8216_ATU_ADDR4) >> AR8216_ATU_ADDR4_S;
                a->mac[2] = (val1 & AR8216_ATU_ADDR3) >> AR8216_ATU_ADDR3_S;
@@ -1516,8 +1520,12 @@ ar8xxx_sw_get_arl_table(struct switch_dev *dev,
                 */
                for (j = 0; j < i; ++j) {
                        a1 = &priv->arl_table[j];
-                       if (a->port == a1->port && !memcmp(a->mac, a1->mac, sizeof(a->mac)))
-                               goto duplicate;
+                       if (!memcmp(a->mac, a1->mac, sizeof(a->mac))) {
+                               /* ignore ports already seen in former entry */
+                               a->portmap &= ~a1->portmap;
+                               if (!a->portmap)
+                                       goto duplicate;
+                       }
                }
        }
 
@@ -1534,7 +1542,7 @@ ar8xxx_sw_get_arl_table(struct switch_dev *dev,
        for (j = 0; j < priv->dev.ports; ++j) {
                for (k = 0; k < i; ++k) {
                        a = &priv->arl_table[k];
-                       if (a->port != j)
+                       if (!(a->portmap & BIT(j)))
                                continue;
                        len += snprintf(buf + len, sizeof(priv->arl_buf) - len,
                                        "Port %d: MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -1804,7 +1812,7 @@ static const struct ar8xxx_chip ar8316_chip = {
 };
 
 static int
-ar8xxx_id_chip(struct ar8xxx_priv *priv)
+ar8xxx_read_id(struct ar8xxx_priv *priv)
 {
        u32 val;
        u16 id;
@@ -1829,6 +1837,17 @@ ar8xxx_id_chip(struct ar8xxx_priv *priv)
 
        priv->chip_ver = (id & AR8216_CTRL_VERSION) >> AR8216_CTRL_VERSION_S;
        priv->chip_rev = (id & AR8216_CTRL_REVISION);
+       return 0;
+}
+
+static int
+ar8xxx_id_chip(struct ar8xxx_priv *priv)
+{
+       int ret;
+
+       ret = ar8xxx_read_id(priv);
+       if(ret)
+               return ret;
 
        switch (priv->chip_ver) {
        case AR8XXX_VER_AR8216:
@@ -2104,7 +2123,8 @@ ar8xxx_phy_read_status(struct phy_device *phydev)
 
        phydev->state = PHY_RUNNING;
        netif_carrier_on(phydev->attached_dev);
-       phydev->adjust_link(phydev->attached_dev);
+       if (phydev->adjust_link)
+               phydev->adjust_link(phydev->attached_dev);
 
        return 0;
 }
@@ -2167,7 +2187,7 @@ ar8xxx_phy_probe(struct phy_device *phydev)
        int ret;
 
        /* skip PHYs at unused adresses */
-       if (phydev->mdio.addr != 0 && phydev->mdio.addr != 4)
+       if (phydev->mdio.addr != 0 && phydev->mdio.addr != 3 && phydev->mdio.addr != 4)
                return -ENODEV;
 
        if (!ar8xxx_is_possible(phydev->mdio.bus))
@@ -2226,6 +2246,8 @@ found:
                        phydev->supported |= SUPPORTED_1000baseT_Full;
                        phydev->advertising |= ADVERTISED_1000baseT_Full;
                }
+               if (priv->chip->phy_rgmii_set)
+                       priv->chip->phy_rgmii_set(priv, phydev);
        }
 
        phydev->priv = priv;