ramips: handle mdio address and switch port seperate
authorMathias Kresin <dev@kresin.me>
Tue, 17 Apr 2018 16:51:42 +0000 (18:51 +0200)
committerPetr Štetiar <ynezz@true.cz>
Thu, 20 Jun 2019 06:48:19 +0000 (08:48 +0200)
The phy handling code forces a phy mdio address and the switch port to
which a phy is attached to be the same. Albeit such a configuration is
used for most boards, it isn't for all.

Pass the switch port number to the ethernet phy connect functions, to
ensure the correct list entry is edited and not the list entry that
matches th phys mdio address.

Use the mdio address with mdiobus_get_phy instead of the port number,
to make sure the expected ethernet phy gets connected.

Signed-off-by: Mathias Kresin <dev@kresin.me>
target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mdio.c
target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mdio.h
target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/mdio_rt2880.c
target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/soc_mt7620.c

index 2e2da6021fe18caef950a461807af597b854e87c..ce27abf69c147b614a8f1f887f1121077b18d257 100644 (file)
@@ -60,19 +60,19 @@ static void fe_phy_link_adjust(struct net_device *dev)
        spin_unlock_irqrestore(&priv->phy->lock, flags);
 }
 
-int fe_connect_phy_node(struct fe_priv *priv, struct device_node *phy_node)
+int fe_connect_phy_node(struct fe_priv *priv, struct device_node *phy_node, int port)
 {
-       const __be32 *_port = NULL;
+       const __be32 *_phy_addr = NULL;
        struct phy_device *phydev;
-       int phy_mode, port;
+       int phy_mode;
 
-       _port = of_get_property(phy_node, "reg", NULL);
+       _phy_addr = of_get_property(phy_node, "reg", NULL);
 
-       if (!_port || (be32_to_cpu(*_port) >= 0x20)) {
-               pr_err("%s: invalid port id\n", phy_node->name);
+       if (!_phy_addr || (be32_to_cpu(*_phy_addr) >= 0x20)) {
+               pr_err("%s: invalid phy id\n", phy_node->name);
                return -EINVAL;
        }
-       port = be32_to_cpu(*_port);
+
        phy_mode = of_get_phy_mode(phy_node);
        if (phy_mode < 0) {
                dev_err(priv->dev, "incorrect phy-mode %d\n", phy_mode);
index 498cf144e6314d7a38a65cfa52f334bbf0776cc7..78364e33a14e56239ccf11372c68ae4027ac91ab 100644 (file)
@@ -19,7 +19,8 @@
 int fe_mdio_init(struct fe_priv *priv);
 void fe_mdio_cleanup(struct fe_priv *priv);
 int fe_connect_phy_node(struct fe_priv *priv,
-                       struct device_node *phy_node);
+                       struct device_node *phy_node,
+                       int port);
 #else
 static inline int fe_mdio_init(struct fe_priv *priv) { return 0; }
 static inline void fe_mdio_cleanup(struct fe_priv *priv) {}
index e53fd7f6288902dea29a61f2bda733fa5fe2e97e..8d82c8f7adcc4ed207bb8010fcbe9a61cd6be423 100644 (file)
@@ -218,5 +218,5 @@ void rt2880_port_init(struct fe_priv *priv, struct device_node *np)
        }
 
        if (priv->phy->phy_node[0] && mdiobus_get_phy(priv->mii_bus, 0))
-               fe_connect_phy_node(priv, priv->phy->phy_node[0]);
+               fe_connect_phy_node(priv, priv->phy->phy_node[0], 0);
 }
index 7f728d142de44b6c86296a6d015858f861da4c23..da8e71c21e7e4f836e0f9edc6c0bb6c9936c96fb 100644 (file)
@@ -140,6 +140,7 @@ static void mt7620_port_init(struct fe_priv *priv, struct device_node *np)
 {
        struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv;
        const __be32 *_id = of_get_property(np, "reg", NULL);
+       const __be32 *phy_addr;
        int phy_mode, size, id;
        int shift = 12;
        u32 val, mask = 0;
@@ -234,12 +235,13 @@ static void mt7620_port_init(struct fe_priv *priv, struct device_node *np)
                return;
        }
 
-       if (priv->phy->phy_node[id] && mdiobus_get_phy(priv->mii_bus, id)) {
+       phy_addr = of_get_property(priv->phy->phy_node[id], "reg", NULL);
+       if (phy_addr && mdiobus_get_phy(priv->mii_bus, be32_to_cpup(phy_addr))) {
                u32 val = PMCR_BACKPRES | PMCR_BACKOFF | PMCR_RX_EN |
                        PMCR_TX_EN |  PMCR_MAC_MODE | PMCR_IPG;
 
                mtk_switch_w32(gsw, val, GSW_REG_PORT_PMCR(id));
-               fe_connect_phy_node(priv, priv->phy->phy_node[id]);
+               fe_connect_phy_node(priv, priv->phy->phy_node[id], id);
                gsw->autopoll |= BIT(id);
                mt7620_auto_poll(gsw);
                return;