| /** | 
 |  * @file | 
 |  * | 
 |  * @brief Public APIs for Ethernet PHY drivers. | 
 |  */ | 
 |  | 
 | /* | 
 |  * Copyright (c) 2021 IP-Logix Inc. | 
 |  * | 
 |  * SPDX-License-Identifier: Apache-2.0 | 
 |  */ | 
 | #ifndef ZEPHYR_INCLUDE_DRIVERS_PHY_H_ | 
 | #define ZEPHYR_INCLUDE_DRIVERS_PHY_H_ | 
 |  | 
 | /** | 
 |  * @brief Ethernet PHY Interface | 
 |  * @defgroup ethernet_phy Ethernet PHY Interface | 
 |  * @ingroup networking | 
 |  * @{ | 
 |  */ | 
 | #include <zephyr/types.h> | 
 | #include <device.h> | 
 |  | 
 | #ifdef __cplusplus | 
 | extern "C" { | 
 | #endif | 
 |  | 
 | /** @brief Ethernet link speeds. */ | 
 | enum phy_link_speed { | 
 | 	/** 10Base-T Half-Duplex */ | 
 | 	LINK_HALF_10BASE_T		= BIT(0), | 
 | 	/** 10Base-T Full-Duplex */ | 
 | 	LINK_FULL_10BASE_T		= BIT(1), | 
 | 	/** 100Base-T Half-Duplex */ | 
 | 	LINK_HALF_100BASE_T		= BIT(2), | 
 | 	/** 100Base-T Full-Duplex */ | 
 | 	LINK_FULL_100BASE_T		= BIT(3), | 
 | }; | 
 |  | 
 | #define PHY_LINK_IS_FULL_DUPLEX(x)	(x & (BIT(1) | BIT(3))) | 
 | #define PHY_LINK_IS_SPEED_100M(x)	(x & (BIT(2) | BIT(3))) | 
 |  | 
 | /** @brief Link state */ | 
 | struct phy_link_state { | 
 | 	/** Link speed */ | 
 | 	enum phy_link_speed speed; | 
 | 	/** When true the link is active and connected */ | 
 | 	bool is_up; | 
 | }; | 
 |  | 
 | /** | 
 |  * @typedef phy_callback_t | 
 |  * @brief Define the callback function signature for | 
 |  * `phy_link_callback_set()` function. | 
 |  * | 
 |  * @param dev       PHY device structure | 
 |  * @param state     Pointer to link_state structure. | 
 |  * @param user_data Pointer to data specified by user | 
 |  */ | 
 | typedef void (*phy_callback_t)(const struct device *dev, | 
 | 			       struct phy_link_state *state, | 
 | 			       void *user_data); | 
 |  | 
 | /** | 
 |  * @cond INTERNAL_HIDDEN | 
 |  * | 
 |  * These are for internal use only, so skip these in | 
 |  * public documentation. | 
 |  */ | 
 | __subsystem struct ethphy_driver_api { | 
 | 	/** Get link state */ | 
 | 	int (*get_link)(const struct device *dev, | 
 | 			struct phy_link_state *state); | 
 |  | 
 | 	/** Configure link */ | 
 | 	int (*cfg_link)(const struct device *dev, | 
 | 			enum phy_link_speed adv_speeds); | 
 |  | 
 | 	/** Set callback to be invoked when link state changes. */ | 
 | 	int (*link_cb_set)(const struct device *dev, phy_callback_t cb, | 
 | 			   void *user_data); | 
 |  | 
 | 	/** Read PHY register */ | 
 | 	int (*read)(const struct device *dev, uint16_t reg_addr, | 
 | 		    uint32_t *data); | 
 |  | 
 | 	/** Write PHY register */ | 
 | 	int (*write)(const struct device *dev, uint16_t reg_addr, | 
 | 		     uint32_t data); | 
 | }; | 
 | /** | 
 |  * @endcond | 
 |  */ | 
 |  | 
 | /** | 
 |  * @brief      Configure PHY link | 
 |  * | 
 |  * This route configures the advertised link speeds. | 
 |  * | 
 |  * @param[in]  dev     PHY device structure | 
 |  * @param      speeds  OR'd link speeds to be advertised by the PHY | 
 |  * | 
 |  * @retval 0 If successful. | 
 |  * @retval -EIO If communication with PHY failed. | 
 |  * @retval -ENOTSUP If not supported. | 
 |  */ | 
 | __syscall int phy_configure_link(const struct device *dev, | 
 | 				 enum phy_link_speed speeds); | 
 |  | 
 | static inline int z_impl_phy_configure_link(const struct device *dev, | 
 | 					    enum phy_link_speed speeds) | 
 | { | 
 | 	const struct ethphy_driver_api *api = | 
 | 		(const struct ethphy_driver_api *)dev->api; | 
 |  | 
 | 	return api->cfg_link(dev, speeds); | 
 | } | 
 |  | 
 | /** | 
 |  * @brief      Get PHY link state | 
 |  * | 
 |  * Returns the current state of the PHY link. This can be used by | 
 |  * to determine when a link is up and the negotiated link speed. | 
 |  * | 
 |  * | 
 |  * @param[in]  dev    PHY device structure | 
 |  * @param      state  Pointer to receive PHY state | 
 |  * | 
 |  * @retval 0 If successful. | 
 |  * @retval -EIO If communication with PHY failed. | 
 |  */ | 
 | __syscall int phy_get_link_state(const struct device *dev, | 
 | 				 struct phy_link_state *state); | 
 |  | 
 | static inline int z_impl_phy_get_link_state(const struct device *dev, | 
 | 					    struct phy_link_state *state) | 
 | { | 
 | 	const struct ethphy_driver_api *api = | 
 | 		(const struct ethphy_driver_api *)dev->api; | 
 |  | 
 | 	return api->get_link(dev, state); | 
 | } | 
 |  | 
 | /** | 
 |  * @brief      Set link state change callback | 
 |  * | 
 |  * Sets a callback that is invoked when link state changes. This is the | 
 |  * preferred method for ethernet drivers to be notified of the PHY link | 
 |  * state change. | 
 |  * | 
 |  * @param[in]  dev        PHY device structure | 
 |  * @param      callback   Callback handler | 
 |  * @param      user_data  Pointer to data specified by user. | 
 |  * | 
 |  * @retval 0 If successful. | 
 |  * @retval -ENOTSUP If not supported. | 
 |  */ | 
 | __syscall int phy_link_callback_set(const struct device *dev, | 
 | 				    phy_callback_t callback, | 
 | 				    void *user_data); | 
 |  | 
 | static inline int z_impl_phy_link_callback_set(const struct device *dev, | 
 | 					       phy_callback_t callback, | 
 | 					       void *user_data) | 
 | { | 
 | 	const struct ethphy_driver_api *api = | 
 | 		(const struct ethphy_driver_api *)dev->api; | 
 |  | 
 | 	return api->link_cb_set(dev, callback, user_data); | 
 | } | 
 |  | 
 | /** | 
 |  * @brief      Read PHY registers | 
 |  * | 
 |  * This routine provides a generic interface to read from a PHY register. | 
 |  * | 
 |  * @param[in]  dev       PHY device structure | 
 |  * @param[in]  reg_addr  Register address | 
 |  * @param      value     Pointer to receive read value | 
 |  * | 
 |  * @retval 0 If successful. | 
 |  * @retval -EIO If communication with PHY failed. | 
 |  */ | 
 | __syscall int phy_read(const struct device *dev, uint16_t reg_addr, | 
 | 		       uint32_t *value); | 
 |  | 
 | static inline int z_impl_phy_read(const struct device *dev, uint16_t reg_addr, | 
 | 				  uint32_t *value) | 
 | { | 
 | 	const struct ethphy_driver_api *api = | 
 | 		(const struct ethphy_driver_api *)dev->api; | 
 |  | 
 | 	return api->read(dev, reg_addr, value); | 
 | } | 
 |  | 
 | /** | 
 |  * @brief      Write PHY register | 
 |  * | 
 |  * This routine provides a generic interface to write to a PHY register. | 
 |  * | 
 |  * @param[in]  dev       PHY device structure | 
 |  * @param[in]  reg_addr  Register address | 
 |  * @param[in]  value     Value to write | 
 |  * | 
 |  * @retval 0 If successful. | 
 |  * @retval -EIO If communication with PHY failed. | 
 |  */ | 
 | __syscall int phy_write(const struct device *dev, uint16_t reg_addr, | 
 | 			uint32_t value); | 
 |  | 
 | static inline int z_impl_phy_write(const struct device *dev, uint16_t reg_addr, | 
 | 				   uint32_t value) | 
 | { | 
 | 	const struct ethphy_driver_api *api = | 
 | 		(const struct ethphy_driver_api *)dev->api; | 
 |  | 
 | 	return api->write(dev, reg_addr, value); | 
 | } | 
 |  | 
 |  | 
 | #ifdef __cplusplus | 
 | } | 
 | #endif | 
 |  | 
 | /** | 
 |  * @} | 
 |  */ | 
 |  | 
 | #include <syscalls/phy.h> | 
 |  | 
 | #endif /* ZEPHYR_INCLUDE_DRIVERS_PHY_H_ */ |