linux/drivers/net/phy/phy_device.c

// SPDX-License-Identifier: GPL-2.0+
/* Framework for finding and configuring PHYs.
 * Also contains generic PHY driver
 *
 * Author: Andy Fleming
 *
 * Copyright (c) 2004 Freescale Semiconductor, Inc.
 */

#define pr_fmt(fmt)

#include <linux/acpi.h>
#include <linux/bitmap.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/mdio.h>
#include <linux/mii.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <linux/phylib_stubs.h>
#include <linux/phy_led_triggers.h>
#include <linux/pse-pd/pse.h>
#include <linux/property.h>
#include <linux/rtnetlink.h>
#include <linux/sfp.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/unistd.h>

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();

__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_features) __ro_after_init;
EXPORT_SYMBOL_GPL();

__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_t1_features) __ro_after_init;
EXPORT_SYMBOL_GPL();

__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_t1s_p2mp_features) __ro_after_init;
EXPORT_SYMBOL_GPL();

__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_features) __ro_after_init;
EXPORT_SYMBOL_GPL();

__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_fibre_features) __ro_after_init;
EXPORT_SYMBOL_GPL();

__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_all_ports_features) __ro_after_init;
EXPORT_SYMBOL_GPL();

__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_features) __ro_after_init;
EXPORT_SYMBOL_GPL();

__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_fec_features) __ro_after_init;
EXPORT_SYMBOL_GPL();

const int phy_basic_ports_array[3] =;
EXPORT_SYMBOL_GPL();

const int phy_fibre_port_array[1] =;
EXPORT_SYMBOL_GPL();

const int phy_all_ports_features_array[7] =;
EXPORT_SYMBOL_GPL();

const int phy_10_100_features_array[4] =;
EXPORT_SYMBOL_GPL();

const int phy_basic_t1_features_array[3] =;
EXPORT_SYMBOL_GPL();

const int phy_basic_t1s_p2mp_features_array[2] =;
EXPORT_SYMBOL_GPL();

const int phy_gbit_features_array[2] =;
EXPORT_SYMBOL_GPL();

const int phy_10gbit_features_array[1] =;
EXPORT_SYMBOL_GPL();

static const int phy_10gbit_fec_features_array[1] =;

__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_init;
EXPORT_SYMBOL_GPL();

static const int phy_10gbit_full_features_array[] =;

static const int phy_eee_cap1_features_array[] =;

__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_eee_cap1_features) __ro_after_init;
EXPORT_SYMBOL_GPL();

static const int phy_eee_cap2_features_array[] =;

__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_eee_cap2_features) __ro_after_init;
EXPORT_SYMBOL_GPL();

static void features_init(void)
{}

void phy_device_free(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

static void phy_mdio_device_free(struct mdio_device *mdiodev)
{}

static void phy_device_release(struct device *dev)
{}

static void phy_mdio_device_remove(struct mdio_device *mdiodev)
{}

static struct phy_driver genphy_driver;

static LIST_HEAD(phy_fixup_list);
static DEFINE_MUTEX(phy_fixup_lock);

static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
{}

static __maybe_unused int mdio_bus_phy_suspend(struct device *dev)
{}

static __maybe_unused int mdio_bus_phy_resume(struct device *dev)
{}

static SIMPLE_DEV_PM_OPS(mdio_bus_phy_pm_ops, mdio_bus_phy_suspend,
			 mdio_bus_phy_resume);

/**
 * phy_register_fixup - creates a new phy_fixup and adds it to the list
 * @bus_id: A string which matches phydev->mdio.dev.bus_id (or PHY_ANY_ID)
 * @phy_uid: Used to match against phydev->phy_id (the UID of the PHY)
 *	It can also be PHY_ANY_UID
 * @phy_uid_mask: Applied to phydev->phy_id and fixup->phy_uid before
 *	comparison
 * @run: The actual code to be run when a matching PHY is found
 */
int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,
		       int (*run)(struct phy_device *))
{}
EXPORT_SYMBOL();

/* Registers a fixup to be run on any PHY with the UID in phy_uid */
int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask,
			       int (*run)(struct phy_device *))
{}
EXPORT_SYMBOL();

/* Registers a fixup to be run on the PHY with id string bus_id */
int phy_register_fixup_for_id(const char *bus_id,
			      int (*run)(struct phy_device *))
{}
EXPORT_SYMBOL();

/**
 * phy_unregister_fixup - remove a phy_fixup from the list
 * @bus_id: A string matches fixup->bus_id (or PHY_ANY_ID) in phy_fixup_list
 * @phy_uid: A phy id matches fixup->phy_id (or PHY_ANY_UID) in phy_fixup_list
 * @phy_uid_mask: Applied to phy_uid and fixup->phy_uid before comparison
 */
int phy_unregister_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask)
{}
EXPORT_SYMBOL();

/* Unregisters a fixup of any PHY with the UID in phy_uid */
int phy_unregister_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask)
{}
EXPORT_SYMBOL();

/* Unregisters a fixup of the PHY with id string bus_id */
int phy_unregister_fixup_for_id(const char *bus_id)
{}
EXPORT_SYMBOL();

/* Returns 1 if fixup matches phydev in bus_id and phy_uid.
 * Fixups can be set to match any in one or more fields.
 */
static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup)
{}

/* Runs any matching fixups for this phydev */
static int phy_scan_fixups(struct phy_device *phydev)
{}

static int phy_bus_match(struct device *dev, const struct device_driver *drv)
{}

static ssize_t
phy_id_show(struct device *dev, struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR_RO(phy_id);

static ssize_t
phy_interface_show(struct device *dev, struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR_RO(phy_interface);

static ssize_t
phy_has_fixups_show(struct device *dev, struct device_attribute *attr,
		    char *buf)
{}
static DEVICE_ATTR_RO(phy_has_fixups);

static ssize_t phy_dev_flags_show(struct device *dev,
				  struct device_attribute *attr,
				  char *buf)
{}
static DEVICE_ATTR_RO(phy_dev_flags);

static struct attribute *phy_dev_attrs[] =;
ATTRIBUTE_GROUPS();

static const struct device_type mdio_bus_phy_type =;

static int phy_request_driver_module(struct phy_device *dev, u32 phy_id)
{}

struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,
				     bool is_c45,
				     struct phy_c45_device_ids *c45_ids)
{}
EXPORT_SYMBOL();

/* phy_c45_probe_present - checks to see if a MMD is present in the package
 * @bus: the target MII bus
 * @prtad: PHY package address on the MII bus
 * @devad: PHY device (MMD) address
 *
 * Read the MDIO_STAT2 register, and check whether a device is responding
 * at this address.
 *
 * Returns: negative error number on bus access error, zero if no device
 * is responding, or positive if a device is present.
 */
static int phy_c45_probe_present(struct mii_bus *bus, int prtad, int devad)
{}

/* get_phy_c45_devs_in_pkg - reads a MMD's devices in package registers.
 * @bus: the target MII bus
 * @addr: PHY address on the MII bus
 * @dev_addr: MMD address in the PHY.
 * @devices_in_package: where to store the devices in package information.
 *
 * Description: reads devices in package registers of a MMD at @dev_addr
 * from PHY at @addr on @bus.
 *
 * Returns: 0 on success, -EIO on failure.
 */
static int get_phy_c45_devs_in_pkg(struct mii_bus *bus, int addr, int dev_addr,
				   u32 *devices_in_package)
{}

/**
 * get_phy_c45_ids - reads the specified addr for its 802.3-c45 IDs.
 * @bus: the target MII bus
 * @addr: PHY address on the MII bus
 * @c45_ids: where to store the c45 ID information.
 *
 * Read the PHY "devices in package". If this appears to be valid, read
 * the PHY identifiers for each device. Return the "devices in package"
 * and identifiers in @c45_ids.
 *
 * Returns zero on success, %-EIO on bus access error, or %-ENODEV if
 * the "devices in package" is invalid or no device responds.
 */
static int get_phy_c45_ids(struct mii_bus *bus, int addr,
			   struct phy_c45_device_ids *c45_ids)
{}

/**
 * get_phy_c22_id - reads the specified addr for its clause 22 ID.
 * @bus: the target MII bus
 * @addr: PHY address on the MII bus
 * @phy_id: where to store the ID retrieved.
 *
 * Read the 802.3 clause 22 PHY ID from the PHY at @addr on the @bus,
 * placing it in @phy_id. Return zero on successful read and the ID is
 * valid, %-EIO on bus access error, or %-ENODEV if no device responds
 * or invalid ID.
 */
static int get_phy_c22_id(struct mii_bus *bus, int addr, u32 *phy_id)
{}

/* Extract the phy ID from the compatible string of the form
 * ethernet-phy-idAAAA.BBBB.
 */
int fwnode_get_phy_id(struct fwnode_handle *fwnode, u32 *phy_id)
{}
EXPORT_SYMBOL();

/**
 * get_phy_device - reads the specified PHY device and returns its @phy_device
 *		    struct
 * @bus: the target MII bus
 * @addr: PHY address on the MII bus
 * @is_c45: If true the PHY uses the 802.3 clause 45 protocol
 *
 * Probe for a PHY at @addr on @bus.
 *
 * When probing for a clause 22 PHY, then read the ID registers. If we find
 * a valid ID, allocate and return a &struct phy_device.
 *
 * When probing for a clause 45 PHY, read the "devices in package" registers.
 * If the "devices in package" appears valid, read the ID registers for each
 * MMD, allocate and return a &struct phy_device.
 *
 * Returns an allocated &struct phy_device on success, %-ENODEV if there is
 * no PHY present, or %-EIO on bus access error.
 */
struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45)
{}
EXPORT_SYMBOL();

/**
 * phy_device_register - Register the phy device on the MDIO bus
 * @phydev: phy_device structure to be added to the MDIO bus
 */
int phy_device_register(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * phy_device_remove - Remove a previously registered phy device from the MDIO bus
 * @phydev: phy_device structure to remove
 *
 * This doesn't free the phy_device itself, it merely reverses the effects
 * of phy_device_register(). Use phy_device_free() to free the device
 * after calling this function.
 */
void phy_device_remove(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * phy_get_c45_ids - Read 802.3-c45 IDs for phy device.
 * @phydev: phy_device structure to read 802.3-c45 IDs
 *
 * Returns zero on success, %-EIO on bus access error, or %-ENODEV if
 * the "devices in package" is invalid.
 */
int phy_get_c45_ids(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * phy_find_first - finds the first PHY device on the bus
 * @bus: the target MII bus
 */
struct phy_device *phy_find_first(struct mii_bus *bus)
{}
EXPORT_SYMBOL();

static void phy_link_change(struct phy_device *phydev, bool up)
{}

/**
 * phy_prepare_link - prepares the PHY layer to monitor link status
 * @phydev: target phy_device struct
 * @handler: callback function for link status change notifications
 *
 * Description: Tells the PHY infrastructure to handle the
 *   gory details on monitoring link status (whether through
 *   polling or an interrupt), and to call back to the
 *   connected device driver when the link status changes.
 *   If you want to monitor your own link state, don't call
 *   this function.
 */
static void phy_prepare_link(struct phy_device *phydev,
			     void (*handler)(struct net_device *))
{}

/**
 * phy_connect_direct - connect an ethernet device to a specific phy_device
 * @dev: the network device to connect
 * @phydev: the pointer to the phy device
 * @handler: callback function for state change notifications
 * @interface: PHY device's interface
 */
int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
		       void (*handler)(struct net_device *),
		       phy_interface_t interface)
{}
EXPORT_SYMBOL();

/**
 * phy_connect - connect an ethernet device to a PHY device
 * @dev: the network device to connect
 * @bus_id: the id string of the PHY device to connect
 * @handler: callback function for state change notifications
 * @interface: PHY device's interface
 *
 * Description: Convenience function for connecting ethernet
 *   devices to PHY devices.  The default behavior is for
 *   the PHY infrastructure to handle everything, and only notify
 *   the connected driver when the link status changes.  If you
 *   don't want, or can't use the provided functionality, you may
 *   choose to call only the subset of functions which provide
 *   the desired functionality.
 */
struct phy_device *phy_connect(struct net_device *dev, const char *bus_id,
			       void (*handler)(struct net_device *),
			       phy_interface_t interface)
{}
EXPORT_SYMBOL();

/**
 * phy_disconnect - disable interrupts, stop state machine, and detach a PHY
 *		    device
 * @phydev: target phy_device struct
 */
void phy_disconnect(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * phy_poll_reset - Safely wait until a PHY reset has properly completed
 * @phydev: The PHY device to poll
 *
 * Description: According to IEEE 802.3, Section 2, Subsection 22.2.4.1.1, as
 *   published in 2008, a PHY reset may take up to 0.5 seconds.  The MII BMCR
 *   register must be polled until the BMCR_RESET bit clears.
 *
 *   Furthermore, any attempts to write to PHY registers may have no effect
 *   or even generate MDIO bus errors until this is complete.
 *
 *   Some PHYs (such as the Marvell 88E1111) don't entirely conform to the
 *   standard and do not fully reset after the BMCR_RESET bit is set, and may
 *   even *REQUIRE* a soft-reset to properly restart autonegotiation.  In an
 *   effort to support such broken PHYs, this function is separate from the
 *   standard phy_init_hw() which will zero all the other bits in the BMCR
 *   and reapply all driver-specific and board-specific fixups.
 */
static int phy_poll_reset(struct phy_device *phydev)
{}

int phy_init_hw(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

void phy_attached_info(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

#define ATTACHED_FMT
char *phy_attached_info_irq(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

void phy_attached_print(struct phy_device *phydev, const char *fmt, ...)
{}
EXPORT_SYMBOL();

static void phy_sysfs_create_links(struct phy_device *phydev)
{}

static ssize_t
phy_standalone_show(struct device *dev, struct device_attribute *attr,
		    char *buf)
{}
static DEVICE_ATTR_RO(phy_standalone);

/**
 * phy_sfp_attach - attach the SFP bus to the PHY upstream network device
 * @upstream: pointer to the phy device
 * @bus: sfp bus representing cage being attached
 *
 * This is used to fill in the sfp_upstream_ops .attach member.
 */
void phy_sfp_attach(void *upstream, struct sfp_bus *bus)
{}
EXPORT_SYMBOL();

/**
 * phy_sfp_detach - detach the SFP bus from the PHY upstream network device
 * @upstream: pointer to the phy device
 * @bus: sfp bus representing cage being attached
 *
 * This is used to fill in the sfp_upstream_ops .detach member.
 */
void phy_sfp_detach(void *upstream, struct sfp_bus *bus)
{}
EXPORT_SYMBOL();

/**
 * phy_sfp_probe - probe for a SFP cage attached to this PHY device
 * @phydev: Pointer to phy_device
 * @ops: SFP's upstream operations
 */
int phy_sfp_probe(struct phy_device *phydev,
		  const struct sfp_upstream_ops *ops)
{}
EXPORT_SYMBOL();

static bool phy_drv_supports_irq(const struct phy_driver *phydrv)
{}

/**
 * phy_attach_direct - attach a network device to a given PHY device pointer
 * @dev: network device to attach
 * @phydev: Pointer to phy_device to attach
 * @flags: PHY device's dev_flags
 * @interface: PHY device's interface
 *
 * Description: Called by drivers to attach to a particular PHY
 *     device. The phy_device is found, and properly hooked up
 *     to the phy_driver.  If no driver is attached, then a
 *     generic driver is used.  The phy_device is given a ptr to
 *     the attaching device, and given a callback for link status
 *     change.  The phy_device is returned to the attaching driver.
 *     This function takes a reference on the phy device.
 */
int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
		      u32 flags, phy_interface_t interface)
{}
EXPORT_SYMBOL();

/**
 * phy_attach - attach a network device to a particular PHY device
 * @dev: network device to attach
 * @bus_id: Bus ID of PHY device to attach
 * @interface: PHY device's interface
 *
 * Description: Same as phy_attach_direct() except that a PHY bus_id
 *     string is passed instead of a pointer to a struct phy_device.
 */
struct phy_device *phy_attach(struct net_device *dev, const char *bus_id,
			      phy_interface_t interface)
{}
EXPORT_SYMBOL();

static bool phy_driver_is_genphy_kind(struct phy_device *phydev,
				      struct device_driver *driver)
{}

bool phy_driver_is_genphy(struct phy_device *phydev)
{}
EXPORT_SYMBOL_GPL();

bool phy_driver_is_genphy_10g(struct phy_device *phydev)
{}
EXPORT_SYMBOL_GPL();

/**
 * phy_package_join - join a common PHY group
 * @phydev: target phy_device struct
 * @base_addr: cookie and base PHY address of PHY package for offset
 *   calculation of global register access
 * @priv_size: if non-zero allocate this amount of bytes for private data
 *
 * This joins a PHY group and provides a shared storage for all phydevs in
 * this group. This is intended to be used for packages which contain
 * more than one PHY, for example a quad PHY transceiver.
 *
 * The base_addr parameter serves as cookie which has to have the same values
 * for all members of one group and as the base PHY address of the PHY package
 * for offset calculation to access generic registers of a PHY package.
 * Usually, one of the PHY addresses of the different PHYs in the package
 * provides access to these global registers.
 * The address which is given here, will be used in the phy_package_read()
 * and phy_package_write() convenience functions as base and added to the
 * passed offset in those functions.
 *
 * This will set the shared pointer of the phydev to the shared storage.
 * If this is the first call for a this cookie the shared storage will be
 * allocated. If priv_size is non-zero, the given amount of bytes are
 * allocated for the priv member.
 *
 * Returns < 1 on error, 0 on success. Esp. calling phy_package_join()
 * with the same cookie but a different priv_size is an error.
 */
int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size)
{}
EXPORT_SYMBOL_GPL();

/**
 * of_phy_package_join - join a common PHY group in PHY package
 * @phydev: target phy_device struct
 * @priv_size: if non-zero allocate this amount of bytes for private data
 *
 * This is a variant of phy_package_join for PHY package defined in DT.
 *
 * The parent node of the @phydev is checked as a valid PHY package node
 * structure (by matching the node name "ethernet-phy-package") and the
 * base_addr for the PHY package is passed to phy_package_join.
 *
 * With this configuration the shared struct will also have the np value
 * filled to use additional DT defined properties in PHY specific
 * probe_once and config_init_once PHY package OPs.
 *
 * Returns < 0 on error, 0 on success. Esp. calling phy_package_join()
 * with the same cookie but a different priv_size is an error. Or a parent
 * node is not detected or is not valid or doesn't match the expected node
 * name for PHY package.
 */
int of_phy_package_join(struct phy_device *phydev, size_t priv_size)
{}
EXPORT_SYMBOL_GPL();

/**
 * phy_package_leave - leave a common PHY group
 * @phydev: target phy_device struct
 *
 * This leaves a PHY group created by phy_package_join(). If this phydev
 * was the last user of the shared data between the group, this data is
 * freed. Resets the phydev->shared pointer to NULL.
 */
void phy_package_leave(struct phy_device *phydev)
{}
EXPORT_SYMBOL_GPL();

static void devm_phy_package_leave(struct device *dev, void *res)
{}

/**
 * devm_phy_package_join - resource managed phy_package_join()
 * @dev: device that is registering this PHY package
 * @phydev: target phy_device struct
 * @base_addr: cookie and base PHY address of PHY package for offset
 *   calculation of global register access
 * @priv_size: if non-zero allocate this amount of bytes for private data
 *
 * Managed phy_package_join(). Shared storage fetched by this function,
 * phy_package_leave() is automatically called on driver detach. See
 * phy_package_join() for more information.
 */
int devm_phy_package_join(struct device *dev, struct phy_device *phydev,
			  int base_addr, size_t priv_size)
{}
EXPORT_SYMBOL_GPL();

/**
 * devm_of_phy_package_join - resource managed of_phy_package_join()
 * @dev: device that is registering this PHY package
 * @phydev: target phy_device struct
 * @priv_size: if non-zero allocate this amount of bytes for private data
 *
 * Managed of_phy_package_join(). Shared storage fetched by this function,
 * phy_package_leave() is automatically called on driver detach. See
 * of_phy_package_join() for more information.
 */
int devm_of_phy_package_join(struct device *dev, struct phy_device *phydev,
			     size_t priv_size)
{}
EXPORT_SYMBOL_GPL();

/**
 * phy_detach - detach a PHY device from its network device
 * @phydev: target phy_device struct
 *
 * This detaches the phy device from its network device and the phy
 * driver, and drops the reference count taken in phy_attach_direct().
 */
void phy_detach(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

int phy_suspend(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

int __phy_resume(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

int phy_resume(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

int phy_loopback(struct phy_device *phydev, bool enable)
{}
EXPORT_SYMBOL();

/**
 * phy_reset_after_clk_enable - perform a PHY reset if needed
 * @phydev: target phy_device struct
 *
 * Description: Some PHYs are known to need a reset after their refclk was
 *   enabled. This function evaluates the flags and perform the reset if it's
 *   needed. Returns < 0 on error, 0 if the phy wasn't reset and 1 if the phy
 *   was reset.
 */
int phy_reset_after_clk_enable(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/* Generic PHY support and helper functions */

/**
 * genphy_config_advert - sanitize and advertise auto-negotiation parameters
 * @phydev: target phy_device struct
 *
 * Description: Writes MII_ADVERTISE with the appropriate values,
 *   after sanitizing the values to make sure we only advertise
 *   what is supported.  Returns < 0 on error, 0 if the PHY's advertisement
 *   hasn't changed, and > 0 if it has changed.
 */
static int genphy_config_advert(struct phy_device *phydev)
{}

/**
 * genphy_c37_config_advert - sanitize and advertise auto-negotiation parameters
 * @phydev: target phy_device struct
 *
 * Description: Writes MII_ADVERTISE with the appropriate values,
 *   after sanitizing the values to make sure we only advertise
 *   what is supported.  Returns < 0 on error, 0 if the PHY's advertisement
 *   hasn't changed, and > 0 if it has changed. This function is intended
 *   for Clause 37 1000Base-X mode.
 */
static int genphy_c37_config_advert(struct phy_device *phydev)
{}

/**
 * genphy_config_eee_advert - disable unwanted eee mode advertisement
 * @phydev: target phy_device struct
 *
 * Description: Writes MDIO_AN_EEE_ADV after disabling unsupported energy
 *   efficent ethernet modes. Returns 0 if the PHY's advertisement hasn't
 *   changed, and 1 if it has changed.
 */
int genphy_config_eee_advert(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * genphy_setup_forced - configures/forces speed/duplex from @phydev
 * @phydev: target phy_device struct
 *
 * Description: Configures MII_BMCR to force speed/duplex
 *   to the values in phydev. Assumes that the values are valid.
 *   Please see phy_sanitize_settings().
 */
int genphy_setup_forced(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

static int genphy_setup_master_slave(struct phy_device *phydev)
{}

int genphy_read_master_slave(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * genphy_restart_aneg - Enable and Restart Autonegotiation
 * @phydev: target phy_device struct
 */
int genphy_restart_aneg(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * genphy_check_and_restart_aneg - Enable and restart auto-negotiation
 * @phydev: target phy_device struct
 * @restart: whether aneg restart is requested
 *
 * Check, and restart auto-negotiation if needed.
 */
int genphy_check_and_restart_aneg(struct phy_device *phydev, bool restart)
{}
EXPORT_SYMBOL();

/**
 * __genphy_config_aneg - restart auto-negotiation or write BMCR
 * @phydev: target phy_device struct
 * @changed: whether autoneg is requested
 *
 * Description: If auto-negotiation is enabled, we configure the
 *   advertising, and then restart auto-negotiation.  If it is not
 *   enabled, then we write the BMCR.
 */
int __genphy_config_aneg(struct phy_device *phydev, bool changed)
{}
EXPORT_SYMBOL();

/**
 * genphy_c37_config_aneg - restart auto-negotiation or write BMCR
 * @phydev: target phy_device struct
 *
 * Description: If auto-negotiation is enabled, we configure the
 *   advertising, and then restart auto-negotiation.  If it is not
 *   enabled, then we write the BMCR. This function is intended
 *   for use with Clause 37 1000Base-X mode.
 */
int genphy_c37_config_aneg(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * genphy_aneg_done - return auto-negotiation status
 * @phydev: target phy_device struct
 *
 * Description: Reads the status register and returns 0 either if
 *   auto-negotiation is incomplete, or if there was an error.
 *   Returns BMSR_ANEGCOMPLETE if auto-negotiation is done.
 */
int genphy_aneg_done(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * genphy_update_link - update link status in @phydev
 * @phydev: target phy_device struct
 *
 * Description: Update the value in phydev->link to reflect the
 *   current link value.  In order to do this, we need to read
 *   the status register twice, keeping the second value.
 */
int genphy_update_link(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

int genphy_read_lpa(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * genphy_read_status_fixed - read the link parameters for !aneg mode
 * @phydev: target phy_device struct
 *
 * Read the current duplex and speed state for a PHY operating with
 * autonegotiation disabled.
 */
int genphy_read_status_fixed(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * genphy_read_status - check the link status and update current link state
 * @phydev: target phy_device struct
 *
 * Description: Check the link, then figure out the current state
 *   by comparing what we advertise with what the link partner
 *   advertises.  Start by checking the gigabit possibilities,
 *   then move on to 10/100.
 */
int genphy_read_status(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * genphy_c37_read_status - check the link status and update current link state
 * @phydev: target phy_device struct
 * @changed: pointer where to store if link changed
 *
 * Description: Check the link, then figure out the current state
 *   by comparing what we advertise with what the link partner
 *   advertises. This function is for Clause 37 1000Base-X mode.
 *
 *   If link has changed, @changed is set to true, false otherwise.
 */
int genphy_c37_read_status(struct phy_device *phydev, bool *changed)
{}
EXPORT_SYMBOL();

/**
 * genphy_soft_reset - software reset the PHY via BMCR_RESET bit
 * @phydev: target phy_device struct
 *
 * Description: Perform a software PHY reset using the standard
 * BMCR_RESET bit and poll for the reset bit to be cleared.
 *
 * Returns: 0 on success, < 0 on failure
 */
int genphy_soft_reset(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

irqreturn_t genphy_handle_interrupt_no_ack(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * genphy_read_abilities - read PHY abilities from Clause 22 registers
 * @phydev: target phy_device struct
 *
 * Description: Reads the PHY's abilities and populates
 * phydev->supported accordingly.
 *
 * Returns: 0 on success, < 0 on failure
 */
int genphy_read_abilities(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/* This is used for the phy device which doesn't support the MMD extended
 * register access, but it does have side effect when we are trying to access
 * the MMD register via indirect method.
 */
int genphy_read_mmd_unsupported(struct phy_device *phdev, int devad, u16 regnum)
{}
EXPORT_SYMBOL();

int genphy_write_mmd_unsupported(struct phy_device *phdev, int devnum,
				 u16 regnum, u16 val)
{}
EXPORT_SYMBOL();

int genphy_suspend(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

int genphy_resume(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

int genphy_loopback(struct phy_device *phydev, bool enable)
{}
EXPORT_SYMBOL();

/**
 * phy_remove_link_mode - Remove a supported link mode
 * @phydev: phy_device structure to remove link mode from
 * @link_mode: Link mode to be removed
 *
 * Description: Some MACs don't support all link modes which the PHY
 * does.  e.g. a 1G MAC often does not support 1000Half. Add a helper
 * to remove a link mode.
 */
void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode)
{}
EXPORT_SYMBOL();

static void phy_copy_pause_bits(unsigned long *dst, unsigned long *src)
{}

/**
 * phy_advertise_supported - Advertise all supported modes
 * @phydev: target phy_device struct
 *
 * Description: Called to advertise all supported modes, doesn't touch
 * pause mode advertising.
 */
void phy_advertise_supported(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * phy_advertise_eee_all - Advertise all supported EEE modes
 * @phydev: target phy_device struct
 *
 * Description: Per default phylib preserves the EEE advertising at the time of
 * phy probing, which might be a subset of the supported EEE modes. Use this
 * function when all supported EEE modes should be advertised. This does not
 * trigger auto-negotiation, so must be called before phy_start()/
 * phylink_start() which will start auto-negotiation.
 */
void phy_advertise_eee_all(struct phy_device *phydev)
{}
EXPORT_SYMBOL_GPL();

/**
 * phy_support_eee - Set initial EEE policy configuration
 * @phydev: Target phy_device struct
 *
 * This function configures the initial policy for Energy Efficient Ethernet
 * (EEE) on the specified PHY device, influencing that EEE capabilities are
 * advertised before the link is established. It should be called during PHY
 * registration by the MAC driver and/or the PHY driver (for SmartEEE PHYs)
 * if MAC supports LPI or PHY is capable to compensate missing LPI functionality
 * of the MAC.
 *
 * The function sets default EEE policy parameters, including preparing the PHY
 * to advertise EEE capabilities based on hardware support.
 *
 * It also sets the expected configuration for Low Power Idle (LPI) in the MAC
 * driver. If the PHY framework determines that both local and remote
 * advertisements support EEE, and the negotiated link mode is compatible with
 * EEE, it will set enable_tx_lpi = true. The MAC driver is expected to act on
 * this setting by enabling the LPI timer if enable_tx_lpi is set.
 */
void phy_support_eee(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * phy_support_sym_pause - Enable support of symmetrical pause
 * @phydev: target phy_device struct
 *
 * Description: Called by the MAC to indicate is supports symmetrical
 * Pause, but not asym pause.
 */
void phy_support_sym_pause(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * phy_support_asym_pause - Enable support of asym pause
 * @phydev: target phy_device struct
 *
 * Description: Called by the MAC to indicate is supports Asym Pause.
 */
void phy_support_asym_pause(struct phy_device *phydev)
{}
EXPORT_SYMBOL();

/**
 * phy_set_sym_pause - Configure symmetric Pause
 * @phydev: target phy_device struct
 * @rx: Receiver Pause is supported
 * @tx: Transmit Pause is supported
 * @autoneg: Auto neg should be used
 *
 * Description: Configure advertised Pause support depending on if
 * receiver pause and pause auto neg is supported. Generally called
 * from the set_pauseparam .ndo.
 */
void phy_set_sym_pause(struct phy_device *phydev, bool rx, bool tx,
		       bool autoneg)
{}
EXPORT_SYMBOL();

/**
 * phy_set_asym_pause - Configure Pause and Asym Pause
 * @phydev: target phy_device struct
 * @rx: Receiver Pause is supported
 * @tx: Transmit Pause is supported
 *
 * Description: Configure advertised Pause support depending on if
 * transmit and receiver pause is supported. If there has been a
 * change in adverting, trigger a new autoneg. Generally called from
 * the set_pauseparam .ndo.
 */
void phy_set_asym_pause(struct phy_device *phydev, bool rx, bool tx)
{}
EXPORT_SYMBOL();

/**
 * phy_validate_pause - Test if the PHY/MAC support the pause configuration
 * @phydev: phy_device struct
 * @pp: requested pause configuration
 *
 * Description: Test if the PHY/MAC combination supports the Pause
 * configuration the user is requesting. Returns True if it is
 * supported, false otherwise.
 */
bool phy_validate_pause(struct phy_device *phydev,
			struct ethtool_pauseparam *pp)
{}
EXPORT_SYMBOL();

/**
 * phy_get_pause - resolve negotiated pause modes
 * @phydev: phy_device struct
 * @tx_pause: pointer to bool to indicate whether transmit pause should be
 * enabled.
 * @rx_pause: pointer to bool to indicate whether receive pause should be
 * enabled.
 *
 * Resolve and return the flow control modes according to the negotiation
 * result. This includes checking that we are operating in full duplex mode.
 * See linkmode_resolve_pause() for further details.
 */
void phy_get_pause(struct phy_device *phydev, bool *tx_pause, bool *rx_pause)
{}
EXPORT_SYMBOL();

#if IS_ENABLED(CONFIG_OF_MDIO)
static int phy_get_int_delay_property(struct device *dev, const char *name)
{}
#else
static int phy_get_int_delay_property(struct device *dev, const char *name)
{
	return -EINVAL;
}
#endif

/**
 * phy_get_internal_delay - returns the index of the internal delay
 * @phydev: phy_device struct
 * @dev: pointer to the devices device struct
 * @delay_values: array of delays the PHY supports
 * @size: the size of the delay array
 * @is_rx: boolean to indicate to get the rx internal delay
 *
 * Returns the index within the array of internal delay passed in.
 * If the device property is not present then the interface type is checked
 * if the interface defines use of internal delay then a 1 is returned otherwise
 * a 0 is returned.
 * The array must be in ascending order. If PHY does not have an ascending order
 * array then size = 0 and the value of the delay property is returned.
 * Return -EINVAL if the delay is invalid or cannot be found.
 */
s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev,
			   const int *delay_values, int size, bool is_rx)
{}
EXPORT_SYMBOL();

static int phy_led_set_brightness(struct led_classdev *led_cdev,
				  enum led_brightness value)
{}

static int phy_led_blink_set(struct led_classdev *led_cdev,
			     unsigned long *delay_on,
			     unsigned long *delay_off)
{}

static __maybe_unused struct device *
phy_led_hw_control_get_device(struct led_classdev *led_cdev)
{}

static int __maybe_unused
phy_led_hw_control_get(struct led_classdev *led_cdev,
		       unsigned long *rules)
{}

static int __maybe_unused
phy_led_hw_control_set(struct led_classdev *led_cdev,
		       unsigned long rules)
{}

static __maybe_unused int phy_led_hw_is_supported(struct led_classdev *led_cdev,
						  unsigned long rules)
{}

static void phy_leds_unregister(struct phy_device *phydev)
{}

static int of_phy_led(struct phy_device *phydev,
		      struct device_node *led)
{}

static int of_phy_leds(struct phy_device *phydev)
{}

/**
 * fwnode_mdio_find_device - Given a fwnode, find the mdio_device
 * @fwnode: pointer to the mdio_device's fwnode
 *
 * If successful, returns a pointer to the mdio_device with the embedded
 * struct device refcount incremented by one, or NULL on failure.
 * The caller should call put_device() on the mdio_device after its use.
 */
struct mdio_device *fwnode_mdio_find_device(struct fwnode_handle *fwnode)
{}
EXPORT_SYMBOL();

/**
 * fwnode_phy_find_device - For provided phy_fwnode, find phy_device.
 *
 * @phy_fwnode: Pointer to the phy's fwnode.
 *
 * If successful, returns a pointer to the phy_device with the embedded
 * struct device refcount incremented by one, or NULL on failure.
 */
struct phy_device *fwnode_phy_find_device(struct fwnode_handle *phy_fwnode)
{}
EXPORT_SYMBOL();

/**
 * device_phy_find_device - For the given device, get the phy_device
 * @dev: Pointer to the given device
 *
 * Refer return conditions of fwnode_phy_find_device().
 */
struct phy_device *device_phy_find_device(struct device *dev)
{}
EXPORT_SYMBOL_GPL();

/**
 * fwnode_get_phy_node - Get the phy_node using the named reference.
 * @fwnode: Pointer to fwnode from which phy_node has to be obtained.
 *
 * Refer return conditions of fwnode_find_reference().
 * For ACPI, only "phy-handle" is supported. Legacy DT properties "phy"
 * and "phy-device" are not supported in ACPI. DT supports all the three
 * named references to the phy node.
 */
struct fwnode_handle *fwnode_get_phy_node(const struct fwnode_handle *fwnode)
{}
EXPORT_SYMBOL_GPL();

/**
 * phy_probe - probe and init a PHY device
 * @dev: device to probe and init
 *
 * Take care of setting up the phy_device structure, set the state to READY.
 */
static int phy_probe(struct device *dev)
{}

static int phy_remove(struct device *dev)
{}

/**
 * phy_driver_register - register a phy_driver with the PHY layer
 * @new_driver: new phy_driver to register
 * @owner: module owning this PHY
 */
int phy_driver_register(struct phy_driver *new_driver, struct module *owner)
{}
EXPORT_SYMBOL();

int phy_drivers_register(struct phy_driver *new_driver, int n,
			 struct module *owner)
{}
EXPORT_SYMBOL();

void phy_driver_unregister(struct phy_driver *drv)
{}
EXPORT_SYMBOL();

void phy_drivers_unregister(struct phy_driver *drv, int n)
{}
EXPORT_SYMBOL();

static struct phy_driver genphy_driver =;

static const struct ethtool_phy_ops phy_ethtool_phy_ops =;

static const struct phylib_stubs __phylib_stubs =;

static void phylib_register_stubs(void)
{}

static void phylib_unregister_stubs(void)
{}

static int __init phy_init(void)
{}

static void __exit phy_exit(void)
{}

subsys_initcall(phy_init);
module_exit(phy_exit);