return priv->hw_params.gphy_rev;
}
-static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port,
- struct phy_device *phydev)
-{
- struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
- struct ethtool_eee *p = &priv->dev->ports[port].eee;
- u32 id_mode_dis = 0, port_mode;
- const char *str = NULL;
- u32 reg, offset;
-
- if (priv->type == BCM7445_DEVICE_ID)
- offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
- else
- offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
-
- switch (phydev->interface) {
- case PHY_INTERFACE_MODE_RGMII:
- str = "RGMII (no delay)";
- id_mode_dis = 1;
- case PHY_INTERFACE_MODE_RGMII_TXID:
- if (!str)
- str = "RGMII (TX delay)";
- port_mode = EXT_GPHY;
- break;
- case PHY_INTERFACE_MODE_MII:
- str = "MII";
- port_mode = EXT_EPHY;
- break;
- case PHY_INTERFACE_MODE_REVMII:
- str = "Reverse MII";
- port_mode = EXT_REVMII;
- break;
- default:
- /* All other PHYs: internal and MoCA */
- goto force_link;
- }
-
- /* If the link is down, just disable the interface to conserve power */
- if (!phydev->link) {
- reg = reg_readl(priv, REG_RGMII_CNTRL_P(port));
- reg &= ~RGMII_MODE_EN;
- reg_writel(priv, reg, REG_RGMII_CNTRL_P(port));
- goto force_link;
- }
-
- /* Clear id_mode_dis bit, and the existing port mode, but
- * make sure we enable the RGMII block for data to pass
- */
- reg = reg_readl(priv, REG_RGMII_CNTRL_P(port));
- reg &= ~ID_MODE_DIS;
- reg &= ~(PORT_MODE_MASK << PORT_MODE_SHIFT);
- reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN);
-
- reg |= port_mode | RGMII_MODE_EN;
- if (id_mode_dis)
- reg |= ID_MODE_DIS;
-
- if (phydev->pause) {
- if (phydev->asym_pause)
- reg |= TX_PAUSE_EN;
- reg |= RX_PAUSE_EN;
- }
-
- reg_writel(priv, reg, REG_RGMII_CNTRL_P(port));
-
- pr_info("Port %d configured for %s\n", port, str);
-
-force_link:
- /* Force link settings detected from the PHY */
- reg = SW_OVERRIDE;
- switch (phydev->speed) {
- case SPEED_1000:
- reg |= SPDSTS_1000 << SPEED_SHIFT;
- break;
- case SPEED_100:
- reg |= SPDSTS_100 << SPEED_SHIFT;
- break;
- }
-
- if (phydev->link)
- reg |= LINK_STS;
- if (phydev->duplex == DUPLEX_FULL)
- reg |= DUPLX_MODE;
-
- core_writel(priv, reg, offset);
-
- if (!phydev->is_pseudo_fixed_link)
- p->eee_enabled = b53_eee_init(ds, port, phydev);
-}
-
-static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port,
- struct fixed_phy_status *status)
-{
- struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
- u32 duplex, pause, offset;
- u32 reg;
-
- if (priv->type == BCM7445_DEVICE_ID)
- offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
- else
- offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
-
- duplex = core_readl(priv, CORE_DUPSTS);
- pause = core_readl(priv, CORE_PAUSESTS);
-
- status->link = 0;
-
- /* MoCA port is special as we do not get link status from CORE_LNKSTS,
- * which means that we need to force the link at the port override
- * level to get the data to flow. We do use what the interrupt handler
- * did determine before.
- *
- * For the other ports, we just force the link status, since this is
- * a fixed PHY device.
- */
- if (port == priv->moca_port) {
- status->link = priv->port_sts[port].link;
- /* For MoCA interfaces, also force a link down notification
- * since some version of the user-space daemon (mocad) use
- * cmd->autoneg to force the link, which messes up the PHY
- * state machine and make it go in PHY_FORCING state instead.
- */
- if (!status->link)
- netif_carrier_off(ds->ports[port].slave);
- status->duplex = 1;
- } else {
- status->link = 1;
- status->duplex = !!(duplex & (1 << port));
- }
-
- reg = core_readl(priv, offset);
- reg |= SW_OVERRIDE;
- if (status->link)
- reg |= LINK_STS;
- else
- reg &= ~LINK_STS;
- core_writel(priv, reg, offset);
-
- if ((pause & (1 << port)) &&
- (pause & (1 << (port + PAUSESTS_TX_PAUSE_SHIFT)))) {
- status->asym_pause = 1;
- status->pause = 1;
- }
-
- if (pause & (1 << port))
- status->pause = 1;
-}
-
static void bcm_sf2_sw_validate(struct dsa_switch *ds, int port,
unsigned long *supported,
struct phylink_link_state *state)
.get_sset_count = b53_get_sset_count,
.get_ethtool_phy_stats = b53_get_ethtool_phy_stats,
.get_phy_flags = bcm_sf2_sw_get_phy_flags,
- .adjust_link = bcm_sf2_sw_adjust_link,
- .fixed_link_update = bcm_sf2_sw_fixed_link_update,
.phylink_validate = bcm_sf2_sw_validate,
.phylink_mac_config = bcm_sf2_sw_mac_config,
.phylink_mac_link_down = bcm_sf2_sw_mac_link_down,