generic: ar8216: add sanity check to ar8216_probe
[openwrt.git] / target / linux / generic / files / drivers / net / phy / ar8216.c
index e6a4607..f356eaf 100644 (file)
@@ -833,9 +833,10 @@ ar8316_hw_init(struct ar8216_priv *priv)
                        ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
                mdiobus_write(bus, i, MII_CTRL1000, ADVERTISE_1000FULL);
                mdiobus_write(bus, i, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
-               msleep(1000);
        }
 
+       msleep(1000);
+
 out:
        priv->initialized = true;
        return 0;
@@ -1955,12 +1956,57 @@ ar8216_config_aneg(struct phy_device *phydev)
        return genphy_config_aneg(phydev);
 }
 
+static const u32 ar8xxx_phy_ids[] = {
+       0x004dd033,
+       0x004dd041,
+       0x004dd042,
+};
+
+static bool
+ar8xxx_phy_match(u32 phy_id)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ar8xxx_phy_ids); i++)
+               if (phy_id == ar8xxx_phy_ids[i])
+                       return true;
+
+       return false;
+}
+
+static bool
+ar8xxx_is_possible(struct mii_bus *bus)
+{
+       unsigned i;
+
+       for (i = 0; i < 4; i++) {
+               u32 phy_id;
+
+               phy_id = mdiobus_read(bus, i, MII_PHYSID1) << 16;
+               phy_id |= mdiobus_read(bus, i, MII_PHYSID2);
+               if (!ar8xxx_phy_match(phy_id)) {
+                       pr_debug("ar8xxx: unknown PHY at %s:%02x id:%08x\n",
+                                dev_name(&bus->dev), i, phy_id);
+                       return false;
+               }
+       }
+
+       return true;
+}
+
 static int
 ar8216_probe(struct phy_device *pdev)
 {
        struct ar8216_priv *priv;
        int ret;
 
+       /* skip PHYs at unused adresses */
+       if (pdev->addr != 0 && pdev->addr != 4)
+               return -ENODEV;
+
+       if (!ar8xxx_is_possible(pdev->bus))
+               return -ENODEV;
+
        priv = kzalloc(sizeof(struct ar8216_priv), GFP_KERNEL);
        if (priv == NULL)
                return -ENOMEM;