1 // Copyright 2019-2021 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #pragma once
15
16 #include <stdbool.h>
17 #include "esp_eth_com.h"
18 #include "sdkconfig.h"
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
24 #define ESP_ETH_PHY_ADDR_AUTO (-1)
25
26 /**
27 * @brief Ethernet PHY
28 *
29 */
30 typedef struct esp_eth_phy_s esp_eth_phy_t;
31
32 /**
33 * @brief Ethernet PHY
34 *
35 */
36 struct esp_eth_phy_s {
37 /**
38 * @brief Set mediator for PHY
39 *
40 * @param[in] phy: Ethernet PHY instance
41 * @param[in] mediator: mediator of Ethernet driver
42 *
43 * @return
44 * - ESP_OK: set mediator for Ethernet PHY instance successfully
45 * - ESP_ERR_INVALID_ARG: set mediator for Ethernet PHY instance failed because of some invalid arguments
46 *
47 */
48 esp_err_t (*set_mediator)(esp_eth_phy_t *phy, esp_eth_mediator_t *mediator);
49
50 /**
51 * @brief Software Reset Ethernet PHY
52 *
53 * @param[in] phy: Ethernet PHY instance
54 *
55 * @return
56 * - ESP_OK: reset Ethernet PHY successfully
57 * - ESP_FAIL: reset Ethernet PHY failed because some error occurred
58 *
59 */
60 esp_err_t (*reset)(esp_eth_phy_t *phy);
61
62 /**
63 * @brief Hardware Reset Ethernet PHY
64 *
65 * @note Hardware reset is mostly done by pull down and up PHY's nRST pin
66 *
67 * @param[in] phy: Ethernet PHY instance
68 *
69 * @return
70 * - ESP_OK: reset Ethernet PHY successfully
71 * - ESP_FAIL: reset Ethernet PHY failed because some error occurred
72 *
73 */
74 esp_err_t (*reset_hw)(esp_eth_phy_t *phy);
75
76 /**
77 * @brief Initialize Ethernet PHY
78 *
79 * @param[in] phy: Ethernet PHY instance
80 *
81 * @return
82 * - ESP_OK: initialize Ethernet PHY successfully
83 * - ESP_FAIL: initialize Ethernet PHY failed because some error occurred
84 *
85 */
86 esp_err_t (*init)(esp_eth_phy_t *phy);
87
88 /**
89 * @brief Deinitialize Ethernet PHY
90 *
91 * @param[in] phyL Ethernet PHY instance
92 *
93 * @return
94 * - ESP_OK: deinitialize Ethernet PHY successfully
95 * - ESP_FAIL: deinitialize Ethernet PHY failed because some error occurred
96 *
97 */
98 esp_err_t (*deinit)(esp_eth_phy_t *phy);
99
100 /**
101 * @brief Start auto negotiation
102 *
103 * @param[in] phy: Ethernet PHY instance
104 *
105 * @return
106 * - ESP_OK: restart auto negotiation successfully
107 * - ESP_FAIL: restart auto negotiation failed because some error occurred
108 *
109 */
110 esp_err_t (*negotiate)(esp_eth_phy_t *phy);
111
112 /**
113 * @brief Get Ethernet PHY link status
114 *
115 * @param[in] phy: Ethernet PHY instance
116 *
117 * @return
118 * - ESP_OK: get Ethernet PHY link status successfully
119 * - ESP_FAIL: get Ethernet PHY link status failed because some error occurred
120 *
121 */
122 esp_err_t (*get_link)(esp_eth_phy_t *phy);
123
124 /**
125 * @brief Power control of Ethernet PHY
126 *
127 * @param[in] phy: Ethernet PHY instance
128 * @param[in] enable: set true to power on Ethernet PHY; ser false to power off Ethernet PHY
129 *
130 * @return
131 * - ESP_OK: control Ethernet PHY power successfully
132 * - ESP_FAIL: control Ethernet PHY power failed because some error occurred
133 *
134 */
135 esp_err_t (*pwrctl)(esp_eth_phy_t *phy, bool enable);
136
137 /**
138 * @brief Set PHY chip address
139 *
140 * @param[in] phy: Ethernet PHY instance
141 * @param[in] addr: PHY chip address
142 *
143 * @return
144 * - ESP_OK: set Ethernet PHY address successfully
145 * - ESP_FAIL: set Ethernet PHY address failed because some error occurred
146 *
147 */
148 esp_err_t (*set_addr)(esp_eth_phy_t *phy, uint32_t addr);
149
150 /**
151 * @brief Get PHY chip address
152 *
153 * @param[in] phy: Ethernet PHY instance
154 * @param[out] addr: PHY chip address
155 *
156 * @return
157 * - ESP_OK: get Ethernet PHY address successfully
158 * - ESP_ERR_INVALID_ARG: get Ethernet PHY address failed because of invalid argument
159 *
160 */
161 esp_err_t (*get_addr)(esp_eth_phy_t *phy, uint32_t *addr);
162
163 /**
164 * @brief Advertise pause function supported by MAC layer
165 *
166 * @param[in] phy: Ethernet PHY instance
167 * @param[out] addr: Pause ability
168 *
169 * @return
170 * - ESP_OK: Advertise pause ability successfully
171 * - ESP_ERR_INVALID_ARG: Advertise pause ability failed because of invalid argument
172 *
173 */
174 esp_err_t (*advertise_pause_ability)(esp_eth_phy_t *phy, uint32_t ability);
175
176 /**
177 * @brief
178 *
179 * @param[in] phy: Ethernet PHY instance
180 * @param[in] enable: enables or disables PHY loopback
181 *
182 * @return
183 * - ESP_OK: configures PHY instance loopback function successfully
184 * - ESP_FAIL: PHY instance loopback configuration failed because some error occurred
185 *
186 */
187 esp_err_t (*loopback)(esp_eth_phy_t *phy, bool enable);
188
189 /**
190 * @brief Free memory of Ethernet PHY instance
191 *
192 * @param[in] phy: Ethernet PHY instance
193 *
194 * @return
195 * - ESP_OK: free PHY instance successfully
196 * - ESP_FAIL: free PHY instance failed because some error occurred
197 *
198 */
199 esp_err_t (*del)(esp_eth_phy_t *phy);
200 };
201
202 /**
203 * @brief Ethernet PHY configuration
204 *
205 */
206 typedef struct {
207 int32_t phy_addr; /*!< PHY address, set -1 to enable PHY address detection at initialization stage */
208 uint32_t reset_timeout_ms; /*!< Reset timeout value (Unit: ms) */
209 uint32_t autonego_timeout_ms; /*!< Auto-negotiation timeout value (Unit: ms) */
210 int reset_gpio_num; /*!< Reset GPIO number, -1 means no hardware reset */
211 } eth_phy_config_t;
212
213 /**
214 * @brief Default configuration for Ethernet PHY object
215 *
216 */
217 #define ETH_PHY_DEFAULT_CONFIG() \
218 { \
219 .phy_addr = ESP_ETH_PHY_ADDR_AUTO, \
220 .reset_timeout_ms = 100, \
221 .autonego_timeout_ms = 4000, \
222 .reset_gpio_num = 5, \
223 }
224
225 /**
226 * @brief Create a PHY instance of IP101
227 *
228 * @param[in] config: configuration of PHY
229 *
230 * @return
231 * - instance: create PHY instance successfully
232 * - NULL: create PHY instance failed because some error occurred
233 */
234 esp_eth_phy_t *esp_eth_phy_new_ip101(const eth_phy_config_t *config);
235
236 /**
237 * @brief Create a PHY instance of RTL8201
238 *
239 * @param[in] config: configuration of PHY
240 *
241 * @return
242 * - instance: create PHY instance successfully
243 * - NULL: create PHY instance failed because some error occurred
244 */
245 esp_eth_phy_t *esp_eth_phy_new_rtl8201(const eth_phy_config_t *config);
246
247 /**
248 * @brief Create a PHY instance of LAN87xx
249 *
250 * @param[in] config: configuration of PHY
251 *
252 * @return
253 * - instance: create PHY instance successfully
254 * - NULL: create PHY instance failed because some error occurred
255 */
256 esp_eth_phy_t *esp_eth_phy_new_lan87xx(const eth_phy_config_t *config);
257
258 /**
259 * @brief Create a PHY instance of LAN8720
260 *
261 * @note For ESP-IDF backwards compatibility reasons. In all other cases, use esp_eth_phy_new_lan87xx instead.
262 *
263 * @param[in] config: configuration of PHY
264 *
265 * @return
266 * - instance: create PHY instance successfully
267 * - NULL: create PHY instance failed because some error occurred
268 */
esp_eth_phy_new_lan8720(const eth_phy_config_t * config)269 static inline esp_eth_phy_t *esp_eth_phy_new_lan8720(const eth_phy_config_t *config)
270 {
271 return esp_eth_phy_new_lan87xx(config);
272 }
273
274 /**
275 * @brief Create a PHY instance of DP83848
276 *
277 * @param[in] config: configuration of PHY
278 *
279 * @return
280 * - instance: create PHY instance successfully
281 * - NULL: create PHY instance failed because some error occurred
282 */
283 esp_eth_phy_t *esp_eth_phy_new_dp83848(const eth_phy_config_t *config);
284
285 /**
286 * @brief Create a PHY instance of KSZ8041
287 *
288 * @param[in] config: configuration of PHY
289 *
290 * @return
291 * - instance: create PHY instance successfully
292 * - NULL: create PHY instance failed because some error occurred
293 */
294 esp_eth_phy_t *esp_eth_phy_new_ksz8041(const eth_phy_config_t *config);
295
296 /**
297 * @brief Create a PHY instance of KSZ8081
298 *
299 * @param[in] config: configuration of PHY
300 *
301 * @return
302 * - instance: create PHY instance successfully
303 * - NULL: create PHY instance failed because some error occurred
304 */
305 esp_eth_phy_t *esp_eth_phy_new_ksz8081(const eth_phy_config_t *config);
306
307 #if CONFIG_ETH_SPI_ETHERNET_DM9051
308 /**
309 * @brief Create a PHY instance of DM9051
310 *
311 * @param[in] config: configuration of PHY
312 *
313 * @return
314 * - instance: create PHY instance successfully
315 * - NULL: create PHY instance failed because some error occurred
316 */
317 esp_eth_phy_t *esp_eth_phy_new_dm9051(const eth_phy_config_t *config);
318 #endif
319
320 #if CONFIG_ETH_SPI_ETHERNET_W5500
321 /**
322 * @brief Create a PHY instance of W5500
323 *
324 * @param[in] config: configuration of PHY
325 *
326 * @return
327 * - instance: create PHY instance successfully
328 * - NULL: create PHY instance failed because some error occurred
329 */
330 esp_eth_phy_t *esp_eth_phy_new_w5500(const eth_phy_config_t *config);
331 #endif
332
333 #if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL
334 /**
335 * @brief Create a PHY instance of KSZ8851SNL
336 *
337 * @param[in] config: configuration of PHY
338 *
339 * @return
340 * - instance: create PHY instance successfully
341 * - NULL: create PHY instance failed because some error occurred
342 */
343 esp_eth_phy_t *esp_eth_phy_new_ksz8851snl(const eth_phy_config_t *config);
344 #endif
345 #ifdef __cplusplus
346 }
347 #endif
348