mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-31 21:14:37 +00:00 
			
		
		
		
	esp_eth: EMAC start/stop optimization
This commit is contained in:
		| @@ -262,7 +262,6 @@ esp_err_t esp_eth_start(esp_eth_handle_t hdl) | |||||||
|     esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl; |     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(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG); | ||||||
|     esp_eth_phy_t *phy = eth_driver->phy; |     esp_eth_phy_t *phy = eth_driver->phy; | ||||||
|     esp_eth_mac_t *mac = eth_driver->mac; |  | ||||||
|     // check if driver has started |     // check if driver has started | ||||||
|     esp_eth_fsm_t expected_fsm = ESP_ETH_FSM_STOP; |     esp_eth_fsm_t expected_fsm = ESP_ETH_FSM_STOP; | ||||||
|     if (!atomic_compare_exchange_strong(ð_driver->fsm, &expected_fsm, ESP_ETH_FSM_START)) { |     if (!atomic_compare_exchange_strong(ð_driver->fsm, &expected_fsm, ESP_ETH_FSM_START)) { | ||||||
| @@ -271,7 +270,6 @@ esp_err_t esp_eth_start(esp_eth_handle_t hdl) | |||||||
|         goto err; |         goto err; | ||||||
|     } |     } | ||||||
|     ETH_CHECK(phy->negotiate(phy) == ESP_OK, "phy negotiation failed", err, ESP_FAIL); |     ETH_CHECK(phy->negotiate(phy) == ESP_OK, "phy negotiation failed", err, ESP_FAIL); | ||||||
|     ETH_CHECK(mac->start(mac) == ESP_OK, "start mac failed", err, ESP_FAIL); |  | ||||||
|     ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_START, ð_driver, sizeof(esp_eth_driver_t *), 0) == ESP_OK, |     ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_START, ð_driver, sizeof(esp_eth_driver_t *), 0) == ESP_OK, | ||||||
|               "send ETHERNET_EVENT_START event failed", err, ESP_FAIL); |               "send ETHERNET_EVENT_START event failed", err, ESP_FAIL); | ||||||
|     ETH_CHECK(phy->get_link(phy) == ESP_OK, "phy get link status failed", err, ESP_FAIL); |     ETH_CHECK(phy->get_link(phy) == ESP_OK, "phy get link status failed", err, ESP_FAIL); | ||||||
|   | |||||||
| @@ -47,7 +47,7 @@ static const char *TAG = "emac_esp32"; | |||||||
|     } while (0) |     } while (0) | ||||||
|  |  | ||||||
| #define PHY_OPERATION_TIMEOUT_US (1000) | #define PHY_OPERATION_TIMEOUT_US (1000) | ||||||
| #define MAC_STOP_TIMEOUT_MS (100) | #define MAC_STOP_TIMEOUT_US (250) | ||||||
| #define FLOW_CONTROL_LOW_WATER_MARK (CONFIG_ETH_DMA_RX_BUFFER_NUM / 3) | #define FLOW_CONTROL_LOW_WATER_MARK (CONFIG_ETH_DMA_RX_BUFFER_NUM / 3) | ||||||
| #define FLOW_CONTROL_HIGH_WATER_MARK (FLOW_CONTROL_LOW_WATER_MARK * 2) | #define FLOW_CONTROL_HIGH_WATER_MARK (FLOW_CONTROL_LOW_WATER_MARK * 2) | ||||||
|  |  | ||||||
| @@ -77,6 +77,8 @@ typedef struct { | |||||||
|  |  | ||||||
| static esp_err_t esp_emac_alloc_driver_obj(const eth_mac_config_t *config, emac_esp32_t **emac_out_hdl, void **out_descriptors); | static esp_err_t esp_emac_alloc_driver_obj(const eth_mac_config_t *config, emac_esp32_t **emac_out_hdl, void **out_descriptors); | ||||||
| static void esp_emac_free_driver_obj(emac_esp32_t *emac, void *descriptors); | static void esp_emac_free_driver_obj(emac_esp32_t *emac, void *descriptors); | ||||||
|  | static esp_err_t emac_esp32_start(esp_eth_mac_t *mac); | ||||||
|  | static esp_err_t emac_esp32_stop(esp_eth_mac_t *mac); | ||||||
|  |  | ||||||
| static esp_err_t emac_esp32_set_mediator(esp_eth_mac_t *mac, esp_eth_mediator_t *eth) | static esp_err_t emac_esp32_set_mediator(esp_eth_mac_t *mac, esp_eth_mediator_t *eth) | ||||||
| { | { | ||||||
| @@ -163,11 +165,11 @@ static esp_err_t emac_esp32_set_link(esp_eth_mac_t *mac, eth_link_t link) | |||||||
|     switch (link) { |     switch (link) { | ||||||
|     case ETH_LINK_UP: |     case ETH_LINK_UP: | ||||||
|         MAC_CHECK(esp_intr_enable(emac->intr_hdl) == ESP_OK, "enable interrupt failed", err, ESP_FAIL); |         MAC_CHECK(esp_intr_enable(emac->intr_hdl) == ESP_OK, "enable interrupt failed", err, ESP_FAIL); | ||||||
|         emac_hal_start(&emac->hal); |         emac_esp32_start(mac); | ||||||
|         break; |         break; | ||||||
|     case ETH_LINK_DOWN: |     case ETH_LINK_DOWN: | ||||||
|         MAC_CHECK(esp_intr_disable(emac->intr_hdl) == ESP_OK, "disable interrupt failed", err, ESP_FAIL); |         MAC_CHECK(esp_intr_disable(emac->intr_hdl) == ESP_OK, "disable interrupt failed", err, ESP_FAIL); | ||||||
|         emac_hal_stop(&emac->hal); |         emac_esp32_stop(mac); | ||||||
|         break; |         break; | ||||||
|     default: |     default: | ||||||
|         MAC_CHECK(false, "unknown link status", err, ESP_ERR_INVALID_ARG); |         MAC_CHECK(false, "unknown link status", err, ESP_ERR_INVALID_ARG); | ||||||
| @@ -402,9 +404,9 @@ static esp_err_t emac_esp32_stop(esp_eth_mac_t *mac) | |||||||
|         if ((ret = emac_hal_stop(&emac->hal)) == ESP_OK) { |         if ((ret = emac_hal_stop(&emac->hal)) == ESP_OK) { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         to += 20; |         to += 25; | ||||||
|         vTaskDelay(pdMS_TO_TICKS(20)); |         esp_rom_delay_us(25); | ||||||
|     } while (to < MAC_STOP_TIMEOUT_MS); |     } while (to < MAC_STOP_TIMEOUT_US); | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -436,22 +436,25 @@ esp_err_t emac_hal_stop(emac_hal_context_t *hal) | |||||||
|  |  | ||||||
|     /* Stop DMA transmission */ |     /* Stop DMA transmission */ | ||||||
|     opm.start_stop_transmission_command = 0; |     opm.start_stop_transmission_command = 0; | ||||||
|     /* Stop DMA reception */ |  | ||||||
|     opm.start_stop_rx = 0; |  | ||||||
|  |  | ||||||
|     hal->dma_regs->dmaoperation_mode = opm; |     hal->dma_regs->dmaoperation_mode = opm; | ||||||
|  |  | ||||||
|     if (hal->mac_regs->emacdebug.mactfcs != 0x0) { |     if (hal->mac_regs->emacdebug.mactfcs != 0x0) { | ||||||
|         /* Previous transmit in progress */ |         /* Previous transmit in progress */ | ||||||
|         return ESP_ERR_INVALID_STATE; |         return ESP_ERR_INVALID_STATE; | ||||||
|     } |     } | ||||||
|  |     /* Disable transmit state machine of the MAC for transmission on the MII */ | ||||||
|  |     cfg.tx = 0; | ||||||
|  |     hal->mac_regs->gmacconfig = cfg; | ||||||
|  |  | ||||||
|     /* Disable receive state machine of the MAC for reception from the MII */ |     /* Disable receive state machine of the MAC for reception from the MII */ | ||||||
|     cfg.rx = 0; |     cfg.rx = 0; | ||||||
|     /* Disable transmit state machine of the MAC for transmission on the MII */ |  | ||||||
|     cfg.tx = 0; |  | ||||||
|  |  | ||||||
|     hal->mac_regs->gmacconfig = cfg; |     hal->mac_regs->gmacconfig = cfg; | ||||||
|  |     if (hal->mac_regs->emacdebug.mtlrfrcs != 0x0) { | ||||||
|  |         /* Previous receive copy in progress */ | ||||||
|  |         return ESP_ERR_INVALID_STATE; | ||||||
|  |     } | ||||||
|  |     /* Stop DMA reception */ | ||||||
|  |     opm.start_stop_rx = 0; | ||||||
|  |     hal->dma_regs->dmaoperation_mode = opm; | ||||||
|  |  | ||||||
|     /* Disable Ethernet MAC and DMA Interrupt */ |     /* Disable Ethernet MAC and DMA Interrupt */ | ||||||
|     hal->dma_regs->dmain_en.val = 0x0; |     hal->dma_regs->dmain_en.val = 0x0; | ||||||
|   | |||||||
| @@ -387,7 +387,7 @@ void emac_hal_start(emac_hal_context_t *hal); | |||||||
|  * @param hal EMAC HAL context infostructure |  * @param hal EMAC HAL context infostructure | ||||||
|  * @return |  * @return | ||||||
|  *     - ESP_OK: succeed |  *     - ESP_OK: succeed | ||||||
|   *    - ESP_ERR_INVALID_STATE: previous frame transmission is not completed. When this error occurs, |   *    - ESP_ERR_INVALID_STATE: previous frame transmission/reception is not completed. When this error occurs, | ||||||
|   *      wait and reapeat the EMAC stop again. |   *      wait and reapeat the EMAC stop again. | ||||||
|  */ |  */ | ||||||
| esp_err_t emac_hal_stop(emac_hal_context_t *hal); | esp_err_t emac_hal_stop(emac_hal_context_t *hal); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Ondrej Kosta
					Ondrej Kosta