summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2023-08-16 20:48:48 +0100
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2024-02-27 15:37:55 +0000
commit5d038a7e98088496c79d57317d15da9a7907bc4a (patch)
tree18fc1f57574f21d65b6fcaeab025c9a0b3c33788
parente17b4adfa24683a779851d5054b21fcc73fd5ed5 (diff)
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) <rmk+kernel@armlinux.org.uk>
-rw-r--r--drivers/net/dsa/mt7530.c95
-rw-r--r--drivers/net/dsa/mt7530.h6
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)