1 // Copyright 2019 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 Free memory of Ethernet PHY instance
178     *
179     * @param[in] phy: Ethernet PHY instance
180     *
181     * @return
182     *      - ESP_OK: free PHY instance successfully
183     *      - ESP_FAIL: free PHY instance failed because some error occurred
184     *
185     */
186     esp_err_t (*del)(esp_eth_phy_t *phy);
187 };
188 
189 /**
190 * @brief Ethernet PHY configuration
191 *
192 */
193 typedef struct {
194     int32_t phy_addr;             /*!< PHY address, set -1 to enable PHY address detection at initialization stage */
195     uint32_t reset_timeout_ms;    /*!< Reset timeout value (Unit: ms) */
196     uint32_t autonego_timeout_ms; /*!< Auto-negotiation timeout value (Unit: ms) */
197     int reset_gpio_num;           /*!< Reset GPIO number, -1 means no hardware reset */
198 } eth_phy_config_t;
199 
200 /**
201  * @brief Default configuration for Ethernet PHY object
202  *
203  */
204 #define ETH_PHY_DEFAULT_CONFIG()           \
205     {                                      \
206         .phy_addr = ESP_ETH_PHY_ADDR_AUTO, \
207         .reset_timeout_ms = 100,           \
208         .autonego_timeout_ms = 4000,       \
209         .reset_gpio_num = 5,               \
210     }
211 
212 /**
213 * @brief Create a PHY instance of IP101
214 *
215 * @param[in] config: configuration of PHY
216 *
217 * @return
218 *      - instance: create PHY instance successfully
219 *      - NULL: create PHY instance failed because some error occurred
220 */
221 esp_eth_phy_t *esp_eth_phy_new_ip101(const eth_phy_config_t *config);
222 
223 /**
224 * @brief Create a PHY instance of RTL8201
225 *
226 * @param[in] config: configuration of PHY
227 *
228 * @return
229 *      - instance: create PHY instance successfully
230 *      - NULL: create PHY instance failed because some error occurred
231 */
232 esp_eth_phy_t *esp_eth_phy_new_rtl8201(const eth_phy_config_t *config);
233 
234 /**
235 * @brief Create a PHY instance of LAN8720
236 *
237 * @param[in] config: configuration of PHY
238 *
239 * @return
240 *      - instance: create PHY instance successfully
241 *      - NULL: create PHY instance failed because some error occurred
242 */
243 esp_eth_phy_t *esp_eth_phy_new_lan8720(const eth_phy_config_t *config);
244 
245 /**
246 * @brief Create a PHY instance of DP83848
247 *
248 * @param[in] config: configuration of PHY
249 *
250 * @return
251 *      - instance: create PHY instance successfully
252 *      - NULL: create PHY instance failed because some error occurred
253 */
254 esp_eth_phy_t *esp_eth_phy_new_dp83848(const eth_phy_config_t *config);
255 
256 /**
257 * @brief Create a PHY instance of KSZ8041
258 *
259 * @param[in] config: configuration of PHY
260 *
261 * @return
262 *      - instance: create PHY instance successfully
263 *      - NULL: create PHY instance failed because some error occurred
264 */
265 esp_eth_phy_t *esp_eth_phy_new_ksz8041(const eth_phy_config_t *config);
266 
267 #if CONFIG_ETH_SPI_ETHERNET_DM9051
268 /**
269 * @brief Create a PHY instance of DM9051
270 *
271 * @param[in] config: configuration of PHY
272 *
273 * @return
274 *      - instance: create PHY instance successfully
275 *      - NULL: create PHY instance failed because some error occurred
276 */
277 esp_eth_phy_t *esp_eth_phy_new_dm9051(const eth_phy_config_t *config);
278 #endif
279 
280 #if CONFIG_ETH_SPI_ETHERNET_W5500
281 /**
282 * @brief Create a PHY instance of W5500
283 *
284 * @param[in] config: configuration of PHY
285 *
286 * @return
287 *      - instance: create PHY instance successfully
288 *      - NULL: create PHY instance failed because some error occurred
289 */
290 esp_eth_phy_t *esp_eth_phy_new_w5500(const eth_phy_config_t *config);
291 #endif
292 #ifdef __cplusplus
293 }
294 #endif
295