summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2023-08-16 14:02:11 +0100
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2024-02-27 15:37:54 +0000
commite17b4adfa24683a779851d5054b21fcc73fd5ed5 (patch)
tree685e82bf7b80d6e686be5f16068aece4f330c134
parent008702833e08fc53171d73373d7125f8246bbfe5 (diff)
net: dsa: add support for phylink managed EEE
Add support to allow DSA drivers to use phylink managed EEE, with only needing support for controlling the LPI state. Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-rw-r--r--include/net/dsa.h3
-rw-r--r--net/dsa/port.c22
-rw-r--r--net/dsa/user.c42
3 files changed, 51 insertions, 16 deletions
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 82135fbdb1e6..55d3a879e44d 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -891,6 +891,9 @@ struct dsa_switch_ops {
struct phy_device *phydev,
int speed, int duplex,
bool tx_pause, bool rx_pause);
+ void (*phylink_mac_disable_tx_lpi)(struct dsa_switch *ds, int port);
+ void (*phylink_mac_enable_tx_lpi)(struct dsa_switch *ds, int port,
+ u32 timer);
void (*phylink_fixed_state)(struct dsa_switch *ds, int port,
struct phylink_link_state *state);
/*
diff --git a/net/dsa/port.c b/net/dsa/port.c
index c42dac87671b..8c52d5a87c17 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -1651,6 +1651,26 @@ static void dsa_port_phylink_mac_link_up(struct phylink_config *config,
speed, duplex, tx_pause, rx_pause);
}
+static void dsa_port_phylink_mac_disable_tx_lpi(struct phylink_config *config)
+{
+ struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
+ struct dsa_switch *ds = dp->ds;
+
+ if (ds->ops->phylink_mac_disable_tx_lpi)
+ ds->ops->phylink_mac_disable_tx_lpi(ds, dp->index);
+
+}
+
+static void dsa_port_phylink_mac_enable_tx_lpi(struct phylink_config *config,
+ u32 timer)
+{
+ struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
+ struct dsa_switch *ds = dp->ds;
+
+ if (ds->ops->phylink_mac_enable_tx_lpi)
+ ds->ops->phylink_mac_enable_tx_lpi(ds, dp->index, timer);
+}
+
static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
.mac_select_pcs = dsa_port_phylink_mac_select_pcs,
.mac_prepare = dsa_port_phylink_mac_prepare,
@@ -1658,6 +1678,8 @@ static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
.mac_finish = dsa_port_phylink_mac_finish,
.mac_link_down = dsa_port_phylink_mac_link_down,
.mac_link_up = dsa_port_phylink_mac_link_up,
+ .mac_disable_tx_lpi = dsa_port_phylink_mac_disable_tx_lpi,
+ .mac_enable_tx_lpi = dsa_port_phylink_mac_enable_tx_lpi,
};
int dsa_port_phylink_create(struct dsa_port *dp)
diff --git a/net/dsa/user.c b/net/dsa/user.c
index d438884a4eb0..0c0f27418c2a 100644
--- a/net/dsa/user.c
+++ b/net/dsa/user.c
@@ -1251,16 +1251,21 @@ static int dsa_user_set_eee(struct net_device *dev, struct ethtool_eee *e)
struct dsa_switch *ds = dp->ds;
int ret;
- /* Port's PHY and MAC both need to be EEE capable */
- if (!dev->phydev || !dp->pl)
- return -ENODEV;
+ /* If the port is using phylink managed EEE, then get_mac_eee is
+ * unnecessary.
+ */
+ if (!dp->pl_config.lpi_capabilities) {
+ /* Port's PHY and MAC both need to be EEE capable */
+ if (!dev->phydev || !dp->pl)
+ return -ENODEV;
- if (!ds->ops->set_mac_eee)
- return -EOPNOTSUPP;
+ if (!ds->ops->set_mac_eee)
+ return -EOPNOTSUPP;
- ret = ds->ops->set_mac_eee(ds, dp->index, e);
- if (ret)
- return ret;
+ ret = ds->ops->set_mac_eee(ds, dp->index, e);
+ if (ret)
+ return ret;
+ }
return phylink_ethtool_set_eee(dp->pl, e);
}
@@ -1271,16 +1276,21 @@ static int dsa_user_get_eee(struct net_device *dev, struct ethtool_eee *e)
struct dsa_switch *ds = dp->ds;
int ret;
- /* Port's PHY and MAC both need to be EEE capable */
- if (!dev->phydev || !dp->pl)
- return -ENODEV;
+ /* If the port is using phylink managed EEE, then get_mac_eee is
+ * unnecessary.
+ */
+ if (!dp->pl_config.lpi_capabilities) {
+ /* Port's PHY and MAC both need to be EEE capable */
+ if (!dev->phydev || !dp->pl)
+ return -ENODEV;
- if (!ds->ops->get_mac_eee)
- return -EOPNOTSUPP;
+ if (!ds->ops->get_mac_eee)
+ return -EOPNOTSUPP;
- ret = ds->ops->get_mac_eee(ds, dp->index, e);
- if (ret)
- return ret;
+ ret = ds->ops->get_mac_eee(ds, dp->index, e);
+ if (ret)
+ return ret;
+ }
return phylink_ethtool_get_eee(dp->pl, e);
}