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