Commit 5b18c705 authored by David S. Miller's avatar David S. Miller

Merge branch 'Better-PHYLINK-compliance-for-SJA1105-DSA'

Vladimir Oltean says:

====================
Better PHYLINK compliance for SJA1105 DSA

After discussing with Russell King, it appears this driver is making a
few confusions and not performing some checks for consistent operation.

Changes in v2:
- Removed redundant print in the phylink_validate callback (in 2/3).
====================
Acked-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f7110b75 9f971573
......@@ -715,7 +715,13 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
switch (speed_mbps) {
case SPEED_UNKNOWN:
/* No speed update requested */
/* PHYLINK called sja1105_mac_config() to inform us about
* the state->interface, but AN has not completed and the
* speed is not yet valid. UM10944.pdf says that setting
* SJA1105_SPEED_AUTO at runtime disables the port, so that is
* ok for power consumption in case AN will never complete -
* otherwise PHYLINK should come back with a new update.
*/
speed = SJA1105_SPEED_AUTO;
break;
case SPEED_10:
......@@ -760,15 +766,51 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port,
return sja1105_clocking_setup_port(priv, port);
}
/* The SJA1105 MAC programming model is through the static config (the xMII
* Mode table cannot be dynamically reconfigured), and we have to program
* that early (earlier than PHYLINK calls us, anyway).
* So just error out in case the connected PHY attempts to change the initial
* system interface MII protocol from what is defined in the DT, at least for
* now.
*/
static bool sja1105_phy_mode_mismatch(struct sja1105_private *priv, int port,
phy_interface_t interface)
{
struct sja1105_xmii_params_entry *mii;
sja1105_phy_interface_t phy_mode;
mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries;
phy_mode = mii->xmii_mode[port];
switch (interface) {
case PHY_INTERFACE_MODE_MII:
return (phy_mode != XMII_MODE_MII);
case PHY_INTERFACE_MODE_RMII:
return (phy_mode != XMII_MODE_RMII);
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
return (phy_mode != XMII_MODE_RGMII);
default:
return true;
}
}
static void sja1105_mac_config(struct dsa_switch *ds, int port,
unsigned int link_an_mode,
const struct phylink_link_state *state)
{
struct sja1105_private *priv = ds->priv;
if (!state->link)
if (sja1105_phy_mode_mismatch(priv, port, state->interface))
return;
if (link_an_mode == MLO_AN_INBAND) {
dev_err(ds->dev, "In-band AN not supported!\n");
return;
}
sja1105_adjust_port_config(priv, port, state->speed);
}
......@@ -801,6 +843,16 @@ static void sja1105_phylink_validate(struct dsa_switch *ds, int port,
mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries;
/* include/linux/phylink.h says:
* When @state->interface is %PHY_INTERFACE_MODE_NA, phylink
* expects the MAC driver to return all supported link modes.
*/
if (state->interface != PHY_INTERFACE_MODE_NA &&
sja1105_phy_mode_mismatch(priv, port, state->interface)) {
bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
return;
}
/* The MAC does not support pause frames, and also doesn't
* support half-duplex traffic modes.
*/
......
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