Commit a18891b5 authored by Russell King (Oracle)'s avatar Russell King (Oracle) Committed by Jakub Kicinski
Browse files

net: dsa: sja1105: simplify static configuration reload



The static configuration reload saves the port speed in the static
configuration tables by first converting it from the internal
respresentation to the SPEED_xxx ethtool representation, and then
converts it back to restore the setting. This is because
sja1105_adjust_port_config() takes the speed as SPEED_xxx.

However, this is unnecessarily complex. If we split
sja1105_adjust_port_config() up, we can simply save and restore the
mac[port].speed member in the static configuration tables.

Signed-off-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Link: https://patch.msgid.link/E1svfMa-005ZIX-If@rmk-PC.armlinux.org.uk


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 155c499f
Loading
Loading
Loading
Loading
+34 −31
Original line number Diff line number Diff line
@@ -1257,29 +1257,11 @@ static int sja1105_parse_dt(struct sja1105_private *priv)
	return rc;
}

/* Convert link speed from SJA1105 to ethtool encoding */
static int sja1105_port_speed_to_ethtool(struct sja1105_private *priv,
					 u64 speed)
{
	if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS])
		return SPEED_10;
	if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS])
		return SPEED_100;
	if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS])
		return SPEED_1000;
	if (speed == priv->info->port_speed[SJA1105_SPEED_2500MBPS])
		return SPEED_2500;
	return SPEED_UNKNOWN;
}

/* Set link speed in the MAC configuration for a specific port. */
static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
static int sja1105_set_port_speed(struct sja1105_private *priv, int port,
				  int speed_mbps)
{
	struct sja1105_mac_config_entry *mac;
	struct device *dev = priv->ds->dev;
	u64 speed;
	int rc;

	/* On P/Q/R/S, one can read from the device via the MAC reconfiguration
	 * tables. On E/T, MAC reconfig tables are not readable, only writable.
@@ -1313,7 +1295,7 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
		speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
		break;
	default:
		dev_err(dev, "Invalid speed %iMbps\n", speed_mbps);
		dev_err(priv->ds->dev, "Invalid speed %iMbps\n", speed_mbps);
		return -EINVAL;
	}

@@ -1325,12 +1307,32 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
	 * we need to configure the PCS only (if even that).
	 */
	if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII)
		mac[port].speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
		speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS];
	else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX)
		mac[port].speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];
	else
		speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS];

	mac[port].speed = speed;

	return 0;
}

/* Write the MAC Configuration Table entry and, if necessary, the CGU settings,
 * after a link speedchange for this port.
 */
static int sja1105_set_port_config(struct sja1105_private *priv, int port)
{
	struct sja1105_mac_config_entry *mac;
	struct device *dev = priv->ds->dev;
	int rc;

	/* On P/Q/R/S, one can read from the device via the MAC reconfiguration
	 * tables. On E/T, MAC reconfig tables are not readable, only writable.
	 * We have to *know* what the MAC looks like.  For the sake of keeping
	 * the code common, we'll use the static configuration tables as a
	 * reasonable approximation for both E/T and P/Q/R/S.
	 */
	mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;

	/* Write to the dynamic reconfiguration tables */
	rc = sja1105_dynamic_config_write(priv, BLK_IDX_MAC_CONFIG, port,
					  &mac[port], true);
@@ -1390,7 +1392,8 @@ static void sja1105_mac_link_up(struct phylink_config *config,
	struct sja1105_private *priv = dp->ds->priv;
	int port = dp->index;

	sja1105_adjust_port_config(priv, port, speed);
	if (!sja1105_set_port_speed(priv, port, speed))
		sja1105_set_port_config(priv, port);

	sja1105_inhibit_tx(priv, BIT(port), false);
}
@@ -2293,8 +2296,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
{
	struct ptp_system_timestamp ptp_sts_before;
	struct ptp_system_timestamp ptp_sts_after;
	int speed_mbps[SJA1105_MAX_NUM_PORTS];
	u16 bmcr[SJA1105_MAX_NUM_PORTS] = {0};
	u64 mac_speed[SJA1105_MAX_NUM_PORTS];
	struct sja1105_mac_config_entry *mac;
	struct dsa_switch *ds = priv->ds;
	s64 t1, t2, t3, t4;
@@ -2307,14 +2310,13 @@ int sja1105_static_config_reload(struct sja1105_private *priv,

	mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;

	/* Back up the dynamic link speed changed by sja1105_adjust_port_config
	/* Back up the dynamic link speed changed by sja1105_set_port_speed()
	 * in order to temporarily restore it to SJA1105_SPEED_AUTO - which the
	 * switch wants to see in the static config in order to allow us to
	 * change it through the dynamic interface later.
	 */
	for (i = 0; i < ds->num_ports; i++) {
		speed_mbps[i] = sja1105_port_speed_to_ethtool(priv,
							      mac[i].speed);
		mac_speed[i] = mac[i].speed;
		mac[i].speed = priv->info->port_speed[SJA1105_SPEED_AUTO];

		if (priv->xpcs[i])
@@ -2377,7 +2379,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv,
		struct dw_xpcs *xpcs = priv->xpcs[i];
		unsigned int neg_mode;

		rc = sja1105_adjust_port_config(priv, i, speed_mbps[i]);
		mac[i].speed = mac_speed[i];
		rc = sja1105_set_port_config(priv, i);
		if (rc < 0)
			goto out;