// SPDX-License-Identifier: GPL-2.0 /* * phylink models the MAC to optional PHY connection, supporting * technologies such as SFP cages where the PHY is hot-pluggable. * * Copyright (C) 2015 Russell King */ #include <linux/acpi.h> #include <linux/ethtool.h> #include <linux/export.h> #include <linux/gpio/consumer.h> #include <linux/netdevice.h> #include <linux/of.h> #include <linux/of_mdio.h> #include <linux/phy.h> #include <linux/phy_fixed.h> #include <linux/phylink.h> #include <linux/rtnetlink.h> #include <linux/spinlock.h> #include <linux/timer.h> #include <linux/workqueue.h> #include "sfp.h" #include "swphy.h" #define SUPPORTED_INTERFACES … #define ADVERTISED_INTERFACES … enum { … }; /** * struct phylink - internal data type for phylink */ struct phylink { … }; #define phylink_printk(level, pl, fmt, ...) … #define phylink_err(pl, fmt, ...) … #define phylink_warn(pl, fmt, ...) … #define phylink_info(pl, fmt, ...) … #if defined(CONFIG_DYNAMIC_DEBUG) #define phylink_dbg(pl, fmt, ...) … #elif defined(DEBUG) #define phylink_dbg … #else #define phylink_dbg … #endif static const phy_interface_t phylink_sfp_interface_preference[] = …; static DECLARE_PHY_INTERFACE_MASK(phylink_sfp_interfaces); /** * phylink_set_port_modes() - set the port type modes in the ethtool mask * @mask: ethtool link mode mask * * Sets all the port type modes in the ethtool mask. MAC drivers should * use this in their 'validate' callback. */ void phylink_set_port_modes(unsigned long *mask) { … } EXPORT_SYMBOL_GPL(…); static int phylink_is_empty_linkmode(const unsigned long *linkmode) { … } static const char *phylink_an_mode_str(unsigned int mode) { … } static unsigned int phylink_interface_signal_rate(phy_interface_t interface) { … } /** * phylink_interface_max_speed() - get the maximum speed of a phy interface * @interface: phy interface mode defined by &typedef phy_interface_t * * Determine the maximum speed of a phy interface. This is intended to help * determine the correct speed to pass to the MAC when the phy is performing * rate matching. * * Return: The maximum speed of @interface */ static int phylink_interface_max_speed(phy_interface_t interface) { … } /** * phylink_caps_to_linkmodes() - Convert capabilities to ethtool link modes * @linkmodes: ethtool linkmode mask (must be already initialised) * @caps: bitmask of MAC capabilities * * Set all possible pause, speed and duplex linkmodes in @linkmodes that are * supported by the @caps. @linkmodes must have been initialised previously. */ static void phylink_caps_to_linkmodes(unsigned long *linkmodes, unsigned long caps) { … } static struct { … } phylink_caps_params[] = …; /** * phylink_limit_mac_speed - limit the phylink_config to a maximum speed * @config: pointer to a &struct phylink_config * @max_speed: maximum speed * * Mask off MAC capabilities for speeds higher than the @max_speed parameter. * Any further motifications of config.mac_capabilities will override this. */ void phylink_limit_mac_speed(struct phylink_config *config, u32 max_speed) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_cap_from_speed_duplex - Get mac capability from speed/duplex * @speed: the speed to search for * @duplex: the duplex to search for * * Find the mac capability for a given speed and duplex. * * Return: A mask with the mac capability patching @speed and @duplex, or 0 if * there were no matches. */ static unsigned long phylink_cap_from_speed_duplex(int speed, unsigned int duplex) { … } /** * phylink_get_capabilities() - get capabilities for a given MAC * @interface: phy interface mode defined by &typedef phy_interface_t * @mac_capabilities: bitmask of MAC capabilities * @rate_matching: type of rate matching being performed * * Get the MAC capabilities that are supported by the @interface mode and * @mac_capabilities. */ static unsigned long phylink_get_capabilities(phy_interface_t interface, unsigned long mac_capabilities, int rate_matching) { … } /** * phylink_validate_mask_caps() - Restrict link modes based on caps * @supported: ethtool bitmask for supported link modes. * @state: pointer to a &struct phylink_link_state. * @mac_capabilities: bitmask of MAC capabilities * * Calculate the supported link modes based on @mac_capabilities, and restrict * @supported and @state based on that. Use this function if your capabiliies * aren't constant, such as if they vary depending on the interface. */ static void phylink_validate_mask_caps(unsigned long *supported, struct phylink_link_state *state, unsigned long mac_capabilities) { … } static int phylink_validate_mac_and_pcs(struct phylink *pl, unsigned long *supported, struct phylink_link_state *state) { … } static void phylink_validate_one(struct phylink *pl, struct phy_device *phy, const unsigned long *supported, const struct phylink_link_state *state, phy_interface_t interface, unsigned long *accum_supported, unsigned long *accum_advertising) { … } static int phylink_validate_mask(struct phylink *pl, struct phy_device *phy, unsigned long *supported, struct phylink_link_state *state, const unsigned long *interfaces) { … } static int phylink_validate(struct phylink *pl, unsigned long *supported, struct phylink_link_state *state) { … } static int phylink_parse_fixedlink(struct phylink *pl, const struct fwnode_handle *fwnode) { … } static int phylink_parse_mode(struct phylink *pl, const struct fwnode_handle *fwnode) { … } static void phylink_apply_manual_flow(struct phylink *pl, struct phylink_link_state *state) { … } static void phylink_resolve_an_pause(struct phylink_link_state *state) { … } static void phylink_pcs_pre_config(struct phylink_pcs *pcs, phy_interface_t interface) { … } static int phylink_pcs_post_config(struct phylink_pcs *pcs, phy_interface_t interface) { … } static void phylink_pcs_disable(struct phylink_pcs *pcs) { … } static int phylink_pcs_enable(struct phylink_pcs *pcs) { … } static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, const struct phylink_link_state *state, bool permit_pause_to_mac) { … } static void phylink_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, int speed, int duplex) { … } static void phylink_pcs_poll_stop(struct phylink *pl) { … } static void phylink_pcs_poll_start(struct phylink *pl) { … } int phylink_pcs_pre_init(struct phylink *pl, struct phylink_pcs *pcs) { … } EXPORT_SYMBOL_GPL(…); static void phylink_mac_config(struct phylink *pl, const struct phylink_link_state *state) { … } static void phylink_pcs_an_restart(struct phylink *pl) { … } /** * phylink_pcs_neg_mode() - helper to determine PCS inband mode * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND. * @interface: interface mode to be used * @advertising: adertisement ethtool link mode mask * * Determines the negotiation mode to be used by the PCS, and returns * one of: * * - %PHYLINK_PCS_NEG_NONE: interface mode does not support inband * - %PHYLINK_PCS_NEG_OUTBAND: an out of band mode (e.g. reading the PHY) * will be used. * - %PHYLINK_PCS_NEG_INBAND_DISABLED: inband mode selected but autoneg * disabled * - %PHYLINK_PCS_NEG_INBAND_ENABLED: inband mode selected and autoneg enabled * * Note: this is for cases where the PCS itself is involved in negotiation * (e.g. Clause 37, SGMII and similar) not Clause 73. */ static unsigned int phylink_pcs_neg_mode(unsigned int mode, phy_interface_t interface, const unsigned long *advertising) { … } static void phylink_major_config(struct phylink *pl, bool restart, const struct phylink_link_state *state) { … } /* * Reconfigure for a change of inband advertisement. * If we have a separate PCS, we only need to call its pcs_config() method, * and then restart AN if it indicates something changed. Otherwise, we do * the full MAC reconfiguration. */ static int phylink_change_inband_advert(struct phylink *pl) { … } static void phylink_mac_pcs_get_state(struct phylink *pl, struct phylink_link_state *state) { … } /* The fixed state is... fixed except for the link state, * which may be determined by a GPIO or a callback. */ static void phylink_get_fixed_state(struct phylink *pl, struct phylink_link_state *state) { … } static void phylink_mac_initial_config(struct phylink *pl, bool force_restart) { … } static const char *phylink_pause_to_str(int pause) { … } static void phylink_link_up(struct phylink *pl, struct phylink_link_state link_state) { … } static void phylink_link_down(struct phylink *pl) { … } static void phylink_resolve(struct work_struct *w) { … } static void phylink_run_resolve(struct phylink *pl) { … } static void phylink_run_resolve_and_disable(struct phylink *pl, int bit) { … } static void phylink_enable_and_run_resolve(struct phylink *pl, int bit) { … } static void phylink_fixed_poll(struct timer_list *t) { … } static const struct sfp_upstream_ops sfp_phylink_ops; static int phylink_register_sfp(struct phylink *pl, const struct fwnode_handle *fwnode) { … } /** * phylink_create() - create a phylink instance * @config: a pointer to the target &struct phylink_config * @fwnode: a pointer to a &struct fwnode_handle describing the network * interface * @iface: the desired link mode defined by &typedef phy_interface_t * @mac_ops: a pointer to a &struct phylink_mac_ops for the MAC. * * Create a new phylink instance, and parse the link parameters found in @np. * This will parse in-band modes, fixed-link or SFP configuration. * * Note: the rtnl lock must not be held when calling this function. * * Returns a pointer to a &struct phylink, or an error-pointer value. Users * must use IS_ERR() to check for errors from this function. */ struct phylink *phylink_create(struct phylink_config *config, const struct fwnode_handle *fwnode, phy_interface_t iface, const struct phylink_mac_ops *mac_ops) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_destroy() - cleanup and destroy the phylink instance * @pl: a pointer to a &struct phylink returned from phylink_create() * * Destroy a phylink instance. Any PHY that has been attached must have been * cleaned up via phylink_disconnect_phy() prior to calling this function. * * Note: the rtnl lock must not be held when calling this function. */ void phylink_destroy(struct phylink *pl) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_expects_phy() - Determine if phylink expects a phy to be attached * @pl: a pointer to a &struct phylink returned from phylink_create() * * When using fixed-link mode, or in-band mode with 1000base-X or 2500base-X, * no PHY is needed. * * Returns true if phylink will be expecting a PHY. */ bool phylink_expects_phy(struct phylink *pl) { … } EXPORT_SYMBOL_GPL(…); static void phylink_phy_change(struct phy_device *phydev, bool up) { … } static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy, unsigned long *supported, struct phylink_link_state *state) { … } static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy, phy_interface_t interface) { … } static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy, phy_interface_t interface) { … } /** * phylink_connect_phy() - connect a PHY to the phylink instance * @pl: a pointer to a &struct phylink returned from phylink_create() * @phy: a pointer to a &struct phy_device. * * Connect @phy to the phylink instance specified by @pl by calling * phy_attach_direct(). Configure the @phy according to the MAC driver's * capabilities, start the PHYLIB state machine and enable any interrupts * that the PHY supports. * * This updates the phylink's ethtool supported and advertising link mode * masks. * * Returns 0 on success or a negative errno. */ int phylink_connect_phy(struct phylink *pl, struct phy_device *phy) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_of_phy_connect() - connect the PHY specified in the DT mode. * @pl: a pointer to a &struct phylink returned from phylink_create() * @dn: a pointer to a &struct device_node. * @flags: PHY-specific flags to communicate to the PHY device driver * * Connect the phy specified in the device node @dn to the phylink instance * specified by @pl. Actions specified in phylink_connect_phy() will be * performed. * * Returns 0 on success or a negative errno. */ int phylink_of_phy_connect(struct phylink *pl, struct device_node *dn, u32 flags) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_fwnode_phy_connect() - connect the PHY specified in the fwnode. * @pl: a pointer to a &struct phylink returned from phylink_create() * @fwnode: a pointer to a &struct fwnode_handle. * @flags: PHY-specific flags to communicate to the PHY device driver * * Connect the phy specified @fwnode to the phylink instance specified * by @pl. * * Returns 0 on success or a negative errno. */ int phylink_fwnode_phy_connect(struct phylink *pl, const struct fwnode_handle *fwnode, u32 flags) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_disconnect_phy() - disconnect any PHY attached to the phylink * instance. * @pl: a pointer to a &struct phylink returned from phylink_create() * * Disconnect any current PHY from the phylink instance described by @pl. */ void phylink_disconnect_phy(struct phylink *pl) { … } EXPORT_SYMBOL_GPL(…); static void phylink_link_changed(struct phylink *pl, bool up, const char *what) { … } /** * phylink_mac_change() - notify phylink of a change in MAC state * @pl: a pointer to a &struct phylink returned from phylink_create() * @up: indicates whether the link is currently up. * * The MAC driver should call this driver when the state of its link * changes (eg, link failure, new negotiation results, etc.) */ void phylink_mac_change(struct phylink *pl, bool up) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_pcs_change() - notify phylink of a change to PCS link state * @pcs: pointer to &struct phylink_pcs * @up: indicates whether the link is currently up. * * The PCS driver should call this when the state of its link changes * (e.g. link failure, new negotiation results, etc.) Note: it should * not determine "up" by reading the BMSR. If in doubt about the link * state at interrupt time, then pass true if pcs_get_state() returns * the latched link-down state, otherwise pass false. */ void phylink_pcs_change(struct phylink_pcs *pcs, bool up) { … } EXPORT_SYMBOL_GPL(…); static irqreturn_t phylink_link_handler(int irq, void *data) { … } /** * phylink_start() - start a phylink instance * @pl: a pointer to a &struct phylink returned from phylink_create() * * Start the phylink instance specified by @pl, configuring the MAC for the * desired link mode(s) and negotiation style. This should be called from the * network device driver's &struct net_device_ops ndo_open() method. */ void phylink_start(struct phylink *pl) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_stop() - stop a phylink instance * @pl: a pointer to a &struct phylink returned from phylink_create() * * Stop the phylink instance specified by @pl. This should be called from the * network device driver's &struct net_device_ops ndo_stop() method. The * network device's carrier state should not be changed prior to calling this * function. * * This will synchronously bring down the link if the link is not already * down (in other words, it will trigger a mac_link_down() method call.) */ void phylink_stop(struct phylink *pl) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_suspend() - handle a network device suspend event * @pl: a pointer to a &struct phylink returned from phylink_create() * @mac_wol: true if the MAC needs to receive packets for Wake-on-Lan * * Handle a network device suspend event. There are several cases: * * - If Wake-on-Lan is not active, we can bring down the link between * the MAC and PHY by calling phylink_stop(). * - If Wake-on-Lan is active, and being handled only by the PHY, we * can also bring down the link between the MAC and PHY. * - If Wake-on-Lan is active, but being handled by the MAC, the MAC * still needs to receive packets, so we can not bring the link down. */ void phylink_suspend(struct phylink *pl, bool mac_wol) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_resume() - handle a network device resume event * @pl: a pointer to a &struct phylink returned from phylink_create() * * Undo the effects of phylink_suspend(), returning the link to an * operational state. */ void phylink_resume(struct phylink *pl) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY * @pl: a pointer to a &struct phylink returned from phylink_create() * @wol: a pointer to &struct ethtool_wolinfo to hold the read parameters * * Read the wake on lan parameters from the PHY attached to the phylink * instance specified by @pl. If no PHY is currently attached, report no * support for wake on lan. */ void phylink_ethtool_get_wol(struct phylink *pl, struct ethtool_wolinfo *wol) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_ethtool_set_wol() - set wake on lan parameters * @pl: a pointer to a &struct phylink returned from phylink_create() * @wol: a pointer to &struct ethtool_wolinfo for the desired parameters * * Set the wake on lan parameters for the PHY attached to the phylink * instance specified by @pl. If no PHY is attached, returns %EOPNOTSUPP * error. * * Returns zero on success or negative errno code. */ int phylink_ethtool_set_wol(struct phylink *pl, struct ethtool_wolinfo *wol) { … } EXPORT_SYMBOL_GPL(…); static void phylink_merge_link_mode(unsigned long *dst, const unsigned long *b) { … } static void phylink_get_ksettings(const struct phylink_link_state *state, struct ethtool_link_ksettings *kset) { … } /** * phylink_ethtool_ksettings_get() - get the current link settings * @pl: a pointer to a &struct phylink returned from phylink_create() * @kset: a pointer to a &struct ethtool_link_ksettings to hold link settings * * Read the current link settings for the phylink instance specified by @pl. * This will be the link settings read from the MAC, PHY or fixed link * settings depending on the current negotiation mode. */ int phylink_ethtool_ksettings_get(struct phylink *pl, struct ethtool_link_ksettings *kset) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_ethtool_ksettings_set() - set the link settings * @pl: a pointer to a &struct phylink returned from phylink_create() * @kset: a pointer to a &struct ethtool_link_ksettings for the desired modes */ int phylink_ethtool_ksettings_set(struct phylink *pl, const struct ethtool_link_ksettings *kset) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_ethtool_nway_reset() - restart negotiation * @pl: a pointer to a &struct phylink returned from phylink_create() * * Restart negotiation for the phylink instance specified by @pl. This will * cause any attached phy to restart negotiation with the link partner, and * if the MAC is in a BaseX mode, the MAC will also be requested to restart * negotiation. * * Returns zero on success, or negative error code. */ int phylink_ethtool_nway_reset(struct phylink *pl) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_ethtool_get_pauseparam() - get the current pause parameters * @pl: a pointer to a &struct phylink returned from phylink_create() * @pause: a pointer to a &struct ethtool_pauseparam */ void phylink_ethtool_get_pauseparam(struct phylink *pl, struct ethtool_pauseparam *pause) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_ethtool_set_pauseparam() - set the current pause parameters * @pl: a pointer to a &struct phylink returned from phylink_create() * @pause: a pointer to a &struct ethtool_pauseparam */ int phylink_ethtool_set_pauseparam(struct phylink *pl, struct ethtool_pauseparam *pause) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_get_eee_err() - read the energy efficient ethernet error * counter * @pl: a pointer to a &struct phylink returned from phylink_create(). * * Read the Energy Efficient Ethernet error counter from the PHY associated * with the phylink instance specified by @pl. * * Returns positive error counter value, or negative error code. */ int phylink_get_eee_err(struct phylink *pl) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_init_eee() - init and check the EEE features * @pl: a pointer to a &struct phylink returned from phylink_create() * @clk_stop_enable: allow PHY to stop receive clock * * Must be called either with RTNL held or within mac_link_up() */ int phylink_init_eee(struct phylink *pl, bool clk_stop_enable) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_ethtool_get_eee() - read the energy efficient ethernet parameters * @pl: a pointer to a &struct phylink returned from phylink_create() * @eee: a pointer to a &struct ethtool_keee for the read parameters */ int phylink_ethtool_get_eee(struct phylink *pl, struct ethtool_keee *eee) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_ethtool_set_eee() - set the energy efficient ethernet parameters * @pl: a pointer to a &struct phylink returned from phylink_create() * @eee: a pointer to a &struct ethtool_keee for the desired parameters */ int phylink_ethtool_set_eee(struct phylink *pl, struct ethtool_keee *eee) { … } EXPORT_SYMBOL_GPL(…); /* This emulates MII registers for a fixed-mode phy operating as per the * passed in state. "aneg" defines if we report negotiation is possible. * * FIXME: should deal with negotiation state too. */ static int phylink_mii_emul_read(unsigned int reg, struct phylink_link_state *state) { … } static int phylink_phy_read(struct phylink *pl, unsigned int phy_id, unsigned int reg) { … } static int phylink_phy_write(struct phylink *pl, unsigned int phy_id, unsigned int reg, unsigned int val) { … } static int phylink_mii_read(struct phylink *pl, unsigned int phy_id, unsigned int reg) { … } static int phylink_mii_write(struct phylink *pl, unsigned int phy_id, unsigned int reg, unsigned int val) { … } /** * phylink_mii_ioctl() - generic mii ioctl interface * @pl: a pointer to a &struct phylink returned from phylink_create() * @ifr: a pointer to a &struct ifreq for socket ioctls * @cmd: ioctl cmd to execute * * Perform the specified MII ioctl on the PHY attached to the phylink instance * specified by @pl. If no PHY is attached, emulate the presence of the PHY. * * Returns: zero on success or negative error code. * * %SIOCGMIIPHY: * read register from the current PHY. * %SIOCGMIIREG: * read register from the specified PHY. * %SIOCSMIIREG: * set a register on the specified PHY. */ int phylink_mii_ioctl(struct phylink *pl, struct ifreq *ifr, int cmd) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_speed_down() - set the non-SFP PHY to lowest speed supported by both * link partners * @pl: a pointer to a &struct phylink returned from phylink_create() * @sync: perform action synchronously * * If we have a PHY that is not part of a SFP module, then set the speed * as described in the phy_speed_down() function. Please see this function * for a description of the @sync parameter. * * Returns zero if there is no PHY, otherwise as per phy_speed_down(). */ int phylink_speed_down(struct phylink *pl, bool sync) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_speed_up() - restore the advertised speeds prior to the call to * phylink_speed_down() * @pl: a pointer to a &struct phylink returned from phylink_create() * * If we have a PHY that is not part of a SFP module, then restore the * PHY speeds as per phy_speed_up(). * * Returns zero if there is no PHY, otherwise as per phy_speed_up(). */ int phylink_speed_up(struct phylink *pl) { … } EXPORT_SYMBOL_GPL(…); static void phylink_sfp_attach(void *upstream, struct sfp_bus *bus) { … } static void phylink_sfp_detach(void *upstream, struct sfp_bus *bus) { … } static phy_interface_t phylink_choose_sfp_interface(struct phylink *pl, const unsigned long *intf) { … } static void phylink_sfp_set_config(struct phylink *pl, u8 mode, unsigned long *supported, struct phylink_link_state *state) { … } static int phylink_sfp_config_phy(struct phylink *pl, u8 mode, struct phy_device *phy) { … } static int phylink_sfp_config_optical(struct phylink *pl) { … } static int phylink_sfp_module_insert(void *upstream, const struct sfp_eeprom_id *id) { … } static int phylink_sfp_module_start(void *upstream) { … } static void phylink_sfp_module_stop(void *upstream) { … } static void phylink_sfp_link_down(void *upstream) { … } static void phylink_sfp_link_up(void *upstream) { … } /* The Broadcom BCM84881 in the Methode DM7052 is unable to provide a SGMII * or 802.3z control word, so inband will not work. */ static bool phylink_phy_no_inband(struct phy_device *phy) { … } static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy) { … } static void phylink_sfp_disconnect_phy(void *upstream) { … } static const struct sfp_upstream_ops sfp_phylink_ops = …; /* Helpers for MAC drivers */ static struct { … } phylink_c73_priority_resolution[] = …; void phylink_resolve_c73(struct phylink_link_state *state) { … } EXPORT_SYMBOL_GPL(…); static void phylink_decode_c37_word(struct phylink_link_state *state, uint16_t config_reg, int speed) { … } static void phylink_decode_sgmii_word(struct phylink_link_state *state, uint16_t config_reg) { … } /** * phylink_decode_usxgmii_word() - decode the USXGMII word from a MAC PCS * @state: a pointer to a struct phylink_link_state. * @lpa: a 16 bit value which stores the USXGMII auto-negotiation word * * Helper for MAC PCS supporting the USXGMII protocol and the auto-negotiation * code word. Decode the USXGMII code word and populate the corresponding fields * (speed, duplex) into the phylink_link_state structure. */ void phylink_decode_usxgmii_word(struct phylink_link_state *state, uint16_t lpa) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_decode_usgmii_word() - decode the USGMII word from a MAC PCS * @state: a pointer to a struct phylink_link_state. * @lpa: a 16 bit value which stores the USGMII auto-negotiation word * * Helper for MAC PCS supporting the USGMII protocol and the auto-negotiation * code word. Decode the USGMII code word and populate the corresponding fields * (speed, duplex) into the phylink_link_state structure. The structure for this * word is the same as the USXGMII word, except it only supports speeds up to * 1Gbps. */ static void phylink_decode_usgmii_word(struct phylink_link_state *state, uint16_t lpa) { … } /** * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers * @state: a pointer to a &struct phylink_link_state. * @bmsr: The value of the %MII_BMSR register * @lpa: The value of the %MII_LPA register * * Helper for MAC PCS supporting the 802.3 clause 22 register set for * clause 37 negotiation and/or SGMII control. * * Parse the Clause 37 or Cisco SGMII link partner negotiation word into * the phylink @state structure. This is suitable to be used for implementing * the pcs_get_state() member of the struct phylink_pcs_ops structure if * accessing @bmsr and @lpa cannot be done with MDIO directly. */ void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state, u16 bmsr, u16 lpa) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_mii_c22_pcs_get_state() - read the MAC PCS state * @pcs: a pointer to a &struct mdio_device. * @state: a pointer to a &struct phylink_link_state. * * Helper for MAC PCS supporting the 802.3 clause 22 register set for * clause 37 negotiation and/or SGMII control. * * Read the MAC PCS state from the MII device configured in @config and * parse the Clause 37 or Cisco SGMII link partner negotiation word into * the phylink @state structure. This is suitable to be directly plugged * into the pcs_get_state() member of the struct phylink_pcs_ops * structure. */ void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs, struct phylink_link_state *state) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS * advertisement * @interface: the PHY interface mode being configured * @advertising: the ethtool advertisement mask * * Helper for MAC PCS supporting the 802.3 clause 22 register set for * clause 37 negotiation and/or SGMII control. * * Encode the clause 37 PCS advertisement as specified by @interface and * @advertising. * * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed. */ int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface, const unsigned long *advertising) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_mii_c22_pcs_config() - configure clause 22 PCS * @pcs: a pointer to a &struct mdio_device. * @interface: the PHY interface mode being configured * @advertising: the ethtool advertisement mask * @neg_mode: PCS negotiation mode * * Configure a Clause 22 PCS PHY with the appropriate negotiation * parameters for the @mode, @interface and @advertising parameters. * Returns negative error number on failure, zero if the advertisement * has not changed, or positive if there is a change. */ int phylink_mii_c22_pcs_config(struct mdio_device *pcs, phy_interface_t interface, const unsigned long *advertising, unsigned int neg_mode) { … } EXPORT_SYMBOL_GPL(…); /** * phylink_mii_c22_pcs_an_restart() - restart 802.3z autonegotiation * @pcs: a pointer to a &struct mdio_device. * * Helper for MAC PCS supporting the 802.3 clause 22 register set for * clause 37 negotiation. * * Restart the clause 37 negotiation with the link partner. This is * suitable to be directly plugged into the pcs_get_state() member * of the struct phylink_pcs_ops structure. */ void phylink_mii_c22_pcs_an_restart(struct mdio_device *pcs) { … } EXPORT_SYMBOL_GPL(…); void phylink_mii_c45_pcs_get_state(struct mdio_device *pcs, struct phylink_link_state *state) { … } EXPORT_SYMBOL_GPL(…); static int __init phylink_init(void) { … } module_init(…) …; MODULE_LICENSE(…) …; MODULE_DESCRIPTION(…) …;