Ubiquiti loco xw eth0 bug: Unterschied zwischen den Versionen

Aus Opennet
Wechseln zu: Navigation, Suche
(Steps for building workaround: More tries)
(Steps for building workaround: further tests and documentation)
Zeile 62: Zeile 62:
 
  [155923.380000] br-lan: port 1(eth0) entered disabled state
 
  [155923.380000] br-lan: port 1(eth0) entered disabled state
  
====Try 2====
+
====Try 2 - mdiobus_read()====
...to write ... read ID was ffffff.....
+
...mdiobus_read?? ... read ID was always ffffff which indicated that the bus is in use.....
  
 
====Try 3 - use get_phy_id()====
 
====Try 3 - use get_phy_id()====
patch from Till
 
  
--- trunk/eth-bug-oni-trunk/on_firmware/openwrt/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.
+
in /home/leo/trunk/eth-bug-oni~rivers/net/phy/phy_device.c
10.49/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c.orig    2015-04-21 18:23:56.000000000 +0200                   
+
+ EXPORT_SYMBOL(get_phy_id);
  +++ trunk/eth-bug-oni-trunk/on_firmware/openwrt/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.
+
 
10.49/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c 2015-04-28 13:21:56.884431730 +0200                           
+
in /home/leo/trunk/eth-bug-oni~3.10.49/include/linux/phy.h
  @@ -533,10 +533,16 @@                                                                                                 
+
int phy_scan_fixups(struct phy_device *phydev);                                                                       
 +
                                                                                                                       
 +
+ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id,
 +
+                      bool is_c45, struct phy_c45_device_ids *c45_ids);
 +
 
 +
in linux-ar71xx_generic/linux-3.10.49/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
 +
  void ag71xx_link_adjust(struct ag71xx *ag)                                                                           
 +
  {                                                                                                                     
 +
      struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);                                                     
 +
+    struct mii_bus *mii = ag->mii_bus;                                                                             
 +
      u32 cfg2;                                                                                                     
 +
      u32 ifctl;                                                                                                     
 +
      u32 fifo5;                                                                                                     
 +
      u32 fifo3;                                                                                                     
 +
+     u32 phy_id;                                                                                                   
 +
  +     int phy_ret;
 +
+     bool is_c45 = true;
 +
+     struct phy_c45_device_ids c45_ids = {0};
 +
+                                                                                                                     
 +
+    phy_ret = get_phy_id(mii, 0, &phy_id, is_c45, &c45_ids);                                                                         
 +
+    pr_info("%s: PHY ID is %08x (ret=%d) (unschoener Opennet-Hack v3a)\n", ag->dev->name, phy_id, phy_ret);         
 +
+    is_c45 = false;
 +
+    phy_ret = get_phy_id(mii, 0, &phy_id, is_c45, &c45_ids);                                                                         
 +
+    pr_info("%s: PHY ID is %08x (ret=%d) (unschoener Opennet-Hack v3b)\n", ag->dev->name, phy_id, phy_ret); 
 +
 
 +
Result:
 +
In file included from /home/leo/trunk/eth-bug-oni-trunk/on_firmware/openwrt/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux- 3.10.49/arch/mips/include/asm/mach-ath79/ag71xx_platform.h:17:0,
 +
                from arch/mips/ath79/dev-eth.h:15,
 +
                from arch/mips/ath79/dev-eth.c:30:
 +
  include/linux/phy.h:583:19: error: 'get_phy_id' declared 'static' but never defined [-Werror=unused-function]
 +
  static inline int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id,                                               
 +
                  ^
 +
cc1: all warnings being treated as errors
 +
 
 +
'''TODO''': further invest error
 +
 
 +
====Try 4 - get_phy_device()====
 +
--- linux-ar71xx_generic/linux-3.10.49/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
 
  void ag71xx_link_adjust(struct ag71xx *ag)                                                                             
 
  void ag71xx_link_adjust(struct ag71xx *ag)                                                                             
 
  {                                                                                                                       
 
  {                                                                                                                       
Zeile 80: Zeile 116:
 
         u32 ifctl;                                                                                                       
 
         u32 ifctl;                                                                                                       
 
         u32 fifo5;                                                                                                       
 
         u32 fifo5;                                                                                                       
         u32 fifo3;                                                                                                    
+
         u32 fifo3;
 
  +      u32 phy_id;                                                                                                     
 
  +      u32 phy_id;                                                                                                     
  +      int phy_ret;                                                                                                  
+
  +      bool is_c45 = true;
  +                                                                                                                      
+
  +       struct phy_device *phydev = NULL;
  +      phy_ret = get_phy_id(mii, 0, &phy_id);                                                                        
+
+
  +       pr_info("%s: PHY ID is %08x (ret=%d) (unschoener Opennet-Hack v3)\n", ag->dev->name, phy_id, phy_ret);        
+
+      //taken from linux-3.10.49/drivers/of/of_mdio.c
                                                                                                                       
+
  +      phydev = get_phy_device(mii, 0, is_c45);
         if (!ag->link) {                                                                                              
+
  + if (!phydev || IS_ERR(phydev)) { 
                ag71xx_hw_stop(ag);  
+
+        pr_info("%s: cannot get PHY at address!! PHY ID is %08x (unschoener Opennet-Hack v3a)\n", ag->dev->name, phy_id);
 +
+      } else {
 +
+   phy_id = phydev->phy_id;
 +
+        pr_info("%s: PHY ID is %08x (unschoener Opennet-Hack v3b)\n", ag->dev->name, phy_id);
 +
+ }
 +
+ is_c45 = false;
 +
+ phydev = get_phy_device(mii, 0, is_c45);
 +
+ if (!phydev || IS_ERR(phydev)) { 
 +
+         pr_info("%s: cannot get PHY at address!! PHY ID is %08x (unschoener Opennet-Hack v3c)\n", ag->dev->name, phy_id);
 +
+      } else {
 +
+   phy_id = phydev->phy_id;
 +
+        pr_info("%s: PHY ID is %08x (unschoener Opennet-Hack v3d)\n", ag->dev->name, phy_id);        
 +
+ }
 +
 
 +
 
 +
Result:
 +
Sun May 10 14:27:29 2015 kern.info kernel: [    1.150000] ag71xx ag71xx.0: connected to PHY at ag71xx-mdio.0:01 [uid=004dd023, driver=Generic PHY]
 +
Sun May 10 14:27:29 2015 kern.info kernel: [    6.230000] eth0: cannot get PHY at address!! PHY ID is 00000000 (unschoener Opennet-Hack v3a)
 +
Sun May 10 14:27:29 2015 kern.info kernel: [    6.230000] eth0: cannot get PHY at address!! PHY ID is 00000000 (unschoener Opennet-Hack v3c)
 +
Sun May 10 14:27:29 2015 kern.info kernel: [  21.640000] eth0: cannot get PHY at address!! PHY ID is 00000000 (unschoener Opennet-Hack v3a)
 +
Sun May 10 14:27:29 2015 kern.info kernel: [  21.640000] eth0: cannot get PHY at address!! PHY ID is 00000000 (unschoener Opennet-Hack v3c)
 +
Sun May 10 14:27:35 2015 kern.info kernel: [  42.380000] eth0: cannot get PHY at address!! PHY ID is 00000000 (unschoener Opennet-Hack v3a)
 +
Sun May 10 14:27:35 2015 kern.info kernel: [  42.380000] eth0: cannot get PHY at address!! PHY ID is 00000000 (unschoener Opennet-Hack v3c)
 +
 
 +
'''Idea''': Should we search for the right address and call function with get_phy_device(mii, ''add'', is_c45) instead of get_phy_device(mii, 0, is_c45) ??
  
The function get_phy_id() needs to be exported...
 
  
 
===Find a way to reset eth0===
 
===Find a way to reset eth0===

Version vom 10. Mai 2015, 16:40 Uhr

Inhaltsverzeichnis

Bug description

Some Ubiquiti loco xw have a hardware bug which results in an interface shutdown with now possibility to bring the interface without reboot. More details, see https://dev.openwrt.org/ticket/19085

Steps for building workaround

Find a way to detect hang of eth0

Try 1

In general there are two places where uid of PHY is printed.

1. ag71xx_phy.c

   function: static int ag71xx_phy_connect_multi(struct ag71xx *ag)   
   ....
   DBG("%s: PHY found at %s, uid=%08x\n",                                                                  
                           dev_name(dev),                                                                                  
                           dev_name(&ag->mii_bus->phy_map[phy_addr]->dev),                                                 
                           ag->mii_bus->phy_map[phy_addr]->phy_id);  
  
   dev_info(dev, "connected to PHY at %s [uid=%08x, driver=%s]\n",                                                 
                       dev_name(&phydev->dev), phydev->phy_id, phydev->drv->name); 

2. ag71xx_main.c

 void ag71xx_link_adjust(struct ag71xx *ag)
   ....
   struct device *dev = &ag->pdev->dev; 
   struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);                                                      
           struct phy_device *phydev = NULL;                                                                               
           int phy_addr;                                                                                                   
           int ret = 0;
  
   for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {                                                       
                   if (!(pdata->phy_mask & (1 << phy_addr)))                                                               
                           continue;                                                                                       
                                                                                                                           
                   if (ag->mii_bus->phy_map[phy_addr] == NULL)                                                             
                           continue;                                                                                       
                                                                                                                           
                   DBG("%s: PHY found at %s, uid=%08x\n",                                                                  
                           dev_name(dev),                                                                                  
                           dev_name(&ag->mii_bus->phy_map[phy_addr]->dev),                                                 
                           ag->mii_bus->phy_map[phy_addr]->phy_id);                                                        
                                                                                                                           
                  if (phydev == NULL)                                                                                     
                           phydev = ag->mii_bus->phy_map[phy_addr];                                                        
    } 
  
   dev_info(dev, "connected to PHY at %s [uid=%08x, driver=%s]\n",                                                 
                       dev_name(&phydev->dev), phydev->phy_id, phydev->drv->name); 


ID can be read in ag71xx_link_adjust() in file ag71xx_main.c. See http://pastebin.com/0ze9iFcb for an example. But the ID is not changing when eth0 hangs. The output when it hangs is:

[155921.360000] ag71xx ag71xx.0: connected to PHY at ag71xx-mdio.0:01 [uid=004dd023, driver=Generic PHY] (Opennet-Info1)
[155921.360000] eth0: link up (10Mbps/Half duplex)
[155923.370000] ag71xx ag71xx.0: connected to PHY at ag71xx-mdio.0:01 [uid=004dd023, driver=Generic PHY] (Opennet-Info1)
[155923.370000] eth0: link down
[155923.380000] br-lan: port 1(eth0) entered disabled state

Try 2 - mdiobus_read()

...mdiobus_read?? ... read ID was always ffffff which indicated that the bus is in use.....

Try 3 - use get_phy_id()

in /home/leo/trunk/eth-bug-oni~rivers/net/phy/phy_device.c

+ EXPORT_SYMBOL(get_phy_id);

in /home/leo/trunk/eth-bug-oni~3.10.49/include/linux/phy.h

int phy_scan_fixups(struct phy_device *phydev);                                                                         
                                                                                                                        
+ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id,
+                      bool is_c45, struct phy_c45_device_ids *c45_ids);

in linux-ar71xx_generic/linux-3.10.49/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c

 void ag71xx_link_adjust(struct ag71xx *ag)                                                                             
 {                                                                                                                      
      struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);                                                      
+     struct mii_bus *mii = ag->mii_bus;                                                                              
      u32 cfg2;                                                                                                       
      u32 ifctl;                                                                                                      
      u32 fifo5;                                                                                                      
      u32 fifo3;                                                                                                      
+     u32 phy_id;                                                                                                     
+     int phy_ret;
+     bool is_c45 = true;
+     struct phy_c45_device_ids c45_ids = {0};
+                                                                                                                       
+     phy_ret = get_phy_id(mii, 0, &phy_id, is_c45, &c45_ids);                                                                          
+     pr_info("%s: PHY ID is %08x (ret=%d) (unschoener Opennet-Hack v3a)\n", ag->dev->name, phy_id, phy_ret);          
+     is_c45 = false;
+     phy_ret = get_phy_id(mii, 0, &phy_id, is_c45, &c45_ids);                                                                          
+     pr_info("%s: PHY ID is %08x (ret=%d) (unschoener Opennet-Hack v3b)\n", ag->dev->name, phy_id, phy_ret);  

Result:

In file included from /home/leo/trunk/eth-bug-oni-trunk/on_firmware/openwrt/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux- 3.10.49/arch/mips/include/asm/mach-ath79/ag71xx_platform.h:17:0,
                from arch/mips/ath79/dev-eth.h:15,
                from arch/mips/ath79/dev-eth.c:30:
include/linux/phy.h:583:19: error: 'get_phy_id' declared 'static' but never defined [-Werror=unused-function]
 static inline int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id,                                                
                  ^
cc1: all warnings being treated as errors

TODO: further invest error

Try 4 - get_phy_device()

--- linux-ar71xx_generic/linux-3.10.49/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c

void ag71xx_link_adjust(struct ag71xx *ag)                                                                             
{                                                                                                                      
       struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);                                                      
+       struct mii_bus *mii = ag->mii_bus;                                                                              
       u32 cfg2;                                                                                                       
       u32 ifctl;                                                                                                      
       u32 fifo5;                                                                                                      
       u32 fifo3;
+       u32 phy_id;                                                                                                     
+       bool is_c45 = true;
+       struct phy_device *phydev = NULL; 
+
+       //taken from linux-3.10.49/drivers/of/of_mdio.c
+       phydev = get_phy_device(mii, 0, is_c45);
+		if (!phydev || IS_ERR(phydev)) {   
+         pr_info("%s: cannot get PHY at address!! PHY ID is %08x (unschoener Opennet-Hack v3a)\n", ag->dev->name, phy_id);
+       } else {
+		  phy_id = phydev->phy_id;
+         pr_info("%s: PHY ID is %08x (unschoener Opennet-Hack v3b)\n", ag->dev->name, phy_id);
+		}
+		is_c45 = false;
+		phydev = get_phy_device(mii, 0, is_c45);
+		if (!phydev || IS_ERR(phydev)) {   
+         pr_info("%s: cannot get PHY at address!! PHY ID is %08x (unschoener Opennet-Hack v3c)\n", ag->dev->name, phy_id);
+       } else {
+		  phy_id = phydev->phy_id;
+         pr_info("%s: PHY ID is %08x (unschoener Opennet-Hack v3d)\n", ag->dev->name, phy_id);          
+		}


Result:

Sun May 10 14:27:29 2015 kern.info kernel: [    1.150000] ag71xx ag71xx.0: connected to PHY at ag71xx-mdio.0:01 [uid=004dd023, driver=Generic PHY]
Sun May 10 14:27:29 2015 kern.info kernel: [    6.230000] eth0: cannot get PHY at address!! PHY ID is 00000000 (unschoener Opennet-Hack v3a)
Sun May 10 14:27:29 2015 kern.info kernel: [    6.230000] eth0: cannot get PHY at address!! PHY ID is 00000000 (unschoener Opennet-Hack v3c)
Sun May 10 14:27:29 2015 kern.info kernel: [   21.640000] eth0: cannot get PHY at address!! PHY ID is 00000000 (unschoener Opennet-Hack v3a)
Sun May 10 14:27:29 2015 kern.info kernel: [   21.640000] eth0: cannot get PHY at address!! PHY ID is 00000000 (unschoener Opennet-Hack v3c)
Sun May 10 14:27:35 2015 kern.info kernel: [   42.380000] eth0: cannot get PHY at address!! PHY ID is 00000000 (unschoener Opennet-Hack v3a)
Sun May 10 14:27:35 2015 kern.info kernel: [   42.380000] eth0: cannot get PHY at address!! PHY ID is 00000000 (unschoener Opennet-Hack v3c)

Idea: Should we search for the right address and call function with get_phy_device(mii, add, is_c45) instead of get_phy_device(mii, 0, is_c45) ??


Find a way to reset eth0

...TODO...

Meine Werkzeuge
Namensräume

Varianten
Aktionen
Start
Opennet
Kommunikation
Karten
Werkzeuge