diff --git a/components/esp_eth/component.mk b/components/esp_eth/component.mk index 4650d5f5c4..3426f54cde 100644 --- a/components/esp_eth/component.mk +++ b/components/esp_eth/component.mk @@ -5,7 +5,7 @@ COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_SRCDIRS := src ifndef CONFIG_ETH_USE_ESP32_EMAC - COMPONENT_OBJEXCLUDE += src/esp_eth_mac_esp32.o + COMPONENT_OBJEXCLUDE += src/esp_eth_mac_esp.o endif ifndef CONFIG_ETH_SPI_ETHERNET_DM9051 diff --git a/components/esp_eth/src/esp_eth.c b/components/esp_eth/src/esp_eth.c index 2e16de1893..611ba936c9 100644 --- a/components/esp_eth/src/esp_eth.c +++ b/components/esp_eth/src/esp_eth.c @@ -269,14 +269,16 @@ esp_err_t esp_eth_start(esp_eth_handle_t hdl) esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl; ESP_GOTO_ON_FALSE(eth_driver, ESP_ERR_INVALID_ARG, err, TAG, "ethernet driver handle can't be null"); esp_eth_phy_t *phy = eth_driver->phy; + esp_eth_mac_t *mac = eth_driver->mac; // check if driver has stopped esp_eth_fsm_t expected_fsm = ESP_ETH_FSM_STOP; ESP_GOTO_ON_FALSE(atomic_compare_exchange_strong(ð_driver->fsm, &expected_fsm, ESP_ETH_FSM_START), ESP_ERR_INVALID_STATE, err, TAG, "driver started already"); - // reset PHY device, to put it back to LINK_DOWN state - ESP_GOTO_ON_ERROR(phy->reset(phy), err, TAG, "reset phy failed"); + ESP_GOTO_ON_ERROR(phy->negotiate(phy), err, TAG, "phy negotiation failed"); + ESP_GOTO_ON_ERROR(mac->start(mac), err, TAG, "start mac failed"); ESP_GOTO_ON_ERROR(esp_event_post(ETH_EVENT, ETHERNET_EVENT_START, ð_driver, sizeof(esp_eth_driver_t *), 0), err, TAG, "send ETHERNET_EVENT_START event failed"); + ESP_GOTO_ON_ERROR(phy->get_link(phy), err, TAG, "phy get link status failed"); ESP_GOTO_ON_ERROR(esp_timer_start_periodic(eth_driver->check_link_timer, eth_driver->check_link_period_ms * 1000), err, TAG, "start link timer failed"); err: diff --git a/components/esp_eth/src/esp_eth_phy_dm9051.c b/components/esp_eth/src/esp_eth_phy_dm9051.c index 95b66a896c..5c1c112a61 100644 --- a/components/esp_eth/src/esp_eth_phy_dm9051.c +++ b/components/esp_eth/src/esp_eth_phy_dm9051.c @@ -200,6 +200,8 @@ static esp_err_t dm9051_negotiate(esp_eth_phy_t *phy) esp_err_t ret = ESP_OK; phy_dm9051_t *dm9051 = __containerof(phy, phy_dm9051_t, parent); esp_eth_mediator_t *eth = dm9051->eth; + /* in case any link status has changed, let's assume we're in link down status */ + dm9051->link_status = ETH_LINK_DOWN; /* Start auto negotiation */ bmcr_reg_t bmcr = { .speed_select = 1, /* 100Mbps */ @@ -212,19 +214,17 @@ static esp_err_t dm9051_negotiate(esp_eth_phy_t *phy) bmsr_reg_t bmsr; dscsr_reg_t dscsr; uint32_t to = 0; - for (to = 0; to < dm9051->autonego_timeout_ms / 10; to++) { - vTaskDelay(pdMS_TO_TICKS(10)); + for (to = 0; to < dm9051->autonego_timeout_ms / 100; to++) { + vTaskDelay(pdMS_TO_TICKS(100)); ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, dm9051->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)), err, TAG, "read BMSR failed"); ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, dm9051->addr, ETH_PHY_DSCSR_REG_ADDR, &(dscsr.val)), err, TAG, "read DSCSR failed"); if (bmsr.auto_nego_complete && dscsr.anmb & 0x08) { break; } } - if (to >= dm9051->autonego_timeout_ms / 10) { + if (to >= dm9051->autonego_timeout_ms / 100) { ESP_LOGW(TAG, "Ethernet PHY auto negotiation timeout"); } - /* Updata information about link, speed, duplex */ - ESP_GOTO_ON_ERROR(dm9051_update_link_duplex_speed(dm9051), err, TAG, "update link duplex speed failed"); return ESP_OK; err: return ret; diff --git a/components/esp_eth/src/esp_eth_phy_dp83848.c b/components/esp_eth/src/esp_eth_phy_dp83848.c index 96508897f7..cafef8d59c 100644 --- a/components/esp_eth/src/esp_eth_phy_dp83848.c +++ b/components/esp_eth/src/esp_eth_phy_dp83848.c @@ -194,6 +194,8 @@ static esp_err_t dp83848_negotiate(esp_eth_phy_t *phy) esp_err_t ret = ESP_OK; phy_dp83848_t *dp83848 = __containerof(phy, phy_dp83848_t, parent); esp_eth_mediator_t *eth = dp83848->eth; + /* in case any link status has changed, let's assume we're in link down status */ + dp83848->link_status = ETH_LINK_DOWN; /* Start auto negotiation */ bmcr_reg_t bmcr = { .speed_select = 1, /* 100Mbps */ @@ -206,8 +208,8 @@ static esp_err_t dp83848_negotiate(esp_eth_phy_t *phy) bmsr_reg_t bmsr; physts_reg_t physts; uint32_t to = 0; - for (to = 0; to < dp83848->autonego_timeout_ms / 10; to++) { - vTaskDelay(pdMS_TO_TICKS(10)); + for (to = 0; to < dp83848->autonego_timeout_ms / 100; to++) { + vTaskDelay(pdMS_TO_TICKS(100)); ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, dp83848->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)), err, TAG, "read BMSR failed"); ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, dp83848->addr, ETH_PHY_STS_REG_ADDR, &(physts.val)), err, TAG, "read PHYSTS failed"); if (bmsr.auto_nego_complete && physts.auto_nego_complete) { @@ -215,11 +217,9 @@ static esp_err_t dp83848_negotiate(esp_eth_phy_t *phy) } } /* Auto negotiation failed, maybe no network cable plugged in, so output a warning */ - if (to >= dp83848->autonego_timeout_ms / 10) { + if (to >= dp83848->autonego_timeout_ms / 100) { ESP_LOGW(TAG, "auto negotiation timeout"); } - /* Updata information about link, speed, duplex */ - ESP_GOTO_ON_ERROR(dp83848_update_link_duplex_speed(dp83848), err, TAG, "update link duplex speed failed"); return ESP_OK; err: return ret; diff --git a/components/esp_eth/src/esp_eth_phy_ip101.c b/components/esp_eth/src/esp_eth_phy_ip101.c index a412a631e6..e8424288b6 100644 --- a/components/esp_eth/src/esp_eth_phy_ip101.c +++ b/components/esp_eth/src/esp_eth_phy_ip101.c @@ -235,6 +235,8 @@ static esp_err_t ip101_negotiate(esp_eth_phy_t *phy) esp_err_t ret = ESP_OK; phy_ip101_t *ip101 = __containerof(phy, phy_ip101_t, parent); esp_eth_mediator_t *eth = ip101->eth; + /* in case any link status has changed, let's assume we're in link down status */ + ip101->link_status = ETH_LINK_DOWN; /* Restart auto negotiation */ bmcr_reg_t bmcr = { .speed_select = 1, /* 100Mbps */ @@ -246,19 +248,17 @@ static esp_err_t ip101_negotiate(esp_eth_phy_t *phy) /* Wait for auto negotiation complete */ bmsr_reg_t bmsr; uint32_t to = 0; - for (to = 0; to < ip101->autonego_timeout_ms / 10; to++) { - vTaskDelay(pdMS_TO_TICKS(10)); + for (to = 0; to < ip101->autonego_timeout_ms / 100; to++) { + vTaskDelay(pdMS_TO_TICKS(100)); ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, ip101->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)), err, TAG, "read BMSR failed"); if (bmsr.auto_nego_complete) { break; } } /* Auto negotiation failed, maybe no network cable plugged in, so output a warning */ - if (to >= ip101->autonego_timeout_ms / 10) { + if (to >= ip101->autonego_timeout_ms / 100) { ESP_LOGW(TAG, "auto negotiation timeout"); } - /* Updata information about link, speed, duplex */ - ESP_GOTO_ON_ERROR(ip101_update_link_duplex_speed(ip101), err, TAG, "update link duplex speed failed"); return ESP_OK; err: return ret; diff --git a/components/esp_eth/src/esp_eth_phy_ksz80xx.c b/components/esp_eth/src/esp_eth_phy_ksz80xx.c index c328ae1232..1674648085 100644 --- a/components/esp_eth/src/esp_eth_phy_ksz80xx.c +++ b/components/esp_eth/src/esp_eth_phy_ksz80xx.c @@ -213,6 +213,8 @@ static esp_err_t ksz80xx_negotiate(esp_eth_phy_t *phy) esp_err_t ret = ESP_OK; phy_ksz80xx_t *ksz80xx = __containerof(phy, phy_ksz80xx_t, parent); esp_eth_mediator_t *eth = ksz80xx->eth; + /* in case any link status has changed, let's assume we're in link down status */ + ksz80xx->link_status = ETH_LINK_DOWN; /* Restart auto negotiation */ bmcr_reg_t bmcr = { .speed_select = 1, /* 100Mbps */ @@ -224,19 +226,17 @@ static esp_err_t ksz80xx_negotiate(esp_eth_phy_t *phy) /* Wait for auto negotiation complete */ bmsr_reg_t bmsr; uint32_t to = 0; - for (to = 0; to < ksz80xx->autonego_timeout_ms / 10; to++) { - vTaskDelay(pdMS_TO_TICKS(10)); + for (to = 0; to < ksz80xx->autonego_timeout_ms / 100; to++) { + vTaskDelay(pdMS_TO_TICKS(100)); ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, ksz80xx->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)), err, TAG, "read BMSR failed"); if (bmsr.auto_nego_complete) { break; } } /* Auto negotiation failed, maybe no network cable plugged in, so output a warning */ - if (to >= ksz80xx->autonego_timeout_ms / 10) { + if (to >= ksz80xx->autonego_timeout_ms / 100) { ESP_LOGW(TAG, "auto negotiation timeout"); } - /* Updata information about link, speed, duplex */ - ESP_GOTO_ON_ERROR(ksz80xx_update_link_duplex_speed(ksz80xx), err, TAG, "update link duplex speed failed"); return ESP_OK; err: return ret; diff --git a/components/esp_eth/src/esp_eth_phy_ksz8851snl.c b/components/esp_eth/src/esp_eth_phy_ksz8851snl.c index ab5cf497ea..2f72e6b394 100644 --- a/components/esp_eth/src/esp_eth_phy_ksz8851snl.c +++ b/components/esp_eth/src/esp_eth_phy_ksz8851snl.c @@ -166,27 +166,27 @@ static esp_err_t phy_ksz8851_negotiate(esp_eth_phy_t *phy) phy_ksz8851snl_t *ksz8851 = __containerof(phy, phy_ksz8851snl_t, parent); esp_eth_mediator_t *eth = ksz8851->eth; ESP_LOGD(TAG, "restart negotiation"); - + /* in case any link status has changed, let's assume we're in link down status */ + ksz8851->link_status = ETH_LINK_DOWN; uint32_t control; ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, ksz8851->addr, KSZ8851_P1CR, &control), err, TAG, "P1CR read failed"); ESP_GOTO_ON_ERROR(eth->phy_reg_write(eth, ksz8851->addr, KSZ8851_P1CR, control | P1CR_RESTART_AN), err, TAG, "P1CR write failed"); uint32_t status; unsigned to; - for (to = 0; to < ksz8851->autonego_timeout_ms / 10; to++) { - vTaskDelay(pdMS_TO_TICKS(10)); + for (to = 0; to < ksz8851->autonego_timeout_ms / 100; to++) { + vTaskDelay(pdMS_TO_TICKS(100)); ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, ksz8851->addr, KSZ8851_P1SR, &status), err, TAG, "P1SR read failed"); if (status & P1SR_AN_DONE) { break; } } - if (to >= ksz8851->autonego_timeout_ms / 10) { + if (to >= ksz8851->autonego_timeout_ms / 100) { ESP_LOGW(TAG, "Ethernet PHY auto negotiation timeout"); } ESP_GOTO_ON_ERROR(eth->phy_reg_write(eth, ksz8851->addr, KSZ8851_P1CR, control), err, TAG, "P1CR write failed"); - ESP_GOTO_ON_ERROR(ksz8851_update_link_duplex_speed(ksz8851), err, TAG, "update link duplex speed failed"); ESP_LOGD(TAG, "negotiation succeeded"); return ESP_OK; err: diff --git a/components/esp_eth/src/esp_eth_phy_lan8720.c b/components/esp_eth/src/esp_eth_phy_lan8720.c index bb84160279..88a04ff1b9 100644 --- a/components/esp_eth/src/esp_eth_phy_lan8720.c +++ b/components/esp_eth/src/esp_eth_phy_lan8720.c @@ -278,6 +278,8 @@ static esp_err_t lan8720_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; + /* in case any link status has changed, let's assume we're in link down status */ + lan8720->link_status = ETH_LINK_DOWN; /* Restart auto negotiation */ bmcr_reg_t bmcr = { .speed_select = 1, /* 100Mbps */ @@ -290,8 +292,8 @@ static esp_err_t lan8720_negotiate(esp_eth_phy_t *phy) bmsr_reg_t bmsr; pscsr_reg_t pscsr; uint32_t to = 0; - for (to = 0; to < lan8720->autonego_timeout_ms / 10; to++) { - vTaskDelay(pdMS_TO_TICKS(10)); + for (to = 0; to < lan8720->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"); if (bmsr.auto_nego_complete && pscsr.auto_nego_done) { @@ -299,11 +301,9 @@ static esp_err_t lan8720_negotiate(esp_eth_phy_t *phy) } } /* Auto negotiation failed, maybe no network cable plugged in, so output a warning */ - if (to >= lan8720->autonego_timeout_ms / 10) { + if (to >= lan8720->autonego_timeout_ms / 100) { ESP_LOGW(TAG, "auto negotiation timeout"); } - /* Updata information about link, speed, duplex */ - ESP_GOTO_ON_ERROR(lan8720_update_link_duplex_speed(lan8720), err, TAG, "update link duplex speed failed"); return ESP_OK; err: return ret; diff --git a/components/esp_eth/src/esp_eth_phy_rtl8201.c b/components/esp_eth/src/esp_eth_phy_rtl8201.c index fe0f6c9014..8ba4a35445 100644 --- a/components/esp_eth/src/esp_eth_phy_rtl8201.c +++ b/components/esp_eth/src/esp_eth_phy_rtl8201.c @@ -188,6 +188,8 @@ static esp_err_t rtl8201_negotiate(esp_eth_phy_t *phy) esp_err_t ret = ESP_OK; phy_rtl8201_t *rtl8201 = __containerof(phy, phy_rtl8201_t, parent); esp_eth_mediator_t *eth = rtl8201->eth; + /* in case any link status has changed, let's assume we're in link down status */ + rtl8201->link_status = ETH_LINK_DOWN; /* Restart auto negotiation */ bmcr_reg_t bmcr = { .speed_select = 1, /* 100Mbps */ @@ -199,19 +201,17 @@ static esp_err_t rtl8201_negotiate(esp_eth_phy_t *phy) /* Wait for auto negotiation complete */ bmsr_reg_t bmsr; uint32_t to = 0; - for (to = 0; to < rtl8201->autonego_timeout_ms / 10; to++) { - vTaskDelay(pdMS_TO_TICKS(10)); + for (to = 0; to < rtl8201->autonego_timeout_ms / 100; to++) { + vTaskDelay(pdMS_TO_TICKS(100)); ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, rtl8201->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)), err, TAG, "read BMSR failed"); if (bmsr.auto_nego_complete) { break; } } /* Auto negotiation failed, maybe no network cable plugged in, so output a warning */ - if (to >= rtl8201->autonego_timeout_ms / 10) { + if (to >= rtl8201->autonego_timeout_ms / 100) { ESP_LOGW(TAG, "auto negotiation timeout"); } - /* Updata information about link, speed, duplex */ - ESP_GOTO_ON_ERROR(rtl8201_update_link_duplex_speed(rtl8201), err, TAG, "update link duplex speed failed"); return ESP_OK; err: return ret; diff --git a/components/esp_eth/src/esp_eth_phy_w5500.c b/components/esp_eth/src/esp_eth_phy_w5500.c index ac43ed7b52..2ec157c6b4 100644 --- a/components/esp_eth/src/esp_eth_phy_w5500.c +++ b/components/esp_eth/src/esp_eth_phy_w5500.c @@ -148,15 +148,13 @@ static esp_err_t w5500_negotiate(esp_eth_phy_t *phy) esp_err_t ret = ESP_OK; phy_w5500_t *w5500 = __containerof(phy, phy_w5500_t, parent); esp_eth_mediator_t *eth = w5500->eth; - + /* in case any link status has changed, let's assume we're in link down status */ + w5500->link_status = ETH_LINK_DOWN; phycfg_reg_t phycfg; ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, w5500->addr, W5500_REG_PHYCFGR, (uint32_t *) & (phycfg.val)), err, TAG, "read PHYCFG failed"); phycfg.opsel = 1; // PHY working mode configured by register phycfg.opmode = 7; // all capable, auto-negotiation enabled ESP_GOTO_ON_ERROR(eth->phy_reg_write(eth, w5500->addr, W5500_REG_PHYCFGR, phycfg.val), err, TAG, "write PHYCFG failed"); - - /* Update information about link, speed, duplex */ - ESP_GOTO_ON_ERROR(w5500_update_link_duplex_speed(w5500), err, TAG, "update link duplex speed failed"); return ESP_OK; err: return ret; diff --git a/examples/ethernet/basic/main/Kconfig.projbuild b/examples/ethernet/basic/main/Kconfig.projbuild index 2d01147086..be155389b2 100644 --- a/examples/ethernet/basic/main/Kconfig.projbuild +++ b/examples/ethernet/basic/main/Kconfig.projbuild @@ -145,7 +145,7 @@ menu "Example Configuration" range 0 34 if IDF_TARGET_ESP32 range 0 46 if IDF_TARGET_ESP32S2 range 0 19 if IDF_TARGET_ESP32C3 - default 5 if IDF_TARGET_ESP32 + default 16 if IDF_TARGET_ESP32 default 21 if IDF_TARGET_ESP32S2 default 10 if IDF_TARGET_ESP32C3 help @@ -169,8 +169,7 @@ menu "Example Configuration" config EXAMPLE_ETH_PHY_RST_GPIO int "PHY Reset GPIO number" - default 16 if IDF_TARGET_ESP32 - default 5 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 + default 5 help Set the GPIO number used to reset PHY chip. Set to -1 to disable PHY chip hardware reset.