summaryrefslogtreecommitdiff
path: root/drivers/net/dsa/bcm_sf2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/dsa/bcm_sf2.c')
-rw-r--r--drivers/net/dsa/bcm_sf2.c70
1 files changed, 40 insertions, 30 deletions
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 13aa43b5cffd..d3e401454ebb 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -672,46 +672,50 @@ static u32 bcm_sf2_sw_get_phy_flags(struct dsa_switch *ds, int port)
PHY_BRCM_IDDQ_SUSPEND;
}
+static void bcm_sf2_sw_get_caps(struct dsa_switch *ds, int port,
+ struct phylink_config *config)
+{
+ unsigned long *interfaces = config->supported_interfaces;
+ struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
+
+ if (priv->int_phy_mask & BIT(port)) {
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, interfaces);
+ } else if (priv->moca_port == port) {
+ __set_bit(PHY_INTERFACE_MODE_MOCA, interfaces);
+ } else {
+ __set_bit(PHY_INTERFACE_MODE_MII, interfaces);
+ __set_bit(PHY_INTERFACE_MODE_REVMII, interfaces);
+ __set_bit(PHY_INTERFACE_MODE_GMII, interfaces);
+
+ /* FIXME: Are RGMII_RXID and RGMII_ID actually supported? */
+ phy_interface_set_rgmii(interfaces);
+ }
+
+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+ 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;
- if (!phy_interface_mode_is_rgmii(state->interface) &&
- state->interface != PHY_INTERFACE_MODE_MII &&
- state->interface != PHY_INTERFACE_MODE_REVMII &&
- state->interface != PHY_INTERFACE_MODE_GMII &&
- state->interface != PHY_INTERFACE_MODE_INTERNAL &&
- state->interface != PHY_INTERFACE_MODE_MOCA) {
- linkmode_zero(supported);
- if (port != core_readl(priv, CORE_IMP0_PRT_ID))
- dev_err(ds->dev,
- "Unsupported interface: %d for port %d\n",
- state->interface, port);
- return;
- }
+ caps = dsa_to_port(ds, port)->pl_config.mac_capabilities;
+
+ /* Pause modes are only programmed for these modes */
+ 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_set(mask, Pause);
- phylink_set(mask, Asym_Pause);
-
- /* With the exclusion of MII and Reverse MII, we support Gigabit,
- * including Half duplex
- */
- if (state->interface != PHY_INTERFACE_MODE_MII &&
- state->interface != PHY_INTERFACE_MODE_REVMII) {
- phylink_set(mask, 1000baseT_Full);
- phylink_set(mask, 1000baseT_Half);
- }
-
- phylink_set(mask, 10baseT_Half);
- phylink_set(mask, 10baseT_Full);
- phylink_set(mask, 100baseT_Half);
- phylink_set(mask, 100baseT_Full);
+ phylink_get_linkmodes(mask, state->interface, caps);
linkmode_and(supported, supported, mask);
linkmode_and(state->advertising, state->advertising, mask);
@@ -730,6 +734,7 @@ static void bcm_sf2_sw_mac_config(struct dsa_switch *ds, int port,
return;
switch (state->interface) {
+ /* FIXME: Are RGMII_RXID and RGMII_ID actually supported? */
case PHY_INTERFACE_MODE_RGMII:
id_mode_dis = 1;
fallthrough;
@@ -830,6 +835,10 @@ static void bcm_sf2_sw_mac_link_up(struct dsa_switch *ds, int port,
else
offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
+ /* FIXME: 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 ||
@@ -862,7 +871,7 @@ static void bcm_sf2_sw_mac_link_up(struct dsa_switch *ds, int port,
core_writel(priv, reg, offset);
}
- if (mode == MLO_AN_PHY && phydev)
+ if (phylink_mode_phy(mode) && phydev)
p->eee_enabled = b53_eee_init(ds, port, phydev);
}
@@ -1181,6 +1190,7 @@ static const struct dsa_switch_ops bcm_sf2_ops = {
.get_sset_count = bcm_sf2_sw_get_sset_count,
.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,