ip17xx: fix autonegotioation issues
[openwrt.git] / target / linux / generic-2.6 / files / drivers / net / phy / ar8216.c
index 394e50d..4ae61da 100644 (file)
@@ -33,6 +33,7 @@
 
 /* size of the vlan table */
 #define AR8X16_MAX_VLANS       128
 
 /* size of the vlan table */
 #define AR8X16_MAX_VLANS       128
+#define AR8X16_PROBE_RETRIES   10
 
 struct ar8216_priv {
        struct switch_dev dev;
 
 struct ar8216_priv {
        struct switch_dev dev;
@@ -119,18 +120,35 @@ ar8216_id_chip(struct ar8216_priv *priv)
 {
        u32 val;
        u16 id;
 {
        u32 val;
        u16 id;
+       int i;
+
        val = ar8216_mii_read(priv, AR8216_REG_CTRL);
        val = ar8216_mii_read(priv, AR8216_REG_CTRL);
+       if (val == ~0)
+               return UNKNOWN;
+
        id = val & (AR8216_CTRL_REVISION | AR8216_CTRL_VERSION);
        id = val & (AR8216_CTRL_REVISION | AR8216_CTRL_VERSION);
+       for (i = 0; i < AR8X16_PROBE_RETRIES; i++) {
+               u16 t;
+
+               val = ar8216_mii_read(priv, AR8216_REG_CTRL);
+               if (val == ~0)
+                       return UNKNOWN;
+
+               t = val & (AR8216_CTRL_REVISION | AR8216_CTRL_VERSION);
+               if (t != id)
+                       return UNKNOWN;
+       }
+
        switch (id) {
        case 0x0101:
                return AR8216;
        case 0x1001:
                return AR8316;
        default:
        switch (id) {
        case 0x0101:
                return AR8216;
        case 0x1001:
                return AR8316;
        default:
-               printk(KERN_ERR
+               printk(KERN_DEBUG
                        "ar8216: Unknown Atheros device [ver=%d, rev=%d, phy_id=%04x%04x]\n",
                        "ar8216: Unknown Atheros device [ver=%d, rev=%d, phy_id=%04x%04x]\n",
-                       (int)(val >> AR8216_CTRL_VERSION_S),
-                       (int)(val & AR8216_CTRL_REVISION),
+                       (int)(id >> AR8216_CTRL_VERSION_S),
+                       (int)(id & AR8216_CTRL_REVISION),
                        priv->phy->bus->read(priv->phy->bus, priv->phy->addr, 2),
                        priv->phy->bus->read(priv->phy->bus, priv->phy->addr, 3));
 
                        priv->phy->bus->read(priv->phy->bus, priv->phy->addr, 2),
                        priv->phy->bus->read(priv->phy->bus, priv->phy->addr, 3));
 
@@ -279,7 +297,7 @@ recv:
 error:
        /* no vlan? eat the packet! */
        dev_kfree_skb_any(skb);
 error:
        /* no vlan? eat the packet! */
        dev_kfree_skb_any(skb);
-       return 0;
+       return NET_RX_DROP;
 }
 
 static int
 }
 
 static int
@@ -628,8 +646,10 @@ ar8216_config_init(struct phy_device *pdev)
 
        priv->chip = ar8216_id_chip(priv);
 
 
        priv->chip = ar8216_id_chip(priv);
 
-       printk(KERN_INFO "%s: AR%d PHY driver attached.\n",
-               pdev->attached_dev->name, priv->chip);
+       if (pdev->addr == 0)
+               printk(KERN_INFO "%s: AR%d switch driver attached.\n",
+                       pdev->attached_dev->name, priv->chip);
+
 
        if (pdev->addr != 0) {
                if (priv->chip == AR8316) {
 
        if (pdev->addr != 0) {
                if (priv->chip == AR8316) {
@@ -736,11 +756,13 @@ static int
 ar8216_probe(struct phy_device *pdev)
 {
        struct ar8216_priv priv;
 ar8216_probe(struct phy_device *pdev)
 {
        struct ar8216_priv priv;
+       u16 chip;
 
        priv.phy = pdev;
 
        priv.phy = pdev;
-       if (ar8216_id_chip(&priv) == UNKNOWN) {
+       chip = ar8216_id_chip(&priv);
+       if (chip == UNKNOWN)
                return -ENODEV;
                return -ENODEV;
-       }
+
        return 0;
 }
 
        return 0;
 }
 
This page took 0.030966 seconds and 4 git commands to generate.