summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2020-06-22 01:05:59 +0100
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2022-06-21 10:57:37 +0100
commit78353a06b7aa098b1dc5bad04970b02cbcf312df (patch)
tree5762090960cf81efc5ccfd028da56b94fe613e53
parentc3f4d2876fb0a903468da18a1740ad906b29a836 (diff)
net: dsa: bcm_sf2: fix pause mode validation
The implementation appears not to appear to support pause modes on anything but RGMII, RGMII_TXID, MII and REVMII interface modes. Let phylink know that detail. Moreover, RGMII_RXID and RGMII_ID appears to be unsupported. (This may not be correct; particularly see the FIXMEs in this patch.) Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-rw-r--r--drivers/net/dsa/bcm_sf2.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index da90e182ae0e..2b184d2949c7 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -727,6 +727,10 @@ static void bcm_sf2_sw_get_caps(struct dsa_switch *ds, int port,
__set_bit(PHY_INTERFACE_MODE_MII, interfaces);
__set_bit(PHY_INTERFACE_MODE_REVMII, interfaces);
__set_bit(PHY_INTERFACE_MODE_GMII, interfaces);
+
+ /* FIXME 1: Are RGMII_RXID and RGMII_ID actually supported?
+ * See FIXME 2 and FIXME 3 below.
+ */
phy_interface_set_rgmii(interfaces);
}
@@ -734,6 +738,35 @@ static void bcm_sf2_sw_get_caps(struct dsa_switch *ds, int port,
MAC_10 | MAC_100 | MAC_1000;
}
+static void bcm_sf2_sw_validate(struct dsa_switch *ds, int port,
+ unsigned long *supported,
+ struct phylink_link_state *state)
+{
+ struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+ u32 caps;
+
+ caps = dsa_to_port(ds, port)->pl_config.mac_capabilities;
+
+ /* Pause modes are only programmed for these modes - see FIXME 3.
+ * So, as pause modes are not configured for other modes, disable
+ * support for them.
+ */
+ if (!(state->interface == PHY_INTERFACE_MODE_RGMII ||
+ state->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
+ state->interface == PHY_INTERFACE_MODE_MII ||
+ state->interface == PHY_INTERFACE_MODE_REVMII))
+ caps &= ~(MAC_ASYM_PAUSE | MAC_SYM_PAUSE);
+
+ /* Allow all the expected bits */
+ phylink_set(mask, Autoneg);
+ phylink_set_port_modes(mask);
+ phylink_get_linkmodes(mask, state->interface, caps);
+
+ linkmode_and(supported, supported, mask);
+ linkmode_and(state->advertising, state->advertising, mask);
+}
+
static void bcm_sf2_sw_mac_config(struct dsa_switch *ds, int port,
unsigned int mode,
const struct phylink_link_state *state)
@@ -747,6 +780,10 @@ static void bcm_sf2_sw_mac_config(struct dsa_switch *ds, int port,
return;
switch (state->interface) {
+ /* FIXME 2: Are RGMII_RXID and RGMII_ID actually supported?
+ * This switch statement means that the RGMII control register
+ * does not get programmed.
+ */
case PHY_INTERFACE_MODE_RGMII:
id_mode_dis = 1;
fallthrough;
@@ -850,6 +887,10 @@ static void bcm_sf2_sw_mac_link_up(struct dsa_switch *ds, int port,
else
offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
+ /* FIXME 3: Are RGMII_RXID and RGMII_ID actually supported?
+ * Why are pause modes only supported for a couple of RGMII
+ * modes?
+ */
if (interface == PHY_INTERFACE_MODE_RGMII ||
interface == PHY_INTERFACE_MODE_RGMII_TXID ||
interface == PHY_INTERFACE_MODE_MII ||
@@ -1202,6 +1243,7 @@ static const struct dsa_switch_ops bcm_sf2_ops = {
.get_ethtool_phy_stats = b53_get_ethtool_phy_stats,
.get_phy_flags = bcm_sf2_sw_get_phy_flags,
.phylink_get_caps = bcm_sf2_sw_get_caps,
+ .phylink_validate = bcm_sf2_sw_validate,
.phylink_mac_config = bcm_sf2_sw_mac_config,
.phylink_mac_link_down = bcm_sf2_sw_mac_link_down,
.phylink_mac_link_up = bcm_sf2_sw_mac_link_up,