ar71xx: fix switch probing on kernel 4.14
authorKoen Vandeputte <koen.vandeputte@ncentric.com>
Thu, 30 Aug 2018 17:09:46 +0000 (19:09 +0200)
committerKoen Vandeputte <koen.vandeputte@ncentric.com>
Fri, 7 Sep 2018 15:21:24 +0000 (17:21 +0200)
The bump to 4.14 changed the way mdio probes behind switches.

While the board_info is added to the list, the code that actually inserted
the list info into the phydev structure was missing.

This resulted in non-working ethernet ports.

Re-add it to fix switch probing.
This mimics the exact behaviour as it was in kernel 4.9.

Before:

[    1.066007] switch0: Atheros AR8327 rev. 4 switch registered on ag71xx-mdio.0
[    1.073409] Atheros AR8216/AR8236/AR8316: probe of ag71xx-mdio.0:00 failed with error -22
[    1.102455] libphy: ag71xx_mdio: probed
[    1.737938] ag71xx ag71xx.0: connected to PHY at ag71xx-mdio.0:00 [uid=004dd034, driver=Generic PHY]
[    1.747994] eth0: Atheros AG71xx at 0xb9000000, irq 4, mode:RGMII
[    2.377642] ag71xx-mdio.1: Found an AR934X built-in switch
[    2.429938] eth1: Atheros AG71xx at 0xba000000, irq 5, mode:GMII

After:

[   11.163357] libphy: Fixed MDIO Bus: probed
[   11.319898] libphy: ag71xx_mdio: probed
[   11.360844] switch0: Atheros AR8327 rev. 4 switch registered on ag71xx-mdio.0
[   12.447398] libphy: ag71xx_mdio: probed
[   13.077402] ag71xx ag71xx.0: connected to PHY at ag71xx-mdio.0:00 [uid=004dd034, driver=Atheros AR8216/AR8236/AR8316]
[   13.088989] eth0: Atheros AG71xx at 0xb9000000, irq 4, mode:RGMII
[   13.717716] ag71xx-mdio.1: Found an AR934X built-in switch
[   13.769990] eth1: Atheros AG71xx at 0xba000000, irq 5, mode:GMII

Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
target/linux/ar71xx/patches-4.14/950-add-boardinfo-platform-data.patch [new file with mode: 0644]

diff --git a/target/linux/ar71xx/patches-4.14/950-add-boardinfo-platform-data.patch b/target/linux/ar71xx/patches-4.14/950-add-boardinfo-platform-data.patch
new file mode 100644 (file)
index 0000000..edeac83
--- /dev/null
@@ -0,0 +1,67 @@
+--- a/drivers/net/phy/mdio-boardinfo.c
++++ b/drivers/net/phy/mdio-boardinfo.c
+@@ -15,8 +15,11 @@
+ #include "mdio-boardinfo.h"
+-static LIST_HEAD(mdio_board_list);
+-static DEFINE_MUTEX(mdio_board_lock);
++LIST_HEAD(mdio_board_list);
++EXPORT_SYMBOL_GPL(mdio_board_list);
++
++DEFINE_MUTEX(mdio_board_lock);
++EXPORT_SYMBOL_GPL(mdio_board_lock);
+ /**
+  * mdiobus_setup_mdiodev_from_board_info - create and setup MDIO devices
+--- a/drivers/net/phy/mdio-boardinfo.h
++++ b/drivers/net/phy/mdio-boardinfo.h
+@@ -20,4 +20,7 @@ void mdiobus_setup_mdiodev_from_board_in
+                                          (struct mii_bus *bus,
+                                           struct mdio_board_info *bi));
++extern struct mutex mdio_board_lock;
++extern struct list_head mdio_board_list;
++
+ #endif /* __MDIO_BOARD_INFO_H */
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -455,6 +455,17 @@ void mdiobus_free(struct mii_bus *bus)
+ }
+ EXPORT_SYMBOL(mdiobus_free);
++static void mdiobus_setup_phydev_from_boardinfo(struct mii_bus *bus,
++                                                struct phy_device *phydev,
++                                                struct mdio_board_info *bi)
++{
++        if (strcmp(bus->id, bi->bus_id) ||
++            bi->mdio_addr != phydev->mdio.addr)
++            return;
++
++        phydev->mdio.dev.platform_data = (void *) bi->platform_data;
++}
++
+ /**
+  * mdiobus_scan - scan a bus for MDIO devices.
+  * @bus: mii_bus to scan
+@@ -470,6 +481,7 @@ EXPORT_SYMBOL(mdiobus_free);
+ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
+ {
+       struct phy_device *phydev;
++      struct mdio_board_entry *be;
+       int err;
+       phydev = get_phy_device(bus, addr, false);
+@@ -482,6 +494,12 @@ struct phy_device *mdiobus_scan(struct m
+        */
+       of_mdiobus_link_mdiodev(bus, &phydev->mdio);
++      mutex_lock(&mdio_board_lock);
++        list_for_each_entry(be, &mdio_board_list, list)
++                mdiobus_setup_phydev_from_boardinfo(bus, phydev,
++                                                    &be->board_info);
++      mutex_unlock(&mdio_board_lock);
++
+       err = phy_device_register(phydev);
+       if (err) {
+               phy_device_free(phydev);