LCOV - code coverage report
Current view: top level - zephyr/net - phy.h Coverage Total Hit
Test: new.info Lines: 100.0 % 32 32
Test Date: 2025-09-05 22:20:39

            Line data    Source code
       1            1 : /**
       2              :  * @file
       3              :  *
       4              :  * @brief Public APIs for Ethernet PHY drivers.
       5              :  */
       6              : 
       7              : /*
       8              :  * Copyright (c) 2021 IP-Logix Inc.
       9              :  * Copyright 2022 NXP
      10              :  * Copyright (c) 2025 Aerlync Labs Inc.
      11              :  *
      12              :  * SPDX-License-Identifier: Apache-2.0
      13              :  */
      14              : #ifndef ZEPHYR_INCLUDE_DRIVERS_PHY_H_
      15              : #define ZEPHYR_INCLUDE_DRIVERS_PHY_H_
      16              : 
      17              : /**
      18              :  * @brief Ethernet PHY Interface
      19              :  * @defgroup ethernet_phy Ethernet PHY Interface
      20              :  * @since 2.7
      21              :  * @version 0.8.0
      22              :  * @ingroup networking
      23              :  * @{
      24              :  */
      25              : #include <zephyr/types.h>
      26              : #include <zephyr/device.h>
      27              : #include <zephyr/sys/util_macro.h>
      28              : #include <errno.h>
      29              : 
      30              : #ifdef __cplusplus
      31              : extern "C" {
      32              : #endif
      33              : 
      34              : /** @brief Ethernet link speeds. */
      35            1 : enum phy_link_speed {
      36              :         /** 10Base Half-Duplex */
      37              :         LINK_HALF_10BASE = BIT(0),
      38              :         /** 10Base Full-Duplex */
      39              :         LINK_FULL_10BASE = BIT(1),
      40              :         /** 100Base Half-Duplex */
      41              :         LINK_HALF_100BASE = BIT(2),
      42              :         /** 100Base Full-Duplex */
      43              :         LINK_FULL_100BASE = BIT(3),
      44              :         /** 1000Base Half-Duplex */
      45              :         LINK_HALF_1000BASE = BIT(4),
      46              :         /** 1000Base Full-Duplex */
      47              :         LINK_FULL_1000BASE = BIT(5),
      48              :         /** 2.5GBase Full-Duplex */
      49              :         LINK_FULL_2500BASE = BIT(6),
      50              :         /** 5GBase Full-Duplex */
      51              :         LINK_FULL_5000BASE = BIT(7),
      52              : };
      53              : 
      54              : /**
      55              :  * @brief Check if phy link is full duplex.
      56              :  *
      57              :  * @param x Link capabilities
      58              :  *
      59              :  * @return True if link is full duplex, false if not.
      60              :  */
      61            1 : #define PHY_LINK_IS_FULL_DUPLEX(x)                                                                 \
      62              :         (x & (LINK_FULL_10BASE | LINK_FULL_100BASE | LINK_FULL_1000BASE | LINK_FULL_2500BASE |     \
      63              :               LINK_FULL_5000BASE))
      64              : 
      65              : /**
      66              :  * @brief Check if phy link speed is 1 Gbit/sec.
      67              :  *
      68              :  * @param x Link capabilities
      69              :  *
      70              :  * @return True if link is 1 Gbit/sec, false if not.
      71              :  */
      72            1 : #define PHY_LINK_IS_SPEED_1000M(x) (x & (LINK_HALF_1000BASE | LINK_FULL_1000BASE))
      73              : 
      74              : /**
      75              :  * @brief Check if phy link speed is 100 Mbit/sec.
      76              :  *
      77              :  * @param x Link capabilities
      78              :  *
      79              :  * @return True if link is 100 Mbit/sec, false if not.
      80              :  */
      81            1 : #define PHY_LINK_IS_SPEED_100M(x) (x & (LINK_HALF_100BASE | LINK_FULL_100BASE))
      82              : 
      83              : /**
      84              :  * @brief Check if phy link speed is 10 Mbit/sec.
      85              :  *
      86              :  * @param x Link capabilities
      87              :  *
      88              :  * @return True if link is 10 Mbit/sec, false if not.
      89              :  */
      90            1 : #define PHY_LINK_IS_SPEED_10M(x) (x & (LINK_HALF_10BASE | LINK_FULL_10BASE))
      91              : 
      92              : /** @brief Link state */
      93            1 : struct phy_link_state {
      94              :         /** Link speed */
      95            1 :         enum phy_link_speed speed;
      96              :         /** When true the link is active and connected */
      97            1 :         bool is_up;
      98              : };
      99              : 
     100              : /** @brief Ethernet configure link flags. */
     101            1 : enum phy_cfg_link_flag {
     102              :         /** Auto-negotiation disable */
     103              :         PHY_FLAG_AUTO_NEGOTIATION_DISABLED = BIT(0),
     104              : };
     105              : 
     106              : /** @brief PLCA (Physical Layer Collision Avoidance) Reconciliation Sublayer configurations */
     107            1 : struct phy_plca_cfg {
     108              :         /** PLCA register map version */
     109            1 :         uint8_t version;
     110              :         /** PLCA configured mode (enable/disable) */
     111            1 :         bool enable;
     112              :         /** PLCA local node identifier */
     113            1 :         uint8_t node_id;
     114              :         /** PLCA node count */
     115            1 :         uint8_t node_count;
     116              :         /** Additional frames a node is allowed to send in single transmit opportunity (TO) */
     117            1 :         uint8_t burst_count;
     118              :         /** Wait time for the MAC to send a new frame before interrupting the burst */
     119            1 :         uint8_t burst_timer;
     120              :         /** PLCA to_timer in bit-times, which determines the PLCA transmit opportunity */
     121            1 :         uint8_t to_timer;
     122              : };
     123              : 
     124              : /**
     125              :  * @brief      Write PHY PLCA configuration
     126              :  *
     127              :  * This routine provides a generic interface to configure PHY PLCA settings.
     128              :  *
     129              :  * @param[in]  dev       PHY device structure
     130              :  * @param[in]  plca_cfg  Pointer to plca configuration structure
     131              :  *
     132              :  * @retval 0 If successful.
     133              :  * @retval -EIO If communication with PHY failed.
     134              :  */
     135            1 : int genphy_get_plca_cfg(const struct device *dev, struct phy_plca_cfg *plca_cfg);
     136              : 
     137              : /**
     138              :  * @brief      Read PHY PLCA configuration
     139              :  *
     140              :  * This routine provides a generic interface to get PHY PLCA settings.
     141              :  *
     142              :  * @param[in]  dev       PHY device structure
     143              :  * @param      plca_cfg  Pointer to plca configuration structure
     144              :  *
     145              :  * @retval 0 If successful.
     146              :  * @retval -EIO If communication with PHY failed.
     147              :  */
     148            1 : int genphy_set_plca_cfg(const struct device *dev, struct phy_plca_cfg *plca_cfg);
     149              : 
     150              : /**
     151              :  * @brief      Read PHY PLCA status
     152              :  *
     153              :  * This routine provides a generic interface to get PHY PLCA status.
     154              :  *
     155              :  * @param[in]  dev          PHY device structure
     156              :  * @param      plca_status  Pointer to plca status
     157              :  *
     158              :  * @retval 0 If successful.
     159              :  * @retval -EIO If communication with PHY failed.
     160              :  */
     161            1 : int genphy_get_plca_sts(const struct device *dev, bool *plca_status);
     162              : 
     163              : /**
     164              :  * @typedef phy_callback_t
     165              :  * @brief Define the callback function signature for
     166              :  * `phy_link_callback_set()` function.
     167              :  *
     168              :  * @param dev       PHY device structure
     169              :  * @param state     Pointer to link_state structure.
     170              :  * @param user_data Pointer to data specified by user
     171              :  */
     172            1 : typedef void (*phy_callback_t)(const struct device *dev, struct phy_link_state *state,
     173              :                                void *user_data);
     174              : 
     175              : /**
     176              :  * @cond INTERNAL_HIDDEN
     177              :  *
     178              :  * These are for internal use only, so skip these in
     179              :  * public documentation.
     180              :  */
     181              : __subsystem struct ethphy_driver_api {
     182              :         /** Get link state */
     183              :         int (*get_link)(const struct device *dev, struct phy_link_state *state);
     184              : 
     185              :         /** Configure link */
     186              :         int (*cfg_link)(const struct device *dev, enum phy_link_speed adv_speeds,
     187              :                         enum phy_cfg_link_flag flags);
     188              : 
     189              :         /** Set callback to be invoked when link state changes. Driver has to invoke
     190              :          * callback once after setting it, even if link state has not changed.
     191              :          */
     192              :         int (*link_cb_set)(const struct device *dev, phy_callback_t cb, void *user_data);
     193              : 
     194              :         /** Read PHY register */
     195              :         int (*read)(const struct device *dev, uint16_t reg_addr, uint32_t *data);
     196              : 
     197              :         /** Write PHY register */
     198              :         int (*write)(const struct device *dev, uint16_t reg_addr, uint32_t data);
     199              : 
     200              :         /** Read PHY C45 register */
     201              :         int (*read_c45)(const struct device *dev, uint8_t devad, uint16_t regad, uint16_t *data);
     202              : 
     203              :         /** Write PHY C45 register */
     204              :         int (*write_c45)(const struct device *dev, uint8_t devad, uint16_t regad, uint16_t data);
     205              : 
     206              :         /* Set PLCA settings */
     207              :         int (*set_plca_cfg)(const struct device *dev, struct phy_plca_cfg *plca_cfg);
     208              : 
     209              :         /* Get PLCA settings */
     210              :         int (*get_plca_cfg)(const struct device *dev, struct phy_plca_cfg *plca_cfg);
     211              : 
     212              :         /* Get PLCA status */
     213              :         int (*get_plca_sts)(const struct device *dev, bool *plca_sts);
     214              : };
     215              : /**
     216              :  * @endcond
     217              :  */
     218              : 
     219              : /**
     220              :  * @brief      Configure PHY link
     221              :  *
     222              :  * This route configures the advertised link speeds.
     223              :  *
     224              :  * @param[in]  dev     PHY device structure
     225              :  * @param      speeds  OR'd link speeds to be advertised by the PHY
     226              :  * @param      flags   OR'd flags to control the link configuration or 0.
     227              :  *
     228              :  * @retval 0 If successful.
     229              :  * @retval -EIO If communication with PHY failed.
     230              :  * @retval -ENOTSUP If not supported.
     231              :  * @retval -EALREADY If already configured with the same speeds and flags.
     232              :  */
     233            1 : static inline int phy_configure_link(const struct device *dev, enum phy_link_speed speeds,
     234              :                                      enum phy_cfg_link_flag flags)
     235              : {
     236              :         if (DEVICE_API_GET(ethphy, dev)->cfg_link == NULL) {
     237              :                 return -ENOSYS;
     238              :         }
     239              : 
     240              :         /* Check if only one speed is set, when auto-negotiation is disabled */
     241              :         if ((flags & PHY_FLAG_AUTO_NEGOTIATION_DISABLED) && !IS_POWER_OF_TWO(speeds)) {
     242              :                 return -EINVAL;
     243              :         }
     244              : 
     245              :         return DEVICE_API_GET(ethphy, dev)->cfg_link(dev, speeds, flags);
     246              : }
     247              : 
     248              : /**
     249              :  * @brief      Get PHY link state
     250              :  *
     251              :  * Returns the current state of the PHY link. This can be used by
     252              :  * to determine when a link is up and the negotiated link speed.
     253              :  *
     254              :  *
     255              :  * @param[in]  dev    PHY device structure
     256              :  * @param      state  Pointer to receive PHY state
     257              :  *
     258              :  * @retval 0 If successful.
     259              :  * @retval -EIO If communication with PHY failed.
     260              :  */
     261            1 : static inline int phy_get_link_state(const struct device *dev, struct phy_link_state *state)
     262              : {
     263              :         if (DEVICE_API_GET(ethphy, dev)->get_link == NULL) {
     264              :                 return -ENOSYS;
     265              :         }
     266              : 
     267              :         return DEVICE_API_GET(ethphy, dev)->get_link(dev, state);
     268              : }
     269              : 
     270              : /**
     271              :  * @brief      Set link state change callback
     272              :  *
     273              :  * Sets a callback that is invoked when link state changes. This is the
     274              :  * preferred method for ethernet drivers to be notified of the PHY link
     275              :  * state change. The callback will be invoked once after setting it,
     276              :  * even if link state has not changed. There can only one callback
     277              :  * function set and active at a time. This function is mainly used
     278              :  * by ethernet drivers to register a callback to be notified of
     279              :  * link state changes and should therefore not be used by applications.
     280              :  *
     281              :  * @param[in]  dev        PHY device structure
     282              :  * @param      callback   Callback handler
     283              :  * @param      user_data  Pointer to data specified by user.
     284              :  *
     285              :  * @retval 0 If successful.
     286              :  * @retval -ENOTSUP If not supported.
     287              :  */
     288            1 : static inline int phy_link_callback_set(const struct device *dev, phy_callback_t callback,
     289              :                                         void *user_data)
     290              : {
     291              :         if (DEVICE_API_GET(ethphy, dev)->link_cb_set == NULL) {
     292              :                 return -ENOSYS;
     293              :         }
     294              : 
     295              :         return DEVICE_API_GET(ethphy, dev)->link_cb_set(dev, callback, user_data);
     296              : }
     297              : 
     298              : /**
     299              :  * @brief      Read PHY registers
     300              :  *
     301              :  * This routine provides a generic interface to read from a PHY register.
     302              :  *
     303              :  * @param[in]  dev       PHY device structure
     304              :  * @param[in]  reg_addr  Register address
     305              :  * @param      value     Pointer to receive read value
     306              :  *
     307              :  * @retval 0 If successful.
     308              :  * @retval -EIO If communication with PHY failed.
     309              :  */
     310            1 : static inline int phy_read(const struct device *dev, uint16_t reg_addr, uint32_t *value)
     311              : {
     312              :         if (DEVICE_API_GET(ethphy, dev)->read == NULL) {
     313              :                 return -ENOSYS;
     314              :         }
     315              : 
     316              :         return DEVICE_API_GET(ethphy, dev)->read(dev, reg_addr, value);
     317              : }
     318              : 
     319              : /**
     320              :  * @brief      Write PHY register
     321              :  *
     322              :  * This routine provides a generic interface to write to a PHY register.
     323              :  *
     324              :  * @param[in]  dev       PHY device structure
     325              :  * @param[in]  reg_addr  Register address
     326              :  * @param[in]  value     Value to write
     327              :  *
     328              :  * @retval 0 If successful.
     329              :  * @retval -EIO If communication with PHY failed.
     330              :  */
     331            1 : static inline int phy_write(const struct device *dev, uint16_t reg_addr, uint32_t value)
     332              : {
     333              :         if (DEVICE_API_GET(ethphy, dev)->write == NULL) {
     334              :                 return -ENOSYS;
     335              :         }
     336              : 
     337              :         return DEVICE_API_GET(ethphy, dev)->write(dev, reg_addr, value);
     338              : }
     339              : 
     340              : /**
     341              :  * @brief      Read PHY C45 register
     342              :  *
     343              :  * This routine provides a generic interface to read to a PHY C45 register.
     344              :  *
     345              :  * @param[in]  dev       PHY device structure
     346              :  * @param[in]  devad       Device address
     347              :  * @param[in]  regad       Register address
     348              :  * @param      data        Pointer to receive read data
     349              :  *
     350              :  * @retval 0 If successful.
     351              :  * @retval -EIO If communication with PHY failed.
     352              :  */
     353            1 : static inline int phy_read_c45(const struct device *dev, uint8_t devad, uint16_t regad,
     354              :                                uint16_t *data)
     355              : {
     356              :         if (DEVICE_API_GET(ethphy, dev)->read_c45 == NULL) {
     357              :                 return -ENOSYS;
     358              :         }
     359              : 
     360              :         return DEVICE_API_GET(ethphy, dev)->read_c45(dev, devad, regad, data);
     361              : }
     362              : 
     363              : /**
     364              :  * @brief      Write PHY C45 register
     365              :  *
     366              :  * This routine provides a generic interface to write to a PHY C45 register.
     367              :  *
     368              :  * @param[in]  dev       PHY device structure
     369              :  * @param[in]  devad       Device address
     370              :  * @param[in]  regad       Register address
     371              :  * @param[in]  data        Data to write
     372              :  *
     373              :  * @retval 0 If successful.
     374              :  * @retval -EIO If communication with PHY failed.
     375              :  */
     376            1 : static inline int phy_write_c45(const struct device *dev, uint8_t devad, uint16_t regad,
     377              :                                 uint16_t data)
     378              : {
     379              :         if (DEVICE_API_GET(ethphy, dev)->write_c45 == NULL) {
     380              :                 return -ENOSYS;
     381              :         }
     382              : 
     383              :         return DEVICE_API_GET(ethphy, dev)->write_c45(dev, devad, regad, data);
     384              : }
     385              : 
     386              : /**
     387              :  * @brief      Write PHY PLCA configuration
     388              :  *
     389              :  * This routine provides a generic interface to configure PHY PLCA settings.
     390              :  *
     391              :  * @param[in]  dev       PHY device structure
     392              :  * @param[in]  plca_cfg  Pointer to plca configuration structure
     393              :  *
     394              :  * @retval 0 If successful.
     395              :  * @retval -EIO If communication with PHY failed.
     396              :  */
     397            1 : static inline int phy_set_plca_cfg(const struct device *dev, struct phy_plca_cfg *plca_cfg)
     398              : {
     399              :         if (DEVICE_API_GET(ethphy, dev)->set_plca_cfg == NULL) {
     400              :                 return -ENOSYS;
     401              :         }
     402              : 
     403              :         return DEVICE_API_GET(ethphy, dev)->set_plca_cfg(dev, plca_cfg);
     404              : }
     405              : 
     406              : /**
     407              :  * @brief      Read PHY PLCA configuration
     408              :  *
     409              :  * This routine provides a generic interface to get PHY PLCA settings.
     410              :  *
     411              :  * @param[in]  dev       PHY device structure
     412              :  * @param      plca_cfg  Pointer to plca configuration structure
     413              :  *
     414              :  * @retval 0 If successful.
     415              :  * @retval -EIO If communication with PHY failed.
     416              :  */
     417            1 : static inline int phy_get_plca_cfg(const struct device *dev, struct phy_plca_cfg *plca_cfg)
     418              : {
     419              :         if (DEVICE_API_GET(ethphy, dev)->get_plca_cfg == NULL) {
     420              :                 return -ENOSYS;
     421              :         }
     422              : 
     423              :         return DEVICE_API_GET(ethphy, dev)->get_plca_cfg(dev, plca_cfg);
     424              : }
     425              : 
     426              : /**
     427              :  * @brief      Read PHY PLCA status
     428              :  *
     429              :  * This routine provides a generic interface to get PHY PLCA status.
     430              :  *
     431              :  * @param[in]  dev          PHY device structure
     432              :  * @param      plca_status  Pointer to plca status
     433              :  *
     434              :  * @retval 0 If successful.
     435              :  * @retval -EIO If communication with PHY failed.
     436              :  */
     437            1 : static inline int phy_get_plca_sts(const struct device *dev, bool *plca_status)
     438              : {
     439              :         if (DEVICE_API_GET(ethphy, dev)->get_plca_sts == NULL) {
     440              :                 return -ENOSYS;
     441              :         }
     442              : 
     443              :         return DEVICE_API_GET(ethphy, dev)->get_plca_sts(dev, plca_status);
     444              : }
     445              : 
     446              : #ifdef __cplusplus
     447              : }
     448              : #endif
     449              : 
     450              : /**
     451              :  * @}
     452              :  */
     453              : 
     454              : #endif /* ZEPHYR_INCLUDE_DRIVERS_PHY_H_ */
        

Generated by: LCOV version 2.0-1