Ubiquiti loco xw eth0 bug: Unterschied zwischen den Versionen
K cat |
Lars (Diskussion | Beiträge) Link zum Opennet-Ticket |
||
| (5 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
==Bug description== |
==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. |
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 |
More details, see [https://dev.openwrt.org/ticket/19085 OpenWrt #19086] and [https://dev.opennet-initiative.de/ticket/94 Opennet #94]. |
||
This bug is solved since around OpenWrt 18.06.01. |
|||
==Steps for building workaround== |
==Steps for building workaround== |
||
===Find a way to detect hang of eth0=== |
===Find a way to detect hang of eth0=== |
||
====Try 1==== |
|||
In general there are two places where uid of PHY is printed. |
In general there are two places where uid of PHY is printed. |
||
| Zeile 52: | Zeile 56: | ||
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) ?? |
|||
Example Log output |
|||
root@OpenWrt:/tmp# logread | grep PHY |
|||
Sun Apr 26 21:09:48 2015 kern.info kernel: [ 6.160000] ag71xx ag71xx.0: connected to PHY at ag71xx-mdio.0:01 [uid=004dd023, driver=Generic PHY] (Opennet-Info1) |
|||
Sun Apr 26 21:09:48 2015 kern.info kernel: [ 7.370000] ag71xx ag71xx.0: connected to PHY at ag71xx-mdio.0:01 [uid=004dd023, driver=Generic PHY] (Opennet-Info1) |
|||
Sun Apr 26 21:09:55 2015 kern.info kernel: [ 20.240000] ag71xx ag71xx.0: connected to PHY at ag71xx-mdio.0:01 [uid=004dd023, driver=Generic PHY] (Opennet-Info1) |
|||
Sun Apr 26 21:15:12 2015 kern.info kernel: [ 337.290000] ag71xx ag71xx.0: connected to PHY at ag71xx-mdio.0:01 [uid=004dd023, driver=Generic PHY] (Opennet-Info1) |
|||
Sun Apr 26 21:15:14 2015 kern.info kernel: [ 339.300000] ag71xx ag71xx.0: connected to PHY at ag71xx-mdio.0:01 [uid=004dd023, driver=Generic PHY] (Opennet-Info1) |
|||
===Find a way to reset eth0=== |
===Find a way to reset eth0=== |
||
Work in progress: see https://pad.hack-hro.de/p/eth0-bug-loco-xw |
|||
...TODO... |
|||
[[Category: |
[[Category:Ubiquiti]] |
||
[[Category:Firmware]] |
[[Category:Firmware]] |
||
Aktuelle Version vom 23. März 2019, 14:55 Uhr
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 OpenWrt #19086 and Opennet #94.
This bug is solved since around OpenWrt 18.06.01.
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
Work in progress: see https://pad.hack-hro.de/p/eth0-bug-loco-xw