From ac11545e0a6456ad0db2fd01586b0556726d8377 Mon Sep 17 00:00:00 2001 From: morris Date: Tue, 3 Dec 2019 15:37:34 +0800 Subject: [PATCH] ethernet: warning when double start/stop --- components/esp_eth/include/esp_eth.h | 2 ++ components/esp_eth/src/esp_eth.c | 27 ++++++++++++++++--- components/esp_eth/src/esp_eth_phy_dm9051.c | 1 + components/esp_eth/src/esp_eth_phy_dp83848.c | 1 + components/esp_eth/src/esp_eth_phy_ip101.c | 1 + components/esp_eth/src/esp_eth_phy_lan8720.c | 1 + components/esp_eth/src/esp_eth_phy_rtl8201.c | 1 + .../tcpip_adapter/tcpip_adapter_compat.c | 1 - .../protocol_examples_common/connect.c | 1 + 9 files changed, 31 insertions(+), 5 deletions(-) diff --git a/components/esp_eth/include/esp_eth.h b/components/esp_eth/include/esp_eth.h index db0124eaf8..34ee91594f 100644 --- a/components/esp_eth/include/esp_eth.h +++ b/components/esp_eth/include/esp_eth.h @@ -142,6 +142,7 @@ esp_err_t esp_eth_driver_uninstall(esp_eth_handle_t hdl); * @return * - ESP_OK: start esp_eth driver successfully * - ESP_ERR_INVALID_ARG: start esp_eth driver failed because of some invalid argument +* - ESP_ERR_INVALID_STATE: start esp_eth driver failed because driver has started already * - ESP_FAIL: start esp_eth driver failed because some other error occurred */ esp_err_t esp_eth_start(esp_eth_handle_t hdl); @@ -155,6 +156,7 @@ esp_err_t esp_eth_start(esp_eth_handle_t hdl); * @return * - ESP_OK: stop esp_eth driver successfully * - ESP_ERR_INVALID_ARG: stop esp_eth driver failed because of some invalid argument +* - ESP_ERR_INVALID_STATE: stop esp_eth driver failed because driver has not started yet * - ESP_FAIL: stop esp_eth driver failed because some other error occurred */ esp_err_t esp_eth_stop(esp_eth_handle_t hdl); diff --git a/components/esp_eth/src/esp_eth.c b/components/esp_eth/src/esp_eth.c index 8b1f90e326..1c87b8a60c 100644 --- a/components/esp_eth/src/esp_eth.c +++ b/components/esp_eth/src/esp_eth.c @@ -34,6 +34,8 @@ static const char *TAG = "esp_eth"; ESP_EVENT_DEFINE_BASE(ETH_EVENT); +#define ESP_ETH_FLAGS_STARTED (1<<0) + /** * @brief The Ethernet driver mainly consists of PHY, MAC and * the mediator who will handle the request/response from/to MAC, PHY and Users. @@ -54,6 +56,7 @@ typedef struct { eth_link_t link; atomic_int ref_count; void *priv; + uint32_t flags; esp_err_t (*stack_input)(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t length, void *priv); esp_err_t (*on_lowlevel_init_done)(esp_eth_handle_t eth_handle); esp_err_t (*on_lowlevel_deinit_done)(esp_eth_handle_t eth_handle); @@ -236,6 +239,14 @@ esp_err_t esp_eth_start(esp_eth_handle_t hdl) esp_err_t ret = ESP_OK; esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl; ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG); + // check if driver has started + if (eth_driver->flags & ESP_ETH_FLAGS_STARTED) { + ESP_LOGW(TAG, "driver started already"); + ret = ESP_ERR_INVALID_STATE; + goto err; + } + eth_driver->flags |= ESP_ETH_FLAGS_STARTED; + ETH_CHECK(eth_driver->phy->reset(eth_driver->phy) == ESP_OK, "reset phy failed", err, ESP_FAIL); ETH_CHECK(xTimerStart(eth_driver->check_link_timer, 0) == pdPASS, "start eth_link_timer failed", err, ESP_FAIL); ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_START, ð_driver, sizeof(eth_driver), 0) == ESP_OK, @@ -252,10 +263,18 @@ esp_err_t esp_eth_stop(esp_eth_handle_t hdl) esp_err_t ret = ESP_OK; esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl; ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG); - ETH_CHECK(xTimerStop(eth_driver->check_link_timer, 0) == pdPASS, - "stop eth_link_timer failed", err, ESP_FAIL); - ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_STOP, ð_driver, sizeof(eth_driver), 0) == ESP_OK, - "send ETHERNET_EVENT_STOP event failed", err, ESP_FAIL); + // check if driver has started + if (eth_driver->flags & ESP_ETH_FLAGS_STARTED) { + eth_driver->flags &= ~ESP_ETH_FLAGS_STARTED; + ETH_CHECK(xTimerStop(eth_driver->check_link_timer, 0) == pdPASS, + "stop eth_link_timer failed", err, ESP_FAIL); + ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_STOP, ð_driver, sizeof(eth_driver), 0) == ESP_OK, + "send ETHERNET_EVENT_STOP event failed", err, ESP_FAIL); + } else { + ESP_LOGW(TAG, "driver not started yet"); + ret = ESP_ERR_INVALID_STATE; + goto err; + } return ESP_OK; err: return ret; diff --git a/components/esp_eth/src/esp_eth_phy_dm9051.c b/components/esp_eth/src/esp_eth_phy_dm9051.c index 655967a4b7..c3775f2042 100644 --- a/components/esp_eth/src/esp_eth_phy_dm9051.c +++ b/components/esp_eth/src/esp_eth_phy_dm9051.c @@ -150,6 +150,7 @@ err: static esp_err_t dm9051_reset(esp_eth_phy_t *phy) { phy_dm9051_t *dm9051 = __containerof(phy, phy_dm9051_t, parent); + dm9051->link_status = ETH_LINK_DOWN; esp_eth_mediator_t *eth = dm9051->eth; dscr_reg_t dscr; PHY_CHECK(eth->phy_reg_read(eth, dm9051->addr, ETH_PHY_DSCR_REG_ADDR, &(dscr.val)) == ESP_OK, diff --git a/components/esp_eth/src/esp_eth_phy_dp83848.c b/components/esp_eth/src/esp_eth_phy_dp83848.c index 0c1cd99cd9..fbb41391a9 100644 --- a/components/esp_eth/src/esp_eth_phy_dp83848.c +++ b/components/esp_eth/src/esp_eth_phy_dp83848.c @@ -156,6 +156,7 @@ err: static esp_err_t dp83848_reset(esp_eth_phy_t *phy) { phy_dp83848_t *dp83848 = __containerof(phy, phy_dp83848_t, parent); + dp83848->link_status = ETH_LINK_DOWN; esp_eth_mediator_t *eth = dp83848->eth; bmcr_reg_t bmcr = {.reset = 1}; PHY_CHECK(eth->phy_reg_write(eth, dp83848->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val) == ESP_OK, diff --git a/components/esp_eth/src/esp_eth_phy_ip101.c b/components/esp_eth/src/esp_eth_phy_ip101.c index 307dca6ebc..6b16c2188a 100644 --- a/components/esp_eth/src/esp_eth_phy_ip101.c +++ b/components/esp_eth/src/esp_eth_phy_ip101.c @@ -196,6 +196,7 @@ err: static esp_err_t ip101_reset(esp_eth_phy_t *phy) { phy_ip101_t *ip101 = __containerof(phy, phy_ip101_t, parent); + ip101->link_status = ETH_LINK_DOWN; esp_eth_mediator_t *eth = ip101->eth; bmcr_reg_t bmcr = {.reset = 1}; PHY_CHECK(eth->phy_reg_write(eth, ip101->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val) == ESP_OK, diff --git a/components/esp_eth/src/esp_eth_phy_lan8720.c b/components/esp_eth/src/esp_eth_phy_lan8720.c index 82ae78b1d8..d7d62bb781 100644 --- a/components/esp_eth/src/esp_eth_phy_lan8720.c +++ b/components/esp_eth/src/esp_eth_phy_lan8720.c @@ -238,6 +238,7 @@ err: static esp_err_t lan8720_reset(esp_eth_phy_t *phy) { phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent); + lan8720->link_status = ETH_LINK_DOWN; esp_eth_mediator_t *eth = lan8720->eth; bmcr_reg_t bmcr = {.reset = 1}; PHY_CHECK(eth->phy_reg_write(eth, lan8720->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val) == ESP_OK, diff --git a/components/esp_eth/src/esp_eth_phy_rtl8201.c b/components/esp_eth/src/esp_eth_phy_rtl8201.c index 7ec624f827..814563fdc1 100644 --- a/components/esp_eth/src/esp_eth_phy_rtl8201.c +++ b/components/esp_eth/src/esp_eth_phy_rtl8201.c @@ -147,6 +147,7 @@ err: static esp_err_t rtl8201_reset(esp_eth_phy_t *phy) { phy_rtl8201_t *rtl8201 = __containerof(phy, phy_rtl8201_t, parent); + rtl8201->link_status = ETH_LINK_DOWN; esp_eth_mediator_t *eth = rtl8201->eth; bmcr_reg_t bmcr = {.reset = 1}; PHY_CHECK(eth->phy_reg_write(eth, rtl8201->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val) == ESP_OK, diff --git a/components/tcpip_adapter/tcpip_adapter_compat.c b/components/tcpip_adapter/tcpip_adapter_compat.c index 1d2dee5b15..7a81fbb13d 100644 --- a/components/tcpip_adapter/tcpip_adapter_compat.c +++ b/components/tcpip_adapter/tcpip_adapter_compat.c @@ -133,7 +133,6 @@ esp_err_t tcpip_adapter_compat_start_eth(void *eth_driver) if (esp_netif) { esp_netif_attach(esp_netif, esp_eth_new_netif_glue(eth_driver)); } - esp_eth_start(eth_driver); } return ESP_OK; } diff --git a/examples/common_components/protocol_examples_common/connect.c b/examples/common_components/protocol_examples_common/connect.c index f33aa70514..b3765d8786 100644 --- a/examples/common_components/protocol_examples_common/connect.c +++ b/examples/common_components/protocol_examples_common/connect.c @@ -287,6 +287,7 @@ static void stop(void) ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6)); ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event)); #endif + ESP_ERROR_CHECK(esp_eth_stop(s_eth_handle)); ESP_ERROR_CHECK(esp_eth_driver_uninstall(s_eth_handle)); ESP_ERROR_CHECK(s_phy->del(s_phy)); ESP_ERROR_CHECK(s_mac->del(s_mac));