Skip to content

Commit 443b5ca

Browse files
committed
Merge branch 'net: dsa: add support for phylink managed EEE'
Russell King says: ==================== net: dsa: add support for phylink managed EEE This series adds support for phylink managed EEE to DSA, and converts mt753x to make use of this feature. Patch 1 implements a helper to indicate whether the MAC LPI operations are populated (suggested by Vladimir) Patch 2 makes the necessary changes to the core code - we retain calling set_mac_eee(), but this method now becomes a way to merely validate the arguments when using phylink managed EEE rather than performing any configuration. Patch 3 converts the mt7530 driver to use phylink managed EEE. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 2f47203 + 9cf2177 commit 443b5ca

File tree

4 files changed

+77
-31
lines changed

4 files changed

+77
-31
lines changed

drivers/net/dsa/mt7530.c

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2957,28 +2957,61 @@ static void mt753x_phylink_mac_link_up(struct phylink_config *config,
29572957
mcr |= PMCR_FORCE_RX_FC_EN;
29582958
}
29592959

2960-
if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, false) >= 0) {
2961-
switch (speed) {
2962-
case SPEED_1000:
2963-
case SPEED_2500:
2964-
mcr |= PMCR_FORCE_EEE1G;
2965-
break;
2966-
case SPEED_100:
2967-
mcr |= PMCR_FORCE_EEE100;
2968-
break;
2969-
}
2970-
}
2971-
29722960
mt7530_set(priv, MT753X_PMCR_P(dp->index), mcr);
29732961
}
29742962

2963+
static void mt753x_phylink_mac_disable_tx_lpi(struct phylink_config *config)
2964+
{
2965+
struct dsa_port *dp = dsa_phylink_to_port(config);
2966+
struct mt7530_priv *priv = dp->ds->priv;
2967+
2968+
mt7530_clear(priv, MT753X_PMCR_P(dp->index),
2969+
PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100);
2970+
}
2971+
2972+
static int mt753x_phylink_mac_enable_tx_lpi(struct phylink_config *config,
2973+
u32 timer, bool tx_clock_stop)
2974+
{
2975+
struct dsa_port *dp = dsa_phylink_to_port(config);
2976+
struct mt7530_priv *priv = dp->ds->priv;
2977+
u32 val;
2978+
2979+
/* If the timer is zero, then set LPI_MODE_EN, which allows the
2980+
* system to enter LPI mode immediately rather than waiting for
2981+
* the LPI threshold.
2982+
*/
2983+
if (!timer)
2984+
val = LPI_MODE_EN;
2985+
else if (FIELD_FIT(LPI_THRESH_MASK, timer))
2986+
val = FIELD_PREP(LPI_THRESH_MASK, timer);
2987+
else
2988+
val = LPI_THRESH_MASK;
2989+
2990+
mt7530_rmw(priv, MT753X_PMEEECR_P(dp->index),
2991+
LPI_THRESH_MASK | LPI_MODE_EN, val);
2992+
2993+
mt7530_set(priv, MT753X_PMCR_P(dp->index),
2994+
PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100);
2995+
2996+
return 0;
2997+
}
2998+
29752999
static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
29763000
struct phylink_config *config)
29773001
{
29783002
struct mt7530_priv *priv = ds->priv;
3003+
u32 eeecr;
29793004

29803005
config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE;
29813006

3007+
config->lpi_capabilities = MAC_100FD | MAC_1000FD | MAC_2500FD;
3008+
3009+
eeecr = mt7530_read(priv, MT753X_PMEEECR_P(port));
3010+
/* tx_lpi_timer should be in microseconds. The time units for
3011+
* LPI threshold are unspecified.
3012+
*/
3013+
config->lpi_timer_default = FIELD_GET(LPI_THRESH_MASK, eeecr);
3014+
29823015
priv->info->mac_port_get_caps(ds, port, config);
29833016
}
29843017

@@ -3088,18 +3121,9 @@ mt753x_setup(struct dsa_switch *ds)
30883121
static int mt753x_set_mac_eee(struct dsa_switch *ds, int port,
30893122
struct ethtool_keee *e)
30903123
{
3091-
struct mt7530_priv *priv = ds->priv;
3092-
u32 set, mask = LPI_THRESH_MASK | LPI_MODE_EN;
3093-
30943124
if (e->tx_lpi_timer > 0xFFF)
30953125
return -EINVAL;
30963126

3097-
set = LPI_THRESH_SET(e->tx_lpi_timer);
3098-
if (!e->tx_lpi_enabled)
3099-
/* Force LPI Mode without a delay */
3100-
set |= LPI_MODE_EN;
3101-
mt7530_rmw(priv, MT753X_PMEEECR_P(port), mask, set);
3102-
31033127
return 0;
31043128
}
31053129

@@ -3238,6 +3262,8 @@ static const struct phylink_mac_ops mt753x_phylink_mac_ops = {
32383262
.mac_config = mt753x_phylink_mac_config,
32393263
.mac_link_down = mt753x_phylink_mac_link_down,
32403264
.mac_link_up = mt753x_phylink_mac_link_up,
3265+
.mac_disable_tx_lpi = mt753x_phylink_mac_disable_tx_lpi,
3266+
.mac_enable_tx_lpi = mt753x_phylink_mac_enable_tx_lpi,
32413267
};
32423268

32433269
const struct mt753x_info mt753x_table[] = {

drivers/net/phy/phylink.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,8 +1957,7 @@ struct phylink *phylink_create(struct phylink_config *config,
19571957
return ERR_PTR(-EINVAL);
19581958
}
19591959

1960-
pl->mac_supports_eee_ops = mac_ops->mac_disable_tx_lpi &&
1961-
mac_ops->mac_enable_tx_lpi;
1960+
pl->mac_supports_eee_ops = phylink_mac_implements_lpi(mac_ops);
19621961
pl->mac_supports_eee = pl->mac_supports_eee_ops &&
19631962
pl->config->lpi_capabilities &&
19641963
!phy_interface_empty(pl->config->lpi_interfaces);

include/linux/phylink.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,18 @@ static inline int phylink_get_link_timer_ns(phy_interface_t interface)
737737
}
738738
}
739739

740+
/**
741+
* phylink_mac_implements_lpi() - determine if MAC implements LPI ops
742+
* @ops: phylink_mac_ops structure
743+
*
744+
* Returns true if the phylink MAC operations structure indicates that the
745+
* LPI operations have been implemented, false otherwise.
746+
*/
747+
static inline bool phylink_mac_implements_lpi(const struct phylink_mac_ops *ops)
748+
{
749+
return ops && ops->mac_disable_tx_lpi && ops->mac_enable_tx_lpi;
750+
}
751+
740752
void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
741753
unsigned int neg_mode, u16 bmsr, u16 lpa);
742754
void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs,

net/dsa/user.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,16 +1243,25 @@ static int dsa_user_set_eee(struct net_device *dev, struct ethtool_keee *e)
12431243
if (!ds->ops->support_eee || !ds->ops->support_eee(ds, dp->index))
12441244
return -EOPNOTSUPP;
12451245

1246-
/* Port's PHY and MAC both need to be EEE capable */
1247-
if (!dev->phydev)
1248-
return -ENODEV;
1246+
/* If the port is using phylink managed EEE, then an unimplemented
1247+
* set_mac_eee() is permissible.
1248+
*/
1249+
if (!phylink_mac_implements_lpi(ds->phylink_mac_ops)) {
1250+
/* Port's PHY and MAC both need to be EEE capable */
1251+
if (!dev->phydev)
1252+
return -ENODEV;
12491253

1250-
if (!ds->ops->set_mac_eee)
1251-
return -EOPNOTSUPP;
1254+
if (!ds->ops->set_mac_eee)
1255+
return -EOPNOTSUPP;
12521256

1253-
ret = ds->ops->set_mac_eee(ds, dp->index, e);
1254-
if (ret)
1255-
return ret;
1257+
ret = ds->ops->set_mac_eee(ds, dp->index, e);
1258+
if (ret)
1259+
return ret;
1260+
} else if (ds->ops->set_mac_eee) {
1261+
ret = ds->ops->set_mac_eee(ds, dp->index, e);
1262+
if (ret)
1263+
return ret;
1264+
}
12561265

12571266
return phylink_ethtool_set_eee(dp->pl, e);
12581267
}

0 commit comments

Comments
 (0)