I have encountered the same issue(s) on A6A boards. 

I couldn't find a patch,  so I wrote this patch to update the device tree 
in the davinci_mdio driver in the 3.15.1 tree, it seems to correct it. I 
would welcome any input on a different approach.

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index 0cca9de..e5a9cdc 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -39,6 +39,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/pinctrl/consumer.h>
+#include <linux/phy.h>
 
 /*
  * This timeout definition is a worst-case ultra defensive measure against
@@ -97,6 +98,10 @@ struct davinci_mdio_data {
     unsigned long    access_time; /* jiffies */
 };
 
+#if IS_ENABLED(CONFIG_OF)
+static void davinci_mdio_update_dt_from_phymask(u32 phy_mask);
+#endif
+
 static void __davinci_mdio_reset(struct davinci_mdio_data *data)
 {
     u32 mdio_in, div, mdio_out_khz, access_time;
@@ -150,6 +155,11 @@ static int davinci_mdio_reset(struct mii_bus *bus)
         /* restrict mdio bus to live phys only */
         dev_info(data->dev, "detected phy mask %x\n", ~phy_mask);
         phy_mask = ~phy_mask;
+
+        #if IS_ENABLED(CONFIG_OF)
+        davinci_mdio_update_dt_from_phymask(phy_mask);
+        #endif
+
     } else {
         /* desperately scan all phys */
         dev_warn(data->dev, "no live phy, scanning all\n");
@@ -312,6 +322,79 @@ static int davinci_mdio_probe_dt(struct 
mdio_platform_data *data,
 }
 #endif
 
+#if IS_ENABLED(CONFIG_OF)
+static void davinci_mdio_update_dt_from_phymask(u32 phy_mask)
+{
+    int i, len;
+    u32 addr;
+    __be32 *old_phy_p, *phy_id_p;
+    struct property *phy_id_property = NULL;
+    struct device_node *node_p, *slave_p;
+    
+    addr = 0;
+
+    for (i = 0; i < PHY_MAX_ADDR; i++) {
+            if ((phy_mask & (1 << i)) == 0) {
+                    addr = (u32) i;
+            break;
+            }
+     }
+
+    for_each_compatible_node(node_p, NULL, "ti,cpsw") {
+        for_each_node_by_name(slave_p, "slave") {
+                
+            old_phy_p = (__be32 *) of_get_property(slave_p, "phy_id", 
&len);
+            
+            if (len != (sizeof(__be32 *) * 2))
+                goto err_out;
+            
+            if (old_phy_p) {
+
+                phy_id_property = kzalloc(sizeof(*phy_id_property), 
GFP_KERNEL);
+                
+                if (! phy_id_property)
+                    goto err_out;
+
+                phy_id_property->length = len;
+                phy_id_property->name = kstrdup("phy_id", GFP_KERNEL);
+                phy_id_property->value = kzalloc(len, GFP_KERNEL);
+                
+                if (! phy_id_property->name)
+                    goto err_out;
+                
+                if (! phy_id_property->value)
+                    goto err_out;
+            
+                memcpy(phy_id_property->value, old_phy_p, len);
+                
+                phy_id_p = (__be32 *) phy_id_property->value + 1;
+                
+                *phy_id_p = cpu_to_be32(addr);
+
+                of_update_property(slave_p, phy_id_property);
+                
+                ++addr;
+            }
+        }
+    }
+    
+    return;
+
+err_out:
+    
+    if (phy_id_property) {
+        if (phy_id_property->name)
+            kfree(phy_id_property->name);
+    
+        if (phy_id_property->value)
+            kfree(phy_id_property->value);
+
+        if (phy_id_property)
+            kfree(phy_id_property);
+    }
+}
+#endif
+
 static int davinci_mdio_probe(struct platform_device *pdev)
 {
     struct mdio_platform_data *pdata = dev_get_platdata(&pdev->dev);

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to