123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- From 027586ae8ecacff49757ed854c020f35d24a599c Mon Sep 17 00:00:00 2001
- From: Daniel Golle <daniel@makrotopia.org>
- Date: Sat, 11 Mar 2023 03:44:41 +0000
- Subject: [PATCH] generic: backport some phylink helper functions
- It isn't feasible to literally backport all upstream phylink_pcs changes
- down to Linux 5.15: It's just too many patches, and many downstream
- drivers and hacks are likely to break. We are too close to branching off
- to risk this, and it's also just too much work.
- Instead just add helper functions used by modern PCS drivers while keeping
- the original functions instact as well. While this may add a kilobyte or
- two of extra kernel size, it has the advantage that we get the best of both
- worlds: None of the existing codepaths are touched, but yet we have the
- option to backport singular improvements to Ethernet drivers where needed.
- Signed-off-by: Daniel Golle <daniel@makrotopia.org>
- --- a/include/linux/phylink.h
- +++ b/include/linux/phylink.h
- @@ -600,10 +600,37 @@ int phylink_speed_up(struct phylink *pl)
- #define phylink_test(bm, mode) __phylink_do_bit(test_bit, bm, mode)
-
- void phylink_set_port_modes(unsigned long *bits);
- +
- +/**
- + * phylink_get_link_timer_ns - return the PCS link timer value
- + * @interface: link &typedef phy_interface_t mode
- + *
- + * Return the PCS link timer setting in nanoseconds for the PHY @interface
- + * mode, or -EINVAL if not appropriate.
- + */
- +static inline int phylink_get_link_timer_ns(phy_interface_t interface)
- +{
- + switch (interface) {
- + case PHY_INTERFACE_MODE_SGMII:
- + return 1600000;
- +
- + case PHY_INTERFACE_MODE_1000BASEX:
- + case PHY_INTERFACE_MODE_2500BASEX:
- + return 10000000;
- +
- + default:
- + return -EINVAL;
- + }
- +}
- +
- void phylink_helper_basex_speed(struct phylink_link_state *state);
-
- +void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
- + u16 bmsr, u16 lpa);
- void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs,
- struct phylink_link_state *state);
- +int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
- + const unsigned long *advertising);
- int phylink_mii_c22_pcs_set_advertisement(struct mdio_device *pcs,
- phy_interface_t interface,
- const unsigned long *advertising);
- --- a/drivers/net/phy/phylink.c
- +++ b/drivers/net/phy/phylink.c
- @@ -931,7 +931,6 @@ static int phylink_change_inband_advert(
-
- return 0;
- }
- -
- static void phylink_mac_pcs_get_state(struct phylink *pl,
- struct phylink_link_state *state)
- {
- @@ -3015,6 +3014,52 @@ void phylink_mii_c22_pcs_get_state(struc
- EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state);
-
- /**
- + * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers
- + * @state: a pointer to a &struct phylink_link_state.
- + * @bmsr: The value of the %MII_BMSR register
- + * @lpa: The value of the %MII_LPA register
- + *
- + * Helper for MAC PCS supporting the 802.3 clause 22 register set for
- + * clause 37 negotiation and/or SGMII control.
- + *
- + * Parse the Clause 37 or Cisco SGMII link partner negotiation word into
- + * the phylink @state structure. This is suitable to be used for implementing
- + * the mac_pcs_get_state() member of the struct phylink_mac_ops structure if
- + * accessing @bmsr and @lpa cannot be done with MDIO directly.
- + */
- +void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
- + u16 bmsr, u16 lpa)
- +{
- + state->link = !!(bmsr & BMSR_LSTATUS);
- + state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
- + /* If there is no link or autonegotiation is disabled, the LP advertisement
- + * data is not meaningful, so don't go any further.
- + */
- + if (!state->link || !state->an_enabled)
- + return;
- +
- + switch (state->interface) {
- + case PHY_INTERFACE_MODE_1000BASEX:
- + phylink_decode_c37_word(state, lpa, SPEED_1000);
- + break;
- +
- + case PHY_INTERFACE_MODE_2500BASEX:
- + phylink_decode_c37_word(state, lpa, SPEED_2500);
- + break;
- +
- + case PHY_INTERFACE_MODE_SGMII:
- + case PHY_INTERFACE_MODE_QSGMII:
- + phylink_decode_sgmii_word(state, lpa);
- + break;
- +
- + default:
- + state->link = false;
- + break;
- + }
- +}
- +EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_decode_state);
- +
- +/**
- * phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS
- * advertisement
- * @pcs: a pointer to a &struct mdio_device.
- @@ -3086,6 +3131,46 @@ int phylink_mii_c22_pcs_set_advertisemen
- EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement);
-
- /**
- + * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS
- + * advertisement
- + * @interface: the PHY interface mode being configured
- + * @advertising: the ethtool advertisement mask
- + *
- + * Helper for MAC PCS supporting the 802.3 clause 22 register set for
- + * clause 37 negotiation and/or SGMII control.
- + *
- + * Encode the clause 37 PCS advertisement as specified by @interface and
- + * @advertising.
- + *
- + * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed.
- + */
- +int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
- + const unsigned long *advertising)
- +{
- + u16 adv;
- +
- + switch (interface) {
- + case PHY_INTERFACE_MODE_1000BASEX:
- + case PHY_INTERFACE_MODE_2500BASEX:
- + adv = ADVERTISE_1000XFULL;
- + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
- + advertising))
- + adv |= ADVERTISE_1000XPAUSE;
- + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
- + advertising))
- + adv |= ADVERTISE_1000XPSE_ASYM;
- + return adv;
- + case PHY_INTERFACE_MODE_SGMII:
- + case PHY_INTERFACE_MODE_QSGMII:
- + return 0x0001;
- + default:
- + /* Nothing to do for other modes */
- + return -EINVAL;
- + }
- +}
- +EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_encode_advertisement);
- +
- +/**
- * phylink_mii_c22_pcs_config() - configure clause 22 PCS
- * @pcs: a pointer to a &struct mdio_device.
- * @mode: link autonegotiation mode
|