diff options
Diffstat (limited to 'include/linux/phylink.h')
-rw-r--r-- | include/linux/phylink.h | 177 |
1 files changed, 130 insertions, 47 deletions
diff --git a/include/linux/phylink.h b/include/linux/phylink.h index 8664b3442a3a..2f8efd3aff10 100644 --- a/include/linux/phylink.h +++ b/include/linux/phylink.h @@ -95,24 +95,9 @@ enum { MAC_400000FD = BIT(18), }; -static inline bool phylink_mode_inband(unsigned int mode) -{ - return mode == MLO_AN_INBAND; -} - -static inline bool phylink_mode_fixed(unsigned int mode) -{ - return mode == MLO_AN_FIXED; -} - -static inline bool phylink_mode_phy(unsigned int mode) -{ - return mode == MLO_AN_PHY; -} - static inline bool phylink_autoneg_inband(unsigned int mode) { - return phylink_mode_inband(mode); + return mode == MLO_AN_INBAND; } /** @@ -155,31 +140,39 @@ enum phylink_op_type { * @poll_fixed_state: if true, starts link_poll, * if MAC link is at %MLO_AN_FIXED mode. * @mac_managed_pm: if true, indicate the MAC driver is responsible for PHY PM. - * @ovr_an_inband: if true, override PCS to MLO_AN_INBAND - * @eee_clk_stop_enable: if true, PHY can stop the receive clock during LPI + * @mac_requires_rxc: if true, the MAC always requires a receive clock from PHY. + * The PHY driver should start the clock signal as soon as + * possible and avoid stopping it during suspend events. + * @default_an_inband: if true, defaults to MLO_AN_INBAND rather than + * MLO_AN_PHY. A fixed-link specification will override. + * @eee_rx_clk_stop_enable: if true, PHY can stop the receive clock during LPI * @get_fixed_state: callback to execute to determine the fixed link state, * if MAC link is at %MLO_AN_FIXED mode. * @supported_interfaces: bitmap describing which PHY_INTERFACE_MODE_xxx * are supported by the MAC/PCS. + * @lpi_interfaces: bitmap describing which PHY interface modes can support + * LPI signalling. * @mac_capabilities: MAC pause/speed/duplex capabilities. * @lpi_capabilities: MAC speeds which can support LPI signalling - * @eee: default EEE configuration. - * @lpi_timer_limit_us: Maximum (inclusive) value of the EEE LPI timer. + * @lpi_timer_default: Default EEE LPI timer setting. + * @eee_enabled_default: If set, EEE will be enabled by phylink at creation time */ struct phylink_config { struct device *dev; enum phylink_op_type type; bool poll_fixed_state; bool mac_managed_pm; - bool ovr_an_inband; - bool eee_clk_stop_enable; + bool mac_requires_rxc; + bool default_an_inband; + bool eee_rx_clk_stop_enable; void (*get_fixed_state)(struct phylink_config *config, struct phylink_link_state *state); DECLARE_PHY_INTERFACE_MASK(supported_interfaces); + DECLARE_PHY_INTERFACE_MASK(lpi_interfaces); unsigned long mac_capabilities; unsigned long lpi_capabilities; - struct eee_config eee; - u32 lpi_timer_limit_us; + u32 lpi_timer_default; + bool eee_enabled_default; }; void phylink_limit_mac_speed(struct phylink_config *config, u32 max_speed); @@ -215,8 +208,11 @@ struct phylink_mac_ops { struct phy_device *phy, unsigned int mode, phy_interface_t interface, int speed, int duplex, bool tx_pause, bool rx_pause); - void (*mac_disable_tx_lpi)(struct phylink_config *config); - void (*mac_enable_tx_lpi)(struct phylink_config *config, u32 timer); + void (*mac_disable_tx_lpi)(struct phylink_config *config, + phy_interface_t interface); + int (*mac_enable_tx_lpi)(struct phylink_config *config, + phy_interface_t interface, u32 timer, + bool tx_clk_stop); }; #if 0 /* For kernel-doc purposes only. */ @@ -415,34 +411,48 @@ void mac_link_up(struct phylink_config *config, struct phy_device *phy, /** * mac_disable_tx_lpi() - disable LPI generation at the MAC * @config: a pointer to a &struct phylink_config. + * @interface: current link &typedef phy_interface_t mode * * Disable generation of LPI at the MAC, effectively preventing the MAC * from indicating that it is idle. */ -void mac_disable_tx_lpi(struct phylink_config *config); +void mac_disable_tx_lpi(struct phylink_config *config, + phy_interface_t interface); /** * mac_enable_tx_lpi() - configure and enable LPI generation at the MAC * @config: a pointer to a &struct phylink_config. + * @interface: current link &typedef phy_interface_t mode * @timer: LPI timeout in microseconds. + * @tx_clk_stop: allow xMII transmit clock to be stopped during LPI * * Configure the LPI timeout accordingly. This will only be called when * the link is already up, to cater for situations where the hardware * needs to be programmed according to the link speed. * - * Enable LPI generation at the MAC. + * Enable LPI generation at the MAC, and configure whether the xMII transmit + * clock may be stopped. + * + * Returns: 0 on success. Please consult with rmk before returning an error. */ -void mac_enable_tx_lpi(struct phylink_config *config, u32 timer); +int mac_enable_tx_lpi(struct phylink_config *config, phy_interface_t interface, + u32 timer, bool tx_clk_stop); #endif struct phylink_pcs_ops; /** * struct phylink_pcs - PHYLINK PCS instance + * @supported_interfaces: describing which PHY_INTERFACE_MODE_xxx + * are supported by this PCS. * @ops: a pointer to the &struct phylink_pcs_ops structure * @phylink: pointer to &struct phylink_config * @neg_mode: provide PCS neg mode via "mode" argument * @poll: poll the PCS for link changes + * @rxc_always_on: The MAC driver requires the reference clock + * to always be on. Standalone PCS drivers which + * do not have access to a PHY device can check + * this instead of PHY_F_RXC_ALWAYS_ON. * * This structure is designed to be embedded within the PCS private data, * and will be passed between phylink and the PCS. @@ -451,16 +461,18 @@ struct phylink_pcs_ops; * the PCS driver. */ struct phylink_pcs { + DECLARE_PHY_INTERFACE_MASK(supported_interfaces); const struct phylink_pcs_ops *ops; struct phylink *phylink; bool neg_mode; bool poll; + bool rxc_always_on; }; /** * struct phylink_pcs_ops - MAC PCS operations structure. * @pcs_validate: validate the link configuration. - * @pcs_query_inband: query inband support for interface mode. + * @pcs_inband_caps: query inband support for interface mode. * @pcs_enable: enable the PCS. * @pcs_disable: disable the PCS. * @pcs_pre_config: pre-mac_config method (for errata) @@ -470,20 +482,25 @@ struct phylink_pcs { * @pcs_an_restart: restart 802.3z BaseX autonegotiation. * @pcs_link_up: program the PCS for the resolved link configuration * (where necessary). + * @pcs_disable_eee: optional notification to PCS that EEE has been disabled + * at the MAC. + * @pcs_enable_eee: optional notification to PCS that EEE will be enabled at + * the MAC. + * @pcs_pre_init: configure PCS components necessary for MAC hardware + * initialization e.g. RX clock for stmmac. */ struct phylink_pcs_ops { - int (*pcs_validate)(struct phylink_pcs *pcs, unsigned int mode, - unsigned long *supported, + int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported, const struct phylink_link_state *state); - unsigned int (*pcs_query_inband)(struct phylink_pcs *pcs, - phy_interface_t interface); + unsigned int (*pcs_inband_caps)(struct phylink_pcs *pcs, + phy_interface_t interface); int (*pcs_enable)(struct phylink_pcs *pcs); void (*pcs_disable)(struct phylink_pcs *pcs); void (*pcs_pre_config)(struct phylink_pcs *pcs, phy_interface_t interface); int (*pcs_post_config)(struct phylink_pcs *pcs, phy_interface_t interface); - void (*pcs_get_state)(struct phylink_pcs *pcs, + void (*pcs_get_state)(struct phylink_pcs *pcs, unsigned int neg_mode, struct phylink_link_state *state); int (*pcs_config)(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, @@ -492,13 +509,15 @@ struct phylink_pcs_ops { void (*pcs_an_restart)(struct phylink_pcs *pcs); void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, int speed, int duplex); + void (*pcs_disable_eee)(struct phylink_pcs *pcs); + void (*pcs_enable_eee)(struct phylink_pcs *pcs); + int (*pcs_pre_init)(struct phylink_pcs *pcs); }; #if 0 /* For kernel-doc purposes only. */ /** * pcs_validate() - validate the link configuration. * @pcs: a pointer to a &struct phylink_pcs. - * @mode: link autonegotiation mode * @supported: ethtool bitmask for supported link modes. * @state: a const pointer to a &struct phylink_link_state. * @@ -510,11 +529,11 @@ struct phylink_pcs_ops { * Returns -EINVAL if the interface mode/autoneg mode is not supported. * Returns non-zero positive if the link state can be supported. */ -int pcs_validate(struct phylink_pcs *pcs, unsigned int mode, - unsigned long *supported, struct phylink_link_state *state); +int pcs_validate(struct phylink_pcs *pcs, unsigned long *supported, + const struct phylink_link_state *state); /** - * pcs_query_inband - query inband support for interface mode. + * pcs_inband_caps - query PCS in-band capabilities for interface mode. * @pcs: a pointer to a &struct phylink_pcs. * @interface: interface mode to be queried * @@ -524,8 +543,8 @@ int pcs_validate(struct phylink_pcs *pcs, unsigned int mode, * &enum link_inband_signalling to describe which inband modes are supported * for this interface mode. */ -unsigned int pcs_query_inband(struct phylink_pcs *pcs, - phy_interface_t interface); +unsigned int pcs_inband_caps(struct phylink_pcs *pcs, + phy_interface_t interface); /** * pcs_enable() - enable the PCS. @@ -542,6 +561,7 @@ void pcs_disable(struct phylink_pcs *pcs); /** * pcs_get_state() - Read the current inband link state from the hardware * @pcs: a pointer to a &struct phylink_pcs. + * @neg_mode: link negotiation mode (PHYLINK_PCS_NEG_xxx) * @state: a pointer to a &struct phylink_link_state. * * Read the current inband link state from the MAC PCS, reporting the @@ -551,10 +571,10 @@ void pcs_disable(struct phylink_pcs *pcs); * in @state->link. If possible, @state->lp_advertising should also be * populated. * - * When present, this overrides pcs_get_state() in &struct - * phylink_pcs_ops. + * Note that the @neg_mode parameter is always the PHYLINK_PCS_NEG_xxx + * state, not MLO_AN_xxx. */ -void pcs_get_state(struct phylink_pcs *pcs, +void pcs_get_state(struct phylink_pcs *pcs, unsigned int neg_mode, struct phylink_link_state *state); /** @@ -615,6 +635,50 @@ void pcs_an_restart(struct phylink_pcs *pcs); */ void pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, int speed, int duplex); + +/** + * pcs_disable_eee() - Disable EEE at the PCS + * @pcs: a pointer to a &struct phylink_pcs + * + * Optional method informing the PCS that EEE has been disabled at the MAC. + */ +void pcs_disable_eee(struct phylink_pcs *pcs); + +/** + * pcs_enable_eee() - Enable EEE at the PCS + * @pcs: a pointer to a &struct phylink_pcs + * + * Optional method informing the PCS that EEE is about to be enabled at the MAC. + */ +void pcs_enable_eee(struct phylink_pcs *pcs); + +/** + * pcs_pre_init() - Configure PCS components necessary for MAC initialization + * @pcs: a pointer to a &struct phylink_pcs. + * + * This function can be called by MAC drivers through the + * phylink_pcs_pre_init() wrapper, before their hardware is initialized. It + * should not be called after the link is brought up, as reconfiguring the PCS + * at this point could break the link. + * + * Some MAC devices require specific hardware initialization to be performed by + * their associated PCS device before they can properly initialize their own + * hardware. An example of this is the initialization of stmmac controllers, + * which requires an active REF_CLK signal to be provided by the PHY/PCS. + * + * By calling phylink_pcs_pre_init(), MAC drivers can ensure that the PCS is + * setup in a way that allows for successful hardware initialization. + * + * The specific configuration performed by pcs_pre_init() is dependent on the + * model of PCS and the requirements of the MAC device attached to it. PCS + * driver authors should consider whether their target device is to be used in + * conjunction with a MAC device whose driver calls phylink_pcs_pre_init(). MAC + * driver authors should document their requirements for the PCS + * pre-initialization. + * + */ +int pcs_pre_init(struct phylink_pcs *pcs); + #endif struct phylink *phylink_create(struct phylink_config *, @@ -630,14 +694,19 @@ int phylink_fwnode_phy_connect(struct phylink *pl, const struct fwnode_handle *fwnode, u32 flags); void phylink_disconnect_phy(struct phylink *); +int phylink_set_fixed_link(struct phylink *, + const struct phylink_link_state *); void phylink_mac_change(struct phylink *, bool up); void phylink_pcs_change(struct phylink_pcs *, bool up); +int phylink_pcs_pre_init(struct phylink *pl, struct phylink_pcs *pcs); + void phylink_start(struct phylink *); void phylink_stop(struct phylink *); void phylink_suspend(struct phylink *pl, bool mac_wol); +void phylink_prepare_resume(struct phylink *pl); void phylink_resume(struct phylink *pl); void phylink_ethtool_get_wol(struct phylink *, struct ethtool_wolinfo *); @@ -654,8 +723,8 @@ int phylink_ethtool_set_pauseparam(struct phylink *, struct ethtool_pauseparam *); int phylink_get_eee_err(struct phylink *); int phylink_init_eee(struct phylink *, bool); -int phylink_ethtool_get_eee(struct phylink *, struct ethtool_eee *); -int phylink_ethtool_set_eee(struct phylink *, struct ethtool_eee *); +int phylink_ethtool_get_eee(struct phylink *link, struct ethtool_keee *eee); +int phylink_ethtool_set_eee(struct phylink *link, struct ethtool_keee *eee); int phylink_mii_ioctl(struct phylink *, struct ifreq *, int); int phylink_speed_down(struct phylink *pl, bool sync); int phylink_speed_up(struct phylink *pl); @@ -684,6 +753,7 @@ static inline int phylink_get_link_timer_ns(phy_interface_t interface) case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_QSGMII: case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_10G_QXGMII: return 1600000; case PHY_INTERFACE_MODE_1000BASEX: @@ -695,9 +765,22 @@ static inline int phylink_get_link_timer_ns(phy_interface_t interface) } } +/** + * phylink_mac_implements_lpi() - determine if MAC implements LPI ops + * @ops: phylink_mac_ops structure + * + * Returns true if the phylink MAC operations structure indicates that the + * LPI operations have been implemented, false otherwise. + */ +static inline bool phylink_mac_implements_lpi(const struct phylink_mac_ops *ops) +{ + return ops && ops->mac_disable_tx_lpi && ops->mac_enable_tx_lpi; +} + void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state, - u16 bmsr, u16 lpa); + unsigned int neg_mode, u16 bmsr, u16 lpa); void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs, + unsigned int neg_mode, struct phylink_link_state *state); int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface, const unsigned long *advertising); |