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