aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2018-08-09 09:38:38 -0400
committerDavid S. Miller <davem@davemloft.net>2018-08-09 14:08:19 -0400
commit624c0f0239f04cce78c86afa95eb2841c84fbab1 (patch)
tree016e270789980671fbf68294802d44f42925d996
parent54186b91bde1711080d0b23ce25f0bee5a058fc9 (diff)
phylink: add helper for configuring 2500BaseX modes
Add a helper for MAC drivers to use in their validate callback to deal with 2500BaseX vs 1000BaseX modes, where the hardware supports both but it is not possible to automatically select between them. This helper defaults to 1000BaseX, as that is the 802.3 standard, and will allow users to select 2500BaseX either by forcing the speed if AN is disabled, or by changing the advertising mask if AN is enabled. Disabling AN is not recommended as it is only the speed that we're interested in controlling, not the duplex or pause mode parameters. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/phy/phylink.c30
-rw-r--r--include/linux/phylink.h1
2 files changed, 31 insertions, 0 deletions
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index af4dc4425be2..3ba5cf2a8a5f 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1688,4 +1688,34 @@ static const struct sfp_upstream_ops sfp_phylink_ops = {
1688 .disconnect_phy = phylink_sfp_disconnect_phy, 1688 .disconnect_phy = phylink_sfp_disconnect_phy,
1689}; 1689};
1690 1690
1691/* Helpers for MAC drivers */
1692
1693/**
1694 * phylink_helper_basex_speed() - 1000BaseX/2500BaseX helper
1695 * @state: a pointer to a &struct phylink_link_state
1696 *
1697 * Inspect the interface mode, advertising mask or forced speed and
1698 * decide whether to run at 2.5Gbit or 1Gbit appropriately, switching
1699 * the interface mode to suit. @state->interface is appropriately
1700 * updated, and the advertising mask has the "other" baseX_Full flag
1701 * cleared.
1702 */
1703void phylink_helper_basex_speed(struct phylink_link_state *state)
1704{
1705 if (phy_interface_mode_is_8023z(state->interface)) {
1706 bool want_2500 = state->an_enabled ?
1707 phylink_test(state->advertising, 2500baseX_Full) :
1708 state->speed == SPEED_2500;
1709
1710 if (want_2500) {
1711 phylink_clear(state->advertising, 1000baseX_Full);
1712 state->interface = PHY_INTERFACE_MODE_2500BASEX;
1713 } else {
1714 phylink_clear(state->advertising, 2500baseX_Full);
1715 state->interface = PHY_INTERFACE_MODE_1000BASEX;
1716 }
1717 }
1718}
1719EXPORT_SYMBOL_GPL(phylink_helper_basex_speed);
1720
1691MODULE_LICENSE("GPL"); 1721MODULE_LICENSE("GPL");
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 50eeae025f1e..021fc6595856 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -234,5 +234,6 @@ int phylink_mii_ioctl(struct phylink *, struct ifreq *, int);
234#define phylink_test(bm, mode) __phylink_do_bit(test_bit, bm, mode) 234#define phylink_test(bm, mode) __phylink_do_bit(test_bit, bm, mode)
235 235
236void phylink_set_port_modes(unsigned long *bits); 236void phylink_set_port_modes(unsigned long *bits);
237void phylink_helper_basex_speed(struct phylink_link_state *state);
237 238
238#endif 239#endif