From 08eadd8d25abb4766807b7ba3aadfbee4791cb69 Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Fri, 6 Sep 2024 18:27:09 +0700 Subject: [PATCH 1/5] fix(newlib): sbom: add CVE-2024-30949 to cve-exclude-list --- components/newlib/sbom.yml | 3 +++ docs/en/security/vulnerabilities.rst | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/components/newlib/sbom.yml b/components/newlib/sbom.yml index f0fee8725557..496cb10c30b2 100644 --- a/components/newlib/sbom.yml +++ b/components/newlib/sbom.yml @@ -4,3 +4,6 @@ cpe: cpe:2.3:a:newlib_project:newlib:{}:*:*:*:*:*:*:* supplier: 'Organization: Espressif Systems (Shanghai) CO LTD' originator: 'Organization: Red Hat Incorporated' description: An open-source C standard library implementation with additional features and patches from Espressif. +cve-exclude-list: + - cve: CVE-2024-30949 + reason: A vulnerability was discovered in the gettimeofday system call implementation within the RISC-V libgloss component of Newlib. ESP-IDF does not link against libgloss for RISC-V, hence the issue is not directly applicable. Still, the relevant fix has been patched through https://github.com/espressif/newlib-esp32/commit/047ba47013c2656a1e7838dc86cbc75aeeaa67a7 diff --git a/docs/en/security/vulnerabilities.rst b/docs/en/security/vulnerabilities.rst index a8629f945e98..00d87aad5ff3 100644 --- a/docs/en/security/vulnerabilities.rst +++ b/docs/en/security/vulnerabilities.rst @@ -10,6 +10,15 @@ This page briefly lists all of the vulnerabilities that are discovered and fixed CVE-2024 -------- +CVE-2024-30949 +~~~~~~~~~~~~~~ + +RISC-V gettimeofday system call vulnerability in Newlib's + +* Impact: ESP-IDF does not use system call implementations from Newlib +* Resolution: NA + + CVE-2024-28183 ~~~~~~~~~~~~~~ From 5888cb8b4c4ef5e5a2deb8fac36f7019f745bde8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Neboj=C5=A1a=20Cvetkovi=C4=87?= Date: Thu, 27 Jun 2024 18:26:11 +0100 Subject: [PATCH 2/5] build: Reduce verbosity of disabled component manager warning closes https://github.com/espressif/esp-idf/pull/14097 --- tools/cmake/build.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cmake/build.cmake b/tools/cmake/build.cmake index 81f133e23019..c9414c437d43 100644 --- a/tools/cmake/build.cmake +++ b/tools/cmake/build.cmake @@ -631,7 +631,7 @@ macro(idf_build_process target) endforeach() if(NOT "${__components_with_manifests}" STREQUAL "") - message(WARNING "\"idf_component.yml\" file was found for components:\n${__components_with_manifests}" + message(NOTICE "\"idf_component.yml\" file was found for components:\n${__components_with_manifests}" "However, the component manager is not enabled.") endif() endif() From 24fa2facd3849c57cc638fab7e410f52807e33b4 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Mon, 30 Sep 2024 10:44:44 +0530 Subject: [PATCH 3/5] docs: update mbedtls guide for TLS 1.3 supported change --- docs/en/api-reference/protocols/mbedtls.rst | 12 ++++-------- docs/zh_CN/api-reference/protocols/mbedtls.rst | 12 ++++-------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/docs/en/api-reference/protocols/mbedtls.rst b/docs/en/api-reference/protocols/mbedtls.rst index 11a9fb02df3b..cc636fd033ca 100644 --- a/docs/en/api-reference/protocols/mbedtls.rst +++ b/docs/en/api-reference/protocols/mbedtls.rst @@ -9,7 +9,7 @@ Mbed TLS ESP-IDF uses a `fork `_ of Mbed TLS which includes a few patches (related to hardware routines of certain modules like ``bignum (MPI)`` and ``ECC``) over vanilla Mbed TLS. -Mbed TLS supports SSL 3.0 up to TLS 1.3 and DTLS 1.0 to 1.2 communication by providing the following: +Mbed TLS supports TLS 1.2, TLS 1.3 and DTLS 1.2 communication by providing the following: - TCP/IP communication functions: listen, connect, accept, read/write. - SSL/TLS communication functions: init, handshake, read/write. @@ -18,8 +18,9 @@ Mbed TLS supports SSL 3.0 up to TLS 1.3 and DTLS 1.0 to 1.2 communication by pro - Hashing - Encryption/decryption -Supported TLS versions include SSL 3.0, TLS 1.0, TLS 1.1, TLS 1.2, and TLS 1.3, but on the latest ESP-IDF, SSL 3.0, TLS 1.0, and TLS 1.1 have been removed from Mbed TLS. Supported DTLS versions include DTLS 1.0, DTLS 1.1, and DTLS 1.2, but on the latest ESP-IDF, DTLS 1.0 has been removed from Mbed TLS. +.. note:: + Mbed TLS v3.x.x series supports only TLS 1.2 and TLS 1.3 protocols. Support for SSL 3.0, TLS 1.0/1.1 and DTLS 1.0 has been removed (deprecated). TLS 1.3 is fully supported starting Mbed TLS v3.6.0 release, before this release some features were still in experimental state. Please refer to :component_file:`Mbed TLS ChangeLog ` for more details. Mbed TLS Documentation ---------------------- @@ -73,11 +74,6 @@ Following is a brief list of important config options accessible at ``Component :SOC_MPI_SUPPORTED: - :ref:`CONFIG_MBEDTLS_HARDWARE_MPI`: Support for hardware MPI (bignum) acceleration :SOC_ECC_SUPPORTED: - :ref:`CONFIG_MBEDTLS_HARDWARE_ECC`: Support for hardware ECC acceleration -.. note:: - - Mbed TLS v3.6.0 and later support only TLS 1.2 and TLS 1.3 (SSL 3.0, TLS 1.0, TLS 1.1, and DTLS 1.0 are not supported). More information about this can be found out `here `__. - - Performance and Memory Tweaks ----------------------------- @@ -122,5 +118,5 @@ Reducing Binary Size Under ``Component Config -> mbedTLS``, there are multiple Mbed TLS features which are enabled by default but can be disabled if not needed to save code size. More information can be about this can be found in :ref:`Minimizing Binary Size ` docs. -.. _`API Reference`: https://mbed-tls.readthedocs.io/projects/api/en/v3.4.1/ +.. _`API Reference`: https://mbed-tls.readthedocs.io/projects/api/en/v3.6.1/ .. _`Knowledge Base`: https://mbed-tls.readthedocs.io/en/latest/kb/ diff --git a/docs/zh_CN/api-reference/protocols/mbedtls.rst b/docs/zh_CN/api-reference/protocols/mbedtls.rst index 976d039ac400..2ed687549696 100644 --- a/docs/zh_CN/api-reference/protocols/mbedtls.rst +++ b/docs/zh_CN/api-reference/protocols/mbedtls.rst @@ -9,7 +9,7 @@ Mbed TLS ESP-IDF 使用的 Mbed TLS `复刻仓库 `_ 中包含对原生 Mbed TLS 的补丁。这些补丁与某些模块的硬件例程有关,如 ``bignum (MPI)`` 和 ``ECC``。 -Mbed TLS 提供以下功能: +Mbed TLS 通过提供以下内容支持 TLS 1.2、TLS 1.3 和 DTLS 1.2 通信: - TCP/IP 通信功能:监听、连接、接收、读/写。 - SSL/TLS 通信功能:初始化、握手、读/写。 @@ -18,8 +18,9 @@ Mbed TLS 提供以下功能: - 哈希 - 加密/解密 -TLS 版本支持 SSL 3.0, TLS 1.0、TLS 1.1、TLS 1.2 和 TLS 1.3,但是最新的 ESP-IDF 上 Mbed TLS 已经移除了 SSL 3.0、TLS 1.0 和 TLS 1.1。DTLS 版本支持 DTLS 1.0、DTLS 1.1 和 DTLS 1.2,但最新的 ESP-IDF 上 Mbed TLS 已经移除了 DTLS 1.0。 +.. note:: + Mbed TLS v3.x.x 系列仅支持 TLS 1.2 和 TLS 1.3 协议。对 SSL 3.0、TLS 1.0/1.1 和 DTLS 1.0 的支持已被删除(弃用)。从 Mbed TLS v3.6.0 版本开始完全支持 TLS 1.3,在此版本之前,某些功能仍处于试验状态。有关更多详细信息,请参阅 :component_file:`Mbed TLS ChangeLog `。 Mbed TLS 文档 ------------------ @@ -73,11 +74,6 @@ ESP-IDF 中的示例使用 :doc:`/api-reference/protocols/esp_tls`,为访问 :SOC_MPI_SUPPORTED: - :ref:`CONFIG_MBEDTLS_HARDWARE_MPI`: 支持硬件 MPI (bignum) 加速 :SOC_ECC_SUPPORTED: - :ref:`CONFIG_MBEDTLS_HARDWARE_ECC`: 支持硬件 ECC 加速 -.. note:: - - Mbed TLS v3.0.0 及其更新版本仅支持 TLS 1.2 和 TLS 1.3,不支持 SSL 3.0、TLS 1.0、TLS 1.1、和 DTLS 1.0)。TLS 1.3 尚在试验阶段,仅支持客户端。要了解更多信息,请点击 `此处 `__。 - - 性能和内存调整 ------------------ @@ -122,5 +118,5 @@ ESP-IDF 中的示例使用 :doc:`/api-reference/protocols/esp_tls`,为访问 在 ``Component Config -> mbedTLS`` 中,有多个 Mbed TLS 功能默认为启用状态。如果不需要这些功能,可将其禁用以减小固件大小。要了解更多信息,请参考 :ref:`Minimizing Binary Size ` 文档。 -.. _`API Reference`: https://mbed-tls.readthedocs.io/projects/api/en/v3.4.1/ +.. _`API Reference`: https://mbed-tls.readthedocs.io/projects/api/en/v3.6.1/ .. _`Knowledge Base`: https://mbed-tls.readthedocs.io/en/latest/kb/ From 0738314308ad36a73601ddb8bb82f1dcbfe1f550 Mon Sep 17 00:00:00 2001 From: Ondrej Kosta Date: Thu, 19 Sep 2024 15:54:26 +0200 Subject: [PATCH 4/5] feat(esp_eth): added new generic PHY driver --- components/esp_eth/CMakeLists.txt | 1 + components/esp_eth/include/esp_eth_phy.h | 44 ++++-- .../esp_eth/include/esp_eth_phy_802_3.h | 29 ++-- .../esp_eth/src/phy/esp_eth_phy_802_3.c | 129 +++++++++++++++--- .../esp_eth/src/phy/esp_eth_phy_generic.c | 37 +++++ .../esp_eth/src/phy/esp_eth_phy_ip101.c | 19 ++- .../esp_eth/src/phy/esp_eth_phy_lan87xx.c | 22 +-- .../esp_eth/src/phy/esp_eth_phy_rtl8201.c | 22 ++- docs/en/api-reference/network/esp_eth.rst | 20 ++- .../Kconfig.projbuild | 9 ++ .../protocol_examples_common/eth_connect.c | 4 +- .../ethernet_init/Kconfig.projbuild | 9 ++ .../components/ethernet_init/ethernet_init.c | 4 +- examples/ethernet/basic/pytest_eth_basic.py | 1 + .../basic/sdkconfig.ci.default_generic | 11 ++ 15 files changed, 283 insertions(+), 78 deletions(-) create mode 100644 components/esp_eth/src/phy/esp_eth_phy_generic.c create mode 100644 examples/ethernet/basic/sdkconfig.ci.default_generic diff --git a/components/esp_eth/CMakeLists.txt b/components/esp_eth/CMakeLists.txt index 132f01a30110..6a6941397d6e 100644 --- a/components/esp_eth/CMakeLists.txt +++ b/components/esp_eth/CMakeLists.txt @@ -30,6 +30,7 @@ if(CONFIG_ETH_ENABLED) list(APPEND srcs "src/mac/esp_eth_mac_esp.c" "src/mac/esp_eth_mac_esp_dma.c" "src/mac/esp_eth_mac_esp_gpio.c" + "src/phy/esp_eth_phy_generic.c" "src/phy/esp_eth_phy_dp83848.c" "src/phy/esp_eth_phy_ip101.c" "src/phy/esp_eth_phy_ksz80xx.c" diff --git a/components/esp_eth/include/esp_eth_phy.h b/components/esp_eth/include/esp_eth_phy.h index 82c16aef41d0..109a8014dc4f 100644 --- a/components/esp_eth/include/esp_eth_phy.h +++ b/components/esp_eth/include/esp_eth_phy.h @@ -13,7 +13,8 @@ extern "C" { #endif -#define ESP_ETH_PHY_ADDR_AUTO (-1) +#define ESP_ETH_PHY_ADDR_AUTO (-1) +#define ESP_ETH_NO_POST_HW_RESET_DELAY (-1) /** * @brief Auto-negotiation control commands @@ -273,24 +274,45 @@ struct esp_eth_phy_s { * */ typedef struct { - int32_t phy_addr; /*!< PHY address, set -1 to enable PHY address detection at initialization stage */ - uint32_t reset_timeout_ms; /*!< Reset timeout value (Unit: ms) */ - uint32_t autonego_timeout_ms; /*!< Auto-negotiation timeout value (Unit: ms) */ - int reset_gpio_num; /*!< Reset GPIO number, -1 means no hardware reset */ + int32_t phy_addr; /*!< PHY address, set -1 to enable PHY address detection at initialization stage */ + uint32_t reset_timeout_ms; /*!< Reset timeout value (Unit: ms) */ + uint32_t autonego_timeout_ms; /*!< Auto-negotiation timeout value (Unit: ms) */ + int reset_gpio_num; /*!< Reset GPIO number, -1 means no hardware reset */ + int32_t hw_reset_assert_time_us; /*!< Time the reset pin is asserted (Unit: us), 0 to use chip specific default */ + int32_t post_hw_reset_delay_ms; /*!< Time to wait after the HW reset (Unit: ms), 0 to use chip specific default, -1 means no wait */ } eth_phy_config_t; /** * @brief Default configuration for Ethernet PHY object * */ -#define ETH_PHY_DEFAULT_CONFIG() \ - { \ - .phy_addr = ESP_ETH_PHY_ADDR_AUTO, \ - .reset_timeout_ms = 100, \ - .autonego_timeout_ms = 4000, \ - .reset_gpio_num = 5, \ +#define ETH_PHY_DEFAULT_CONFIG() \ + { \ + .phy_addr = ESP_ETH_PHY_ADDR_AUTO, \ + .reset_timeout_ms = 100, \ + .autonego_timeout_ms = 4000, \ + .reset_gpio_num = 5, \ + .hw_reset_assert_time_us = 0, \ + .post_hw_reset_delay_ms = 0 \ } +/** +* @brief Create a PHY instance of generic chip which conforms with IEEE 802.3 +* +* @note Default reset timing configuration is set conservatively( @c DEFAULT_PHY_RESET_ASSERTION_TIME_US ). +* If you need faster response and your chip supports it, configure it via @c config parameter. +* +* @warning While basic functionality should always work, some specific features might be limited, +* even if the PHY meets IEEE 802.3 standard. A typical example is loopback functionality, +* where certain PHYs may require setting a specific speed mode to operate correctly. +* +* @param[in] config configuration of PHY +* @return +* - instance: create PHY instance successfully +* - NULL: create PHY instance failed because some error occurred + */ +esp_eth_phy_t *esp_eth_phy_new_generic(const eth_phy_config_t *config); + /** * @brief Create a PHY instance of IP101 * diff --git a/components/esp_eth/include/esp_eth_phy_802_3.h b/components/esp_eth/include/esp_eth_phy_802_3.h index 0cc83ed1390c..e90646bd37d8 100644 --- a/components/esp_eth/include/esp_eth_phy_802_3.h +++ b/components/esp_eth/include/esp_eth_phy_802_3.h @@ -19,13 +19,15 @@ extern "C" { * */ typedef struct { - esp_eth_phy_t parent; /*!< Parent Ethernet PHY instance */ - esp_eth_mediator_t *eth; /*!< Mediator of Ethernet driver */ - int addr; /*!< PHY address */ - uint32_t reset_timeout_ms; /*!< Reset timeout value (Unit: ms) */ - uint32_t autonego_timeout_ms; /*!< Auto-negotiation timeout value (Unit: ms) */ - eth_link_t link_status; /*!< Current Link status */ - int reset_gpio_num; /*!< Reset GPIO number, -1 means no hardware reset */ + esp_eth_phy_t parent; /*!< Parent Ethernet PHY instance */ + esp_eth_mediator_t *eth; /*!< Mediator of Ethernet driver */ + int addr; /*!< PHY address */ + uint32_t reset_timeout_ms; /*!< Reset timeout value (Unit: ms) */ + uint32_t autonego_timeout_ms; /*!< Auto-negotiation timeout value (Unit: ms) */ + eth_link_t link_status; /*!< Current Link status */ + int reset_gpio_num; /*!< Reset GPIO number, -1 means no hardware reset */ + int32_t hw_reset_assert_time_us; /*!< Time the reset pin is asserted (Unit: us) */ + int32_t post_hw_reset_delay_ms; /*!< Time to wait after the HW reset (Unit: ms) */ } phy_802_3_t; /** @@ -73,6 +75,16 @@ esp_err_t esp_eth_phy_802_3_reset(phy_802_3_t *phy_802_3); */ esp_err_t esp_eth_phy_802_3_autonego_ctrl(phy_802_3_t *phy_802_3, eth_phy_autoneg_cmd_t cmd, bool *autonego_en_stat); +/** + * @brief Retrieve link status and propagate the status to higher layers if the status changed + * + * @param phy_802_3 IEEE 802.3 PHY object infostructure + * @return + * - ESP_OK: Ethernet PHY link status retrieved successfully + * - ESP_FAIL: Error occurred during reading registry + */ +esp_err_t esp_eth_phy_802_3_updt_link_dup_spd(phy_802_3_t *phy_802_3); + /** * @brief Power control of Ethernet PHY * @@ -183,7 +195,7 @@ esp_err_t esp_eth_phy_802_3_deinit(phy_802_3_t *phy_802_3); * * @param phy_802_3 IEEE 802.3 PHY object infostructure * @return - * - ESP_OK: Ethrnet PHY infostructure deleted + * - ESP_OK: Ethernet PHY infostructure deleted */ esp_err_t esp_eth_phy_802_3_del(phy_802_3_t *phy_802_3); @@ -194,6 +206,7 @@ esp_err_t esp_eth_phy_802_3_del(phy_802_3_t *phy_802_3); * @param reset_assert_us Hardware reset pin assertion time * @return * - ESP_OK: reset Ethernet PHY successfully + * - ESP_ERR_NOT_ALLOWED: reset GPIO not defined */ esp_err_t esp_eth_phy_802_3_reset_hw(phy_802_3_t *phy_802_3, uint32_t reset_assert_us); diff --git a/components/esp_eth/src/phy/esp_eth_phy_802_3.c b/components/esp_eth/src/phy/esp_eth_phy_802_3.c index f120821187f1..b0c22cb53f46 100644 --- a/components/esp_eth/src/phy/esp_eth_phy_802_3.c +++ b/components/esp_eth/src/phy/esp_eth_phy_802_3.c @@ -16,11 +16,14 @@ #include "esp_rom_sys.h" #include "esp_eth_phy_802_3.h" -// Default reset assertion time is selected to be 100us as it is most commonly used value among PHY chips. +// Default reset assertion time is selected to be 100us as it is most commonly used value among ESP-IDF supported PHY chips. #define PHY_RESET_ASSERTION_TIME_US 100 static const char *TAG = "eth_phy_802_3"; +// TODO: IDF-11362 (should be renamed to esp_eth_phy_802_3_reset_hw with the next major release) +static esp_err_t esp_eth_phy_802_3_reset_hw_internal(phy_802_3_t *phy_802_3); + static esp_err_t set_mediator(esp_eth_phy_t *phy, esp_eth_mediator_t *eth) { phy_802_3_t *phy_802_3 = esp_eth_phy_into_phy_802_3(phy); @@ -33,10 +36,10 @@ static esp_err_t reset(esp_eth_phy_t *phy) return esp_eth_phy_802_3_reset(phy_802_3); } -static esp_err_t reset_hw_default(esp_eth_phy_t *phy) +static esp_err_t reset_hw(esp_eth_phy_t *phy) { phy_802_3_t *phy_802_3 = esp_eth_phy_into_phy_802_3(phy); - return esp_eth_phy_802_3_reset_hw(phy_802_3, PHY_RESET_ASSERTION_TIME_US); + return esp_eth_phy_802_3_reset_hw_internal(phy_802_3); } static esp_err_t autonego_ctrl(esp_eth_phy_t *phy, eth_phy_autoneg_cmd_t cmd, bool *autonego_en_stat) @@ -93,6 +96,14 @@ static esp_err_t set_link(esp_eth_phy_t *phy, eth_link_t link) return esp_eth_phy_802_3_set_link(phy_802_3, link); } +static esp_err_t get_link(esp_eth_phy_t *phy) +{ + phy_802_3_t *phy_802_3 = esp_eth_phy_into_phy_802_3(phy); + + /* Update information about link, speed, duplex */ + return esp_eth_phy_802_3_updt_link_dup_spd(phy_802_3); +} + static esp_err_t init(esp_eth_phy_t *phy) { phy_802_3_t *phy_802_3 = esp_eth_phy_into_phy_802_3(phy); @@ -143,21 +154,6 @@ esp_err_t esp_eth_phy_802_3_reset(phy_802_3_t *phy_802_3) return ret; } -/** - * @brief PHY hardware reset with default assert time - * - * @note Default reset assertion time is selected to be 100us as it is most commonly used value among PHY chips. - * If your PHY chip requires different value, redefine the `reset_hw` function in derived PHY specific driver structure. - * - * @param phy Ethernet PHY instance - * @return - * - ESP_OK on success - */ -esp_err_t esp_eth_phy_802_3_reset_hw_default(phy_802_3_t *phy_802_3) -{ - return esp_eth_phy_802_3_reset_hw(phy_802_3, PHY_RESET_ASSERTION_TIME_US); -} - esp_err_t esp_eth_phy_802_3_autonego_ctrl(phy_802_3_t *phy_802_3, eth_phy_autoneg_cmd_t cmd, bool *autonego_en_stat) { esp_err_t ret = ESP_OK; @@ -220,6 +216,67 @@ esp_err_t esp_eth_phy_802_3_autonego_ctrl(phy_802_3_t *phy_802_3, eth_phy_autone return ret; } +esp_err_t esp_eth_phy_802_3_updt_link_dup_spd(phy_802_3_t *phy_802_3) +{ + esp_err_t ret = ESP_OK; + esp_eth_mediator_t *eth = phy_802_3->eth; + uint32_t addr = phy_802_3->addr; + eth_speed_t speed = ETH_SPEED_10M; + eth_duplex_t duplex = ETH_DUPLEX_HALF; + uint32_t peer_pause_ability = false; + bmcr_reg_t bmcr; + bmsr_reg_t bmsr; + anar_reg_t anar; + anlpar_reg_t anlpar; + + ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)), err, TAG, "read BMSR failed"); + eth_link_t link = bmsr.link_status ? ETH_LINK_UP : ETH_LINK_DOWN; + /* check if link status changed */ + if (phy_802_3->link_status != link) { + /* when link up, read negotiation result */ + if (link == ETH_LINK_UP) { + ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)), err, TAG, "read BMCR failed"); + ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_ANAR_REG_ADDR, &(anar.val)), err, TAG, "read ANAR failed"); + ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_ANLPAR_REG_ADDR, &(anlpar.val)), err, TAG, "read ANLPAR failed"); + if (bmcr.en_auto_nego) { + if (anar.base100_tx_fd && anlpar.base100_tx_fd) { + speed = ETH_SPEED_100M; + duplex = ETH_DUPLEX_FULL; + } else if (anar.base100_tx && anlpar.base100_tx) { + speed = ETH_SPEED_100M; + duplex = ETH_DUPLEX_HALF; + } else if (anar.base10_t_fd && anlpar.base10_t_fd) { + speed = ETH_SPEED_10M; + duplex = ETH_DUPLEX_FULL; + } else if (anar.base10_t && anlpar.base10_t) { + speed = ETH_SPEED_10M; + duplex = ETH_DUPLEX_HALF; + } else { + ESP_GOTO_ON_FALSE(false, ESP_FAIL, err, TAG, "invalid auto-nego speed/duplex advertising"); + } + } else { + speed = bmcr.speed_select ? ETH_SPEED_100M : ETH_SPEED_10M; + duplex = bmcr.duplex_mode ? ETH_DUPLEX_FULL : ETH_DUPLEX_HALF; + } + + ESP_GOTO_ON_ERROR(eth->on_state_changed(eth, ETH_STATE_SPEED, (void *)speed), err, TAG, "change speed failed"); + ESP_GOTO_ON_ERROR(eth->on_state_changed(eth, ETH_STATE_DUPLEX, (void *)duplex), err, TAG, "change duplex failed"); + /* if we're in duplex mode, and peer has the flow control ability */ + if (duplex == ETH_DUPLEX_FULL && anlpar.symmetric_pause) { + peer_pause_ability = 1; + } else { + peer_pause_ability = 0; + } + ESP_GOTO_ON_ERROR(eth->on_state_changed(eth, ETH_STATE_PAUSE, (void *)peer_pause_ability), err, TAG, "change pause ability failed"); + } + ESP_GOTO_ON_ERROR(eth->on_state_changed(eth, ETH_STATE_LINK, (void *)link), err, TAG, "change link failed"); + phy_802_3->link_status = link; + } + return ESP_OK; +err: + return ret; +} + esp_err_t esp_eth_phy_802_3_pwrctl(phy_802_3_t *phy_802_3, bool enable) { esp_err_t ret = ESP_OK; @@ -392,8 +449,28 @@ esp_err_t esp_eth_phy_802_3_reset_hw(phy_802_3_t *phy_802_3, uint32_t reset_asse vTaskDelay(pdMS_TO_TICKS(reset_assert_us/1000)); } gpio_set_level(phy_802_3->reset_gpio_num, 1); + return ESP_OK; } - return ESP_OK; + return ESP_ERR_NOT_ALLOWED; +} + +/** + * @brief Hardware reset with internal timing configuration defined during initialization + * + * @param phy_802_3 IEEE 802.3 PHY object infostructure + * @return + * - ESP_OK: reset Ethernet PHY successfully + * - ESP_ERR_NOT_ALLOWED: reset GPIO not defined + */ +static esp_err_t esp_eth_phy_802_3_reset_hw_internal(phy_802_3_t *phy_802_3) +{ + esp_err_t ret = ESP_OK; + if ((ret = esp_eth_phy_802_3_reset_hw(phy_802_3, phy_802_3->hw_reset_assert_time_us)) == ESP_OK) { + if (phy_802_3->post_hw_reset_delay_ms > 0) { + vTaskDelay(pdMS_TO_TICKS(phy_802_3->post_hw_reset_delay_ms)); + } + } + return ret; } esp_err_t esp_eth_phy_802_3_detect_phy_addr(esp_eth_mediator_t *eth, int *detected_addr) @@ -601,9 +678,19 @@ esp_err_t esp_eth_phy_802_3_obj_config_init(phy_802_3_t *phy_802_3, const eth_ph phy_802_3->reset_timeout_ms = config->reset_timeout_ms; phy_802_3->reset_gpio_num = config->reset_gpio_num; phy_802_3->autonego_timeout_ms = config->autonego_timeout_ms; + if (config->hw_reset_assert_time_us > 0) { + phy_802_3->hw_reset_assert_time_us = config->hw_reset_assert_time_us; + } else { + phy_802_3->hw_reset_assert_time_us = PHY_RESET_ASSERTION_TIME_US; + } + if (config->post_hw_reset_delay_ms > 0) { + phy_802_3->post_hw_reset_delay_ms = config->post_hw_reset_delay_ms; + } else { + phy_802_3->post_hw_reset_delay_ms = ESP_ETH_NO_POST_HW_RESET_DELAY; + } phy_802_3->parent.reset = reset; - phy_802_3->parent.reset_hw = reset_hw_default; + phy_802_3->parent.reset_hw = reset_hw; phy_802_3->parent.init = init; phy_802_3->parent.deinit = deinit; phy_802_3->parent.set_mediator = set_mediator; @@ -617,7 +704,7 @@ esp_err_t esp_eth_phy_802_3_obj_config_init(phy_802_3_t *phy_802_3, const eth_ph phy_802_3->parent.set_duplex = set_duplex; phy_802_3->parent.del = del; phy_802_3->parent.set_link = set_link; - phy_802_3->parent.get_link = NULL; + phy_802_3->parent.get_link = get_link; phy_802_3->parent.custom_ioctl = NULL; err: diff --git a/components/esp_eth/src/phy/esp_eth_phy_generic.c b/components/esp_eth/src/phy/esp_eth_phy_generic.c new file mode 100644 index 000000000000..0003758bf866 --- /dev/null +++ b/components/esp_eth/src/phy/esp_eth_phy_generic.c @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_log.h" +#include "esp_check.h" +#include "esp_eth.h" +#include "esp_eth_phy_802_3.h" + +static const char *TAG = "eth_phy_generic"; + +// Default reset timing is intentionally conservative +#define DEFAULT_PHY_GENERIC_RESET_ASSERTION_TIME_US 10000 +#define DEFAULT_PHY_GENERIC_POST_RESET_DELAY_MS 500 + +esp_eth_phy_t *esp_eth_phy_new_generic(const eth_phy_config_t *config) +{ + esp_eth_phy_t *ret = NULL; + phy_802_3_t *phy_802_3 = calloc(1, sizeof(phy_802_3_t)); + eth_phy_config_t phy_802_3_config = *config; + // default chip specific configuration if not defined by user + if (config->hw_reset_assert_time_us == 0) { + phy_802_3_config.hw_reset_assert_time_us = DEFAULT_PHY_GENERIC_RESET_ASSERTION_TIME_US; + } + if (config->post_hw_reset_delay_ms == 0) { + phy_802_3_config.post_hw_reset_delay_ms = DEFAULT_PHY_GENERIC_POST_RESET_DELAY_MS; + } + ESP_GOTO_ON_FALSE(esp_eth_phy_802_3_obj_config_init(phy_802_3, &phy_802_3_config) == ESP_OK, + NULL, err, TAG, "configuration initialization of PHY 802.3 failed"); + + return &phy_802_3->parent; +err: + return ret; +} diff --git a/components/esp_eth/src/phy/esp_eth_phy_ip101.c b/components/esp_eth/src/phy/esp_eth_phy_ip101.c index e66fb78b93e5..42fce95b3177 100644 --- a/components/esp_eth/src/phy/esp_eth_phy_ip101.c +++ b/components/esp_eth/src/phy/esp_eth_phy_ip101.c @@ -173,14 +173,6 @@ static esp_err_t ip101_get_link(esp_eth_phy_t *phy) return ret; } -static esp_err_t ip101_reset_hw(esp_eth_phy_t *phy) -{ - phy_802_3_t *phy_802_3 = esp_eth_phy_into_phy_802_3(phy); - esp_err_t ret = esp_eth_phy_802_3_reset_hw(phy_802_3, IP101_PHY_RESET_ASSERTION_TIME_US); - vTaskDelay(pdMS_TO_TICKS(IP101_PHY_POST_RESET_INIT_TIME_MS)); - return ret; -} - static esp_err_t ip101_init(esp_eth_phy_t *phy) { esp_err_t ret = ESP_OK; @@ -206,13 +198,20 @@ esp_eth_phy_t *esp_eth_phy_new_ip101(const eth_phy_config_t *config) esp_eth_phy_t *ret = NULL; phy_ip101_t *ip101 = calloc(1, sizeof(phy_ip101_t)); ESP_GOTO_ON_FALSE(ip101, NULL, err, TAG, "calloc ip101 failed"); - ESP_GOTO_ON_FALSE(esp_eth_phy_802_3_obj_config_init(&ip101->phy_802_3, config) == ESP_OK, + eth_phy_config_t ip101_config = *config; + // default chip specific configuration + if (config->hw_reset_assert_time_us == 0) { + ip101_config.hw_reset_assert_time_us = IP101_PHY_RESET_ASSERTION_TIME_US; + } + if (config->post_hw_reset_delay_ms == 0) { + ip101_config.post_hw_reset_delay_ms = IP101_PHY_POST_RESET_INIT_TIME_MS; + } + ESP_GOTO_ON_FALSE(esp_eth_phy_802_3_obj_config_init(&ip101->phy_802_3, &ip101_config) == ESP_OK, NULL, err, TAG, "configuration initialization of PHY 802.3 failed"); // redefine functions which need to be customized for sake of IP101 ip101->phy_802_3.parent.init = ip101_init; ip101->phy_802_3.parent.get_link = ip101_get_link; - ip101->phy_802_3.parent.reset_hw = ip101_reset_hw; return &ip101->phy_802_3.parent; err: diff --git a/components/esp_eth/src/phy/esp_eth_phy_lan87xx.c b/components/esp_eth/src/phy/esp_eth_phy_lan87xx.c index d6f8e148fd1d..1d9f666f9a7a 100644 --- a/components/esp_eth/src/phy/esp_eth_phy_lan87xx.c +++ b/components/esp_eth/src/phy/esp_eth_phy_lan87xx.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,9 @@ static const char *TAG = "lan87xx"; +/* It was observed that assert nRST signal on LAN87xx needs to be a little longer than the minimum specified in datasheet */ +#define LAN87XX_PHY_RESET_ASSERTION_TIME_US 150 + /***************List of Supported Models***************/ // See Microchip's Application Note AN25.3 summarizing differences among below models @@ -287,12 +290,6 @@ static esp_err_t lan87xx_get_link(esp_eth_phy_t *phy) return ret; } -static esp_err_t lan87xx_reset_hw(esp_eth_phy_t *phy) -{ - /* It was observed that assert nRST signal on LAN87xx needs to be a little longer than the minimum specified in datasheet */ - return esp_eth_phy_802_3_reset_hw(esp_eth_phy_into_phy_802_3(phy), 150); -} - static esp_err_t lan87xx_autonego_ctrl(esp_eth_phy_t *phy, eth_phy_autoneg_cmd_t cmd, bool *autonego_en_stat) { esp_err_t ret = ESP_OK; @@ -366,11 +363,18 @@ esp_eth_phy_t *esp_eth_phy_new_lan87xx(const eth_phy_config_t *config) esp_eth_phy_t *ret = NULL; phy_lan87xx_t *lan87xx = calloc(1, sizeof(phy_lan87xx_t)); ESP_GOTO_ON_FALSE(lan87xx, NULL, err, TAG, "calloc lan87xx failed"); - ESP_GOTO_ON_FALSE(esp_eth_phy_802_3_obj_config_init(&lan87xx->phy_802_3, config) == ESP_OK, + eth_phy_config_t lan87xx_config = *config; + // default chip specific configuration + if (config->hw_reset_assert_time_us == 0) { + lan87xx_config.hw_reset_assert_time_us = LAN87XX_PHY_RESET_ASSERTION_TIME_US; + } + if (config->post_hw_reset_delay_ms == 0) { + lan87xx_config.post_hw_reset_delay_ms = ESP_ETH_NO_POST_HW_RESET_DELAY; + } + ESP_GOTO_ON_FALSE(esp_eth_phy_802_3_obj_config_init(&lan87xx->phy_802_3, &lan87xx_config) == ESP_OK, NULL, err, TAG, "configuration initialization of PHY 802.3 failed"); // redefine functions which need to be customized for sake of LAN87xx - lan87xx->phy_802_3.parent.reset_hw = lan87xx_reset_hw; lan87xx->phy_802_3.parent.init = lan87xx_init; lan87xx->phy_802_3.parent.get_link = lan87xx_get_link; lan87xx->phy_802_3.parent.autonego_ctrl = lan87xx_autonego_ctrl; diff --git a/components/esp_eth/src/phy/esp_eth_phy_rtl8201.c b/components/esp_eth/src/phy/esp_eth_phy_rtl8201.c index 4f3a9337b4fa..c2bf0900e3a5 100644 --- a/components/esp_eth/src/phy/esp_eth_phy_rtl8201.c +++ b/components/esp_eth/src/phy/esp_eth_phy_rtl8201.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -149,15 +149,6 @@ static esp_err_t rtl8201_loopback(esp_eth_phy_t *phy, bool enable) return ret; } -static esp_err_t rtl8201_reset_hw(esp_eth_phy_t *phy) -{ - phy_802_3_t *phy_802_3 = esp_eth_phy_into_phy_802_3(phy); - esp_err_t ret = esp_eth_phy_802_3_reset_hw(phy_802_3, RTL8201_PHY_RESET_ASSERTION_TIME_US); - vTaskDelay(pdMS_TO_TICKS(RTL8201_PHY_POST_RESET_INIT_TIME_MS)); - return ret; -} - - static esp_err_t rtl8201_init(esp_eth_phy_t *phy) { esp_err_t ret = ESP_OK; @@ -183,7 +174,15 @@ esp_eth_phy_t *esp_eth_phy_new_rtl8201(const eth_phy_config_t *config) esp_eth_phy_t *ret = NULL; phy_rtl8201_t *rtl8201 = calloc(1, sizeof(phy_rtl8201_t)); ESP_GOTO_ON_FALSE(rtl8201, NULL, err, TAG, "calloc rtl8201 failed"); - ESP_GOTO_ON_FALSE(esp_eth_phy_802_3_obj_config_init(&rtl8201->phy_802_3, config) == ESP_OK, + eth_phy_config_t rtl8201_config = *config; + // default chip specific configuration + if (config->hw_reset_assert_time_us == 0) { + rtl8201_config.hw_reset_assert_time_us = RTL8201_PHY_RESET_ASSERTION_TIME_US; + } + if (config->post_hw_reset_delay_ms == 0) { + rtl8201_config.post_hw_reset_delay_ms = RTL8201_PHY_POST_RESET_INIT_TIME_MS; + } + ESP_GOTO_ON_FALSE(esp_eth_phy_802_3_obj_config_init(&rtl8201->phy_802_3, &rtl8201_config) == ESP_OK, NULL, err, TAG, "configuration initialization of PHY 802.3 failed"); // redefine functions which need to be customized for sake of RTL8201 @@ -191,7 +190,6 @@ esp_eth_phy_t *esp_eth_phy_new_rtl8201(const eth_phy_config_t *config) rtl8201->phy_802_3.parent.get_link = rtl8201_get_link; rtl8201->phy_802_3.parent.autonego_ctrl = rtl8201_autonego_ctrl; rtl8201->phy_802_3.parent.loopback = rtl8201_loopback; - rtl8201->phy_802_3.parent.reset_hw = rtl8201_reset_hw; return &rtl8201->phy_802_3.parent; err: diff --git a/docs/en/api-reference/network/esp_eth.rst b/docs/en/api-reference/network/esp_eth.rst index bf22ff5b8c39..ced34bb9822f 100644 --- a/docs/en/api-reference/network/esp_eth.rst +++ b/docs/en/api-reference/network/esp_eth.rst @@ -269,6 +269,10 @@ Configuration for PHY is described in :cpp:class:`eth_phy_config_t`, including: * :cpp:member:`eth_phy_config_t::reset_gpio_num`: if your board also connects the PHY reset pin to one of the GPIO, then set it here. Otherwise, set this field to ``-1``. + * :cpp:member:`eth_phy_config_t::hw_reset_assert_time_us`: Time the PHY reset pin is asserted in usec. Set this field to ``0`` to use chip specific default timing. + + * :cpp:member:`eth_phy_config_t::post_hw_reset_delay_ms`: Time to wait after the PHY hardware reset is done in msec. Set this field to ``0`` to use chip specific default timing. Set this field to ``-1`` to not wait after the PHY hardware reset. + ESP-IDF provides a default configuration for MAC and PHY in macro :c:macro:`ETH_MAC_DEFAULT_CONFIG` and :c:macro:`ETH_PHY_DEFAULT_CONFIG`. @@ -288,19 +292,23 @@ The Ethernet driver is implemented in an Object-Oriented style. Any operation on eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); // apply default common MAC configuration eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); // apply default vendor-specific MAC configuration - esp32_emac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; // alter the GPIO used for MDC signal - esp32_emac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; // alter the GPIO used for MDIO signal + esp32_emac_config.smi_gpio.mdc_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; // alter the GPIO used for MDC signal + esp32_emac_config.smi_gpio.mdio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; // alter the GPIO used for MDIO signa esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); // create MAC instance eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); // apply default PHY configuration phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR; // alter the PHY address according to your board design phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; // alter the GPIO used for PHY reset - esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); // create PHY instance - // ESP-IDF officially supports several different Ethernet PHY chip driver + esp_eth_phy_t *phy = esp_eth_phy_new_generic(&phy_config); // create generic PHY instance + // ESP-IDF officially supports several different specific Ethernet PHY chip driver + // esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); // esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config); // esp_eth_phy_t *phy = esp_eth_phy_new_lan8720(&phy_config); // esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config); + .. note:: + Any Ethernet PHY chip compliant with IEEE 802.3 can be used when creating new PHY instance with :cpp:func:`esp_eth_phy_new_generic`. However, while basic functionality should always work, some specific features might be limited, even if the PHY meets IEEE 802.3 standard. A typical example is loopback functionality, where certain PHYs may require setting a specific speed mode to operate correctly. If this is the concern and you need PHY driver specifically tailored to your chip needs, use drivers for PHY chips the ESP-IDF already officially supports or consult with :ref:`Custom PHY Driver ` section to create a new custom driver. + Optional Runtime MAC Clock Configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -557,10 +565,12 @@ Application Examples Advanced Topics --------------- +.. _custom-phy-driver: + Custom PHY Driver ^^^^^^^^^^^^^^^^^ -There are multiple PHY manufacturers with wide portfolios of chips available. The ESP-IDF already supports several PHY chips however one can easily get to a point where none of them satisfies the user's actual needs due to price, features, stock availability, etc. +There are multiple PHY manufacturers with wide portfolios of chips available. The ESP-IDF supports ``Generic PHY`` and also several specific PHY chips however one can easily get to a point where none of them satisfies the user's actual needs due to price, features, stock availability, etc. Luckily, a management interface between EMAC and PHY is standardized by IEEE 802.3 in Section 22.2.4 Management Functions. It defines provisions of the so-called "MII Management Interface" to control the PHY and gather status from the PHY. A set of management registers is defined to control chip behavior, link properties, auto-negotiation configuration, etc. This basic management functionality is addressed by :component_file:`esp_eth/src/phy/esp_eth_phy_802_3.c` in ESP-IDF and so it makes the creation of a new custom PHY chip driver quite a simple task. diff --git a/examples/common_components/protocol_examples_common/Kconfig.projbuild b/examples/common_components/protocol_examples_common/Kconfig.projbuild index 800f136a09c9..a890bfbe07f3 100644 --- a/examples/common_components/protocol_examples_common/Kconfig.projbuild +++ b/examples/common_components/protocol_examples_common/Kconfig.projbuild @@ -183,6 +183,15 @@ menu "Example Connection Configuration" help Select the Ethernet PHY device to use in the example. + config EXAMPLE_ETH_PHY_GENERIC + bool "Generic 802.3 PHY" + help + Any Ethernet PHY chip compliant with IEEE 802.3 can be used. However, while + basic functionality should always work, some specific features might be limited, + even if the PHY meets IEEE 802.3 standard. A typical example is loopback + functionality, where certain PHYs may require setting a specific speed mode to + operate correctly. + config EXAMPLE_ETH_PHY_IP101 bool "IP101" help diff --git a/examples/common_components/protocol_examples_common/eth_connect.c b/examples/common_components/protocol_examples_common/eth_connect.c index 8e89dbe28eb3..86e856527c2b 100644 --- a/examples/common_components/protocol_examples_common/eth_connect.c +++ b/examples/common_components/protocol_examples_common/eth_connect.c @@ -103,7 +103,9 @@ static esp_netif_t *eth_start(void) esp32_emac_config.smi_gpio.mdc_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; esp32_emac_config.smi_gpio.mdio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; s_mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); -#if CONFIG_EXAMPLE_ETH_PHY_IP101 +#if CONFIG_EXAMPLE_ETH_PHY_GENERIC + s_phy = esp_eth_phy_new_generic(&phy_config); +#elif CONFIG_EXAMPLE_ETH_PHY_IP101 s_phy = esp_eth_phy_new_ip101(&phy_config); #elif CONFIG_EXAMPLE_ETH_PHY_RTL8201 s_phy = esp_eth_phy_new_rtl8201(&phy_config); diff --git a/examples/ethernet/basic/components/ethernet_init/Kconfig.projbuild b/examples/ethernet/basic/components/ethernet_init/Kconfig.projbuild index caca0c4211a0..325908b57537 100644 --- a/examples/ethernet/basic/components/ethernet_init/Kconfig.projbuild +++ b/examples/ethernet/basic/components/ethernet_init/Kconfig.projbuild @@ -17,6 +17,15 @@ menu "Example Ethernet Configuration" help Select the Ethernet PHY device to use in the example. + config EXAMPLE_ETH_PHY_GENERIC + bool "Generic 802.3 PHY" + help + Any Ethernet PHY chip compliant with IEEE 802.3 can be used. However, while + basic functionality should always work, some specific features might be limited, + even if the PHY meets IEEE 802.3 standard. A typical example is loopback + functionality, where certain PHYs may require setting a specific speed mode to + operate correctly. + config EXAMPLE_ETH_PHY_IP101 bool "IP101" help diff --git a/examples/ethernet/basic/components/ethernet_init/ethernet_init.c b/examples/ethernet/basic/components/ethernet_init/ethernet_init.c index b34304e4a372..831e8cb2079d 100644 --- a/examples/ethernet/basic/components/ethernet_init/ethernet_init.c +++ b/examples/ethernet/basic/components/ethernet_init/ethernet_init.c @@ -83,7 +83,9 @@ static esp_eth_handle_t eth_init_internal(esp_eth_mac_t **mac_out, esp_eth_phy_t // Create new ESP32 Ethernet MAC instance esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); // Create new PHY instance based on board configuration -#if CONFIG_EXAMPLE_ETH_PHY_IP101 +#if CONFIG_EXAMPLE_ETH_PHY_GENERIC + esp_eth_phy_t *phy = esp_eth_phy_new_generic(&phy_config); +#elif CONFIG_EXAMPLE_ETH_PHY_IP101 esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); #elif CONFIG_EXAMPLE_ETH_PHY_RTL8201 esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config); diff --git a/examples/ethernet/basic/pytest_eth_basic.py b/examples/ethernet/basic/pytest_eth_basic.py index 44ce6db4af2f..74c5a2ac63fe 100644 --- a/examples/ethernet/basic/pytest_eth_basic.py +++ b/examples/ethernet/basic/pytest_eth_basic.py @@ -10,6 +10,7 @@ @pytest.mark.esp32 @pytest.mark.parametrize('config', [ pytest.param('default_ip101', marks=[pytest.mark.ethernet_router]), + pytest.param('default_generic', marks=[pytest.mark.ethernet_router]), pytest.param('default_dm9051', marks=[pytest.mark.eth_dm9051]), ], indirect=True) def test_esp_eth_basic( diff --git a/examples/ethernet/basic/sdkconfig.ci.default_generic b/examples/ethernet/basic/sdkconfig.ci.default_generic new file mode 100644 index 000000000000..dae839a7c87d --- /dev/null +++ b/examples/ethernet/basic/sdkconfig.ci.default_generic @@ -0,0 +1,11 @@ +CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y +CONFIG_EXAMPLE_ETH_PHY_GENERIC=y +CONFIG_EXAMPLE_ETH_MDC_GPIO=23 +CONFIG_EXAMPLE_ETH_MDIO_GPIO=18 +CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5 +CONFIG_EXAMPLE_ETH_PHY_ADDR=1 + +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_ESP32_EMAC=y +CONFIG_ETH_PHY_INTERFACE_RMII=y +CONFIG_ETH_RMII_CLK_INPUT=y From d792f7d86de9cdcaa014e240f9dc6544aa18bf07 Mon Sep 17 00:00:00 2001 From: Zhang Shuxian Date: Tue, 8 Oct 2024 14:34:36 +0800 Subject: [PATCH 5/5] docs: Update CN translation for esp_eth.rst --- docs/en/api-reference/network/esp_eth.rst | 2 +- docs/zh_CN/api-reference/network/esp_eth.rst | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/docs/en/api-reference/network/esp_eth.rst b/docs/en/api-reference/network/esp_eth.rst index ced34bb9822f..0b1ee221755a 100644 --- a/docs/en/api-reference/network/esp_eth.rst +++ b/docs/en/api-reference/network/esp_eth.rst @@ -293,7 +293,7 @@ The Ethernet driver is implemented in an Object-Oriented style. Any operation on eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); // apply default common MAC configuration eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); // apply default vendor-specific MAC configuration esp32_emac_config.smi_gpio.mdc_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; // alter the GPIO used for MDC signal - esp32_emac_config.smi_gpio.mdio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; // alter the GPIO used for MDIO signa + esp32_emac_config.smi_gpio.mdio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; // alter the GPIO used for MDIO signal esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); // create MAC instance eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); // apply default PHY configuration diff --git a/docs/zh_CN/api-reference/network/esp_eth.rst b/docs/zh_CN/api-reference/network/esp_eth.rst index d4acdfb6d133..96ffa63b23cb 100644 --- a/docs/zh_CN/api-reference/network/esp_eth.rst +++ b/docs/zh_CN/api-reference/network/esp_eth.rst @@ -269,6 +269,10 @@ PHY 的相关配置可以在 :cpp:class:`eth_phy_config_t` 中找到,具体包 * :cpp:member:`eth_phy_config_t::reset_gpio_num`:如果开发板同时将 PHY 复位管脚连接至了任意 GPIO 管脚,请使用该字段进行配置。否则,配置为 ``-1``。 + * :cpp:member:`eth_phy_config_t::hw_reset_assert_time_us`:PHY 复位引脚被置为有效状态的时间(以微秒为单位)。将该值配置为 ``0``,即可使用芯片默认的复位时长。 + + * :cpp:member:`eth_phy_config_t::post_hw_reset_delay_ms`:PHY 硬件复位完成后的等待时间(以毫秒为单位)。将该值配置为 ``0``,即可使用芯片默认的等待时长,配置为 ``-1``,表示执行 PHY 硬件复位后不等待。 + ESP-IDF 在宏 :c:macro:`ETH_MAC_DEFAULT_CONFIG` 和 :c:macro:`ETH_PHY_DEFAULT_CONFIG` 中为 MAC 和 PHY 提供了默认配置。 @@ -288,19 +292,23 @@ ESP-IDF 在宏 :c:macro:`ETH_MAC_DEFAULT_CONFIG` 和 :c:macro:`ETH_PHY_DEFAULT_C eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); // 应用默认的通用 MAC 配置 eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); // 应用默认的供应商特定 MAC 配置 - esp32_emac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; // 更改用于 MDC 信号的 GPIO - esp32_emac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; // 更改用于 MDIO 信号的 GPIO + esp32_emac_config.smi_gpio.mdc_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; // 更改用于 MDC 信号的 GPIO + esp32_emac_config.smi_gpio.mdio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; // 更改用于 MDIO 信号的 GPIO esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); // 创建 MAC 实例 eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); // 应用默认的 PHY 配置 phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR; // 根据开发板设计更改 PHY 地址 phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; // 更改用于 PHY 复位的 GPIO - esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); // 创建 PHY 实例 - // ESP-IDF 为数种以太网 PHY 芯片驱动提供官方支持 + esp_eth_phy_t *phy = esp_eth_phy_new_generic(&phy_config); // 创建通用 PHY 实例 + // ESP-IDF 为数种特定以太网 PHY 芯片驱动提供官方支持 + // esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); // esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config); // esp_eth_phy_t *phy = esp_eth_phy_new_lan8720(&phy_config); // esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config); + .. note:: + 使用 :cpp:func:`esp_eth_phy_new_generic` 创建新的 PHY 实例时,可以使用任何符合 IEEE 802.3 标准的以太网 PHY 芯片。然而,尽管 PHY 芯片符合 IEEE 802.3 标准,能提供基本功能,但某些特定的功能可能无法完全实现。例如,某些以太网 PHY 芯片可能需要配置特定的速度模式才能启用环回功能。遇到这种情况,需要配置 PHY 驱动程序以满足特定芯片需求,请使用 ESP-IDF 官方支持的 PHY 芯片驱动程序,或参阅 :ref:`Custom PHY Driver ` 小节以创建新的自定义驱动程序。 + 可选的运行时 MAC 时钟配置 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -557,10 +565,12 @@ ESP-IDF 在宏 :c:macro:`ETH_DEFAULT_CONFIG` 中为安装驱动程序提供了 进阶操作 --------------- +.. _custom-phy-driver: + 自定义 PHY 驱动程序 ^^^^^^^^^^^^^^^^^^^^^^^^^ -市面上有多家 PHY 芯片制造商提供各种类型的芯片。ESP-IDF 现已支持数种 PHY 芯片,但是由于价格、功能、库存等原因,有时用户还是无法找到一款能满足其实际需求的芯片。 +市面上有多家 PHY 芯片制造商提供各种类型的芯片。ESP-IDF 现已支持 ``通用 PHY`` 和数种特定的 PHY 芯片,但是由于价格、功能、库存等原因,有时用户还是无法找到一款能满足其实际需求的芯片。 好在 IEEE 802.3 在其 22.2.4 管理功能部分对 EMAC 和 PHY 之间的管理接口进行了标准化。该部分定义了所谓的 ”MII 管理接口”规范,用于控制 PHY 和收集 PHY 的状态,还定义了一组管理寄存器来控制芯片行为、链接属性、自动协商配置等。在 ESP-IDF 中,这项基本的管理功能是由 :component_file:`esp_eth/src/phy/esp_eth_phy_802_3.c` 实现的,这也大大降低了创建新的自定义 PHY 芯片驱动的难度。