aboutsummaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorDavid S. Miller <[email protected]>2022-09-23 11:56:36 +0100
committerDavid S. Miller <[email protected]>2022-09-23 11:56:36 +0100
commit793cc3c78e828d26723433c590cd90d20fc91011 (patch)
treef3f3c4f1eaefb00d82b712c0e0c6bd6fb920514b /include/linux
parent1a4019f4922ea33547eb7f7a84616cd74045a4e2 (diff)
parent3c42563b30417afc8855a3b4c1b38c2f36f78657 (diff)
Merge branch 'phy-rate-matching'
Sean Anderson says: ==================== net: phy: Add support for rate matching This adds support for phy rate matching: when a phy adapts between differing phy interface and link speeds. It was originally submitted as part of [1], which is considered "v1" of this series. Several past discussions [2-4] around adding rate adaptation provide some context. Although in earlier versions of this series, userspace could disable rate matching, now it is only possible to determine the current rate adaptation type. Disabling or otherwise configuring rate adaptation has been left for future work. However, because currently only RATE_MATCH_PAUSE is implemented, it is possible to disable rate adaptation by modifying the advertisement appropriately. [1] https://lore.kernel.org/netdev/[email protected]/T/#t [2] https://lore.kernel.org/netdev/[email protected]/ [3] https://lore.kernel.org/netdev/[email protected]/ [4] https://lore.kernel.org/netdev/[email protected]/ Changes in v6: - Don't announce that we've enabled pause frames for rate adaptation - Merry Christmas - Rename rate adaptation to rate matching - Reword documentation, (hopefully) taking into account feedback Changes in v5: - Break off patch "net: phy: Add 1000BASE-KX interface mode" for separate submission. - Document phy_rate_adaptation_to_str - Drop patch "Add some helpers for working with mac caps"; it has been incorperated into the autonegotiation patch. - Move phylink_cap_from_speed_duplex to this commit - Rebase onto net-next/master - Remove unnecessary comma Changes in v4: - Export phy_rate_adaptation_to_str - Remove phylink_interface_max_speed, which was accidentally added - Split off the LS1046ARDB 1G fix Changes in v3: - Add phylink_cap_from_speed_duplex to look up the mac capability corresponding to the interface's speed. - Document MAC_(A)SYM_PAUSE - Include RATE_ADAPT_CRS; it's a few lines and it doesn't hurt. - Modify link settings directly in phylink_link_up, instead of doing things more indirectly via link_*. - Move unused defines to next commit (where they will be used) - Remove "Support differing link/interface speed/duplex". It has been rendered unnecessary due to simplification of the rate adaptation patches. Thanks Russell! - Rewrite cover letter to better reflect the opinions of the developers involved Changes in v2: - Add (read-only) ethtool support for rate adaptation - Add comments clarifying the register defines - Add locking to phy_get_rate_adaptation - Always use the rate adaptation setting to determine the interface speed/duplex (instead of sometimes using the interface mode). - Determine the interface speed and max mac speed directly instead of guessing based on the caps. - Move part of commit message to cover letter, as it gives a good overview of the whole series, and allows this patch to focus more on the specifics. - Reorder variables in aqr107_read_rate - Use int/defines instead of enum to allow for use in ioctls/netlink - Use the phy's rate adaptation setting to determine whether to use its link speed/duplex or the MAC's speed/duplex with MLO_AN_INBAND. ==================== Signed-off-by: David S. Miller <[email protected]>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/phy.h22
-rw-r--r--include/linux/phylink.h40
2 files changed, 59 insertions, 3 deletions
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 337230c135f7..9c66f357f489 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -280,7 +280,6 @@ static inline const char *phy_modes(phy_interface_t interface)
}
}
-
#define PHY_INIT_TIMEOUT 100000
#define PHY_FORCE_TIMEOUT 10
@@ -574,6 +573,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
@@ -641,6 +641,8 @@ struct phy_device {
unsigned irq_suspended:1;
unsigned irq_rerun:1;
+ int rate_matching;
+
enum phy_state state;
u32 dev_flags;
@@ -805,6 +807,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);
@@ -971,6 +988,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);
@@ -1687,6 +1705,8 @@ int phy_disable_interrupts(struct phy_device *phydev);
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);
void 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);
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 6d06896fc20d..664dd409feb9 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -21,6 +21,35 @@ enum {
MLO_AN_FIXED, /* Fixed-link mode */
MLO_AN_INBAND, /* In-band protocol */
+ /* MAC_SYM_PAUSE and MAC_ASYM_PAUSE are used when configuring our
+ * autonegotiation advertisement. They correspond to the PAUSE and
+ * ASM_DIR bits defined by 802.3, respectively.
+ *
+ * The following table lists the values of tx_pause and rx_pause which
+ * might be requested in mac_link_up. The exact values depend on either
+ * the results of autonegotation (if MLO_PAUSE_AN is set) or user
+ * configuration (if MLO_PAUSE_AN is not set).
+ *
+ * MAC_SYM_PAUSE MAC_ASYM_PAUSE MLO_PAUSE_AN tx_pause/rx_pause
+ * ============= ============== ============ ==================
+ * 0 0 0 0/0
+ * 0 0 1 0/0
+ * 0 1 0 0/0, 0/1, 1/0, 1/1
+ * 0 1 1 0/0, 1/0
+ * 1 0 0 0/0, 1/1
+ * 1 0 1 0/0, 1/1
+ * 1 1 0 0/0, 0/1, 1/0, 1/1
+ * 1 1 1 0/0, 0/1, 1/1
+ *
+ * If you set MAC_ASYM_PAUSE, the user may request any combination of
+ * tx_pause and rx_pause. You do not have to support these
+ * combinations.
+ *
+ * However, you should support combinations of tx_pause and rx_pause
+ * which might be the result of autonegotation. For example, don't set
+ * MAC_SYM_PAUSE unless your device can support tx_pause and rx_pause
+ * at the same time.
+ */
MAC_SYM_PAUSE = BIT(0),
MAC_ASYM_PAUSE = BIT(1),
MAC_10HD = BIT(2),
@@ -59,6 +88,10 @@ static inline bool phylink_autoneg_inband(unsigned int mode)
* @speed: link speed, one of the SPEED_* constants.
* @duplex: link duplex mode, one of DUPLEX_* constants.
* @pause: link pause state, described by MLO_PAUSE_* constants.
+ * @rate_matching: rate matching being performed, one of the RATE_MATCH_*
+ * constants. If rate matching is taking place, then the speed/duplex of
+ * the medium link mode (@speed and @duplex) and the speed/duplex of the phy
+ * interface mode (@interface) are different.
* @link: true if the link is up.
* @an_enabled: true if autonegotiation is enabled/desired.
* @an_complete: true if autonegotiation has completed.
@@ -70,6 +103,7 @@ struct phylink_link_state {
int speed;
int duplex;
int pause;
+ int rate_matching;
unsigned int link:1;
unsigned int an_enabled:1;
unsigned int an_complete:1;
@@ -518,8 +552,10 @@ void pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
phy_interface_t interface, int speed, int duplex);
#endif
-void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface,
- unsigned long mac_capabilities);
+void phylink_caps_to_linkmodes(unsigned long *linkmodes, unsigned long caps);
+unsigned long phylink_get_capabilities(phy_interface_t interface,
+ unsigned long mac_capabilities,
+ int rate_matching);
void phylink_generic_validate(struct phylink_config *config,
unsigned long *supported,
struct phylink_link_state *state);