Commit c009b903 authored by Yoshihiro Shimoda's avatar Yoshihiro Shimoda Committed by Jakub Kicinski

net: renesas: rswitch: Add runtime speed change support

The latest SoC version can support runtime speed change. So,
add detect SoC version by using soc_device_match() and then
reconfigure the hardware of this and SerDes if needed.
Signed-off-by: default avatarYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20230807003231.1552062-2-yoshihiro.shimoda.uh@renesas.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f1d152eb
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/sys_soc.h>
#include "rswitch.h" #include "rswitch.h"
...@@ -1243,7 +1244,6 @@ static void rswitch_adjust_link(struct net_device *ndev) ...@@ -1243,7 +1244,6 @@ static void rswitch_adjust_link(struct net_device *ndev)
struct rswitch_device *rdev = netdev_priv(ndev); struct rswitch_device *rdev = netdev_priv(ndev);
struct phy_device *phydev = ndev->phydev; struct phy_device *phydev = ndev->phydev;
/* Current hardware has a restriction not to change speed at runtime */
if (phydev->link != rdev->etha->link) { if (phydev->link != rdev->etha->link) {
phy_print_status(phydev); phy_print_status(phydev);
if (phydev->link) if (phydev->link)
...@@ -1252,13 +1252,23 @@ static void rswitch_adjust_link(struct net_device *ndev) ...@@ -1252,13 +1252,23 @@ static void rswitch_adjust_link(struct net_device *ndev)
phy_power_off(rdev->serdes); phy_power_off(rdev->serdes);
rdev->etha->link = phydev->link; rdev->etha->link = phydev->link;
if (!rdev->priv->etha_no_runtime_change &&
phydev->speed != rdev->etha->speed) {
rdev->etha->speed = phydev->speed;
rswitch_etha_hw_init(rdev->etha, rdev->ndev->dev_addr);
phy_set_speed(rdev->serdes, rdev->etha->speed);
}
} }
} }
static void rswitch_phy_remove_link_mode(struct rswitch_device *rdev, static void rswitch_phy_remove_link_mode(struct rswitch_device *rdev,
struct phy_device *phydev) struct phy_device *phydev)
{ {
/* Current hardware has a restriction not to change speed at runtime */ if (!rdev->priv->etha_no_runtime_change)
return;
switch (rdev->etha->speed) { switch (rdev->etha->speed) {
case SPEED_2500: case SPEED_2500:
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Full_BIT); phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Full_BIT);
...@@ -1347,6 +1357,7 @@ static int rswitch_ether_port_init_one(struct rswitch_device *rdev) ...@@ -1347,6 +1357,7 @@ static int rswitch_ether_port_init_one(struct rswitch_device *rdev)
err = rswitch_etha_hw_init(rdev->etha, rdev->ndev->dev_addr); err = rswitch_etha_hw_init(rdev->etha, rdev->ndev->dev_addr);
if (err < 0) if (err < 0)
return err; return err;
if (rdev->priv->etha_no_runtime_change)
rdev->etha->operated = true; rdev->etha->operated = true;
} }
...@@ -1853,8 +1864,14 @@ static int rswitch_init(struct rswitch_private *priv) ...@@ -1853,8 +1864,14 @@ static int rswitch_init(struct rswitch_private *priv)
return err; return err;
} }
static const struct soc_device_attribute rswitch_soc_no_speed_change[] = {
{ .soc_id = "r8a779f0", .revision = "ES1.0" },
{ /* Sentinel */ }
};
static int renesas_eth_sw_probe(struct platform_device *pdev) static int renesas_eth_sw_probe(struct platform_device *pdev)
{ {
const struct soc_device_attribute *attr;
struct rswitch_private *priv; struct rswitch_private *priv;
struct resource *res; struct resource *res;
int ret; int ret;
...@@ -1869,6 +1886,10 @@ static int renesas_eth_sw_probe(struct platform_device *pdev) ...@@ -1869,6 +1886,10 @@ static int renesas_eth_sw_probe(struct platform_device *pdev)
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
attr = soc_device_match(rswitch_soc_no_speed_change);
if (attr)
priv->etha_no_runtime_change = true;
priv->ptp_priv = rcar_gen4_ptp_alloc(pdev); priv->ptp_priv = rcar_gen4_ptp_alloc(pdev);
if (!priv->ptp_priv) if (!priv->ptp_priv)
return -ENOMEM; return -ENOMEM;
......
...@@ -1011,6 +1011,7 @@ struct rswitch_private { ...@@ -1011,6 +1011,7 @@ struct rswitch_private {
struct rswitch_etha etha[RSWITCH_NUM_PORTS]; struct rswitch_etha etha[RSWITCH_NUM_PORTS];
struct rswitch_mfwd mfwd; struct rswitch_mfwd mfwd;
bool etha_no_runtime_change;
bool gwca_halt; bool gwca_halt;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment