diff mbox series

[OpenWrt-Devel,RFC] ar71xx: fix Mikrotik wAP AC QCA955X SGMII link loss

Message ID 20190707052628.23083-1-champetier.etienne@gmail.com
State Superseded
Headers show
Series [OpenWrt-Devel,RFC] ar71xx: fix Mikrotik wAP AC QCA955X SGMII link loss | expand

Commit Message

Etienne Champetier July 7, 2019, 5:26 a.m. UTC
This commit rework
"ar71xx: allow to override at803x sgmii aneg status" (4e39e213af7e3e0cd747403e8c227e145cfef988)
by moving override_sgmii_aneg param from "at803x_platform_data" to "device" struct
Not sure if it's the right place for it, but wAP AC uses "mdio_gpio_platform_data" struct,
so the current patch is currently accessing some random memory.

Fixes FS#2236

Signed-off-by: Etienne Champetier <champetier.etienne@gmail.com>
---
 .../files/arch/mips/ath79/mach-fritz450e.c    |  2 +-
 .../files/arch/mips/ath79/mach-rambutan.c     |  2 +-
 .../ar71xx/files/arch/mips/ath79/mach-rbspi.c |  2 ++
 ...at803x-add-sgmii-aneg-override-pdata.patch | 36 ++++++-------------
 4 files changed, 14 insertions(+), 28 deletions(-)

Comments

David Bauer July 10, 2019, 7:04 p.m. UTC | #1
Hello Etienne,

sorry for my late reply.

On 7/7/19 7:26 AM, Etienne Champetier wrote:
> This commit rework
> "ar71xx: allow to override at803x sgmii aneg status" (4e39e213af7e3e0cd747403e8c227e145cfef988)
> by moving override_sgmii_aneg param from "at803x_platform_data" to "device" struct
> Not sure if it's the right place for it, but wAP AC uses "mdio_gpio_platform_data" struct,
> so the current patch is currently accessing some random memory.

This commit moves 'override_sgmii_aneg' to the generic device struct,
which is less than an ideal place for it. 'override_sgmii_aneg' enables a
hack which overrides an early exit in the PHY state-machine. Otherwise, the
ethernet driver is never informed of the link state-change and does not do it's
fixup work while the PHY driver cries over the broken link.

There's nothing wrong with adding the 'mdio_gpio_platform_data' struct as platform_data
for the mdio-gpio device. Remember, the platform-data is only for the device providing the
mdio-bus, not the mdio device (the PHY).

Have a look how it's done for the AVM FRITZ!WLAN Repeater 450E (mach-fritz450e.c).
The 'mdio_board_info' struct (which contains the 'at803x_platform_data' struct) is registered
to the mdio-device by calling 'mdiobus_register_board_info' in the initiaization code.
Your bus-id is most likely 'mdio-gpio.0'.

I hope this helps you into the right direction :)

Best wishes
David
diff mbox series

Patch

diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-fritz450e.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-fritz450e.c
index 83127e4c64..f21b2664ba 100644
--- a/target/linux/ar71xx/files/arch/mips/ath79/mach-fritz450e.c
+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-fritz450e.c
@@ -122,7 +122,6 @@  static struct gpio_keys_button fritz450E_gpio_keys[] __initdata = {
 static struct at803x_platform_data fritz450E_at803x_data = {
 	.disable_smarteee = 1,
 	.has_reset_gpio = 1,
-	.override_sgmii_aneg = 1,
 	.reset_gpio = FRITZ450E_GPIO_PHY_RESET,
 };
 
@@ -157,6 +156,7 @@  static void __init fritz450E_setup(void) {
 	ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII;
 	ath79_eth0_data.phy_mask = BIT(FRITZ450E_PHY_ADDRESS);
 	ath79_eth0_data.enable_sgmii_fixup = 1;
+	ath79_eth0_data.mii_bus_dev->override_sgmii_aneg = 1;
 	ath79_eth0_pll_data.pll_1000 = 0x03000000;
 	ath79_eth0_pll_data.pll_100 = 0x00000101;
 	ath79_eth0_pll_data.pll_10 = 0x00001313;
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rambutan.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rambutan.c
index 1730a29f33..cb76ddcb0f 100644
--- a/target/linux/ar71xx/files/arch/mips/ath79/mach-rambutan.c
+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rambutan.c
@@ -46,7 +46,6 @@  static struct mdio_board_info rambutan_mdio0_info[] = {
 
 static struct at803x_platform_data rambutan_ar8033_data = {
 	.has_reset_gpio = 1,
-	.override_sgmii_aneg = 1,
 	.reset_gpio = 23,
 };
 
@@ -82,6 +81,7 @@  static void __init rambutan_setup(void)
 	ath79_eth1_data.phy_mask = BIT(0);
 	ath79_eth1_data.mii_bus_dev = &ath79_mdio1_device.dev;
 	ath79_eth1_data.enable_sgmii_fixup = 1;
+	ath79_eth1_data.mii_bus_dev->override_sgmii_aneg = 1;
 	ath79_eth1_pll_data.pll_1000 = 0x17000000;
 	ath79_eth1_pll_data.pll_10 = 0x1313;
 	ath79_register_eth(1);
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rbspi.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rbspi.c
index 96511a4080..f737d8f5b0 100644
--- a/target/linux/ar71xx/files/arch/mips/ath79/mach-rbspi.c
+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rbspi.c
@@ -1115,6 +1115,8 @@  static void __init rbwapgsc_setup(void)
 	ath79_eth1_pll_data.pll_10 = 0x80001313;
 	ath79_eth1_data.speed = SPEED_1000;
 	ath79_eth1_data.duplex = DUPLEX_FULL;
+	ath79_eth1_data.enable_sgmii_fixup = 1;
+	ath79_eth1_data.mii_bus_dev->override_sgmii_aneg = 1;
 	ath79_register_eth(1);
 
 	rbspi_wlan_init(1, 2);
diff --git a/target/linux/ar71xx/patches-4.14/903-at803x-add-sgmii-aneg-override-pdata.patch b/target/linux/ar71xx/patches-4.14/903-at803x-add-sgmii-aneg-override-pdata.patch
index 8948fd4954..60a6d1a9a3 100644
--- a/target/linux/ar71xx/patches-4.14/903-at803x-add-sgmii-aneg-override-pdata.patch
+++ b/target/linux/ar71xx/patches-4.14/903-at803x-add-sgmii-aneg-override-pdata.patch
@@ -1,38 +1,22 @@ 
 --- a/drivers/net/phy/at803x.c
 +++ b/drivers/net/phy/at803x.c
-@@ -478,12 +478,15 @@ static void at803x_link_change_notify(st
- 
- static int at803x_aneg_done(struct phy_device *phydev)
- {
-+	struct at803x_platform_data *pdata;
- 	int ccr;
- 
- 	int aneg_done = genphy_aneg_done(phydev);
- 	if (aneg_done != BMSR_ANEGCOMPLETE)
- 		return aneg_done;
- 
-+	pdata = dev_get_platdata(&phydev->mdio.dev);
-+
- 	/*
- 	 * in SGMII mode, if copper side autoneg is successful,
- 	 * also check SGMII side autoneg result
-@@ -498,7 +501,8 @@ static int at803x_aneg_done(struct phy_d
+@@ -498,7 +498,8 @@ static int at803x_aneg_done(struct phy_d
  	/* check if the SGMII link is OK. */
  	if (!(phy_read(phydev, AT803X_PSSR) & AT803X_PSSR_MR_AN_COMPLETE)) {
  		pr_warn("803x_aneg_done: SGMII link is not ok\n");
 -		aneg_done = 0;
-+		if (!pdata || !pdata->override_sgmii_aneg)
++		if (phydev->mdio.dev.override_sgmii_aneg)
 +			aneg_done = 0;
  	}
  	/* switch back to copper page */
  	phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL);
---- a/include/linux/platform_data/phy-at803x.h
-+++ b/include/linux/platform_data/phy-at803x.h
-@@ -7,6 +7,7 @@ struct at803x_platform_data {
- 	int enable_rgmii_rx_delay:1;
- 	int fixup_rgmii_tx_delay:1;
- 	int has_reset_gpio:1;
-+	int override_sgmii_aneg:1;
- 	int reset_gpio;
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -964,6 +964,7 @@ struct device {
+ 	bool			offline_disabled:1;
+ 	bool			offline:1;
+ 	bool			of_node_reused:1;
++	bool			override_sgmii_aneg:1;
  };
  
+ static inline struct device *kobj_to_dev(struct kobject *kobj)