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 *
11 * SPDX-License-Identifier: Apache-2.0
12 */
13 #ifndef ZEPHYR_INCLUDE_DRIVERS_PHY_H_
14 #define ZEPHYR_INCLUDE_DRIVERS_PHY_H_
15
16 /**
17 * @brief Ethernet PHY Interface
18 * @defgroup ethernet_phy Ethernet PHY Interface
19 * @ingroup networking
20 * @{
21 */
22 #include <zephyr/types.h>
23 #include <zephyr/device.h>
24
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28
29 /** @brief Ethernet link speeds. */
30 enum phy_link_speed {
31 /** 10Base-T Half-Duplex */
32 LINK_HALF_10BASE_T = BIT(0),
33 /** 10Base-T Full-Duplex */
34 LINK_FULL_10BASE_T = BIT(1),
35 /** 100Base-T Half-Duplex */
36 LINK_HALF_100BASE_T = BIT(2),
37 /** 100Base-T Full-Duplex */
38 LINK_FULL_100BASE_T = BIT(3),
39 /** 1000Base-T Half-Duplex */
40 LINK_HALF_1000BASE_T = BIT(4),
41 /** 1000Base-T Full-Duplex */
42 LINK_FULL_1000BASE_T = BIT(5),
43 };
44
45 #define PHY_LINK_IS_FULL_DUPLEX(x) (x & (BIT(1) | BIT(3) | BIT(5)))
46 #define PHY_LINK_IS_SPEED_1000M(x) (x & (BIT(4) | BIT(5)))
47 #define PHY_LINK_IS_SPEED_100M(x) (x & (BIT(2) | BIT(3)))
48
49 /** @brief Link state */
50 struct phy_link_state {
51 /** Link speed */
52 enum phy_link_speed speed;
53 /** When true the link is active and connected */
54 bool is_up;
55 };
56
57 /**
58 * @typedef phy_callback_t
59 * @brief Define the callback function signature for
60 * `phy_link_callback_set()` function.
61 *
62 * @param dev PHY device structure
63 * @param state Pointer to link_state structure.
64 * @param user_data Pointer to data specified by user
65 */
66 typedef void (*phy_callback_t)(const struct device *dev,
67 struct phy_link_state *state,
68 void *user_data);
69
70 /**
71 * @cond INTERNAL_HIDDEN
72 *
73 * These are for internal use only, so skip these in
74 * public documentation.
75 */
76 __subsystem struct ethphy_driver_api {
77 /** Get link state */
78 int (*get_link)(const struct device *dev,
79 struct phy_link_state *state);
80
81 /** Configure link */
82 int (*cfg_link)(const struct device *dev,
83 enum phy_link_speed adv_speeds);
84
85 /** Set callback to be invoked when link state changes. */
86 int (*link_cb_set)(const struct device *dev, phy_callback_t cb,
87 void *user_data);
88
89 /** Read PHY register */
90 int (*read)(const struct device *dev, uint16_t reg_addr,
91 uint32_t *data);
92
93 /** Write PHY register */
94 int (*write)(const struct device *dev, uint16_t reg_addr,
95 uint32_t data);
96 };
97 /**
98 * @endcond
99 */
100
101 /**
102 * @brief Configure PHY link
103 *
104 * This route configures the advertised link speeds.
105 *
106 * @param[in] dev PHY device structure
107 * @param speeds OR'd link speeds to be advertised by the PHY
108 *
109 * @retval 0 If successful.
110 * @retval -EIO If communication with PHY failed.
111 * @retval -ENOTSUP If not supported.
112 */
113 __syscall int phy_configure_link(const struct device *dev,
114 enum phy_link_speed speeds);
115
z_impl_phy_configure_link(const struct device * dev,enum phy_link_speed speeds)116 static inline int z_impl_phy_configure_link(const struct device *dev,
117 enum phy_link_speed speeds)
118 {
119 const struct ethphy_driver_api *api =
120 (const struct ethphy_driver_api *)dev->api;
121
122 return api->cfg_link(dev, speeds);
123 }
124
125 /**
126 * @brief Get PHY link state
127 *
128 * Returns the current state of the PHY link. This can be used by
129 * to determine when a link is up and the negotiated link speed.
130 *
131 *
132 * @param[in] dev PHY device structure
133 * @param state Pointer to receive PHY state
134 *
135 * @retval 0 If successful.
136 * @retval -EIO If communication with PHY failed.
137 */
138 __syscall int phy_get_link_state(const struct device *dev,
139 struct phy_link_state *state);
140
z_impl_phy_get_link_state(const struct device * dev,struct phy_link_state * state)141 static inline int z_impl_phy_get_link_state(const struct device *dev,
142 struct phy_link_state *state)
143 {
144 const struct ethphy_driver_api *api =
145 (const struct ethphy_driver_api *)dev->api;
146
147 return api->get_link(dev, state);
148 }
149
150 /**
151 * @brief Set link state change callback
152 *
153 * Sets a callback that is invoked when link state changes. This is the
154 * preferred method for ethernet drivers to be notified of the PHY link
155 * state change.
156 *
157 * @param[in] dev PHY device structure
158 * @param callback Callback handler
159 * @param user_data Pointer to data specified by user.
160 *
161 * @retval 0 If successful.
162 * @retval -ENOTSUP If not supported.
163 */
164 __syscall int phy_link_callback_set(const struct device *dev,
165 phy_callback_t callback,
166 void *user_data);
167
z_impl_phy_link_callback_set(const struct device * dev,phy_callback_t callback,void * user_data)168 static inline int z_impl_phy_link_callback_set(const struct device *dev,
169 phy_callback_t callback,
170 void *user_data)
171 {
172 const struct ethphy_driver_api *api =
173 (const struct ethphy_driver_api *)dev->api;
174
175 return api->link_cb_set(dev, callback, user_data);
176 }
177
178 /**
179 * @brief Read PHY registers
180 *
181 * This routine provides a generic interface to read from a PHY register.
182 *
183 * @param[in] dev PHY device structure
184 * @param[in] reg_addr Register address
185 * @param value Pointer to receive read value
186 *
187 * @retval 0 If successful.
188 * @retval -EIO If communication with PHY failed.
189 */
190 __syscall int phy_read(const struct device *dev, uint16_t reg_addr,
191 uint32_t *value);
192
z_impl_phy_read(const struct device * dev,uint16_t reg_addr,uint32_t * value)193 static inline int z_impl_phy_read(const struct device *dev, uint16_t reg_addr,
194 uint32_t *value)
195 {
196 const struct ethphy_driver_api *api =
197 (const struct ethphy_driver_api *)dev->api;
198
199 return api->read(dev, reg_addr, value);
200 }
201
202 /**
203 * @brief Write PHY register
204 *
205 * This routine provides a generic interface to write to a PHY register.
206 *
207 * @param[in] dev PHY device structure
208 * @param[in] reg_addr Register address
209 * @param[in] value Value to write
210 *
211 * @retval 0 If successful.
212 * @retval -EIO If communication with PHY failed.
213 */
214 __syscall int phy_write(const struct device *dev, uint16_t reg_addr,
215 uint32_t value);
216
z_impl_phy_write(const struct device * dev,uint16_t reg_addr,uint32_t value)217 static inline int z_impl_phy_write(const struct device *dev, uint16_t reg_addr,
218 uint32_t value)
219 {
220 const struct ethphy_driver_api *api =
221 (const struct ethphy_driver_api *)dev->api;
222
223 return api->write(dev, reg_addr, value);
224 }
225
226
227 #ifdef __cplusplus
228 }
229 #endif
230
231 /**
232 * @}
233 */
234
235 #include <syscalls/phy.h>
236
237 #endif /* ZEPHYR_INCLUDE_DRIVERS_PHY_H_ */
238