kernel: 5.15: backport v6.1 PHY changes required for Aquantia
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
(cherry picked from commit 2df8a0ccb0)
			
			
This commit is contained in:
		| @@ -0,0 +1,99 @@ | |||||||
|  | From 5e61fe157a27afc7c0d4f7bcbceefdca536c015f Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Maxime Chevallier <maxime.chevallier@bootlin.com> | ||||||
|  | Date: Wed, 17 Aug 2022 14:32:52 +0200 | ||||||
|  | Subject: [PATCH] net: phy: Introduce QUSGMII PHY mode | ||||||
|  |  | ||||||
|  | The QUSGMII mode is a derivative of Cisco's USXGMII standard. This | ||||||
|  | standard is pretty similar to SGMII, but allows for faster speeds, and | ||||||
|  | has the build-in bits for Quad and Octa variants (like QSGMII). | ||||||
|  |  | ||||||
|  | The main difference with SGMII/QSGMII is that USXGMII/QUSGMII re-uses | ||||||
|  | the preamble to carry various information, named 'Extensions'. | ||||||
|  |  | ||||||
|  | As of today, the USXGMII standard only mentions the "PCH" extension, | ||||||
|  | which is used to convey timestamps, allowing in-band signaling of PTP | ||||||
|  | timestamps without having to modify the frame itself. | ||||||
|  |  | ||||||
|  | This commit adds support for that mode. When no extension is in use, it | ||||||
|  | behaves exactly like QSGMII, although it's not compatible with QSGMII. | ||||||
|  |  | ||||||
|  | Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> | ||||||
|  | Reviewed-by: Andrew Lunn <andrew@lunn.ch> | ||||||
|  | Signed-off-by: David S. Miller <davem@davemloft.net> | ||||||
|  | --- | ||||||
|  |  Documentation/networking/phy.rst | 9 +++++++++ | ||||||
|  |  drivers/net/phy/phylink.c        | 3 +++ | ||||||
|  |  include/linux/phy.h              | 4 ++++ | ||||||
|  |  3 files changed, 16 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/Documentation/networking/phy.rst | ||||||
|  | +++ b/Documentation/networking/phy.rst | ||||||
|  | @@ -303,6 +303,15 @@ Some of the interface modes are describe | ||||||
|  |      rate of 125Mpbs using a 4B/5B encoding scheme, resulting in an underlying | ||||||
|  |      data rate of 100Mpbs. | ||||||
|  |   | ||||||
|  | +``PHY_INTERFACE_MODE_QUSGMII`` | ||||||
|  | +    This defines the Cisco the Quad USGMII mode, which is the Quad variant of | ||||||
|  | +    the USGMII (Universal SGMII) link. It's very similar to QSGMII, but uses | ||||||
|  | +    a Packet Control Header (PCH) instead of the 7 bytes preamble to carry not | ||||||
|  | +    only the port id, but also so-called "extensions". The only documented | ||||||
|  | +    extension so-far in the specification is the inclusion of timestamps, for | ||||||
|  | +    PTP-enabled PHYs. This mode isn't compatible with QSGMII, but offers the | ||||||
|  | +    same capabilities in terms of link speed and negociation. | ||||||
|  | + | ||||||
|  |  Pause frames / flow control | ||||||
|  |  =========================== | ||||||
|  |   | ||||||
|  | --- a/drivers/net/phy/phylink.c | ||||||
|  | +++ b/drivers/net/phy/phylink.c | ||||||
|  | @@ -367,6 +367,7 @@ void phylink_get_linkmodes(unsigned long | ||||||
|  |  	case PHY_INTERFACE_MODE_RGMII_ID: | ||||||
|  |  	case PHY_INTERFACE_MODE_RGMII: | ||||||
|  |  	case PHY_INTERFACE_MODE_QSGMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_QUSGMII: | ||||||
|  |  	case PHY_INTERFACE_MODE_SGMII: | ||||||
|  |  	case PHY_INTERFACE_MODE_GMII: | ||||||
|  |  		caps |= MAC_1000HD | MAC_1000FD; | ||||||
|  | @@ -630,6 +631,7 @@ static int phylink_parse_mode(struct phy | ||||||
|  |  		switch (pl->link_config.interface) { | ||||||
|  |  		case PHY_INTERFACE_MODE_SGMII: | ||||||
|  |  		case PHY_INTERFACE_MODE_QSGMII: | ||||||
|  | +		case PHY_INTERFACE_MODE_QUSGMII: | ||||||
|  |  			phylink_set(pl->supported, 10baseT_Half); | ||||||
|  |  			phylink_set(pl->supported, 10baseT_Full); | ||||||
|  |  			phylink_set(pl->supported, 100baseT_Half); | ||||||
|  | @@ -2956,6 +2958,7 @@ void phylink_mii_c22_pcs_get_state(struc | ||||||
|  |   | ||||||
|  |  	case PHY_INTERFACE_MODE_SGMII: | ||||||
|  |  	case PHY_INTERFACE_MODE_QSGMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_QUSGMII: | ||||||
|  |  		phylink_decode_sgmii_word(state, lpa); | ||||||
|  |  		break; | ||||||
|  |   | ||||||
|  | --- a/include/linux/phy.h | ||||||
|  | +++ b/include/linux/phy.h | ||||||
|  | @@ -115,6 +115,7 @@ extern const int phy_10gbit_features_arr | ||||||
|  |   * @PHY_INTERFACE_MODE_25GBASER: 25G BaseR | ||||||
|  |   * @PHY_INTERFACE_MODE_USXGMII:  Universal Serial 10GE MII | ||||||
|  |   * @PHY_INTERFACE_MODE_10GKR: 10GBASE-KR - with Clause 73 AN | ||||||
|  | + * @PHY_INTERFACE_MODE_QUSGMII: Quad Universal SGMII | ||||||
|  |   * @PHY_INTERFACE_MODE_MAX: Book keeping | ||||||
|  |   * | ||||||
|  |   * Describes the interface between the MAC and PHY. | ||||||
|  | @@ -152,6 +153,7 @@ typedef enum { | ||||||
|  |  	PHY_INTERFACE_MODE_USXGMII, | ||||||
|  |  	/* 10GBASE-KR - with Clause 73 AN */ | ||||||
|  |  	PHY_INTERFACE_MODE_10GKR, | ||||||
|  | +	PHY_INTERFACE_MODE_QUSGMII, | ||||||
|  |  	PHY_INTERFACE_MODE_MAX, | ||||||
|  |  } phy_interface_t; | ||||||
|  |   | ||||||
|  | @@ -267,6 +269,8 @@ static inline const char *phy_modes(phy_ | ||||||
|  |  		return "10gbase-kr"; | ||||||
|  |  	case PHY_INTERFACE_MODE_100BASEX: | ||||||
|  |  		return "100base-x"; | ||||||
|  | +	case PHY_INTERFACE_MODE_QUSGMII: | ||||||
|  | +		return "qusgmii"; | ||||||
|  |  	default: | ||||||
|  |  		return "unknown"; | ||||||
|  |  	} | ||||||
| @@ -0,0 +1,93 @@ | |||||||
|  | From c04ade27cb7b952b6b9b9a0efa0a6129cc63f2ae Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Maxime Chevallier <maxime.chevallier@bootlin.com> | ||||||
|  | Date: Wed, 17 Aug 2022 14:32:54 +0200 | ||||||
|  | Subject: [PATCH] net: phy: Add helper to derive the number of ports from a phy | ||||||
|  |  mode | ||||||
|  |  | ||||||
|  | Some phy modes such as QSGMII multiplex several MAC<->PHY links on one | ||||||
|  | single physical interface. QSGMII used to be the only one supported, but | ||||||
|  | other modes such as QUSGMII also carry multiple links. | ||||||
|  |  | ||||||
|  | This helper allows getting the number of links that are multiplexed | ||||||
|  | on a given interface. | ||||||
|  |  | ||||||
|  | Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> | ||||||
|  | Reviewed-by: Andrew Lunn <andrew@lunn.ch> | ||||||
|  | Signed-off-by: David S. Miller <davem@davemloft.net> | ||||||
|  | --- | ||||||
|  |  drivers/net/phy/phy-core.c | 52 ++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  include/linux/phy.h        |  2 ++ | ||||||
|  |  2 files changed, 54 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/phy/phy-core.c | ||||||
|  | +++ b/drivers/net/phy/phy-core.c | ||||||
|  | @@ -74,6 +74,58 @@ const char *phy_duplex_to_str(unsigned i | ||||||
|  |  } | ||||||
|  |  EXPORT_SYMBOL_GPL(phy_duplex_to_str); | ||||||
|  |   | ||||||
|  | +/** | ||||||
|  | + * phy_interface_num_ports - Return the number of links that can be carried by | ||||||
|  | + *			     a given MAC-PHY physical link. Returns 0 if this is | ||||||
|  | + *			     unknown, the number of links else. | ||||||
|  | + * | ||||||
|  | + * @interface: The interface mode we want to get the number of ports | ||||||
|  | + */ | ||||||
|  | +int phy_interface_num_ports(phy_interface_t interface) | ||||||
|  | +{ | ||||||
|  | +	switch (interface) { | ||||||
|  | +	case PHY_INTERFACE_MODE_NA: | ||||||
|  | +		return 0; | ||||||
|  | +	case PHY_INTERFACE_MODE_INTERNAL: | ||||||
|  | +	case PHY_INTERFACE_MODE_MII: | ||||||
|  | +	case PHY_INTERFACE_MODE_GMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_TBI: | ||||||
|  | +	case PHY_INTERFACE_MODE_REVMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_RMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_REVRMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_RGMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_RGMII_ID: | ||||||
|  | +	case PHY_INTERFACE_MODE_RGMII_RXID: | ||||||
|  | +	case PHY_INTERFACE_MODE_RGMII_TXID: | ||||||
|  | +	case PHY_INTERFACE_MODE_RTBI: | ||||||
|  | +	case PHY_INTERFACE_MODE_XGMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_XLGMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_MOCA: | ||||||
|  | +	case PHY_INTERFACE_MODE_TRGMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_USXGMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_SGMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_SMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_1000BASEX: | ||||||
|  | +	case PHY_INTERFACE_MODE_2500BASEX: | ||||||
|  | +	case PHY_INTERFACE_MODE_5GBASER: | ||||||
|  | +	case PHY_INTERFACE_MODE_10GBASER: | ||||||
|  | +	case PHY_INTERFACE_MODE_25GBASER: | ||||||
|  | +	case PHY_INTERFACE_MODE_10GKR: | ||||||
|  | +	case PHY_INTERFACE_MODE_100BASEX: | ||||||
|  | +	case PHY_INTERFACE_MODE_RXAUI: | ||||||
|  | +	case PHY_INTERFACE_MODE_XAUI: | ||||||
|  | +		return 1; | ||||||
|  | +	case PHY_INTERFACE_MODE_QSGMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_QUSGMII: | ||||||
|  | +		return 4; | ||||||
|  | +	case PHY_INTERFACE_MODE_MAX: | ||||||
|  | +		WARN_ONCE(1, "PHY_INTERFACE_MODE_MAX isn't a valid interface mode"); | ||||||
|  | +		return 0; | ||||||
|  | +	} | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL_GPL(phy_interface_num_ports); | ||||||
|  | + | ||||||
|  |  /* A mapping of all SUPPORTED settings to speed/duplex.  This table | ||||||
|  |   * must be grouped by speed and sorted in descending match priority | ||||||
|  |   * - iow, descending speed. | ||||||
|  | --- a/include/linux/phy.h | ||||||
|  | +++ b/include/linux/phy.h | ||||||
|  | @@ -964,6 +964,8 @@ struct phy_fixup { | ||||||
|  |  const char *phy_speed_to_str(int speed); | ||||||
|  |  const char *phy_duplex_to_str(unsigned int duplex); | ||||||
|  |   | ||||||
|  | +int phy_interface_num_ports(phy_interface_t interface); | ||||||
|  | + | ||||||
|  |  /* A structure for mapping a particular speed and duplex | ||||||
|  |   * combination to a particular SUPPORTED and ADVERTISED value | ||||||
|  |   */ | ||||||
| @@ -0,0 +1,96 @@ | |||||||
|  | From 05ad5d4581c3c1cc724fe50d4652833fb9f3037b Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sean Anderson <sean.anderson@seco.com> | ||||||
|  | Date: Fri, 2 Sep 2022 18:02:39 -0400 | ||||||
|  | Subject: [PATCH] net: phy: Add 1000BASE-KX interface mode | ||||||
|  |  | ||||||
|  | Add 1000BASE-KX interface mode. This 1G backplane ethernet as described in | ||||||
|  | clause 70. Clause 73 autonegotiation is mandatory, and only full duplex | ||||||
|  | operation is supported. | ||||||
|  |  | ||||||
|  | Although at the PMA level this interface mode is identical to | ||||||
|  | 1000BASE-X, it uses a different form of in-band autonegation. This | ||||||
|  | justifies a separate interface mode, since the interface mode (along | ||||||
|  | with the MLO_AN_* autonegotiation mode) sets the type of autonegotiation | ||||||
|  | which will be used on a link. This results in more than just electrical | ||||||
|  | differences between the link modes. | ||||||
|  |  | ||||||
|  | With regard to 1000BASE-X, 1000BASE-KX holds a similar position to | ||||||
|  | SGMII: same signaling, but different autonegotiation. PCS drivers | ||||||
|  | (which typically handle in-band autonegotiation) may only support | ||||||
|  | 1000BASE-X, and not 1000BASE-KX. Similarly, the phy mode is used to | ||||||
|  | configure serdes phys with phy_set_mode_ext. Due to the different | ||||||
|  | electrical standards (SFI or XFI vs Clause 70), they will likely want to | ||||||
|  | use different configuration. Adding a phy interface mode for | ||||||
|  | 1000BASE-KX helps simplify configuration in these areas. | ||||||
|  |  | ||||||
|  | Signed-off-by: Sean Anderson <sean.anderson@seco.com> | ||||||
|  | Signed-off-by: David S. Miller <davem@davemloft.net> | ||||||
|  | --- | ||||||
|  |  Documentation/networking/phy.rst | 6 ++++++ | ||||||
|  |  drivers/net/phy/phy-core.c       | 1 + | ||||||
|  |  drivers/net/phy/phylink.c        | 1 + | ||||||
|  |  include/linux/phy.h              | 4 ++++ | ||||||
|  |  4 files changed, 12 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/Documentation/networking/phy.rst | ||||||
|  | +++ b/Documentation/networking/phy.rst | ||||||
|  | @@ -312,6 +312,12 @@ Some of the interface modes are describe | ||||||
|  |      PTP-enabled PHYs. This mode isn't compatible with QSGMII, but offers the | ||||||
|  |      same capabilities in terms of link speed and negociation. | ||||||
|  |   | ||||||
|  | +``PHY_INTERFACE_MODE_1000BASEKX`` | ||||||
|  | +    This is 1000BASE-X as defined by IEEE 802.3 Clause 36 with Clause 73 | ||||||
|  | +    autonegotiation. Generally, it will be used with a Clause 70 PMD. To | ||||||
|  | +    contrast with the 1000BASE-X phy mode used for Clause 38 and 39 PMDs, this | ||||||
|  | +    interface mode has different autonegotiation and only supports full duplex. | ||||||
|  | + | ||||||
|  |  Pause frames / flow control | ||||||
|  |  =========================== | ||||||
|  |   | ||||||
|  | --- a/drivers/net/phy/phy-core.c | ||||||
|  | +++ b/drivers/net/phy/phy-core.c | ||||||
|  | @@ -114,6 +114,7 @@ int phy_interface_num_ports(phy_interfac | ||||||
|  |  	case PHY_INTERFACE_MODE_100BASEX: | ||||||
|  |  	case PHY_INTERFACE_MODE_RXAUI: | ||||||
|  |  	case PHY_INTERFACE_MODE_XAUI: | ||||||
|  | +	case PHY_INTERFACE_MODE_1000BASEKX: | ||||||
|  |  		return 1; | ||||||
|  |  	case PHY_INTERFACE_MODE_QSGMII: | ||||||
|  |  	case PHY_INTERFACE_MODE_QUSGMII: | ||||||
|  | --- a/drivers/net/phy/phylink.c | ||||||
|  | +++ b/drivers/net/phy/phylink.c | ||||||
|  | @@ -390,6 +390,7 @@ void phylink_get_linkmodes(unsigned long | ||||||
|  |  	case PHY_INTERFACE_MODE_1000BASEX: | ||||||
|  |  		caps |= MAC_1000HD; | ||||||
|  |  		fallthrough; | ||||||
|  | +	case PHY_INTERFACE_MODE_1000BASEKX: | ||||||
|  |  	case PHY_INTERFACE_MODE_TRGMII: | ||||||
|  |  		caps |= MAC_1000FD; | ||||||
|  |  		break; | ||||||
|  | --- a/include/linux/phy.h | ||||||
|  | +++ b/include/linux/phy.h | ||||||
|  | @@ -116,6 +116,7 @@ extern const int phy_10gbit_features_arr | ||||||
|  |   * @PHY_INTERFACE_MODE_USXGMII:  Universal Serial 10GE MII | ||||||
|  |   * @PHY_INTERFACE_MODE_10GKR: 10GBASE-KR - with Clause 73 AN | ||||||
|  |   * @PHY_INTERFACE_MODE_QUSGMII: Quad Universal SGMII | ||||||
|  | + * @PHY_INTERFACE_MODE_1000BASEKX: 1000Base-KX - with Clause 73 AN | ||||||
|  |   * @PHY_INTERFACE_MODE_MAX: Book keeping | ||||||
|  |   * | ||||||
|  |   * Describes the interface between the MAC and PHY. | ||||||
|  | @@ -154,6 +155,7 @@ typedef enum { | ||||||
|  |  	/* 10GBASE-KR - with Clause 73 AN */ | ||||||
|  |  	PHY_INTERFACE_MODE_10GKR, | ||||||
|  |  	PHY_INTERFACE_MODE_QUSGMII, | ||||||
|  | +	PHY_INTERFACE_MODE_1000BASEKX, | ||||||
|  |  	PHY_INTERFACE_MODE_MAX, | ||||||
|  |  } phy_interface_t; | ||||||
|  |   | ||||||
|  | @@ -251,6 +253,8 @@ static inline const char *phy_modes(phy_ | ||||||
|  |  		return "trgmii"; | ||||||
|  |  	case PHY_INTERFACE_MODE_1000BASEX: | ||||||
|  |  		return "1000base-x"; | ||||||
|  | +	case PHY_INTERFACE_MODE_1000BASEKX: | ||||||
|  | +		return "1000base-kx"; | ||||||
|  |  	case PHY_INTERFACE_MODE_2500BASEX: | ||||||
|  |  		return "2500base-x"; | ||||||
|  |  	case PHY_INTERFACE_MODE_5GBASER: | ||||||
| @@ -0,0 +1,294 @@ | |||||||
|  | From 0c3e10cb44232833a50cb8e3e784c432906a60c1 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sean Anderson <sean.anderson@seco.com> | ||||||
|  | Date: Tue, 20 Sep 2022 18:12:31 -0400 | ||||||
|  | Subject: [PATCH] net: phy: Add support for rate matching | ||||||
|  |  | ||||||
|  | This adds support for rate matching (also known as rate adaptation) to | ||||||
|  | the phy subsystem. The general idea is that the phy interface runs at | ||||||
|  | one speed, and the MAC throttles the rate at which it sends packets to | ||||||
|  | the link speed. There's a good overview of several techniques for | ||||||
|  | achieving this at [1]. This patch adds support for three: pause-frame | ||||||
|  | based (such as in Aquantia phys), CRS-based (such as in 10PASS-TS and | ||||||
|  | 2BASE-TL), and open-loop-based (such as in 10GBASE-W). | ||||||
|  |  | ||||||
|  | This patch makes a few assumptions and a few non assumptions about the | ||||||
|  | types of rate matching available. First, it assumes that different phys | ||||||
|  | may use different forms of rate matching. Second, it assumes that phys | ||||||
|  | can use rate matching for any of their supported link speeds (e.g. if a | ||||||
|  | phy supports 10BASE-T and XGMII, then it can adapt XGMII to 10BASE-T). | ||||||
|  | Third, it does not assume that all interface modes will use the same | ||||||
|  | form of rate matching. Fourth, it does not assume that all phy devices | ||||||
|  | will support rate matching (even if some do). Relaxing or strengthening | ||||||
|  | these (non-)assumptions could result in a different API. For example, if | ||||||
|  | all interface modes were assumed to use the same form of rate matching, | ||||||
|  | then a bitmask of interface modes supportting rate matching would | ||||||
|  | suffice. | ||||||
|  |  | ||||||
|  | For some better visibility into the process, the current rate matching | ||||||
|  | mode is exposed as part of the ethtool ksettings. For the moment, only | ||||||
|  | read access is supported. I'm not sure what userspace might want to | ||||||
|  | configure yet (disable it altogether, disable just one mode, specify the | ||||||
|  | mode to use, etc.). For the moment, since only pause-based rate | ||||||
|  | adaptation support is added in the next few commits, rate matching can | ||||||
|  | be disabled altogether by adjusting the advertisement. | ||||||
|  |  | ||||||
|  | 802.3 calls this feature "rate adaptation" in clause 49 (10GBASE-R) and | ||||||
|  | "rate matching" in clause 61 (10PASS-TL and 2BASE-TS). Aquantia also calls | ||||||
|  | this feature "rate adaptation". I chose "rate matching" because it is | ||||||
|  | shorter, and because Russell doesn't think "adaptation" is correct in this | ||||||
|  | context. | ||||||
|  |  | ||||||
|  | Signed-off-by: Sean Anderson <sean.anderson@seco.com> | ||||||
|  | Signed-off-by: David S. Miller <davem@davemloft.net> | ||||||
|  | --- | ||||||
|  |  Documentation/networking/ethtool-netlink.rst |  2 ++ | ||||||
|  |  drivers/net/phy/phy-core.c                   | 21 +++++++++++++++ | ||||||
|  |  drivers/net/phy/phy.c                        | 28 ++++++++++++++++++++ | ||||||
|  |  include/linux/phy.h                          | 22 ++++++++++++++- | ||||||
|  |  include/uapi/linux/ethtool.h                 | 18 +++++++++++-- | ||||||
|  |  include/uapi/linux/ethtool_netlink.h         |  1 + | ||||||
|  |  net/ethtool/ioctl.c                          |  1 + | ||||||
|  |  net/ethtool/linkmodes.c                      |  5 ++++ | ||||||
|  |  8 files changed, 95 insertions(+), 3 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/Documentation/networking/ethtool-netlink.rst | ||||||
|  | +++ b/Documentation/networking/ethtool-netlink.rst | ||||||
|  | @@ -418,6 +418,7 @@ Kernel response contents: | ||||||
|  |    ``ETHTOOL_A_LINKMODES_DUPLEX``              u8      duplex mode | ||||||
|  |    ``ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG``    u8      Master/slave port mode | ||||||
|  |    ``ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE``  u8      Master/slave port state | ||||||
|  | +  ``ETHTOOL_A_LINKMODES_RATE_MATCHING``       u8      PHY rate matching | ||||||
|  |    ==========================================  ======  ========================== | ||||||
|  |   | ||||||
|  |  For ``ETHTOOL_A_LINKMODES_OURS``, value represents advertised modes and mask | ||||||
|  | @@ -441,6 +442,7 @@ Request contents: | ||||||
|  |    ``ETHTOOL_A_LINKMODES_SPEED``               u32     link speed (Mb/s) | ||||||
|  |    ``ETHTOOL_A_LINKMODES_DUPLEX``              u8      duplex mode | ||||||
|  |    ``ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG``    u8      Master/slave port mode | ||||||
|  | +  ``ETHTOOL_A_LINKMODES_RATE_MATCHING``       u8      PHY rate matching | ||||||
|  |    ``ETHTOOL_A_LINKMODES_LANES``               u32     lanes | ||||||
|  |    ==========================================  ======  ========================== | ||||||
|  |   | ||||||
|  | --- a/drivers/net/phy/phy-core.c | ||||||
|  | +++ b/drivers/net/phy/phy-core.c | ||||||
|  | @@ -75,6 +75,27 @@ const char *phy_duplex_to_str(unsigned i | ||||||
|  |  EXPORT_SYMBOL_GPL(phy_duplex_to_str); | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  | + * phy_rate_matching_to_str - Return a string describing the rate matching | ||||||
|  | + * | ||||||
|  | + * @rate_matching: Type of rate matching to describe | ||||||
|  | + */ | ||||||
|  | +const char *phy_rate_matching_to_str(int rate_matching) | ||||||
|  | +{ | ||||||
|  | +	switch (rate_matching) { | ||||||
|  | +	case RATE_MATCH_NONE: | ||||||
|  | +		return "none"; | ||||||
|  | +	case RATE_MATCH_PAUSE: | ||||||
|  | +		return "pause"; | ||||||
|  | +	case RATE_MATCH_CRS: | ||||||
|  | +		return "crs"; | ||||||
|  | +	case RATE_MATCH_OPEN_LOOP: | ||||||
|  | +		return "open-loop"; | ||||||
|  | +	} | ||||||
|  | +	return "Unsupported (update phy-core.c)"; | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL_GPL(phy_rate_matching_to_str); | ||||||
|  | + | ||||||
|  | +/** | ||||||
|  |   * phy_interface_num_ports - Return the number of links that can be carried by | ||||||
|  |   *			     a given MAC-PHY physical link. Returns 0 if this is | ||||||
|  |   *			     unknown, the number of links else. | ||||||
|  | --- a/drivers/net/phy/phy.c | ||||||
|  | +++ b/drivers/net/phy/phy.c | ||||||
|  | @@ -127,6 +127,33 @@ void phy_print_status(struct phy_device | ||||||
|  |  EXPORT_SYMBOL(phy_print_status); | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  | + * phy_get_rate_matching - determine if rate matching is supported | ||||||
|  | + * @phydev: The phy device to return rate matching for | ||||||
|  | + * @iface: The interface mode to use | ||||||
|  | + * | ||||||
|  | + * This determines the type of rate matching (if any) that @phy supports | ||||||
|  | + * using @iface. @iface may be %PHY_INTERFACE_MODE_NA to determine if any | ||||||
|  | + * interface supports rate matching. | ||||||
|  | + * | ||||||
|  | + * Return: The type of rate matching @phy supports for @iface, or | ||||||
|  | + *         %RATE_MATCH_NONE. | ||||||
|  | + */ | ||||||
|  | +int phy_get_rate_matching(struct phy_device *phydev, | ||||||
|  | +			  phy_interface_t iface) | ||||||
|  | +{ | ||||||
|  | +	int ret = RATE_MATCH_NONE; | ||||||
|  | + | ||||||
|  | +	if (phydev->drv->get_rate_matching) { | ||||||
|  | +		mutex_lock(&phydev->lock); | ||||||
|  | +		ret = phydev->drv->get_rate_matching(phydev, iface); | ||||||
|  | +		mutex_unlock(&phydev->lock); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return ret; | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL_GPL(phy_get_rate_matching); | ||||||
|  | + | ||||||
|  | +/** | ||||||
|  |   * phy_config_interrupt - configure the PHY device for the requested interrupts | ||||||
|  |   * @phydev: the phy_device struct | ||||||
|  |   * @interrupts: interrupt flags to configure for this @phydev | ||||||
|  | @@ -268,6 +295,7 @@ void phy_ethtool_ksettings_get(struct ph | ||||||
|  |  	cmd->base.duplex = phydev->duplex; | ||||||
|  |  	cmd->base.master_slave_cfg = phydev->master_slave_get; | ||||||
|  |  	cmd->base.master_slave_state = phydev->master_slave_state; | ||||||
|  | +	cmd->base.rate_matching = phydev->rate_matching; | ||||||
|  |  	if (phydev->interface == PHY_INTERFACE_MODE_MOCA) | ||||||
|  |  		cmd->base.port = PORT_BNC; | ||||||
|  |  	else | ||||||
|  | --- a/include/linux/phy.h | ||||||
|  | +++ b/include/linux/phy.h | ||||||
|  | @@ -280,7 +280,6 @@ static inline const char *phy_modes(phy_ | ||||||
|  |  	} | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | - | ||||||
|  |  #define PHY_INIT_TIMEOUT	100000 | ||||||
|  |  #define PHY_FORCE_TIMEOUT	10 | ||||||
|  |   | ||||||
|  | @@ -573,6 +572,7 @@ struct macsec_ops; | ||||||
|  |   * @lp_advertising: Current link partner advertised linkmodes | ||||||
|  |   * @eee_broken_modes: Energy efficient ethernet modes which should be prohibited | ||||||
|  |   * @autoneg: Flag autoneg being used | ||||||
|  | + * @rate_matching: Current rate matching mode | ||||||
|  |   * @link: Current link state | ||||||
|  |   * @autoneg_complete: Flag auto negotiation of the link has completed | ||||||
|  |   * @mdix: Current crossover | ||||||
|  | @@ -639,6 +639,8 @@ struct phy_device { | ||||||
|  |  	unsigned irq_suspended:1; | ||||||
|  |  	unsigned irq_rerun:1; | ||||||
|  |   | ||||||
|  | +	int rate_matching; | ||||||
|  | + | ||||||
|  |  	enum phy_state state; | ||||||
|  |   | ||||||
|  |  	u32 dev_flags; | ||||||
|  | @@ -801,6 +803,21 @@ struct phy_driver { | ||||||
|  |  	 */ | ||||||
|  |  	int (*get_features)(struct phy_device *phydev); | ||||||
|  |   | ||||||
|  | +	/** | ||||||
|  | +	 * @get_rate_matching: Get the supported type of rate matching for a | ||||||
|  | +	 * particular phy interface. This is used by phy consumers to determine | ||||||
|  | +	 * whether to advertise lower-speed modes for that interface. It is | ||||||
|  | +	 * assumed that if a rate matching mode is supported on an interface, | ||||||
|  | +	 * then that interface's rate can be adapted to all slower link speeds | ||||||
|  | +	 * supported by the phy. If iface is %PHY_INTERFACE_MODE_NA, and the phy | ||||||
|  | +	 * supports any kind of rate matching for any interface, then it must | ||||||
|  | +	 * return that rate matching mode (preferring %RATE_MATCH_PAUSE to | ||||||
|  | +	 * %RATE_MATCH_CRS). If the interface is not supported, this should | ||||||
|  | +	 * return %RATE_MATCH_NONE. | ||||||
|  | +	 */ | ||||||
|  | +	int (*get_rate_matching)(struct phy_device *phydev, | ||||||
|  | +				   phy_interface_t iface); | ||||||
|  | + | ||||||
|  |  	/* PHY Power Management */ | ||||||
|  |  	/** @suspend: Suspend the hardware, saving state if needed */ | ||||||
|  |  	int (*suspend)(struct phy_device *phydev); | ||||||
|  | @@ -967,6 +984,7 @@ struct phy_fixup { | ||||||
|  |   | ||||||
|  |  const char *phy_speed_to_str(int speed); | ||||||
|  |  const char *phy_duplex_to_str(unsigned int duplex); | ||||||
|  | +const char *phy_rate_matching_to_str(int rate_matching); | ||||||
|  |   | ||||||
|  |  int phy_interface_num_ports(phy_interface_t interface); | ||||||
|  |   | ||||||
|  | @@ -1675,6 +1693,8 @@ int phy_disable_interrupts(struct phy_de | ||||||
|  |  void phy_request_interrupt(struct phy_device *phydev); | ||||||
|  |  void phy_free_interrupt(struct phy_device *phydev); | ||||||
|  |  void phy_print_status(struct phy_device *phydev); | ||||||
|  | +int phy_get_rate_matching(struct phy_device *phydev, | ||||||
|  | +			    phy_interface_t iface); | ||||||
|  |  int phy_set_max_speed(struct phy_device *phydev, u32 max_speed); | ||||||
|  |  void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode); | ||||||
|  |  void phy_advertise_supported(struct phy_device *phydev); | ||||||
|  | --- a/include/uapi/linux/ethtool.h | ||||||
|  | +++ b/include/uapi/linux/ethtool.h | ||||||
|  | @@ -1809,6 +1809,20 @@ static inline int ethtool_validate_duple | ||||||
|  |  #define MASTER_SLAVE_STATE_SLAVE		3 | ||||||
|  |  #define MASTER_SLAVE_STATE_ERR			4 | ||||||
|  |   | ||||||
|  | +/* These are used to throttle the rate of data on the phy interface when the | ||||||
|  | + * native speed of the interface is higher than the link speed. These should | ||||||
|  | + * not be used for phy interfaces which natively support multiple speeds (e.g. | ||||||
|  | + * MII or SGMII). | ||||||
|  | + */ | ||||||
|  | +/* No rate matching performed. */ | ||||||
|  | +#define RATE_MATCH_NONE		0 | ||||||
|  | +/* The phy sends pause frames to throttle the MAC. */ | ||||||
|  | +#define RATE_MATCH_PAUSE	1 | ||||||
|  | +/* The phy asserts CRS to prevent the MAC from transmitting. */ | ||||||
|  | +#define RATE_MATCH_CRS		2 | ||||||
|  | +/* The MAC is programmed with a sufficiently-large IPG. */ | ||||||
|  | +#define RATE_MATCH_OPEN_LOOP	3 | ||||||
|  | + | ||||||
|  |  /* Which connector port. */ | ||||||
|  |  #define PORT_TP			0x00 | ||||||
|  |  #define PORT_AUI		0x01 | ||||||
|  | @@ -2002,8 +2016,8 @@ enum ethtool_reset_flags { | ||||||
|  |   *	reported consistently by PHYLIB.  Read-only. | ||||||
|  |   * @master_slave_cfg: Master/slave port mode. | ||||||
|  |   * @master_slave_state: Master/slave port state. | ||||||
|  | + * @rate_matching: Rate adaptation performed by the PHY | ||||||
|  |   * @reserved: Reserved for future use; see the note on reserved space. | ||||||
|  | - * @reserved1: Reserved for future use; see the note on reserved space. | ||||||
|  |   * @link_mode_masks: Variable length bitmaps. | ||||||
|  |   * | ||||||
|  |   * If autonegotiation is disabled, the speed and @duplex represent the | ||||||
|  | @@ -2054,7 +2068,7 @@ struct ethtool_link_settings { | ||||||
|  |  	__u8	transceiver; | ||||||
|  |  	__u8	master_slave_cfg; | ||||||
|  |  	__u8	master_slave_state; | ||||||
|  | -	__u8	reserved1[1]; | ||||||
|  | +	__u8	rate_matching; | ||||||
|  |  	__u32	reserved[7]; | ||||||
|  |  	__u32	link_mode_masks[0]; | ||||||
|  |  	/* layout of link_mode_masks fields: | ||||||
|  | --- a/include/uapi/linux/ethtool_netlink.h | ||||||
|  | +++ b/include/uapi/linux/ethtool_netlink.h | ||||||
|  | @@ -238,6 +238,7 @@ enum { | ||||||
|  |  	ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG,	/* u8 */ | ||||||
|  |  	ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE,	/* u8 */ | ||||||
|  |  	ETHTOOL_A_LINKMODES_LANES,		/* u32 */ | ||||||
|  | +	ETHTOOL_A_LINKMODES_RATE_MATCHING,	/* u8 */ | ||||||
|  |   | ||||||
|  |  	/* add new constants above here */ | ||||||
|  |  	__ETHTOOL_A_LINKMODES_CNT, | ||||||
|  | --- a/net/ethtool/ioctl.c | ||||||
|  | +++ b/net/ethtool/ioctl.c | ||||||
|  | @@ -559,6 +559,7 @@ static int ethtool_get_link_ksettings(st | ||||||
|  |  		= __ETHTOOL_LINK_MODE_MASK_NU32; | ||||||
|  |  	link_ksettings.base.master_slave_cfg = MASTER_SLAVE_CFG_UNSUPPORTED; | ||||||
|  |  	link_ksettings.base.master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED; | ||||||
|  | +	link_ksettings.base.rate_matching = RATE_MATCH_NONE; | ||||||
|  |   | ||||||
|  |  	return store_link_ksettings_for_user(useraddr, &link_ksettings); | ||||||
|  |  } | ||||||
|  | --- a/net/ethtool/linkmodes.c | ||||||
|  | +++ b/net/ethtool/linkmodes.c | ||||||
|  | @@ -70,6 +70,7 @@ static int linkmodes_reply_size(const st | ||||||
|  |  		+ nla_total_size(sizeof(u32)) /* LINKMODES_SPEED */ | ||||||
|  |  		+ nla_total_size(sizeof(u32)) /* LINKMODES_LANES */ | ||||||
|  |  		+ nla_total_size(sizeof(u8)) /* LINKMODES_DUPLEX */ | ||||||
|  | +		+ nla_total_size(sizeof(u8)) /* LINKMODES_RATE_MATCHING */ | ||||||
|  |  		+ 0; | ||||||
|  |  	ret = ethnl_bitset_size(ksettings->link_modes.advertising, | ||||||
|  |  				ksettings->link_modes.supported, | ||||||
|  | @@ -143,6 +144,10 @@ static int linkmodes_fill_reply(struct s | ||||||
|  |  		       lsettings->master_slave_state)) | ||||||
|  |  		return -EMSGSIZE; | ||||||
|  |   | ||||||
|  | +	if (nla_put_u8(skb, ETHTOOL_A_LINKMODES_RATE_MATCHING, | ||||||
|  | +		       lsettings->rate_matching)) | ||||||
|  | +		return -EMSGSIZE; | ||||||
|  | + | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
| @@ -17,7 +17,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org> | |||||||
|  |  | ||||||
| --- a/drivers/net/phy/phylink.c | --- a/drivers/net/phy/phylink.c | ||||||
| +++ b/drivers/net/phy/phylink.c | +++ b/drivers/net/phy/phylink.c | ||||||
| @@ -756,6 +756,18 @@ static void phylink_resolve_flow(struct | @@ -759,6 +759,18 @@ static void phylink_resolve_flow(struct | ||||||
|  	} |  	} | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -36,7 +36,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org> | |||||||
|  static void phylink_mac_config(struct phylink *pl, |  static void phylink_mac_config(struct phylink *pl, | ||||||
|  			       const struct phylink_link_state *state) |  			       const struct phylink_link_state *state) | ||||||
|  { |  { | ||||||
| @@ -787,6 +799,7 @@ static void phylink_major_config(struct | @@ -790,6 +802,7 @@ static void phylink_major_config(struct | ||||||
|  				  const struct phylink_link_state *state) |  				  const struct phylink_link_state *state) | ||||||
|  { |  { | ||||||
|  	struct phylink_pcs *pcs = NULL; |  	struct phylink_pcs *pcs = NULL; | ||||||
| @@ -44,7 +44,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org> | |||||||
|  	int err; |  	int err; | ||||||
|   |   | ||||||
|  	phylink_dbg(pl, "major config %s\n", phy_modes(state->interface)); |  	phylink_dbg(pl, "major config %s\n", phy_modes(state->interface)); | ||||||
| @@ -799,8 +812,12 @@ static void phylink_major_config(struct | @@ -802,8 +815,12 @@ static void phylink_major_config(struct | ||||||
|  				    pcs); |  				    pcs); | ||||||
|  			return; |  			return; | ||||||
|  		} |  		} | ||||||
| @@ -57,7 +57,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org> | |||||||
|  	if (pl->mac_ops->mac_prepare) { |  	if (pl->mac_ops->mac_prepare) { | ||||||
|  		err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode, |  		err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode, | ||||||
|  					       state->interface); |  					       state->interface); | ||||||
| @@ -814,8 +831,10 @@ static void phylink_major_config(struct | @@ -817,8 +834,10 @@ static void phylink_major_config(struct | ||||||
|  	/* If we have a new PCS, switch to the new PCS after preparing the MAC |  	/* If we have a new PCS, switch to the new PCS after preparing the MAC | ||||||
|  	 * for the change. |  	 * for the change. | ||||||
|  	 */ |  	 */ | ||||||
| @@ -70,7 +70,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org> | |||||||
|   |   | ||||||
|  	phylink_mac_config(pl, state); |  	phylink_mac_config(pl, state); | ||||||
|   |   | ||||||
| @@ -841,6 +860,8 @@ static void phylink_major_config(struct | @@ -844,6 +863,8 @@ static void phylink_major_config(struct | ||||||
|  			phylink_err(pl, "mac_finish failed: %pe\n", |  			phylink_err(pl, "mac_finish failed: %pe\n", | ||||||
|  				    ERR_PTR(err)); |  				    ERR_PTR(err)); | ||||||
|  	} |  	} | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org> | |||||||
|  |  | ||||||
| --- a/drivers/net/phy/phylink.c | --- a/drivers/net/phy/phylink.c | ||||||
| +++ b/drivers/net/phy/phylink.c | +++ b/drivers/net/phy/phylink.c | ||||||
| @@ -764,7 +764,7 @@ static void phylink_pcs_poll_stop(struct | @@ -767,7 +767,7 @@ static void phylink_pcs_poll_stop(struct | ||||||
|   |   | ||||||
|  static void phylink_pcs_poll_start(struct phylink *pl) |  static void phylink_pcs_poll_start(struct phylink *pl) | ||||||
|  { |  { | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> | |||||||
|   |   | ||||||
|  	bool mac_link_dropped; |  	bool mac_link_dropped; | ||||||
|  	bool using_mac_select_pcs; |  	bool using_mac_select_pcs; | ||||||
| @@ -795,6 +800,22 @@ static void phylink_mac_pcs_an_restart(s | @@ -798,6 +803,22 @@ static void phylink_mac_pcs_an_restart(s | ||||||
|  	} |  	} | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -58,7 +58,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> | |||||||
|  static void phylink_major_config(struct phylink *pl, bool restart, |  static void phylink_major_config(struct phylink *pl, bool restart, | ||||||
|  				  const struct phylink_link_state *state) |  				  const struct phylink_link_state *state) | ||||||
|  { |  { | ||||||
| @@ -832,12 +853,16 @@ static void phylink_major_config(struct | @@ -835,12 +856,16 @@ static void phylink_major_config(struct | ||||||
|  	 * for the change. |  	 * for the change. | ||||||
|  	 */ |  	 */ | ||||||
|  	if (pcs_changed) { |  	if (pcs_changed) { | ||||||
| @@ -75,7 +75,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> | |||||||
|  	if (pl->pcs_ops) { |  	if (pl->pcs_ops) { | ||||||
|  		err = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode, |  		err = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode, | ||||||
|  					      state->interface, |  					      state->interface, | ||||||
| @@ -1261,6 +1286,7 @@ struct phylink *phylink_create(struct ph | @@ -1264,6 +1289,7 @@ struct phylink *phylink_create(struct ph | ||||||
|  	pl->link_config.speed = SPEED_UNKNOWN; |  	pl->link_config.speed = SPEED_UNKNOWN; | ||||||
|  	pl->link_config.duplex = DUPLEX_UNKNOWN; |  	pl->link_config.duplex = DUPLEX_UNKNOWN; | ||||||
|  	pl->link_config.an_enabled = true; |  	pl->link_config.an_enabled = true; | ||||||
| @@ -83,7 +83,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> | |||||||
|  	pl->mac_ops = mac_ops; |  	pl->mac_ops = mac_ops; | ||||||
|  	__set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); |  	__set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); | ||||||
|  	timer_setup(&pl->link_poll, phylink_fixed_poll, 0); |  	timer_setup(&pl->link_poll, phylink_fixed_poll, 0); | ||||||
| @@ -1652,6 +1678,8 @@ void phylink_start(struct phylink *pl) | @@ -1655,6 +1681,8 @@ void phylink_start(struct phylink *pl) | ||||||
|  	if (pl->netdev) |  	if (pl->netdev) | ||||||
|  		netif_carrier_off(pl->netdev); |  		netif_carrier_off(pl->netdev); | ||||||
|   |   | ||||||
| @@ -92,7 +92,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> | |||||||
|  	/* Apply the link configuration to the MAC when starting. This allows |  	/* Apply the link configuration to the MAC when starting. This allows | ||||||
|  	 * a fixed-link to start with the correct parameters, and also |  	 * a fixed-link to start with the correct parameters, and also | ||||||
|  	 * ensures that we set the appropriate advertisement for Serdes links. |  	 * ensures that we set the appropriate advertisement for Serdes links. | ||||||
| @@ -1662,6 +1690,8 @@ void phylink_start(struct phylink *pl) | @@ -1665,6 +1693,8 @@ void phylink_start(struct phylink *pl) | ||||||
|  	 */ |  	 */ | ||||||
|  	phylink_mac_initial_config(pl, true); |  	phylink_mac_initial_config(pl, true); | ||||||
|   |   | ||||||
| @@ -101,7 +101,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> | |||||||
|  	clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); |  	clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); | ||||||
|  	phylink_run_resolve(pl); |  	phylink_run_resolve(pl); | ||||||
|   |   | ||||||
| @@ -1681,16 +1711,9 @@ void phylink_start(struct phylink *pl) | @@ -1684,16 +1714,9 @@ void phylink_start(struct phylink *pl) | ||||||
|  			poll = true; |  			poll = true; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @@ -120,7 +120,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> | |||||||
|  	if (poll) |  	if (poll) | ||||||
|  		mod_timer(&pl->link_poll, jiffies + HZ); |  		mod_timer(&pl->link_poll, jiffies + HZ); | ||||||
|  	if (pl->phydev) |  	if (pl->phydev) | ||||||
| @@ -1727,6 +1750,10 @@ void phylink_stop(struct phylink *pl) | @@ -1730,6 +1753,10 @@ void phylink_stop(struct phylink *pl) | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
|  	phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED); |  	phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED); | ||||||
|   | |||||||
| @@ -153,7 +153,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> | |||||||
|  #include <linux/linkmode.h> |  #include <linux/linkmode.h> | ||||||
|  #include <linux/netlink.h> |  #include <linux/netlink.h> | ||||||
|  #include <linux/mdio.h> |  #include <linux/mdio.h> | ||||||
| @@ -582,6 +583,7 @@ struct macsec_ops; | @@ -590,6 +591,7 @@ struct macsec_ops; | ||||||
|   * @phy_num_led_triggers: Number of triggers in @phy_led_triggers |   * @phy_num_led_triggers: Number of triggers in @phy_led_triggers | ||||||
|   * @led_link_trigger: LED trigger for link up/down |   * @led_link_trigger: LED trigger for link up/down | ||||||
|   * @last_triggered: last LED trigger for link speed |   * @last_triggered: last LED trigger for link speed | ||||||
| @@ -161,7 +161,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> | |||||||
|   * @master_slave_set: User requested master/slave configuration |   * @master_slave_set: User requested master/slave configuration | ||||||
|   * @master_slave_get: Current master/slave advertisement |   * @master_slave_get: Current master/slave advertisement | ||||||
|   * @master_slave_state: Current master/slave configuration |   * @master_slave_state: Current master/slave configuration | ||||||
| @@ -668,6 +670,7 @@ struct phy_device { | @@ -678,6 +680,7 @@ struct phy_device { | ||||||
|   |   | ||||||
|  	struct phy_led_trigger *led_link_trigger; |  	struct phy_led_trigger *led_link_trigger; | ||||||
|  #endif |  #endif | ||||||
| @@ -169,7 +169,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> | |||||||
|   |   | ||||||
|  	/* |  	/* | ||||||
|  	 * Interrupt number for this PHY |  	 * Interrupt number for this PHY | ||||||
| @@ -739,6 +742,19 @@ struct phy_tdr_config { | @@ -749,6 +752,19 @@ struct phy_tdr_config { | ||||||
|  #define PHY_PAIR_ALL -1 |  #define PHY_PAIR_ALL -1 | ||||||
|   |   | ||||||
|  /** |  /** | ||||||
|   | |||||||
| @@ -59,7 +59,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> | |||||||
|  	init_data.fwnode = of_fwnode_handle(led); |  	init_data.fwnode = of_fwnode_handle(led); | ||||||
| --- a/include/linux/phy.h | --- a/include/linux/phy.h | ||||||
| +++ b/include/linux/phy.h | +++ b/include/linux/phy.h | ||||||
| @@ -745,15 +745,19 @@ struct phy_tdr_config { | @@ -755,15 +755,19 @@ struct phy_tdr_config { | ||||||
|   * struct phy_led: An LED driven by the PHY |   * struct phy_led: An LED driven by the PHY | ||||||
|   * |   * | ||||||
|   * @list: List of LEDs |   * @list: List of LEDs | ||||||
| @@ -79,7 +79,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> | |||||||
|  /** |  /** | ||||||
|   * struct phy_driver - Driver structure for a particular PHY type |   * struct phy_driver - Driver structure for a particular PHY type | ||||||
|   * |   * | ||||||
| @@ -953,6 +957,15 @@ struct phy_driver { | @@ -978,6 +982,15 @@ struct phy_driver { | ||||||
|  	int (*get_sqi)(struct phy_device *dev); |  	int (*get_sqi)(struct phy_device *dev); | ||||||
|  	/** @get_sqi_max: Get the maximum signal quality indication */ |  	/** @get_sqi_max: Get the maximum signal quality indication */ | ||||||
|  	int (*get_sqi_max)(struct phy_device *dev); |  	int (*get_sqi_max)(struct phy_device *dev); | ||||||
|   | |||||||
| @@ -52,7 +52,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> | |||||||
|  	init_data.fwnode = of_fwnode_handle(led); |  	init_data.fwnode = of_fwnode_handle(led); | ||||||
| --- a/include/linux/phy.h | --- a/include/linux/phy.h | ||||||
| +++ b/include/linux/phy.h | +++ b/include/linux/phy.h | ||||||
| @@ -966,6 +966,18 @@ struct phy_driver { | @@ -991,6 +991,18 @@ struct phy_driver { | ||||||
|  	 */ |  	 */ | ||||||
|  	int (*led_brightness_set)(struct phy_device *dev, |  	int (*led_brightness_set)(struct phy_device *dev, | ||||||
|  				  u8 index, enum led_brightness value); |  				  u8 index, enum led_brightness value); | ||||||
|   | |||||||
| @@ -123,7 +123,7 @@ Signed-off-by: Justin Stitt <justinstitt@google.com> | |||||||
|  #endif /* _LINUX_ETHTOOL_H */ |  #endif /* _LINUX_ETHTOOL_H */ | ||||||
| --- a/net/ethtool/ioctl.c | --- a/net/ethtool/ioctl.c | ||||||
| +++ b/net/ethtool/ioctl.c | +++ b/net/ethtool/ioctl.c | ||||||
| @@ -1953,6 +1953,13 @@ __printf(2, 3) void ethtool_sprintf(u8 * | @@ -1954,6 +1954,13 @@ __printf(2, 3) void ethtool_sprintf(u8 * | ||||||
|  } |  } | ||||||
|  EXPORT_SYMBOL(ethtool_sprintf); |  EXPORT_SYMBOL(ethtool_sprintf); | ||||||
|   |   | ||||||
|   | |||||||
| @@ -57,7 +57,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | |||||||
|  					  const unsigned long *advertising); |  					  const unsigned long *advertising); | ||||||
| --- a/drivers/net/phy/phylink.c | --- a/drivers/net/phy/phylink.c | ||||||
| +++ b/drivers/net/phy/phylink.c | +++ b/drivers/net/phy/phylink.c | ||||||
| @@ -931,7 +931,6 @@ static int phylink_change_inband_advert( | @@ -934,7 +934,6 @@ static int phylink_change_inband_advert( | ||||||
|   |   | ||||||
|  	return 0; |  	return 0; | ||||||
|  } |  } | ||||||
| @@ -65,7 +65,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | |||||||
|  static void phylink_mac_pcs_get_state(struct phylink *pl, |  static void phylink_mac_pcs_get_state(struct phylink *pl, | ||||||
|  				      struct phylink_link_state *state) |  				      struct phylink_link_state *state) | ||||||
|  { |  { | ||||||
| @@ -3015,6 +3014,52 @@ void phylink_mii_c22_pcs_get_state(struc | @@ -3019,6 +3018,52 @@ void phylink_mii_c22_pcs_get_state(struc | ||||||
|  EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state); |  EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state); | ||||||
|   |   | ||||||
|  /** |  /** | ||||||
| @@ -118,7 +118,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | |||||||
|   * phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS |   * phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS | ||||||
|   *	advertisement |   *	advertisement | ||||||
|   * @pcs: a pointer to a &struct mdio_device. |   * @pcs: a pointer to a &struct mdio_device. | ||||||
| @@ -3086,6 +3131,46 @@ int phylink_mii_c22_pcs_set_advertisemen | @@ -3090,6 +3135,46 @@ int phylink_mii_c22_pcs_set_advertisemen | ||||||
|  EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement); |  EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement); | ||||||
|   |   | ||||||
|  /** |  /** | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org> | |||||||
|  			sysfs_remove_link(&dev->dev.kobj, "phydev"); |  			sysfs_remove_link(&dev->dev.kobj, "phydev"); | ||||||
| --- a/include/linux/phy.h | --- a/include/linux/phy.h | ||||||
| +++ b/include/linux/phy.h | +++ b/include/linux/phy.h | ||||||
| @@ -843,6 +843,12 @@ struct phy_driver { | @@ -868,6 +868,12 @@ struct phy_driver { | ||||||
|  	/** @handle_interrupt: Override default interrupt handling */ |  	/** @handle_interrupt: Override default interrupt handling */ | ||||||
|  	irqreturn_t (*handle_interrupt)(struct phy_device *phydev); |  	irqreturn_t (*handle_interrupt)(struct phy_device *phydev); | ||||||
|   |   | ||||||
|   | |||||||
| @@ -38,19 +38,19 @@ Signed-off-by: Gabor Juhos <j4g8y7@gmail.com> | |||||||
|  	case PHY_INTERFACE_MODE_RGMII: |  	case PHY_INTERFACE_MODE_RGMII: | ||||||
| +	case PHY_INTERFACE_MODE_PSGMII: | +	case PHY_INTERFACE_MODE_PSGMII: | ||||||
|  	case PHY_INTERFACE_MODE_QSGMII: |  	case PHY_INTERFACE_MODE_QSGMII: | ||||||
|  |  	case PHY_INTERFACE_MODE_QUSGMII: | ||||||
|  	case PHY_INTERFACE_MODE_SGMII: |  	case PHY_INTERFACE_MODE_SGMII: | ||||||
|  	case PHY_INTERFACE_MODE_GMII: | @@ -636,6 +637,7 @@ static int phylink_parse_mode(struct phy | ||||||
| @@ -634,6 +635,7 @@ static int phylink_parse_mode(struct phy |  | ||||||
|   |   | ||||||
|  		switch (pl->link_config.interface) { |  		switch (pl->link_config.interface) { | ||||||
|  		case PHY_INTERFACE_MODE_SGMII: |  		case PHY_INTERFACE_MODE_SGMII: | ||||||
| +		case PHY_INTERFACE_MODE_PSGMII: | +		case PHY_INTERFACE_MODE_PSGMII: | ||||||
|  		case PHY_INTERFACE_MODE_QSGMII: |  		case PHY_INTERFACE_MODE_QSGMII: | ||||||
|  |  		case PHY_INTERFACE_MODE_QUSGMII: | ||||||
|  			phylink_set(pl->supported, 10baseT_Half); |  			phylink_set(pl->supported, 10baseT_Half); | ||||||
|  			phylink_set(pl->supported, 10baseT_Full); |  | ||||||
| --- a/include/linux/phy.h | --- a/include/linux/phy.h | ||||||
| +++ b/include/linux/phy.h | +++ b/include/linux/phy.h | ||||||
| @@ -139,6 +139,7 @@ typedef enum { | @@ -141,6 +141,7 @@ typedef enum { | ||||||
|  	PHY_INTERFACE_MODE_XGMII, |  	PHY_INTERFACE_MODE_XGMII, | ||||||
|  	PHY_INTERFACE_MODE_XLGMII, |  	PHY_INTERFACE_MODE_XLGMII, | ||||||
|  	PHY_INTERFACE_MODE_MOCA, |  	PHY_INTERFACE_MODE_MOCA, | ||||||
| @@ -58,7 +58,7 @@ Signed-off-by: Gabor Juhos <j4g8y7@gmail.com> | |||||||
|  	PHY_INTERFACE_MODE_QSGMII, |  	PHY_INTERFACE_MODE_QSGMII, | ||||||
|  	PHY_INTERFACE_MODE_TRGMII, |  	PHY_INTERFACE_MODE_TRGMII, | ||||||
|  	PHY_INTERFACE_MODE_100BASEX, |  	PHY_INTERFACE_MODE_100BASEX, | ||||||
| @@ -244,6 +245,8 @@ static inline const char *phy_modes(phy_ | @@ -248,6 +249,8 @@ static inline const char *phy_modes(phy_ | ||||||
|  		return "xlgmii"; |  		return "xlgmii"; | ||||||
|  	case PHY_INTERFACE_MODE_MOCA: |  	case PHY_INTERFACE_MODE_MOCA: | ||||||
|  		return "moca"; |  		return "moca"; | ||||||
|   | |||||||
| @@ -11,9 +11,19 @@ Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com> | |||||||
|  include/linux/phy.h | 3 +++ |  include/linux/phy.h | 3 +++ | ||||||
|  1 file changed, 3 insertions(+) |  1 file changed, 3 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/phy/phy-core.c | ||||||
|  | +++ b/drivers/net/phy/phy-core.c | ||||||
|  | @@ -136,6 +136,7 @@ int phy_interface_num_ports(phy_interfac | ||||||
|  |  	case PHY_INTERFACE_MODE_RXAUI: | ||||||
|  |  	case PHY_INTERFACE_MODE_XAUI: | ||||||
|  |  	case PHY_INTERFACE_MODE_1000BASEKX: | ||||||
|  | +	case PHY_INTERFACE_MODE_2500SGMII: | ||||||
|  |  		return 1; | ||||||
|  |  	case PHY_INTERFACE_MODE_QSGMII: | ||||||
|  |  	case PHY_INTERFACE_MODE_QUSGMII: | ||||||
| --- a/drivers/net/phy/phylink.c | --- a/drivers/net/phy/phylink.c | ||||||
| +++ b/drivers/net/phy/phylink.c | +++ b/drivers/net/phy/phylink.c | ||||||
| @@ -398,6 +398,7 @@ void phylink_get_linkmodes(unsigned long | @@ -400,6 +400,7 @@ void phylink_get_linkmodes(unsigned long | ||||||
|  		caps |= MAC_1000FD; |  		caps |= MAC_1000FD; | ||||||
|  		break; |  		break; | ||||||
|   |   | ||||||
| @@ -21,7 +31,7 @@ Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com> | |||||||
|  	case PHY_INTERFACE_MODE_2500BASEX: |  	case PHY_INTERFACE_MODE_2500BASEX: | ||||||
|  		caps |= MAC_2500FD; |  		caps |= MAC_2500FD; | ||||||
|  		break; |  		break; | ||||||
| @@ -651,6 +652,10 @@ static int phylink_parse_mode(struct phy | @@ -654,6 +655,10 @@ static int phylink_parse_mode(struct phy | ||||||
|  			phylink_set(pl->supported, 2500baseX_Full); |  			phylink_set(pl->supported, 2500baseX_Full); | ||||||
|  			break; |  			break; | ||||||
|   |   | ||||||
| @@ -34,18 +44,18 @@ Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com> | |||||||
|  			break; |  			break; | ||||||
| --- a/include/linux/phy.h | --- a/include/linux/phy.h | ||||||
| +++ b/include/linux/phy.h | +++ b/include/linux/phy.h | ||||||
| @@ -153,6 +153,7 @@ typedef enum { | @@ -157,6 +157,7 @@ typedef enum { | ||||||
|  	PHY_INTERFACE_MODE_USXGMII, |  | ||||||
|  	/* 10GBASE-KR - with Clause 73 AN */ |  | ||||||
|  	PHY_INTERFACE_MODE_10GKR, |  	PHY_INTERFACE_MODE_10GKR, | ||||||
|  |  	PHY_INTERFACE_MODE_QUSGMII, | ||||||
|  |  	PHY_INTERFACE_MODE_1000BASEKX, | ||||||
| +	PHY_INTERFACE_MODE_2500SGMII, | +	PHY_INTERFACE_MODE_2500SGMII, | ||||||
|  	PHY_INTERFACE_MODE_MAX, |  	PHY_INTERFACE_MODE_MAX, | ||||||
|  } phy_interface_t; |  } phy_interface_t; | ||||||
|   |   | ||||||
| @@ -268,6 +269,8 @@ static inline const char *phy_modes(phy_ | @@ -276,6 +277,8 @@ static inline const char *phy_modes(phy_ | ||||||
|  		return "10gbase-kr"; |  | ||||||
|  	case PHY_INTERFACE_MODE_100BASEX: |  | ||||||
|  		return "100base-x"; |  		return "100base-x"; | ||||||
|  |  	case PHY_INTERFACE_MODE_QUSGMII: | ||||||
|  |  		return "qusgmii"; | ||||||
| +	case PHY_INTERFACE_MODE_2500SGMII: | +	case PHY_INTERFACE_MODE_2500SGMII: | ||||||
| +		return "sgmii-2500"; | +		return "sgmii-2500"; | ||||||
|  	default: |  	default: | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c | |||||||
|  	phy_led_trigger_change_speed(phydev); |  	phy_led_trigger_change_speed(phydev); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -563,7 +563,7 @@ int phy_start_cable_test(struct phy_devi | @@ -591,7 +591,7 @@ int phy_start_cable_test(struct phy_devi | ||||||
|  		goto out; |  		goto out; | ||||||
|   |   | ||||||
|  	/* Mark the carrier down until the test is complete */ |  	/* Mark the carrier down until the test is complete */ | ||||||
| @@ -42,7 +42,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c | |||||||
|   |   | ||||||
|  	netif_testing_on(dev); |  	netif_testing_on(dev); | ||||||
|  	err = phydev->drv->cable_test_start(phydev); |  	err = phydev->drv->cable_test_start(phydev); | ||||||
| @@ -634,7 +634,7 @@ int phy_start_cable_test_tdr(struct phy_ | @@ -662,7 +662,7 @@ int phy_start_cable_test_tdr(struct phy_ | ||||||
|  		goto out; |  		goto out; | ||||||
|   |   | ||||||
|  	/* Mark the carrier down until the test is complete */ |  	/* Mark the carrier down until the test is complete */ | ||||||
| @@ -51,7 +51,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c | |||||||
|   |   | ||||||
|  	netif_testing_on(dev); |  	netif_testing_on(dev); | ||||||
|  	err = phydev->drv->cable_test_tdr_start(phydev, config); |  	err = phydev->drv->cable_test_tdr_start(phydev, config); | ||||||
| @@ -706,7 +706,7 @@ static int phy_check_link_status(struct | @@ -734,7 +734,7 @@ static int phy_check_link_status(struct | ||||||
|  		phy_link_up(phydev); |  		phy_link_up(phydev); | ||||||
|  	} else if (!phydev->link && phydev->state != PHY_NOLINK) { |  	} else if (!phydev->link && phydev->state != PHY_NOLINK) { | ||||||
|  		phydev->state = PHY_NOLINK; |  		phydev->state = PHY_NOLINK; | ||||||
| @@ -60,7 +60,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c | |||||||
|  	} |  	} | ||||||
|   |   | ||||||
|  	return 0; |  	return 0; | ||||||
| @@ -1192,7 +1192,7 @@ void phy_state_machine(struct work_struc | @@ -1220,7 +1220,7 @@ void phy_state_machine(struct work_struc | ||||||
|  	case PHY_HALTED: |  	case PHY_HALTED: | ||||||
|  		if (phydev->link) { |  		if (phydev->link) { | ||||||
|  			phydev->link = 0; |  			phydev->link = 0; | ||||||
| @@ -95,7 +95,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c | |||||||
|  		phydev->mii_ts->link_state(phydev->mii_ts, phydev); |  		phydev->mii_ts->link_state(phydev->mii_ts, phydev); | ||||||
| --- a/drivers/net/phy/phylink.c | --- a/drivers/net/phy/phylink.c | ||||||
| +++ b/drivers/net/phy/phylink.c | +++ b/drivers/net/phy/phylink.c | ||||||
| @@ -1370,7 +1370,8 @@ void phylink_destroy(struct phylink *pl) | @@ -1373,7 +1373,8 @@ void phylink_destroy(struct phylink *pl) | ||||||
|  } |  } | ||||||
|  EXPORT_SYMBOL_GPL(phylink_destroy); |  EXPORT_SYMBOL_GPL(phylink_destroy); | ||||||
|   |   | ||||||
| @@ -107,7 +107,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c | |||||||
|  	bool tx_pause, rx_pause; |  	bool tx_pause, rx_pause; | ||||||
| --- a/include/linux/phy.h | --- a/include/linux/phy.h | ||||||
| +++ b/include/linux/phy.h | +++ b/include/linux/phy.h | ||||||
| @@ -706,7 +706,7 @@ struct phy_device { | @@ -716,7 +716,7 @@ struct phy_device { | ||||||
|  	u8 mdix; |  	u8 mdix; | ||||||
|  	u8 mdix_ctrl; |  	u8 mdix_ctrl; | ||||||
|   |   | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org> | |||||||
|  |  | ||||||
| --- a/drivers/net/phy/phy.c | --- a/drivers/net/phy/phy.c | ||||||
| +++ b/drivers/net/phy/phy.c | +++ b/drivers/net/phy/phy.c | ||||||
| @@ -706,7 +706,10 @@ static int phy_check_link_status(struct | @@ -734,7 +734,10 @@ static int phy_check_link_status(struct | ||||||
|  		phy_link_up(phydev); |  		phy_link_up(phydev); | ||||||
|  	} else if (!phydev->link && phydev->state != PHY_NOLINK) { |  	} else if (!phydev->link && phydev->state != PHY_NOLINK) { | ||||||
|  		phydev->state = PHY_NOLINK; |  		phydev->state = PHY_NOLINK; | ||||||
| @@ -23,7 +23,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org> | |||||||
|  	} |  	} | ||||||
|   |   | ||||||
|  	return 0; |  	return 0; | ||||||
| @@ -1192,7 +1195,10 @@ void phy_state_machine(struct work_struc | @@ -1220,7 +1223,10 @@ void phy_state_machine(struct work_struc | ||||||
|  	case PHY_HALTED: |  	case PHY_HALTED: | ||||||
|  		if (phydev->link) { |  		if (phydev->link) { | ||||||
|  			phydev->link = 0; |  			phydev->link = 0; | ||||||
| @@ -37,7 +37,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org> | |||||||
|  		break; |  		break; | ||||||
| --- a/include/linux/phy.h | --- a/include/linux/phy.h | ||||||
| +++ b/include/linux/phy.h | +++ b/include/linux/phy.h | ||||||
| @@ -622,6 +622,7 @@ struct phy_device { | @@ -630,6 +630,7 @@ struct phy_device { | ||||||
|  	unsigned downshifted_rate:1; |  	unsigned downshifted_rate:1; | ||||||
|  	unsigned is_on_sfp_module:1; |  	unsigned is_on_sfp_module:1; | ||||||
|  	unsigned mac_managed_pm:1; |  	unsigned mac_managed_pm:1; | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ Submitted-by: John Crispin <john@phrozen.org> | |||||||
|  |  | ||||||
| --- a/include/linux/phy.h | --- a/include/linux/phy.h | ||||||
| +++ b/include/linux/phy.h | +++ b/include/linux/phy.h | ||||||
| @@ -984,6 +984,10 @@ struct phy_driver { | @@ -1009,6 +1009,10 @@ struct phy_driver { | ||||||
|  	int (*led_blink_set)(struct phy_device *dev, u8 index, |  	int (*led_blink_set)(struct phy_device *dev, u8 index, | ||||||
|  			     unsigned long *delay_on, |  			     unsigned long *delay_on, | ||||||
|  			     unsigned long *delay_off); |  			     unsigned long *delay_off); | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ Submitted-by: John Crispin <john@phrozen.org> | |||||||
|  |  | ||||||
| --- a/drivers/net/phy/phylink.c | --- a/drivers/net/phy/phylink.c | ||||||
| +++ b/drivers/net/phy/phylink.c | +++ b/drivers/net/phy/phylink.c | ||||||
| @@ -1991,6 +1991,11 @@ int phylink_ethtool_ksettings_set(struct | @@ -1994,6 +1994,11 @@ int phylink_ethtool_ksettings_set(struct | ||||||
|  		 *   the presence of a PHY, this should not be changed as that |  		 *   the presence of a PHY, this should not be changed as that | ||||||
|  		 *   should be determined from the media side advertisement. |  		 *   should be determined from the media side advertisement. | ||||||
|  		 */ |  		 */ | ||||||
| @@ -33,7 +33,7 @@ Submitted-by: John Crispin <john@phrozen.org> | |||||||
|  		return phy_ethtool_ksettings_set(pl->phydev, kset); |  		return phy_ethtool_ksettings_set(pl->phydev, kset); | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @@ -2294,8 +2299,11 @@ int phylink_ethtool_get_eee(struct phyli | @@ -2297,8 +2302,11 @@ int phylink_ethtool_get_eee(struct phyli | ||||||
|   |   | ||||||
|  	ASSERT_RTNL(); |  	ASSERT_RTNL(); | ||||||
|   |   | ||||||
| @@ -46,7 +46,7 @@ Submitted-by: John Crispin <john@phrozen.org> | |||||||
|   |   | ||||||
|  	return ret; |  	return ret; | ||||||
|  } |  } | ||||||
| @@ -2312,8 +2320,11 @@ int phylink_ethtool_set_eee(struct phyli | @@ -2315,8 +2323,11 @@ int phylink_ethtool_set_eee(struct phyli | ||||||
|   |   | ||||||
|  	ASSERT_RTNL(); |  	ASSERT_RTNL(); | ||||||
|   |   | ||||||
|   | |||||||
| @@ -13,9 +13,19 @@ Submitted-by: Birger Koblitz <git@birger-koblitz.de> | |||||||
|  include/linux/phy.h                           | 3 +++ |  include/linux/phy.h                           | 3 +++ | ||||||
|  2 file changed, 5 insertions(+) |  2 file changed, 5 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/phy/phy-core.c | ||||||
|  | +++ b/drivers/net/phy/phy-core.c | ||||||
|  | @@ -124,6 +124,7 @@ int phy_interface_num_ports(phy_interfac | ||||||
|  |  	case PHY_INTERFACE_MODE_MOCA: | ||||||
|  |  	case PHY_INTERFACE_MODE_TRGMII: | ||||||
|  |  	case PHY_INTERFACE_MODE_USXGMII: | ||||||
|  | +	case PHY_INTERFACE_MODE_HSGMII: | ||||||
|  |  	case PHY_INTERFACE_MODE_SGMII: | ||||||
|  |  	case PHY_INTERFACE_MODE_SMII: | ||||||
|  |  	case PHY_INTERFACE_MODE_1000BASEX: | ||||||
| --- a/drivers/net/phy/phylink.c | --- a/drivers/net/phy/phylink.c | ||||||
| +++ b/drivers/net/phy/phylink.c | +++ b/drivers/net/phy/phylink.c | ||||||
| @@ -408,6 +408,7 @@ void phylink_get_linkmodes(unsigned long | @@ -410,6 +410,7 @@ void phylink_get_linkmodes(unsigned long | ||||||
|   |   | ||||||
|  	case PHY_INTERFACE_MODE_XGMII: |  	case PHY_INTERFACE_MODE_XGMII: | ||||||
|  	case PHY_INTERFACE_MODE_RXAUI: |  	case PHY_INTERFACE_MODE_RXAUI: | ||||||
| @@ -23,7 +33,7 @@ Submitted-by: Birger Koblitz <git@birger-koblitz.de> | |||||||
|  	case PHY_INTERFACE_MODE_XAUI: |  	case PHY_INTERFACE_MODE_XAUI: | ||||||
|  	case PHY_INTERFACE_MODE_10GBASER: |  	case PHY_INTERFACE_MODE_10GBASER: | ||||||
|  	case PHY_INTERFACE_MODE_10GKR: |  	case PHY_INTERFACE_MODE_10GKR: | ||||||
| @@ -662,6 +663,7 @@ static int phylink_parse_mode(struct phy | @@ -665,6 +666,7 @@ static int phylink_parse_mode(struct phy | ||||||
|  			fallthrough; |  			fallthrough; | ||||||
|  		case PHY_INTERFACE_MODE_USXGMII: |  		case PHY_INTERFACE_MODE_USXGMII: | ||||||
|  		case PHY_INTERFACE_MODE_10GKR: |  		case PHY_INTERFACE_MODE_10GKR: | ||||||
| @@ -33,7 +43,7 @@ Submitted-by: Birger Koblitz <git@birger-koblitz.de> | |||||||
|  			phylink_set(pl->supported, 10baseT_Full); |  			phylink_set(pl->supported, 10baseT_Full); | ||||||
| --- a/include/linux/phy.h | --- a/include/linux/phy.h | ||||||
| +++ b/include/linux/phy.h | +++ b/include/linux/phy.h | ||||||
| @@ -139,6 +139,7 @@ typedef enum { | @@ -141,6 +141,7 @@ typedef enum { | ||||||
|  	PHY_INTERFACE_MODE_XGMII, |  	PHY_INTERFACE_MODE_XGMII, | ||||||
|  	PHY_INTERFACE_MODE_XLGMII, |  	PHY_INTERFACE_MODE_XLGMII, | ||||||
|  	PHY_INTERFACE_MODE_MOCA, |  	PHY_INTERFACE_MODE_MOCA, | ||||||
| @@ -41,7 +51,7 @@ Submitted-by: Birger Koblitz <git@birger-koblitz.de> | |||||||
|  	PHY_INTERFACE_MODE_QSGMII, |  	PHY_INTERFACE_MODE_QSGMII, | ||||||
|  	PHY_INTERFACE_MODE_TRGMII, |  	PHY_INTERFACE_MODE_TRGMII, | ||||||
|  	PHY_INTERFACE_MODE_100BASEX, |  	PHY_INTERFACE_MODE_100BASEX, | ||||||
| @@ -244,6 +245,8 @@ static inline const char *phy_modes(phy_ | @@ -248,6 +249,8 @@ static inline const char *phy_modes(phy_ | ||||||
|  		return "xlgmii"; |  		return "xlgmii"; | ||||||
|  	case PHY_INTERFACE_MODE_MOCA: |  	case PHY_INTERFACE_MODE_MOCA: | ||||||
|  		return "moca"; |  		return "moca"; | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ Submitted-by: John Crispin <john@phrozen.org> | |||||||
|  |  | ||||||
| --- a/include/linux/phy.h | --- a/include/linux/phy.h | ||||||
| +++ b/include/linux/phy.h | +++ b/include/linux/phy.h | ||||||
| @@ -280,7 +280,7 @@ static inline const char *phy_modes(phy_ | @@ -287,7 +287,7 @@ static inline const char *phy_modes(phy_ | ||||||
|  #define PHY_INIT_TIMEOUT	100000 |  #define PHY_INIT_TIMEOUT	100000 | ||||||
|  #define PHY_FORCE_TIMEOUT	10 |  #define PHY_FORCE_TIMEOUT	10 | ||||||
|   |   | ||||||
|   | |||||||
| @@ -443,7 +443,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | |||||||
|   * @dev: target MDIO device |   * @dev: target MDIO device | ||||||
| --- a/drivers/net/phy/phy-core.c | --- a/drivers/net/phy/phy-core.c | ||||||
| +++ b/drivers/net/phy/phy-core.c | +++ b/drivers/net/phy/phy-core.c | ||||||
| @@ -482,10 +482,16 @@ int __phy_read_mmd(struct phy_device *ph | @@ -557,10 +557,16 @@ int __phy_read_mmd(struct phy_device *ph | ||||||
|  		struct mii_bus *bus = phydev->mdio.bus; |  		struct mii_bus *bus = phydev->mdio.bus; | ||||||
|  		int phy_addr = phydev->mdio.addr; |  		int phy_addr = phydev->mdio.addr; | ||||||
|   |   | ||||||
| @@ -464,7 +464,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | |||||||
|  	} |  	} | ||||||
|  	return val; |  	return val; | ||||||
|  } |  } | ||||||
| @@ -538,12 +544,18 @@ int __phy_write_mmd(struct phy_device *p | @@ -613,12 +619,18 @@ int __phy_write_mmd(struct phy_device *p | ||||||
|  		struct mii_bus *bus = phydev->mdio.bus; |  		struct mii_bus *bus = phydev->mdio.bus; | ||||||
|  		int phy_addr = phydev->mdio.addr; |  		int phy_addr = phydev->mdio.addr; | ||||||
|   |   | ||||||
| @@ -487,7 +487,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | |||||||
|  	} |  	} | ||||||
|  	return ret; |  	return ret; | ||||||
|  } |  } | ||||||
| @@ -749,6 +761,13 @@ EXPORT_SYMBOL_GPL(phy_modify_mmd); | @@ -824,6 +836,13 @@ EXPORT_SYMBOL_GPL(phy_modify_mmd); | ||||||
|   |   | ||||||
|  static int __phy_read_page(struct phy_device *phydev) |  static int __phy_read_page(struct phy_device *phydev) | ||||||
|  { |  { | ||||||
| @@ -501,7 +501,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | |||||||
|  	if (WARN_ONCE(!phydev->drv->read_page, "read_page callback not available, PHY driver not loaded?\n")) |  	if (WARN_ONCE(!phydev->drv->read_page, "read_page callback not available, PHY driver not loaded?\n")) | ||||||
|  		return -EOPNOTSUPP; |  		return -EOPNOTSUPP; | ||||||
|   |   | ||||||
| @@ -757,6 +776,13 @@ static int __phy_read_page(struct phy_de | @@ -832,6 +851,13 @@ static int __phy_read_page(struct phy_de | ||||||
|   |   | ||||||
|  static int __phy_write_page(struct phy_device *phydev, int page) |  static int __phy_write_page(struct phy_device *phydev, int page) | ||||||
|  { |  { | ||||||
| @@ -515,7 +515,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | |||||||
|  	if (WARN_ONCE(!phydev->drv->write_page, "write_page callback not available, PHY driver not loaded?\n")) |  	if (WARN_ONCE(!phydev->drv->write_page, "write_page callback not available, PHY driver not loaded?\n")) | ||||||
|  		return -EOPNOTSUPP; |  		return -EOPNOTSUPP; | ||||||
|   |   | ||||||
| @@ -858,6 +884,18 @@ int phy_read_paged(struct phy_device *ph | @@ -933,6 +959,18 @@ int phy_read_paged(struct phy_device *ph | ||||||
|  { |  { | ||||||
|  	int ret = 0, oldpage; |  	int ret = 0, oldpage; | ||||||
|   |   | ||||||
| @@ -534,7 +534,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | |||||||
|  	oldpage = phy_select_page(phydev, page); |  	oldpage = phy_select_page(phydev, page); | ||||||
|  	if (oldpage >= 0) |  	if (oldpage >= 0) | ||||||
|  		ret = __phy_read(phydev, regnum); |  		ret = __phy_read(phydev, regnum); | ||||||
| @@ -879,6 +917,18 @@ int phy_write_paged(struct phy_device *p | @@ -954,6 +992,18 @@ int phy_write_paged(struct phy_device *p | ||||||
|  { |  { | ||||||
|  	int ret = 0, oldpage; |  	int ret = 0, oldpage; | ||||||
|   |   | ||||||
| @@ -665,7 +665,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | |||||||
|  #define MDIO_DEVICE_IS_PHY	0x80000000 |  #define MDIO_DEVICE_IS_PHY	0x80000000 | ||||||
|   |   | ||||||
|  /** |  /** | ||||||
| @@ -421,6 +422,22 @@ struct mii_bus { | @@ -428,6 +429,22 @@ struct mii_bus { | ||||||
|   |   | ||||||
|  	/** @shared: shared state across different PHYs */ |  	/** @shared: shared state across different PHYs */ | ||||||
|  	struct phy_package_shared *shared[PHY_MAX_ADDR]; |  	struct phy_package_shared *shared[PHY_MAX_ADDR]; | ||||||
| @@ -688,7 +688,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | |||||||
|  }; |  }; | ||||||
|  #define to_mii_bus(d) container_of(d, struct mii_bus, dev) |  #define to_mii_bus(d) container_of(d, struct mii_bus, dev) | ||||||
|   |   | ||||||
| @@ -1795,6 +1812,66 @@ static inline int __phy_package_read(str | @@ -1825,6 +1842,66 @@ static inline int __phy_package_read(str | ||||||
|  	return __mdiobus_read(phydev->mdio.bus, shared->addr, regnum); |  	return __mdiobus_read(phydev->mdio.bus, shared->addr, regnum); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -755,7 +755,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | |||||||
|  static inline int phy_package_write(struct phy_device *phydev, |  static inline int phy_package_write(struct phy_device *phydev, | ||||||
|  				    u32 regnum, u16 val) |  				    u32 regnum, u16 val) | ||||||
|  { |  { | ||||||
| @@ -1817,6 +1894,72 @@ static inline int __phy_package_write(st | @@ -1847,6 +1924,72 @@ static inline int __phy_package_write(st | ||||||
|  	return __mdiobus_write(phydev->mdio.bus, shared->addr, regnum, val); |  	return __mdiobus_write(phydev->mdio.bus, shared->addr, regnum, val); | ||||||
|  } |  } | ||||||
|   |   | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Rafał Miłecki
					Rafał Miłecki