On some platforms the external phy can only interface with the port 5 of the switch because the xMII TX and RX lines are swapped. But it still can be useful to use the internal phy of the switch to act as a WAN port which connectes to the 2nd GMAC. This gives the SOC a double the bandwidth between LAN and WAN. Because LAN and WAN don't share the same interface anymore.
By adding an optional property mediatek,ephy-handle, the external phy is put in isolation mode when internal phy is linked with 2nd GMAC via phy-handle property. Signed-off-by: René van Dorst <opensou...@vdorst.com> --- drivers/net/dsa/mt7530.c | 28 ++++++++++++++++++++++++++++ drivers/net/dsa/mt7530.h | 2 ++ 2 files changed, 30 insertions(+) diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c index 838a921ca83e..25b0f35df75b 100644 --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c @@ -633,6 +633,26 @@ mt7530_get_sset_count(struct dsa_switch *ds, int port, int sset) return ARRAY_SIZE(mt7530_mib); } +static int mt7530_isolate_ephy(struct dsa_switch *ds, + struct device_node *ephy_node) +{ + struct phy_device *phydev = of_phy_find_device(ephy_node); + int ret; + + if (!phydev) + return 0; + + ret = phy_modify(phydev, MII_BMCR, 0, (BMCR_ISOLATE | BMCR_PDOWN)); + if (ret) + dev_err(ds->dev, "Failed to put phy %s in isolation mode!\n", + ephy_node->full_name); + else + dev_info(ds->dev, "Phy %s in isolation mode!\n", + ephy_node->full_name); + + return ret; +} + static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface) { struct mt7530_priv *priv = ds->priv; @@ -655,6 +675,10 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface) /* MT7530_P5_MODE_GPHY_P4: 2nd GMAC -> P5 -> P4 */ val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS; + /* Isolate the external phy */ + if (priv->ephy_node) + if (mt7530_isolate_ephy(ds, priv->ephy_node) < 0) + goto unlock_exit; /* Setup the MAC by default for the cpu port */ mt7530_write(priv, MT7530_PMCR_P(5), 0x56300); break; @@ -1330,6 +1354,10 @@ mt7530_setup(struct dsa_switch *ds) mt7530_port_disable(ds, i); } + /* Get external phy phandle */ + priv->ephy_node = of_parse_phandle(priv->dev->of_node, + "mediatek,ephy-handle", 0); + /* Setup port 5 */ priv->p5_mode = P5_MODE_DISABLED; interface = PHY_INTERFACE_MODE_NA; diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h index f2a84ef48548..eb079e81a8e8 100644 --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h @@ -459,6 +459,7 @@ static const char *p5_modes(unsigned int p5_mode) * @reg_mutex: The lock for protecting among process accessing * registers * @p5_mode: PORT 5 mode status + * @ephy_node: External phy of_node. */ struct mt7530_priv { struct device *dev; @@ -472,6 +473,7 @@ struct mt7530_priv { unsigned int id; bool mcm; unsigned int p5_mode; + struct device_node *ephy_node; struct mt7530_port ports[MT7530_NUM_PORTS]; /* protect among processes for registers access*/ -- 2.20.1