Skip to content

Commit b53b147

Browse files
Russell King (Oracle)kuba-moo
authored andcommitted
net: mvpp2: add EEE implementation
Add EEE support for mvpp2, using phylink's EEE implementation, which means we just need to implement the two methods for LPI control, and with the initial configuration. Only SGMII mode is supported, so only 100M and 1G speeds. Disabling LPI requires clearing a single bit. Enabling LPI needs a full configuration of several values, as the timer values are dependent on the MAC operating speed. Signed-off-by: Russell King (Oracle) <[email protected]> Reviewed-by: Maxime Chevallier <[email protected]> Reviewed-by: Jacob Keller <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent ac79927 commit b53b147

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

drivers/net/ethernet/marvell/mvpp2/mvpp2.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,11 @@
481481
#define MVPP22_GMAC_INT_SUM_MASK 0xa4
482482
#define MVPP22_GMAC_INT_SUM_MASK_LINK_STAT BIT(1)
483483
#define MVPP22_GMAC_INT_SUM_MASK_PTP BIT(2)
484+
#define MVPP2_GMAC_LPI_CTRL0 0xc0
485+
#define MVPP2_GMAC_LPI_CTRL0_TS_MASK GENMASK(15, 8)
486+
#define MVPP2_GMAC_LPI_CTRL1 0xc4
487+
#define MVPP2_GMAC_LPI_CTRL1_REQ_EN BIT(0)
488+
#define MVPP2_GMAC_LPI_CTRL1_TW_MASK GENMASK(15, 4)
484489

485490
/* Per-port XGMAC registers. PPv2.2 and PPv2.3, only for GOP port 0,
486491
* relative to port->base.

drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5757,6 +5757,28 @@ static int mvpp2_ethtool_set_rxfh(struct net_device *dev,
57575757
return mvpp2_modify_rxfh_context(dev, NULL, rxfh, extack);
57585758
}
57595759

5760+
static int mvpp2_ethtool_get_eee(struct net_device *dev,
5761+
struct ethtool_keee *eee)
5762+
{
5763+
struct mvpp2_port *port = netdev_priv(dev);
5764+
5765+
if (!port->phylink)
5766+
return -EOPNOTSUPP;
5767+
5768+
return phylink_ethtool_get_eee(port->phylink, eee);
5769+
}
5770+
5771+
static int mvpp2_ethtool_set_eee(struct net_device *dev,
5772+
struct ethtool_keee *eee)
5773+
{
5774+
struct mvpp2_port *port = netdev_priv(dev);
5775+
5776+
if (!port->phylink)
5777+
return -EOPNOTSUPP;
5778+
5779+
return phylink_ethtool_set_eee(port->phylink, eee);
5780+
}
5781+
57605782
/* Device ops */
57615783

57625784
static const struct net_device_ops mvpp2_netdev_ops = {
@@ -5802,6 +5824,8 @@ static const struct ethtool_ops mvpp2_eth_tool_ops = {
58025824
.create_rxfh_context = mvpp2_create_rxfh_context,
58035825
.modify_rxfh_context = mvpp2_modify_rxfh_context,
58045826
.remove_rxfh_context = mvpp2_remove_rxfh_context,
5827+
.get_eee = mvpp2_ethtool_get_eee,
5828+
.set_eee = mvpp2_ethtool_set_eee,
58055829
};
58065830

58075831
/* Used for PPv2.1, or PPv2.2 with the old Device Tree binding that
@@ -6674,13 +6698,64 @@ static void mvpp2_mac_link_down(struct phylink_config *config,
66746698
mvpp2_port_disable(port);
66756699
}
66766700

6701+
static void mvpp2_mac_disable_tx_lpi(struct phylink_config *config)
6702+
{
6703+
struct mvpp2_port *port = mvpp2_phylink_to_port(config);
6704+
6705+
mvpp2_modify(port->base + MVPP2_GMAC_LPI_CTRL1,
6706+
MVPP2_GMAC_LPI_CTRL1_REQ_EN, 0);
6707+
}
6708+
6709+
static int mvpp2_mac_enable_tx_lpi(struct phylink_config *config, u32 timer,
6710+
bool tx_clk_stop)
6711+
{
6712+
struct mvpp2_port *port = mvpp2_phylink_to_port(config);
6713+
u32 ts, tw, lpi1, status;
6714+
6715+
status = readl(port->base + MVPP2_GMAC_STATUS0);
6716+
if (status & MVPP2_GMAC_STATUS0_GMII_SPEED) {
6717+
/* At 1G speeds, the timer resolution are 1us, and
6718+
* 802.3 says tw is 16.5us. Round up to 17us.
6719+
*/
6720+
tw = 17;
6721+
ts = timer;
6722+
} else {
6723+
/* At 100M speeds, the timer resolutions are 10us, and
6724+
* 802.3 says tw is 30us.
6725+
*/
6726+
tw = 3;
6727+
ts = DIV_ROUND_UP(timer, 10);
6728+
}
6729+
6730+
if (ts > 255)
6731+
ts = 255;
6732+
6733+
/* Configure ts */
6734+
mvpp2_modify(port->base + MVPP2_GMAC_LPI_CTRL0,
6735+
MVPP2_GMAC_LPI_CTRL0_TS_MASK,
6736+
FIELD_PREP(MVPP2_GMAC_LPI_CTRL0_TS_MASK, ts));
6737+
6738+
lpi1 = readl(port->base + MVPP2_GMAC_LPI_CTRL1);
6739+
6740+
/* Configure tw */
6741+
lpi1 = u32_replace_bits(lpi1, tw, MVPP2_GMAC_LPI_CTRL1_TW_MASK);
6742+
6743+
/* Enable LPI generation */
6744+
writel(lpi1 | MVPP2_GMAC_LPI_CTRL1_REQ_EN,
6745+
port->base + MVPP2_GMAC_LPI_CTRL1);
6746+
6747+
return 0;
6748+
}
6749+
66776750
static const struct phylink_mac_ops mvpp2_phylink_ops = {
66786751
.mac_select_pcs = mvpp2_select_pcs,
66796752
.mac_prepare = mvpp2_mac_prepare,
66806753
.mac_config = mvpp2_mac_config,
66816754
.mac_finish = mvpp2_mac_finish,
66826755
.mac_link_up = mvpp2_mac_link_up,
66836756
.mac_link_down = mvpp2_mac_link_down,
6757+
.mac_enable_tx_lpi = mvpp2_mac_enable_tx_lpi,
6758+
.mac_disable_tx_lpi = mvpp2_mac_disable_tx_lpi,
66846759
};
66856760

66866761
/* Work-around for ACPI */
@@ -6959,6 +7034,15 @@ static int mvpp2_port_probe(struct platform_device *pdev,
69597034
port->phylink_config.mac_capabilities =
69607035
MAC_2500FD | MAC_1000FD | MAC_100 | MAC_10;
69617036

7037+
__set_bit(PHY_INTERFACE_MODE_SGMII,
7038+
port->phylink_config.lpi_interfaces);
7039+
7040+
port->phylink_config.lpi_capabilities = MAC_1000FD | MAC_100FD;
7041+
7042+
/* Setup EEE. Choose 250us idle. */
7043+
port->phylink_config.lpi_timer_default = 250;
7044+
port->phylink_config.eee_enabled_default = true;
7045+
69627046
if (port->priv->global_tx_fc)
69637047
port->phylink_config.mac_capabilities |=
69647048
MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
@@ -7033,6 +7117,8 @@ static int mvpp2_port_probe(struct platform_device *pdev,
70337117
goto err_free_port_pcpu;
70347118
}
70357119
port->phylink = phylink;
7120+
7121+
mvpp2_mac_disable_tx_lpi(&port->phylink_config);
70367122
} else {
70377123
dev_warn(&pdev->dev, "Use link irqs for port#%d. FW update required\n", port->id);
70387124
port->phylink = NULL;

0 commit comments

Comments
 (0)