|  | /** | 
|  | * @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_ */ |