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

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.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f1d152eb
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/rtnetlink.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/sys_soc.h>

#include "rswitch.h"

@@ -1243,7 +1244,6 @@ static void rswitch_adjust_link(struct net_device *ndev)
	struct rswitch_device *rdev = netdev_priv(ndev);
	struct phy_device *phydev = ndev->phydev;

	/* Current hardware has a restriction not to change speed at runtime */
	if (phydev->link != rdev->etha->link) {
		phy_print_status(phydev);
		if (phydev->link)
@@ -1252,13 +1252,23 @@ static void rswitch_adjust_link(struct net_device *ndev)
			phy_power_off(rdev->serdes);

		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,
					 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) {
	case SPEED_2500:
		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)
		err = rswitch_etha_hw_init(rdev->etha, rdev->ndev->dev_addr);
		if (err < 0)
			return err;
		if (rdev->priv->etha_no_runtime_change)
			rdev->etha->operated = true;
	}

@@ -1853,8 +1864,14 @@ static int rswitch_init(struct rswitch_private *priv)
	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)
{
	const struct soc_device_attribute *attr;
	struct rswitch_private *priv;
	struct resource *res;
	int ret;
@@ -1869,6 +1886,10 @@ static int renesas_eth_sw_probe(struct platform_device *pdev)
	if (!priv)
		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);
	if (!priv->ptp_priv)
		return -ENOMEM;
+1 −0
Original line number Diff line number Diff line
@@ -1011,6 +1011,7 @@ struct rswitch_private {
	struct rswitch_etha etha[RSWITCH_NUM_PORTS];
	struct rswitch_mfwd mfwd;

	bool etha_no_runtime_change;
	bool gwca_halt;
};