From 5d038a7e98088496c79d57317d15da9a7907bc4a Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Wed, 16 Aug 2023 20:48:48 +0100 Subject: net: dsa: mt7530: convert to phylink managed EEE Fixme: doesn't bit 25 and 26 also need to be set in the PMCR for PMCR_FORCE_EEE100 and PMCR_FORCE_EEE1G to take effect? Signed-off-by: Russell King (Oracle) --- drivers/net/dsa/mt7530.c | 95 ++++++++++++++++++++++++++---------------------- drivers/net/dsa/mt7530.h | 6 +-- 2 files changed, 52 insertions(+), 49 deletions(-) diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c index d27c6b70a2f6..466cb0a15332 100644 --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c @@ -1080,7 +1080,8 @@ mt7530_port_enable(struct dsa_switch *ds, int port, priv->ports[port].enable = true; mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, priv->ports[port].pm); - mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK); + mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK | + PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100); mutex_unlock(&priv->reg_mutex); @@ -2861,20 +2862,45 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port, mcr |= PMCR_RX_FC_EN; } - if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, false) >= 0) { - switch (speed) { - case SPEED_1000: - mcr |= PMCR_FORCE_EEE1G; - break; - case SPEED_100: - mcr |= PMCR_FORCE_EEE100; - break; - } - } - mt7530_set(priv, MT7530_PMCR_P(port), mcr); } +static void mt753x_phylink_mac_disable_tx_lpi(struct dsa_switch *ds, int port) +{ + struct mt7530_priv *priv = ds->priv; + + mt7530_clear(priv, MT7530_PMCR_P(port), + PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100); +} + +static void mt753x_phylink_mac_enable_tx_lpi(struct dsa_switch *ds, int port, + u32 timer) +{ + struct mt7530_priv *priv = ds->priv; + u32 val; + + /* If the timer is zero, then set LPI_MODE_EN, which allows the + * system to enter LPI mode immediately rather than waiting for + * the LPI threshold. + */ + if (!timer) + val = LPI_MODE_EN; + else if (FIELD_FIT(LPI_THRESH_MASK, timer)) + val = FIELD_PREP(LPI_THRESH_MASK, timer); + else + val = LPI_THRESH_MASK; + + mt7530_rmw(priv, MT7530_PMEEECR_P(port), + LPI_THRESH_MASK | LPI_MODE_EN, val); + + /* FIXME: mt7531 docs say that bits 26 and 25 need to be set to + * enable EEE forcing. The PMCR_FORCE_EEE* bits just determine + * whether we force-enable or force-disable these modes. + */ + mt7530_set(priv, MT7530_PMCR_P(port), + PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100); +} + static int mt7531_cpu_port_config(struct dsa_switch *ds, int port) { @@ -2936,11 +2962,22 @@ static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port, struct phylink_config *config) { struct mt7530_priv *priv = ds->priv; + u32 eeecr; /* This switch only supports full-duplex at 1Gbps */ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD; + config->lpi_capabilities = MAC_100FD | MAC_1000FD; + config->lpi_timer_limit_us = FIELD_GET(LPI_THRESH_MASK, + LPI_THRESH_MASK); + + eeecr = mt7530_read(priv, MT7530_PMEEECR_P(port)); + /* tx_lpi_timer should be in microseconds. The time units for + * LPI threshold are unspecified. + */ + config->eee.tx_lpi_timer = FIELD_GET(LPI_THRESH_MASK, eeecr); + priv->info->mac_port_get_caps(ds, port, config); } @@ -3045,36 +3082,6 @@ mt753x_setup(struct dsa_switch *ds) return ret; } -static int mt753x_get_mac_eee(struct dsa_switch *ds, int port, - struct ethtool_eee *e) -{ - struct mt7530_priv *priv = ds->priv; - u32 eeecr = mt7530_read(priv, MT7530_PMEEECR_P(port)); - - e->tx_lpi_enabled = !(eeecr & LPI_MODE_EN); - e->tx_lpi_timer = GET_LPI_THRESH(eeecr); - - return 0; -} - -static int mt753x_set_mac_eee(struct dsa_switch *ds, int port, - struct ethtool_eee *e) -{ - struct mt7530_priv *priv = ds->priv; - u32 set, mask = LPI_THRESH_MASK | LPI_MODE_EN; - - if (e->tx_lpi_timer > 0xFFF) - return -EINVAL; - - set = SET_LPI_THRESH(e->tx_lpi_timer); - if (!e->tx_lpi_enabled) - /* Force LPI Mode without a delay */ - set |= LPI_MODE_EN; - mt7530_rmw(priv, MT7530_PMEEECR_P(port), mask, set); - - return 0; -} - static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface) { return 0; @@ -3128,8 +3135,8 @@ const struct dsa_switch_ops mt7530_switch_ops = { .phylink_mac_config = mt753x_phylink_mac_config, .phylink_mac_link_down = mt753x_phylink_mac_link_down, .phylink_mac_link_up = mt753x_phylink_mac_link_up, - .get_mac_eee = mt753x_get_mac_eee, - .set_mac_eee = mt753x_set_mac_eee, + .phylink_mac_disable_tx_lpi = mt753x_phylink_mac_disable_tx_lpi, + .phylink_mac_enable_tx_lpi = mt753x_phylink_mac_enable_tx_lpi, }; EXPORT_SYMBOL_GPL(mt7530_switch_ops); diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h index 17e42d30fff4..cdab7ea79294 100644 --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h @@ -309,8 +309,7 @@ enum mt7530_vlan_port_acc_frm { #define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \ PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \ PMCR_TX_FC_EN | PMCR_RX_FC_EN | \ - PMCR_FORCE_FDX | PMCR_FORCE_LNK | \ - PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100) + PMCR_FORCE_FDX | PMCR_FORCE_LNK) #define PMCR_CPU_PORT_SETTING(id) (PMCR_FORCE_MODE_ID((id)) | \ PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \ PMCR_BACKOFF_EN | PMCR_BACKPR_EN | \ @@ -323,9 +322,6 @@ enum mt7530_vlan_port_acc_frm { #define WAKEUP_TIME_1000(x) (((x) & 0xFF) << 24) #define WAKEUP_TIME_100(x) (((x) & 0xFF) << 16) #define LPI_THRESH_MASK GENMASK(15, 4) -#define LPI_THRESH_SHT 4 -#define SET_LPI_THRESH(x) (((x) << LPI_THRESH_SHT) & LPI_THRESH_MASK) -#define GET_LPI_THRESH(x) (((x) & LPI_THRESH_MASK) >> LPI_THRESH_SHT) #define LPI_MODE_EN BIT(0) #define MT7530_PMSR_P(x) (0x3008 + (x) * 0x100) -- cgit