Skip to content

Commit ac79927

Browse files
Russell King (Oracle)kuba-moo
authored andcommitted
net: mvneta: convert to phylink EEE implementation
Convert mvneta to use phylink's EEE implementation by implementing the two LPI control methods, and adding the initial configuration and capabilities. Although disabling LPI requires clearing a single bit, for safety we clear the manual mode and force bits to ensure that auto mode will be used. Enabling LPI needs a full configuration of several values, as the timer values are dependent on the MAC operating speed, as per the original code. As Armada 388 states that EEE is only supported in "SGMII" modes, mark this in lpi_interfaces. Testing with RGMII on the Clearfog platform indicates that the receive path fails to detect LPI over RGMII. Signed-off-by: Russell King (Oracle) <[email protected]> Reviewed-by: Jacob Keller <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 03abf2a commit ac79927

File tree

1 file changed

+65
-42
lines changed

1 file changed

+65
-42
lines changed

drivers/net/ethernet/marvell/mvneta.c

Lines changed: 65 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,12 @@
284284
MVNETA_TXQ_BUCKET_REFILL_PERIOD))
285285

286286
#define MVNETA_LPI_CTRL_0 0x2cc0
287+
#define MVNETA_LPI_CTRL_0_TS (0xff << 8)
287288
#define MVNETA_LPI_CTRL_1 0x2cc4
288-
#define MVNETA_LPI_REQUEST_ENABLE BIT(0)
289+
#define MVNETA_LPI_CTRL_1_REQUEST_ENABLE BIT(0)
290+
#define MVNETA_LPI_CTRL_1_REQUEST_FORCE BIT(1)
291+
#define MVNETA_LPI_CTRL_1_MANUAL_MODE BIT(2)
292+
#define MVNETA_LPI_CTRL_1_TW (0xfff << 4)
289293
#define MVNETA_LPI_CTRL_2 0x2cc8
290294
#define MVNETA_LPI_STATUS 0x2ccc
291295

@@ -541,10 +545,6 @@ struct mvneta_port {
541545
struct mvneta_bm_pool *pool_short;
542546
int bm_win_id;
543547

544-
bool eee_enabled;
545-
bool eee_active;
546-
bool tx_lpi_enabled;
547-
548548
u64 ethtool_stats[ARRAY_SIZE(mvneta_statistics)];
549549

550550
u32 indir[MVNETA_RSS_LU_TABLE_SIZE];
@@ -4213,18 +4213,6 @@ static int mvneta_mac_finish(struct phylink_config *config, unsigned int mode,
42134213
return 0;
42144214
}
42154215

4216-
static void mvneta_set_eee(struct mvneta_port *pp, bool enable)
4217-
{
4218-
u32 lpi_ctl1;
4219-
4220-
lpi_ctl1 = mvreg_read(pp, MVNETA_LPI_CTRL_1);
4221-
if (enable)
4222-
lpi_ctl1 |= MVNETA_LPI_REQUEST_ENABLE;
4223-
else
4224-
lpi_ctl1 &= ~MVNETA_LPI_REQUEST_ENABLE;
4225-
mvreg_write(pp, MVNETA_LPI_CTRL_1, lpi_ctl1);
4226-
}
4227-
42284216
static void mvneta_mac_link_down(struct phylink_config *config,
42294217
unsigned int mode, phy_interface_t interface)
42304218
{
@@ -4240,9 +4228,6 @@ static void mvneta_mac_link_down(struct phylink_config *config,
42404228
val |= MVNETA_GMAC_FORCE_LINK_DOWN;
42414229
mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
42424230
}
4243-
4244-
pp->eee_active = false;
4245-
mvneta_set_eee(pp, false);
42464231
}
42474232

42484233
static void mvneta_mac_link_up(struct phylink_config *config,
@@ -4291,11 +4276,56 @@ static void mvneta_mac_link_up(struct phylink_config *config,
42914276
}
42924277

42934278
mvneta_port_up(pp);
4279+
}
42944280

4295-
if (phy && pp->eee_enabled) {
4296-
pp->eee_active = phy_init_eee(phy, false) >= 0;
4297-
mvneta_set_eee(pp, pp->eee_active && pp->tx_lpi_enabled);
4281+
static void mvneta_mac_disable_tx_lpi(struct phylink_config *config)
4282+
{
4283+
struct mvneta_port *pp = netdev_priv(to_net_dev(config->dev));
4284+
u32 lpi1;
4285+
4286+
lpi1 = mvreg_read(pp, MVNETA_LPI_CTRL_1);
4287+
lpi1 &= ~(MVNETA_LPI_CTRL_1_REQUEST_ENABLE |
4288+
MVNETA_LPI_CTRL_1_REQUEST_FORCE |
4289+
MVNETA_LPI_CTRL_1_MANUAL_MODE);
4290+
mvreg_write(pp, MVNETA_LPI_CTRL_1, lpi1);
4291+
}
4292+
4293+
static int mvneta_mac_enable_tx_lpi(struct phylink_config *config, u32 timer,
4294+
bool tx_clk_stop)
4295+
{
4296+
struct mvneta_port *pp = netdev_priv(to_net_dev(config->dev));
4297+
u32 ts, tw, lpi0, lpi1, status;
4298+
4299+
status = mvreg_read(pp, MVNETA_GMAC_STATUS);
4300+
if (status & MVNETA_GMAC_SPEED_1000) {
4301+
/* At 1G speeds, the timer resolution are 1us, and
4302+
* 802.3 says tw is 16.5us. Round up to 17us.
4303+
*/
4304+
tw = 17;
4305+
ts = timer;
4306+
} else {
4307+
/* At 100M speeds, the timer resolutions are 10us, and
4308+
* 802.3 says tw is 30us.
4309+
*/
4310+
tw = 3;
4311+
ts = DIV_ROUND_UP(timer, 10);
42984312
}
4313+
4314+
if (ts > 255)
4315+
ts = 255;
4316+
4317+
/* Configure ts */
4318+
lpi0 = mvreg_read(pp, MVNETA_LPI_CTRL_0);
4319+
lpi0 = u32_replace_bits(lpi0, ts, MVNETA_LPI_CTRL_0_TS);
4320+
mvreg_write(pp, MVNETA_LPI_CTRL_0, lpi0);
4321+
4322+
/* Configure tw and enable LPI generation */
4323+
lpi1 = mvreg_read(pp, MVNETA_LPI_CTRL_1);
4324+
lpi1 = u32_replace_bits(lpi1, tw, MVNETA_LPI_CTRL_1_TW);
4325+
lpi1 |= MVNETA_LPI_CTRL_1_REQUEST_ENABLE;
4326+
mvreg_write(pp, MVNETA_LPI_CTRL_1, lpi1);
4327+
4328+
return 0;
42994329
}
43004330

43014331
static const struct phylink_mac_ops mvneta_phylink_ops = {
@@ -4305,6 +4335,8 @@ static const struct phylink_mac_ops mvneta_phylink_ops = {
43054335
.mac_finish = mvneta_mac_finish,
43064336
.mac_link_down = mvneta_mac_link_down,
43074337
.mac_link_up = mvneta_mac_link_up,
4338+
.mac_disable_tx_lpi = mvneta_mac_disable_tx_lpi,
4339+
.mac_enable_tx_lpi = mvneta_mac_enable_tx_lpi,
43084340
};
43094341

43104342
static int mvneta_mdio_probe(struct mvneta_port *pp)
@@ -5109,14 +5141,6 @@ static int mvneta_ethtool_get_eee(struct net_device *dev,
51095141
struct ethtool_keee *eee)
51105142
{
51115143
struct mvneta_port *pp = netdev_priv(dev);
5112-
u32 lpi_ctl0;
5113-
5114-
lpi_ctl0 = mvreg_read(pp, MVNETA_LPI_CTRL_0);
5115-
5116-
eee->eee_enabled = pp->eee_enabled;
5117-
eee->eee_active = pp->eee_active;
5118-
eee->tx_lpi_enabled = pp->tx_lpi_enabled;
5119-
eee->tx_lpi_timer = (lpi_ctl0) >> 8; // * scale;
51205144

51215145
return phylink_ethtool_get_eee(pp->phylink, eee);
51225146
}
@@ -5125,24 +5149,13 @@ static int mvneta_ethtool_set_eee(struct net_device *dev,
51255149
struct ethtool_keee *eee)
51265150
{
51275151
struct mvneta_port *pp = netdev_priv(dev);
5128-
u32 lpi_ctl0;
51295152

51305153
/* The Armada 37x documents do not give limits for this other than
51315154
* it being an 8-bit register.
51325155
*/
51335156
if (eee->tx_lpi_enabled && eee->tx_lpi_timer > 255)
51345157
return -EINVAL;
51355158

5136-
lpi_ctl0 = mvreg_read(pp, MVNETA_LPI_CTRL_0);
5137-
lpi_ctl0 &= ~(0xff << 8);
5138-
lpi_ctl0 |= eee->tx_lpi_timer << 8;
5139-
mvreg_write(pp, MVNETA_LPI_CTRL_0, lpi_ctl0);
5140-
5141-
pp->eee_enabled = eee->eee_enabled;
5142-
pp->tx_lpi_enabled = eee->tx_lpi_enabled;
5143-
5144-
mvneta_set_eee(pp, eee->tx_lpi_enabled && eee->eee_enabled);
5145-
51465159
return phylink_ethtool_set_eee(pp->phylink, eee);
51475160
}
51485161

@@ -5456,6 +5469,9 @@ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
54565469
!phy_interface_mode_is_rgmii(phy_mode))
54575470
return -EINVAL;
54585471

5472+
/* Ensure LPI is disabled */
5473+
mvneta_mac_disable_tx_lpi(&pp->phylink_config);
5474+
54595475
return 0;
54605476
}
54615477

@@ -5547,6 +5563,13 @@ static int mvneta_probe(struct platform_device *pdev)
55475563
pp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_10 |
55485564
MAC_100 | MAC_1000FD | MAC_2500FD;
55495565

5566+
/* Setup EEE. Choose 250us idle. Only supported in SGMII modes. */
5567+
__set_bit(PHY_INTERFACE_MODE_QSGMII, pp->phylink_config.lpi_interfaces);
5568+
__set_bit(PHY_INTERFACE_MODE_SGMII, pp->phylink_config.lpi_interfaces);
5569+
pp->phylink_config.lpi_capabilities = MAC_100FD | MAC_1000FD;
5570+
pp->phylink_config.lpi_timer_default = 250;
5571+
pp->phylink_config.eee_enabled_default = true;
5572+
55505573
phy_interface_set_rgmii(pp->phylink_config.supported_interfaces);
55515574
__set_bit(PHY_INTERFACE_MODE_QSGMII,
55525575
pp->phylink_config.supported_interfaces);

0 commit comments

Comments
 (0)