소스 검색

Merge branch 'feature/lan87xx_support' into 'master'

Feature/lan87xx support

Closes IDFGH-5345

See merge request espressif/esp-idf!14142
Ondrej Kosta 4 년 전
부모
커밋
bf7b1689de

+ 1 - 1
components/esp_eth/CMakeLists.txt

@@ -23,7 +23,7 @@ if(CONFIG_ETH_ENABLED)
                          "src/esp_eth_phy_dp83848.c"
                          "src/esp_eth_phy_ip101.c"
                          "src/esp_eth_phy_ksz80xx.c"
-                         "src/esp_eth_phy_lan8720.c"
+                         "src/esp_eth_phy_lan87xx.c"
                          "src/esp_eth_phy_rtl8201.c")
     endif()
 

+ 18 - 2
components/esp_eth/include/esp_eth_phy.h

@@ -1,4 +1,4 @@
-// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
+// Copyright 2019-2021 Espressif Systems (Shanghai) PTE LTD
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -231,16 +231,32 @@ esp_eth_phy_t *esp_eth_phy_new_ip101(const eth_phy_config_t *config);
 */
 esp_eth_phy_t *esp_eth_phy_new_rtl8201(const eth_phy_config_t *config);
 
+/**
+* @brief Create a PHY instance of LAN87xx
+*
+* @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_lan87xx(const eth_phy_config_t *config);
+
 /**
 * @brief Create a PHY instance of LAN8720
 *
+* @note For ESP-IDF backwards compatibility reasons. In all other cases, use esp_eth_phy_new_lan87xx instead.
+*
 * @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_lan8720(const eth_phy_config_t *config);
+static inline esp_eth_phy_t *esp_eth_phy_new_lan8720(const eth_phy_config_t *config)
+{
+    return esp_eth_phy_new_lan87xx(config);
+}
 
 /**
 * @brief Create a PHY instance of DP83848

+ 123 - 96
components/esp_eth/src/esp_eth_phy_lan8720.c → components/esp_eth/src/esp_eth_phy_lan87xx.c

@@ -1,4 +1,4 @@
-// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
+// Copyright 2019-2021 Espressif Systems (Shanghai) PTE LTD
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -24,7 +24,26 @@
 #include "esp_rom_gpio.h"
 #include "esp_rom_sys.h"
 
-static const char *TAG = "lan8720";
+static const char *TAG = "lan87xx";
+
+/***************List of Supported Models***************/
+
+// See Microchip's Application Note AN25.3 summarizing differences among below models
+#define LAN8710A_MODEL_NUM 0x0F
+#define LAN8720A_MODEL_NUM 0x0F
+#define LAN8740A_MODEL_NUM 0x11
+#define LAN8741A_MODEL_NUM 0x12
+#define LAN8742A_MODEL_NUM 0x13
+
+static const uint8_t supported_models[] = {
+    LAN8710A_MODEL_NUM,
+#if (LAN8710A_MODEL_NUM != LAN8720A_MODEL_NUM)
+    LAN8720A_MODEL_NUM,
+#endif
+    LAN8740A_MODEL_NUM,
+    LAN8741A_MODEL_NUM,
+    LAN8742A_MODEL_NUM
+};
 
 /***************Vendor Specific Register***************/
 
@@ -157,26 +176,26 @@ typedef struct {
     uint32_t autonego_timeout_ms;
     eth_link_t link_status;
     int reset_gpio_num;
-} phy_lan8720_t;
+} phy_lan87xx_t;
 
-static esp_err_t lan8720_update_link_duplex_speed(phy_lan8720_t *lan8720)
+static esp_err_t lan87xx_update_link_duplex_speed(phy_lan87xx_t *lan87xx)
 {
     esp_err_t ret = ESP_OK;
-    esp_eth_mediator_t *eth = lan8720->eth;
+    esp_eth_mediator_t *eth = lan87xx->eth;
     eth_speed_t speed = ETH_SPEED_10M;
     eth_duplex_t duplex = ETH_DUPLEX_HALF;
     bmsr_reg_t bmsr;
     pscsr_reg_t pscsr;
     uint32_t peer_pause_ability = false;
     anlpar_reg_t anlpar;
-    ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan8720->addr, ETH_PHY_ANLPAR_REG_ADDR, &(anlpar.val)), err, TAG, "read ANLPAR failed");
-    ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan8720->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)), err, TAG, "read BMSR failed");
+    ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan87xx->addr, ETH_PHY_ANLPAR_REG_ADDR, &(anlpar.val)), err, TAG, "read ANLPAR failed");
+    ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan87xx->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 (lan8720->link_status != link) {
+    if (lan87xx->link_status != link) {
         /* when link up, read negotiation result */
         if (link == ETH_LINK_UP) {
-            ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan8720->addr, ETH_PHY_PSCSR_REG_ADDR, &(pscsr.val)), err, TAG, "read PSCSR failed");
+            ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan87xx->addr, ETH_PHY_PSCSR_REG_ADDR, &(pscsr.val)), err, TAG, "read PSCSR failed");
             switch (pscsr.speed_indication) {
             case 1: //10Base-T half-duplex
                 speed = ETH_SPEED_10M;
@@ -208,78 +227,78 @@ static esp_err_t lan8720_update_link_duplex_speed(phy_lan8720_t *lan8720)
             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");
-        lan8720->link_status = link;
+        lan87xx->link_status = link;
     }
     return ESP_OK;
 err:
     return ret;
 }
 
-static esp_err_t lan8720_set_mediator(esp_eth_phy_t *phy, esp_eth_mediator_t *eth)
+static esp_err_t lan87xx_set_mediator(esp_eth_phy_t *phy, esp_eth_mediator_t *eth)
 {
     esp_err_t ret = ESP_OK;
     ESP_GOTO_ON_FALSE(eth, ESP_ERR_INVALID_ARG, err, TAG, "can't set mediator to null");
-    phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent);
-    lan8720->eth = eth;
+    phy_lan87xx_t *lan87xx = __containerof(phy, phy_lan87xx_t, parent);
+    lan87xx->eth = eth;
     return ESP_OK;
 err:
     return ret;
 }
 
-static esp_err_t lan8720_get_link(esp_eth_phy_t *phy)
+static esp_err_t lan87xx_get_link(esp_eth_phy_t *phy)
 {
     esp_err_t ret = ESP_OK;
-    phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent);
+    phy_lan87xx_t *lan87xx = __containerof(phy, phy_lan87xx_t, parent);
     /* Updata information about link, speed, duplex */
-    ESP_GOTO_ON_ERROR(lan8720_update_link_duplex_speed(lan8720), err, TAG, "update link duplex speed failed");
+    ESP_GOTO_ON_ERROR(lan87xx_update_link_duplex_speed(lan87xx), err, TAG, "update link duplex speed failed");
     return ESP_OK;
 err:
     return ret;
 }
 
-static esp_err_t lan8720_reset(esp_eth_phy_t *phy)
+static esp_err_t lan87xx_reset(esp_eth_phy_t *phy)
 {
     esp_err_t ret = ESP_OK;
-    phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent);
-    lan8720->link_status = ETH_LINK_DOWN;
-    esp_eth_mediator_t *eth = lan8720->eth;
+    phy_lan87xx_t *lan87xx = __containerof(phy, phy_lan87xx_t, parent);
+    lan87xx->link_status = ETH_LINK_DOWN;
+    esp_eth_mediator_t *eth = lan87xx->eth;
     bmcr_reg_t bmcr = {.reset = 1};
-    ESP_GOTO_ON_ERROR(eth->phy_reg_write(eth, lan8720->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val), err, TAG, "write BMCR failed");
+    ESP_GOTO_ON_ERROR(eth->phy_reg_write(eth, lan87xx->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val), err, TAG, "write BMCR failed");
     /* wait for reset complete */
     uint32_t to = 0;
-    for (to = 0; to < lan8720->reset_timeout_ms / 10; to++) {
+    for (to = 0; to < lan87xx->reset_timeout_ms / 10; to++) {
         vTaskDelay(pdMS_TO_TICKS(10));
-        ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan8720->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)), err, TAG, "read BMCR failed");
+        ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan87xx->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)), err, TAG, "read BMCR failed");
         if (!bmcr.reset) {
             break;
         }
     }
-    ESP_GOTO_ON_FALSE(to < lan8720->reset_timeout_ms / 10, ESP_FAIL, err, TAG, "reset timeout");
+    ESP_GOTO_ON_FALSE(to < lan87xx->reset_timeout_ms / 10, ESP_FAIL, err, TAG, "reset timeout");
     return ESP_OK;
 err:
     return ret;
 }
 
-static esp_err_t lan8720_reset_hw(esp_eth_phy_t *phy)
+static esp_err_t lan87xx_reset_hw(esp_eth_phy_t *phy)
 {
-    phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent);
-    if (lan8720->reset_gpio_num >= 0) {
-        esp_rom_gpio_pad_select_gpio(lan8720->reset_gpio_num);
-        gpio_set_direction(lan8720->reset_gpio_num, GPIO_MODE_OUTPUT);
-        gpio_set_level(lan8720->reset_gpio_num, 0);
+    phy_lan87xx_t *lan87xx = __containerof(phy, phy_lan87xx_t, parent);
+    if (lan87xx->reset_gpio_num >= 0) {
+        esp_rom_gpio_pad_select_gpio(lan87xx->reset_gpio_num);
+        gpio_set_direction(lan87xx->reset_gpio_num, GPIO_MODE_OUTPUT);
+        gpio_set_level(lan87xx->reset_gpio_num, 0);
         esp_rom_delay_us(100); // insert min input assert time
-        gpio_set_level(lan8720->reset_gpio_num, 1);
+        gpio_set_level(lan87xx->reset_gpio_num, 1);
     }
     return ESP_OK;
 }
 
-static esp_err_t lan8720_negotiate(esp_eth_phy_t *phy)
+static esp_err_t lan87xx_negotiate(esp_eth_phy_t *phy)
 {
     esp_err_t ret = ESP_OK;
-    phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent);
-    esp_eth_mediator_t *eth = lan8720->eth;
+    phy_lan87xx_t *lan87xx = __containerof(phy, phy_lan87xx_t, parent);
+    esp_eth_mediator_t *eth = lan87xx->eth;
     /* in case any link status has changed, let's assume we're in link down status */
-    lan8720->link_status = ETH_LINK_DOWN;
+    lan87xx->link_status = ETH_LINK_DOWN;
     /* Restart auto negotiation */
     bmcr_reg_t bmcr = {
         .speed_select = 1,     /* 100Mbps */
@@ -287,21 +306,21 @@ static esp_err_t lan8720_negotiate(esp_eth_phy_t *phy)
         .en_auto_nego = 1,     /* Auto Negotiation */
         .restart_auto_nego = 1 /* Restart Auto Negotiation */
     };
-    ESP_GOTO_ON_ERROR(eth->phy_reg_write(eth, lan8720->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val), err, TAG, "write BMCR failed");
+    ESP_GOTO_ON_ERROR(eth->phy_reg_write(eth, lan87xx->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val), err, TAG, "write BMCR failed");
     /* Wait for auto negotiation complete */
     bmsr_reg_t bmsr;
     pscsr_reg_t pscsr;
     uint32_t to = 0;
-    for (to = 0; to < lan8720->autonego_timeout_ms / 100; to++) {
+    for (to = 0; to < lan87xx->autonego_timeout_ms / 100; to++) {
         vTaskDelay(pdMS_TO_TICKS(100));
-        ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan8720->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)), err, TAG, "read BMSR failed");
-        ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan8720->addr, ETH_PHY_PSCSR_REG_ADDR, &(pscsr.val)), err, TAG, "read PSCSR failed");
+        ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan87xx->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)), err, TAG, "read BMSR failed");
+        ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan87xx->addr, ETH_PHY_PSCSR_REG_ADDR, &(pscsr.val)), err, TAG, "read PSCSR failed");
         if (bmsr.auto_nego_complete && pscsr.auto_nego_done) {
             break;
         }
     }
     /* Auto negotiation failed, maybe no network cable plugged in, so output a warning */
-    if (to >= lan8720->autonego_timeout_ms / 100) {
+    if (to >= lan87xx->autonego_timeout_ms / 100) {
         ESP_LOGW(TAG, "auto negotiation timeout");
     }
     return ESP_OK;
@@ -309,13 +328,13 @@ err:
     return ret;
 }
 
-static esp_err_t lan8720_pwrctl(esp_eth_phy_t *phy, bool enable)
+static esp_err_t lan87xx_pwrctl(esp_eth_phy_t *phy, bool enable)
 {
     esp_err_t ret = ESP_OK;
-    phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent);
-    esp_eth_mediator_t *eth = lan8720->eth;
+    phy_lan87xx_t *lan87xx = __containerof(phy, phy_lan87xx_t, parent);
+    esp_eth_mediator_t *eth = lan87xx->eth;
     bmcr_reg_t bmcr;
-    ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan8720->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)), err, TAG, "read BMCR failed");
+    ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan87xx->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)), err, TAG, "read BMCR failed");
     if (!enable) {
         /* General Power Down Mode */
         bmcr.power_down = 1;
@@ -323,60 +342,60 @@ static esp_err_t lan8720_pwrctl(esp_eth_phy_t *phy, bool enable)
         /* Normal operation Mode */
         bmcr.power_down = 0;
     }
-    ESP_GOTO_ON_ERROR(eth->phy_reg_write(eth, lan8720->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val), err, TAG, "write BMCR failed");
+    ESP_GOTO_ON_ERROR(eth->phy_reg_write(eth, lan87xx->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val), err, TAG, "write BMCR failed");
     if (!enable) {
-        ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan8720->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)), err, TAG, "read BMCR failed");
+        ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan87xx->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)), err, TAG, "read BMCR failed");
         ESP_GOTO_ON_FALSE(bmcr.power_down == 1, ESP_FAIL, err, TAG, "power down failed");
     } else {
         /* wait for power up complete */
         uint32_t to = 0;
-        for (to = 0; to < lan8720->reset_timeout_ms / 10; to++) {
+        for (to = 0; to < lan87xx->reset_timeout_ms / 10; to++) {
             vTaskDelay(pdMS_TO_TICKS(10));
-            ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan8720->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)), err, TAG, "read BMCR failed");
+            ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan87xx->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)), err, TAG, "read BMCR failed");
             if (bmcr.power_down == 0) {
                 break;
             }
         }
-        ESP_GOTO_ON_FALSE(to < lan8720->reset_timeout_ms / 10, ESP_FAIL, err, TAG, "power up timeout");
+        ESP_GOTO_ON_FALSE(to < lan87xx->reset_timeout_ms / 10, ESP_FAIL, err, TAG, "power up timeout");
     }
     return ESP_OK;
 err:
     return ret;
 }
 
-static esp_err_t lan8720_set_addr(esp_eth_phy_t *phy, uint32_t addr)
+static esp_err_t lan87xx_set_addr(esp_eth_phy_t *phy, uint32_t addr)
 {
-    phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent);
-    lan8720->addr = addr;
+    phy_lan87xx_t *lan87xx = __containerof(phy, phy_lan87xx_t, parent);
+    lan87xx->addr = addr;
     return ESP_OK;
 }
 
-static esp_err_t lan8720_get_addr(esp_eth_phy_t *phy, uint32_t *addr)
+static esp_err_t lan87xx_get_addr(esp_eth_phy_t *phy, uint32_t *addr)
 {
     esp_err_t ret = ESP_OK;
     ESP_GOTO_ON_FALSE(addr, ESP_ERR_INVALID_ARG, err, TAG, "addr can't be null");
-    phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent);
-    *addr = lan8720->addr;
+    phy_lan87xx_t *lan87xx = __containerof(phy, phy_lan87xx_t, parent);
+    *addr = lan87xx->addr;
     return ESP_OK;
 err:
     return ret;
 }
 
-static esp_err_t lan8720_del(esp_eth_phy_t *phy)
+static esp_err_t lan87xx_del(esp_eth_phy_t *phy)
 {
-    phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent);
-    free(lan8720);
+    phy_lan87xx_t *lan87xx = __containerof(phy, phy_lan87xx_t, parent);
+    free(lan87xx);
     return ESP_OK;
 }
 
-static esp_err_t lan8720_advertise_pause_ability(esp_eth_phy_t *phy, uint32_t ability)
+static esp_err_t lan87xx_advertise_pause_ability(esp_eth_phy_t *phy, uint32_t ability)
 {
     esp_err_t ret = ESP_OK;
-    phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent);
-    esp_eth_mediator_t *eth = lan8720->eth;
+    phy_lan87xx_t *lan87xx = __containerof(phy, phy_lan87xx_t, parent);
+    esp_eth_mediator_t *eth = lan87xx->eth;
     /* Set PAUSE function ability */
     anar_reg_t anar;
-    ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan8720->addr, ETH_PHY_ANAR_REG_ADDR, &(anar.val)), err, TAG, "read ANAR failed");
+    ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan87xx->addr, ETH_PHY_ANAR_REG_ADDR, &(anar.val)), err, TAG, "read ANAR failed");
     if (ability) {
         anar.asymmetric_pause = 1;
         anar.symmetric_pause = 1;
@@ -384,71 +403,79 @@ static esp_err_t lan8720_advertise_pause_ability(esp_eth_phy_t *phy, uint32_t ab
         anar.asymmetric_pause = 0;
         anar.symmetric_pause = 0;
     }
-    ESP_GOTO_ON_ERROR(eth->phy_reg_write(eth, lan8720->addr, ETH_PHY_ANAR_REG_ADDR, anar.val), err, TAG, "write ANAR failed");
+    ESP_GOTO_ON_ERROR(eth->phy_reg_write(eth, lan87xx->addr, ETH_PHY_ANAR_REG_ADDR, anar.val), err, TAG, "write ANAR failed");
     return ESP_OK;
 err:
     return ret;
 }
 
-static esp_err_t lan8720_init(esp_eth_phy_t *phy)
+static esp_err_t lan87xx_init(esp_eth_phy_t *phy)
 {
     esp_err_t ret = ESP_OK;
-    phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent);
-    esp_eth_mediator_t *eth = lan8720->eth;
+    phy_lan87xx_t *lan87xx = __containerof(phy, phy_lan87xx_t, parent);
+    esp_eth_mediator_t *eth = lan87xx->eth;
     // Detect PHY address
-    if (lan8720->addr == ESP_ETH_PHY_ADDR_AUTO) {
-        ESP_GOTO_ON_ERROR(esp_eth_detect_phy_addr(eth, &lan8720->addr), err, TAG, "Detect PHY address failed");
+    if (lan87xx->addr == ESP_ETH_PHY_ADDR_AUTO) {
+        ESP_GOTO_ON_ERROR(esp_eth_detect_phy_addr(eth, &lan87xx->addr), err, TAG, "Detect PHY address failed");
     }
     /* Power on Ethernet PHY */
-    ESP_GOTO_ON_ERROR(lan8720_pwrctl(phy, true), err, TAG, "power control failed");
+    ESP_GOTO_ON_ERROR(lan87xx_pwrctl(phy, true), err, TAG, "power control failed");
     /* Reset Ethernet PHY */
-    ESP_GOTO_ON_ERROR(lan8720_reset(phy), err, TAG, "reset failed");
+    ESP_GOTO_ON_ERROR(lan87xx_reset(phy), err, TAG, "reset failed");
     /* Check PHY ID */
     phyidr1_reg_t id1;
     phyidr2_reg_t id2;
-    ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan8720->addr, ETH_PHY_IDR1_REG_ADDR, &(id1.val)), err, TAG, "read ID1 failed");
-    ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan8720->addr, ETH_PHY_IDR2_REG_ADDR, &(id2.val)), err, TAG, "read ID2 failed");
-    ESP_GOTO_ON_FALSE(id1.oui_msb == 0x7 && id2.oui_lsb == 0x30 && id2.vendor_model == 0xF, ESP_FAIL, err, TAG, "wrong chip ID");
+    ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan87xx->addr, ETH_PHY_IDR1_REG_ADDR, &(id1.val)), err, TAG, "read ID1 failed");
+    ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, lan87xx->addr, ETH_PHY_IDR2_REG_ADDR, &(id2.val)), err, TAG, "read ID2 failed");
+    ESP_GOTO_ON_FALSE(id1.oui_msb == 0x7 && id2.oui_lsb == 0x30, ESP_FAIL, err, TAG, "wrong chip ID");
+    bool supported_model = false;
+    for (unsigned int i = 0; i < sizeof(supported_models); i++) {
+        if (id2.vendor_model == supported_models[i]) {
+            supported_model = true;
+            break;
+        }
+    }
+    ESP_GOTO_ON_FALSE(supported_model, ESP_FAIL, err, TAG, "unsupported chip model");
     return ESP_OK;
 err:
     return ret;
 }
 
-static esp_err_t lan8720_deinit(esp_eth_phy_t *phy)
+static esp_err_t lan87xx_deinit(esp_eth_phy_t *phy)
 {
     esp_err_t ret = ESP_OK;
     /* Power off Ethernet PHY */
-    ESP_GOTO_ON_ERROR(lan8720_pwrctl(phy, false), err, TAG, "power control failed");
+    ESP_GOTO_ON_ERROR(lan87xx_pwrctl(phy, false), err, TAG, "power control failed");
     return ESP_OK;
 err:
     return ret;
 }
 
-esp_eth_phy_t *esp_eth_phy_new_lan8720(const eth_phy_config_t *config)
+esp_eth_phy_t *esp_eth_phy_new_lan87xx(const eth_phy_config_t *config)
 {
     esp_eth_phy_t *ret = NULL;
     ESP_GOTO_ON_FALSE(config, NULL, err, TAG, "can't set phy config to null");
-    phy_lan8720_t *lan8720 = calloc(1, sizeof(phy_lan8720_t));
-    ESP_GOTO_ON_FALSE(lan8720, NULL, err, TAG, "calloc lan8720 failed");
-    lan8720->addr = config->phy_addr;
-    lan8720->reset_gpio_num = config->reset_gpio_num;
-    lan8720->reset_timeout_ms = config->reset_timeout_ms;
-    lan8720->link_status = ETH_LINK_DOWN;
-    lan8720->autonego_timeout_ms = config->autonego_timeout_ms;
-    lan8720->parent.reset = lan8720_reset;
-    lan8720->parent.reset_hw = lan8720_reset_hw;
-    lan8720->parent.init = lan8720_init;
-    lan8720->parent.deinit = lan8720_deinit;
-    lan8720->parent.set_mediator = lan8720_set_mediator;
-    lan8720->parent.negotiate = lan8720_negotiate;
-    lan8720->parent.get_link = lan8720_get_link;
-    lan8720->parent.pwrctl = lan8720_pwrctl;
-    lan8720->parent.get_addr = lan8720_get_addr;
-    lan8720->parent.set_addr = lan8720_set_addr;
-    lan8720->parent.advertise_pause_ability = lan8720_advertise_pause_ability;
-    lan8720->parent.del = lan8720_del;
+    phy_lan87xx_t *lan87xx = calloc(1, sizeof(phy_lan87xx_t));
+    ESP_GOTO_ON_FALSE(lan87xx, NULL, err, TAG, "calloc lan87xx failed");
+    lan87xx->addr = config->phy_addr;
+    lan87xx->reset_gpio_num = config->reset_gpio_num;
+    lan87xx->reset_timeout_ms = config->reset_timeout_ms;
+    lan87xx->link_status = ETH_LINK_DOWN;
+    lan87xx->autonego_timeout_ms = config->autonego_timeout_ms;
+    lan87xx->parent.reset = lan87xx_reset;
+    lan87xx->parent.reset_hw = lan87xx_reset_hw;
+    lan87xx->parent.init = lan87xx_init;
+    lan87xx->parent.deinit = lan87xx_deinit;
+    lan87xx->parent.set_mediator = lan87xx_set_mediator;
+    lan87xx->parent.negotiate = lan87xx_negotiate;
+    lan87xx->parent.get_link = lan87xx_get_link;
+    lan87xx->parent.pwrctl = lan87xx_pwrctl;
+    lan87xx->parent.get_addr = lan87xx_get_addr;
+    lan87xx->parent.set_addr = lan87xx_set_addr;
+    lan87xx->parent.advertise_pause_ability = lan87xx_advertise_pause_ability;
+    lan87xx->parent.del = lan87xx_del;
 
-    return &(lan8720->parent);
+    return &(lan87xx->parent);
 err:
     return ret;
 }

+ 10 - 3
examples/common_components/protocol_examples_common/Kconfig.projbuild

@@ -162,11 +162,18 @@ menu "Example Connection Configuration"
                         RTL8201F/SR8201F is a single port 10/100Mb Ethernet Transceiver with auto MDIX.
                         Goto http://www.corechip-sz.com/productsview.asp?id=22 for more information about it.
 
-                config EXAMPLE_ETH_PHY_LAN8720
-                    bool "LAN8720"
+                config EXAMPLE_ETH_PHY_LAN87XX
+                    bool "LAN87xx"
                     help
+                        Below chips are supported:
+                        LAN8710A is a small footprint MII/RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
+                            flexPWR® Technology.
                         LAN8720A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX Support.
-                        Goto https://www.microchip.com/LAN8720A for more information about it.
+                        LAN8740A/LAN8741A is a small footprint MII/RMII 10/100 Energy Efficient Ethernet Transceiver
+                            with HP Auto-MDIX and flexPWR® Technology.
+                        LAN8742A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
+                            flexPWR® Technology.
+                        Goto https://www.microchip.com for more information about them.
 
                 config EXAMPLE_ETH_PHY_DP83848
                     bool "DP83848"

+ 2 - 2
examples/common_components/protocol_examples_common/connect.c

@@ -393,8 +393,8 @@ static esp_netif_t *eth_start(void)
     s_phy = esp_eth_phy_new_ip101(&phy_config);
 #elif CONFIG_EXAMPLE_ETH_PHY_RTL8201
     s_phy = esp_eth_phy_new_rtl8201(&phy_config);
-#elif CONFIG_EXAMPLE_ETH_PHY_LAN8720
-    s_phy = esp_eth_phy_new_lan8720(&phy_config);
+#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX
+    s_phy = esp_eth_phy_new_lan87xx(&phy_config);
 #elif CONFIG_EXAMPLE_ETH_PHY_DP83848
     s_phy = esp_eth_phy_new_dp83848(&phy_config);
 #endif

+ 10 - 3
examples/ethernet/basic/main/Kconfig.projbuild

@@ -61,11 +61,18 @@ menu "Example Configuration"
                     RTL8201F/SR8201F is a single port 10/100Mb Ethernet Transceiver with auto MDIX.
                     Goto http://www.corechip-sz.com/productsview.asp?id=22 for more information about it.
 
-            config EXAMPLE_ETH_PHY_LAN8720
-                bool "LAN8720"
+            config EXAMPLE_ETH_PHY_LAN87XX
+                bool "LAN87xx"
                 help
+                    Below chips are supported:
+                    LAN8710A is a small footprint MII/RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
+                        flexPWR® Technology.
                     LAN8720A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX Support.
-                    Goto https://www.microchip.com/LAN8720A for more information about it.
+                    LAN8740A/LAN8741A is a small footprint MII/RMII 10/100 Energy Efficient Ethernet Transceiver
+                        with HP Auto-MDIX and flexPWR® Technology.
+                    LAN8742A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
+                        flexPWR® Technology.
+                    Goto https://www.microchip.com for more information about them.
 
             config EXAMPLE_ETH_PHY_DP83848
                 bool "DP83848"

+ 2 - 2
examples/ethernet/basic/main/ethernet_example_main.c

@@ -92,8 +92,8 @@ void app_main(void)
     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);
-#elif CONFIG_EXAMPLE_ETH_PHY_LAN8720
-    esp_eth_phy_t *phy = esp_eth_phy_new_lan8720(&phy_config);
+#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX
+    esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
 #elif CONFIG_EXAMPLE_ETH_PHY_DP83848
     esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
 #elif CONFIG_EXAMPLE_ETH_PHY_KSZ8041

+ 52 - 13
examples/ethernet/eth2ap/main/Kconfig.projbuild

@@ -32,6 +32,14 @@ menu "Example Configuration"
             select ETH_SPI_ETHERNET_W5500
             help
                 Select external SPI-Ethernet module (W5500).
+
+        config EXAMPLE_USE_KSZ8851SNL
+            bool "KSZ8851SNL Module"
+            select EXAMPLE_USE_SPI_ETHERNET
+            select ETH_USE_SPI_ETHERNET
+            select ETH_SPI_ETHERNET_KSZ8851SNL
+            help
+                Select external SPI-Ethernet module (KSZ8851SNL).
     endchoice # EXAMPLE_ETHERNET_TYPE
 
     if EXAMPLE_USE_INTERNAL_ETHERNET
@@ -53,11 +61,18 @@ menu "Example Configuration"
                     RTL8201F/SR8201F is a single port 10/100Mb Ethernet Transceiver with auto MDIX.
                     Goto http://www.corechip-sz.com/productsview.asp?id=22 for more information about it.
 
-            config EXAMPLE_ETH_PHY_LAN8720
-                bool "LAN8720"
+            config EXAMPLE_ETH_PHY_LAN87XX
+                bool "LAN87xx"
                 help
+                    Below chips are supported:
+                    LAN8710A is a small footprint MII/RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
+                        flexPWR® Technology.
                     LAN8720A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX Support.
-                    Goto https://www.microchip.com/LAN8720A for more information about it.
+                    LAN8740A/LAN8741A is a small footprint MII/RMII 10/100 Energy Efficient Ethernet Transceiver
+                        with HP Auto-MDIX and flexPWR® Technology.
+                    LAN8742A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
+                        flexPWR® Technology.
+                    Goto https://www.microchip.com for more information about them.
 
             config EXAMPLE_ETH_PHY_DP83848
                 bool "DP83848"
@@ -70,6 +85,12 @@ menu "Example Configuration"
                 help
                     The KSZ8041 is a single supply 10Base-T/100Base-TX Physical Layer Transceiver.
                     Goto https://www.microchip.com/wwwproducts/en/KSZ8041 for more information about it.
+
+            config EXAMPLE_ETH_PHY_KSZ8081
+                bool "KSZ8081"
+                help
+                    The KSZ8081 is a single supply 10Base-T/100Base-TX Physical Layer Transceiver.
+                    Goto https://www.microchip.com/wwwproducts/en/KSZ8081 for more information about it.
         endchoice # EXAMPLE_ETH_PHY_MODEL
 
         config EXAMPLE_ETH_MDC_GPIO
@@ -95,42 +116,60 @@ menu "Example Configuration"
 
         config EXAMPLE_ETH_SPI_SCLK_GPIO
             int "SPI SCLK GPIO number"
-            range 0 33
-            default 20
+            range 0 34 if IDF_TARGET_ESP32
+            range 0 46 if IDF_TARGET_ESP32S2
+            range 0 19 if IDF_TARGET_ESP32C3
+            default 18 if IDF_TARGET_ESP32
+            default 20 if IDF_TARGET_ESP32S2
+            default 6 if IDF_TARGET_ESP32C3
             help
                 Set the GPIO number used by SPI SCLK.
 
         config EXAMPLE_ETH_SPI_MOSI_GPIO
             int "SPI MOSI GPIO number"
-            range 0 33
-            default 19
+            range 0 34 if IDF_TARGET_ESP32
+            range 0 46 if IDF_TARGET_ESP32S2
+            range 0 19 if IDF_TARGET_ESP32C3
+            default 23 if IDF_TARGET_ESP32
+            default 19 if IDF_TARGET_ESP32S2
+            default 7 if IDF_TARGET_ESP32C3
             help
                 Set the GPIO number used by SPI MOSI.
 
         config EXAMPLE_ETH_SPI_MISO_GPIO
             int "SPI MISO GPIO number"
-            range 0 33
-            default 18
+            range 0 34 if IDF_TARGET_ESP32
+            range 0 46 if IDF_TARGET_ESP32S2
+            range 0 19 if IDF_TARGET_ESP32C3
+            default 19 if IDF_TARGET_ESP32
+            default 18 if IDF_TARGET_ESP32S2
+            default 2 if IDF_TARGET_ESP32C3
             help
                 Set the GPIO number used by SPI MISO.
 
         config EXAMPLE_ETH_SPI_CS_GPIO
             int "SPI CS GPIO number"
-            range 0 33
-            default 21
+            range 0 34 if IDF_TARGET_ESP32
+            range 0 46 if IDF_TARGET_ESP32S2
+            range 0 19 if IDF_TARGET_ESP32C3
+            default 16 if IDF_TARGET_ESP32
+            default 21 if IDF_TARGET_ESP32S2
+            default 10 if IDF_TARGET_ESP32C3
             help
                 Set the GPIO number used by SPI CS.
 
         config EXAMPLE_ETH_SPI_CLOCK_MHZ
             int "SPI clock speed (MHz)"
             range 5 80
-            default 36
+            default 12 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C3
+            default 36 if IDF_TARGET_ESP32S2
             help
                 Set the clock speed (MHz) of SPI interface.
 
         config EXAMPLE_ETH_SPI_INT_GPIO
             int "Interrupt GPIO number"
-            default 4
+            default 17 if IDF_TARGET_ESP32
+            default 4 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3
             help
                 Set the GPIO number used by the SPI Ethernet module interrupt line.
     endif # EXAMPLE_USE_SPI_ETHERNET

+ 19 - 3
examples/ethernet/eth2ap/main/ethernet_example_main.c

@@ -165,12 +165,14 @@ static void initialize_ethernet(void)
     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);
-#elif CONFIG_EXAMPLE_ETH_PHY_LAN8720
-    esp_eth_phy_t *phy = esp_eth_phy_new_lan8720(&phy_config);
+#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX
+    esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
 #elif CONFIG_EXAMPLE_ETH_PHY_DP83848
     esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
 #elif CONFIG_EXAMPLE_ETH_PHY_KSZ8041
     esp_eth_phy_t *phy = esp_eth_phy_new_ksz8041(&phy_config);
+#elif CONFIG_EXAMPLE_ETH_PHY_KSZ8081
+    esp_eth_phy_t *phy = esp_eth_phy_new_ksz8081(&phy_config);
 #endif
 #elif CONFIG_ETH_USE_SPI_ETHERNET
     gpio_install_isr_service(0);
@@ -183,7 +185,21 @@ static void initialize_ethernet(void)
         .quadhd_io_num = -1,
     };
     ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 1));
-#if CONFIG_EXAMPLE_USE_DM9051
+
+#if CONFIG_EXAMPLE_USE_KSZ8851SNL
+    spi_device_interface_config_t devcfg = {
+        .mode = 0,
+        .clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
+        .spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
+        .queue_size = 20
+    };
+    ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle));
+    /* KSZ8851SNL ethernet driver is based on spi driver */
+    eth_ksz8851snl_config_t ksz8851snl_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(spi_handle);
+    ksz8851snl_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
+    esp_eth_mac_t *mac = esp_eth_mac_new_ksz8851snl(&ksz8851snl_config, &mac_config);
+    esp_eth_phy_t *phy = esp_eth_phy_new_ksz8851snl(&phy_config);
+#elif CONFIG_EXAMPLE_USE_DM9051
     spi_device_interface_config_t devcfg = {
         .command_bits = 1,
         .address_bits = 7,

+ 52 - 13
examples/ethernet/iperf/main/Kconfig.projbuild

@@ -40,6 +40,14 @@ menu "Example Configuration"
             help
                 Select external SPI-Ethernet module (W5500).
 
+        config EXAMPLE_USE_KSZ8851SNL
+            bool "KSZ8851SNL Module"
+            select EXAMPLE_USE_SPI_ETHERNET
+            select ETH_USE_SPI_ETHERNET
+            select ETH_SPI_ETHERNET_KSZ8851SNL
+            help
+                Select external SPI-Ethernet module (KSZ8851SNL).
+
         config EXAMPLE_USE_ENC28J60
             bool "ENC28J60 Module"
             select EXAMPLE_USE_SPI_ETHERNET
@@ -68,11 +76,18 @@ menu "Example Configuration"
                     RTL8201F/SR8201F is a single port 10/100Mb Ethernet Transceiver with auto MDIX.
                     Goto http://www.corechip-sz.com/productsview.asp?id=22 for more information about it.
 
-            config EXAMPLE_ETH_PHY_LAN8720
-                bool "LAN8720"
+            config EXAMPLE_ETH_PHY_LAN87XX
+                bool "LAN87xx"
                 help
+                    Below chips are supported:
+                    LAN8710A is a small footprint MII/RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
+                        flexPWR® Technology.
                     LAN8720A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX Support.
-                    Goto https://www.microchip.com/LAN8720A for more information about it.
+                    LAN8740A/LAN8741A is a small footprint MII/RMII 10/100 Energy Efficient Ethernet Transceiver
+                        with HP Auto-MDIX and flexPWR® Technology.
+                    LAN8742A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
+                        flexPWR® Technology.
+                    Goto https://www.microchip.com for more information about them.
 
             config EXAMPLE_ETH_PHY_DP83848
                 bool "DP83848"
@@ -85,6 +100,12 @@ menu "Example Configuration"
                 help
                     The KSZ8041 is a single supply 10Base-T/100Base-TX Physical Layer Transceiver.
                     Goto https://www.microchip.com/wwwproducts/en/KSZ8041 for more information about it.
+
+            config EXAMPLE_ETH_PHY_KSZ8081
+                bool "KSZ8081"
+                help
+                    The KSZ8081 is a single supply 10Base-T/100Base-TX Physical Layer Transceiver.
+                    Goto https://www.microchip.com/wwwproducts/en/KSZ8081 for more information about it.
         endchoice # EXAMPLE_ETH_PHY_MODEL
 
         config EXAMPLE_ETH_MDC_GPIO
@@ -110,29 +131,45 @@ menu "Example Configuration"
 
         config EXAMPLE_ETH_SPI_SCLK_GPIO
             int "SPI SCLK GPIO number"
-            range 0 33
-            default 20
+            range 0 34 if IDF_TARGET_ESP32
+            range 0 46 if IDF_TARGET_ESP32S2
+            range 0 19 if IDF_TARGET_ESP32C3
+            default 18 if IDF_TARGET_ESP32
+            default 20 if IDF_TARGET_ESP32S2
+            default 6 if IDF_TARGET_ESP32C3
             help
                 Set the GPIO number used by SPI SCLK.
 
         config EXAMPLE_ETH_SPI_MOSI_GPIO
             int "SPI MOSI GPIO number"
-            range 0 33
-            default 19
+            range 0 34 if IDF_TARGET_ESP32
+            range 0 46 if IDF_TARGET_ESP32S2
+            range 0 19 if IDF_TARGET_ESP32C3
+            default 23 if IDF_TARGET_ESP32
+            default 19 if IDF_TARGET_ESP32S2
+            default 7 if IDF_TARGET_ESP32C3
             help
                 Set the GPIO number used by SPI MOSI.
 
         config EXAMPLE_ETH_SPI_MISO_GPIO
             int "SPI MISO GPIO number"
-            range 0 33
-            default 18
+            range 0 34 if IDF_TARGET_ESP32
+            range 0 46 if IDF_TARGET_ESP32S2
+            range 0 19 if IDF_TARGET_ESP32C3
+            default 19 if IDF_TARGET_ESP32
+            default 18 if IDF_TARGET_ESP32S2
+            default 2 if IDF_TARGET_ESP32C3
             help
                 Set the GPIO number used by SPI MISO.
 
         config EXAMPLE_ETH_SPI_CS_GPIO
             int "SPI CS GPIO number"
-            range 0 33
-            default 21
+            range 0 34 if IDF_TARGET_ESP32
+            range 0 46 if IDF_TARGET_ESP32S2
+            range 0 19 if IDF_TARGET_ESP32C3
+            default 16 if IDF_TARGET_ESP32
+            default 21 if IDF_TARGET_ESP32S2
+            default 10 if IDF_TARGET_ESP32C3
             help
                 Set the GPIO number used by SPI CS.
 
@@ -140,13 +177,15 @@ menu "Example Configuration"
             int "SPI clock speed (MHz)"
             range 5 80
             default 8 if EXAMPLE_USE_ENC28J60
-            default 36
+            default 12 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C3
+            default 36 if IDF_TARGET_ESP32S2
             help
                 Set the clock speed (MHz) of SPI interface.
 
         config EXAMPLE_ETH_SPI_INT_GPIO
             int "Interrupt GPIO number"
-            default 4
+            default 17 if IDF_TARGET_ESP32
+            default 4 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3
             help
                 Set the GPIO number used by the SPI Ethernet module interrupt line.
     endif # EXAMPLE_USE_SPI_ETHERNET

+ 20 - 4
examples/ethernet/iperf/main/cmd_ethernet.c

@@ -204,12 +204,14 @@ void register_ethernet(void)
     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);
-#elif CONFIG_EXAMPLE_ETH_PHY_LAN8720
-    esp_eth_phy_t *phy = esp_eth_phy_new_lan8720(&phy_config);
+#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX
+    esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
 #elif CONFIG_EXAMPLE_ETH_PHY_DP83848
     esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
 #elif CONFIG_EXAMPLE_ETH_PHY_KSZ8041
     esp_eth_phy_t *phy = esp_eth_phy_new_ksz8041(&phy_config);
+#elif CONFIG_EXAMPLE_ETH_PHY_KSZ8081
+    esp_eth_phy_t *phy = esp_eth_phy_new_ksz8081(&phy_config);
 #endif
 #elif CONFIG_ETH_USE_SPI_ETHERNET
     gpio_install_isr_service(0);
@@ -221,8 +223,22 @@ void register_ethernet(void)
         .quadwp_io_num = -1,
         .quadhd_io_num = -1,
     };
-    ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
-#if CONFIG_EXAMPLE_USE_DM9051
+    ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 1));
+
+#if CONFIG_EXAMPLE_USE_KSZ8851SNL
+    spi_device_interface_config_t devcfg = {
+        .mode = 0,
+        .clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
+        .spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
+        .queue_size = 20
+    };
+    ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle));
+    /* KSZ8851SNL ethernet driver is based on spi driver */
+    eth_ksz8851snl_config_t ksz8851snl_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(spi_handle);
+    ksz8851snl_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
+    esp_eth_mac_t *mac = esp_eth_mac_new_ksz8851snl(&ksz8851snl_config, &mac_config);
+    esp_eth_phy_t *phy = esp_eth_phy_new_ksz8851snl(&phy_config);
+#elif CONFIG_EXAMPLE_USE_DM9051
     spi_device_interface_config_t devcfg = {
         .command_bits = 1,
         .address_bits = 7,

+ 10 - 3
examples/wifi/simple_sniffer/main/Kconfig.projbuild

@@ -138,11 +138,18 @@ menu "Example Configuration"
                     RTL8201F/SR8201F is a single port 10/100Mb Ethernet Transceiver with auto MDIX.
                     Goto http://www.corechip-sz.com/productsview.asp?id=22 for more information about it.
 
-            config SNIFFER_ETH_PHY_LAN8720
-                bool "LAN8720"
+            config SNIFFER_ETH_PHY_LAN87XX
+                bool "LAN87xx"
                 help
+                    Below chips are supported:
+                    LAN8710A is a small footprint MII/RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
+                        flexPWR® Technology.
                     LAN8720A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX Support.
-                    Goto https://www.microchip.com/LAN8720A for more information about it.
+                    LAN8740A/LAN8741A is a small footprint MII/RMII 10/100 Energy Efficient Ethernet Transceiver
+                        with HP Auto-MDIX and flexPWR® Technology.
+                    LAN8742A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
+                        flexPWR® Technology.
+                    Goto https://www.microchip.com for more information about them.
 
             config SNIFFER_ETH_PHY_DP83848
                 bool "DP83848"

+ 2 - 2
examples/wifi/simple_sniffer/main/simple_sniffer_example_main.c

@@ -142,8 +142,8 @@ static void initialize_eth(void)
     esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
 #elif CONFIG_SNIFFER_ETH_PHY_RTL8201
     esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config);
-#elif CONFIG_SNIFFER_ETH_PHY_LAN8720
-    esp_eth_phy_t *phy = esp_eth_phy_new_lan8720(&phy_config);
+#elif CONFIG_SNIFFER_ETH_PHY_LAN87XX
+    esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
 #elif CONFIG_SNIFFER_ETH_PHY_DP83848
     esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
 #elif CONFIG_SNIFFER_ETH_PHY_KSZ8041