aboutsummaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
authorGabor Juhos <juhosg@openwrt.org>2013-02-10 13:05:14 +0000
committerGabor Juhos <juhosg@openwrt.org>2013-02-10 13:05:14 +0000
commite04207b25ab6d4db0de29efbc901b15ccd89a342 (patch)
treedbd7e3bbe5fb9603bd9d85517efc6f4d939e69d2 /target
parent03f0a836a7924a6ada3258b07dcc718df8097126 (diff)
downloadupstream-e04207b25ab6d4db0de29efbc901b15ccd89a342.tar.gz
upstream-e04207b25ab6d4db0de29efbc901b15ccd89a342.tar.bz2
upstream-e04207b25ab6d4db0de29efbc901b15ccd89a342.zip
generic: ar8216: add sanity check to ar8216_probe
Verify that the mdio bus has PHY devices with a supported PHY ID at address 0-4. Signed-off-by: Gabor Juhos <juhosg@openwrt.org> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35537 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target')
-rw-r--r--target/linux/generic/files/drivers/net/phy/ar8216.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c
index 45b2bd7a65..f356eafe5d 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.c
@@ -1956,6 +1956,44 @@ 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)
{
@@ -1966,6 +2004,9 @@ ar8216_probe(struct phy_device *pdev)
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;