ethernet: esp_eth_stop API should stop emac hardware

This commit is contained in:
morris 2020-05-08 21:44:30 +08:00
parent 3c882991b5
commit 496ab2a83f
5 changed files with 58 additions and 7 deletions

View file

@ -73,6 +73,30 @@ struct esp_eth_mac_s {
*/ */
esp_err_t (*deinit)(esp_eth_mac_t *mac); esp_err_t (*deinit)(esp_eth_mac_t *mac);
/**
* @brief Start Ethernet MAC
*
* @param[in] mac: Ethernet MAC instance
*
* @return
* - ESP_OK: start Ethernet MAC successfully
* - ESP_FAIL: start Ethernet MAC failed because some other error occurred
*
*/
esp_err_t (*start)(esp_eth_mac_t *mac);
/**
* @brief Stop Ethernet MAC
*
* @param[in] mac: Ethernet MAC instance
*
* @return
* - ESP_OK: stop Ethernet MAC successfully
* - ESP_FAIL: stop Ethernet MAC failed because some error occurred
*
*/
esp_err_t (*stop)(esp_eth_mac_t *mac);
/** /**
* @brief Transmit packet from Ethernet MAC * @brief Transmit packet from Ethernet MAC
* *

View file

@ -258,6 +258,8 @@ esp_err_t esp_eth_stop(esp_eth_handle_t hdl)
// check if driver has started // check if driver has started
if (eth_driver->flags & ESP_ETH_FLAGS_STARTED) { if (eth_driver->flags & ESP_ETH_FLAGS_STARTED) {
eth_driver->flags &= ~ESP_ETH_FLAGS_STARTED; eth_driver->flags &= ~ESP_ETH_FLAGS_STARTED;
esp_eth_mac_t *mac = eth_driver->mac;
ETH_CHECK(mac->stop(mac) == ESP_OK, "stop mac failed", err, ESP_FAIL);
ETH_CHECK(xTimerStop(eth_driver->check_link_timer, 0) == pdPASS, ETH_CHECK(xTimerStop(eth_driver->check_link_timer, 0) == pdPASS,
"stop eth_link_timer failed", err, ESP_FAIL); "stop eth_link_timer failed", err, ESP_FAIL);
ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_STOP, &eth_driver, sizeof(eth_driver), 0) == ESP_OK, ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_STOP, &eth_driver, sizeof(eth_driver), 0) == ESP_OK,

View file

@ -337,9 +337,10 @@ err:
/** /**
* @brief start dm9051: enable interrupt and start receive * @brief start dm9051: enable interrupt and start receive
*/ */
static esp_err_t dm9051_start(emac_dm9051_t *emac) static esp_err_t emac_dm9051_start(esp_eth_mac_t *mac)
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
/* enable interrupt */ /* enable interrupt */
MAC_CHECK(dm9051_register_write(emac, DM9051_IMR, IMR_ALL) == ESP_OK, "write IMR failed", err, ESP_FAIL); MAC_CHECK(dm9051_register_write(emac, DM9051_IMR, IMR_ALL) == ESP_OK, "write IMR failed", err, ESP_FAIL);
/* enable rx */ /* enable rx */
@ -355,9 +356,10 @@ err:
/** /**
* @brief stop dm9051: disable interrupt and stop receive * @brief stop dm9051: disable interrupt and stop receive
*/ */
static esp_err_t dm9051_stop(emac_dm9051_t *emac) static esp_err_t emac_dm9051_stop(esp_eth_mac_t *mac)
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
/* disable interrupt */ /* disable interrupt */
MAC_CHECK(dm9051_register_write(emac, DM9051_IMR, 0x00) == ESP_OK, "write IMR failed", err, ESP_FAIL); MAC_CHECK(dm9051_register_write(emac, DM9051_IMR, 0x00) == ESP_OK, "write IMR failed", err, ESP_FAIL);
/* disable rx */ /* disable rx */
@ -519,11 +521,11 @@ static esp_err_t emac_dm9051_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(nsr & NSR_LINKST, "phy is not link up", err, ESP_ERR_INVALID_STATE); MAC_CHECK(nsr & NSR_LINKST, "phy is not link up", err, ESP_ERR_INVALID_STATE);
MAC_CHECK(dm9051_start(emac) == ESP_OK, "dm9051 start failed", err, ESP_FAIL); MAC_CHECK(mac->start(mac) == ESP_OK, "dm9051 start failed", err, ESP_FAIL);
break; break;
case ETH_LINK_DOWN: case ETH_LINK_DOWN:
MAC_CHECK(!(nsr & NSR_LINKST), "phy is not link down", err, ESP_ERR_INVALID_STATE); MAC_CHECK(!(nsr & NSR_LINKST), "phy is not link down", err, ESP_ERR_INVALID_STATE);
MAC_CHECK(dm9051_stop(emac) == ESP_OK, "dm9051 stop failed", err, ESP_FAIL); MAC_CHECK(mac->stop(mac) == ESP_OK, "dm9051 stop failed", err, ESP_FAIL);
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);
@ -629,12 +631,12 @@ static esp_err_t emac_dm9051_receive(esp_eth_mac_t *mac, uint8_t *buf, uint32_t
MAC_CHECK(dm9051_register_read(emac, DM9051_MRCMDX, &rxbyte) == ESP_OK, "read MRCMDX failed", err, ESP_FAIL); MAC_CHECK(dm9051_register_read(emac, DM9051_MRCMDX, &rxbyte) == ESP_OK, "read MRCMDX failed", err, ESP_FAIL);
/* rxbyte must be 0xFF, 0 or 1 */ /* rxbyte must be 0xFF, 0 or 1 */
if (rxbyte > 1) { if (rxbyte > 1) {
MAC_CHECK(dm9051_stop(emac) == ESP_OK, "stop dm9051 failed", err, ESP_FAIL); MAC_CHECK(mac->stop(mac) == ESP_OK, "stop dm9051 failed", err, ESP_FAIL);
/* reset rx fifo pointer */ /* reset rx fifo pointer */
MAC_CHECK(dm9051_register_write(emac, DM9051_MPTRCR, MPTRCR_RST_RX) == ESP_OK, MAC_CHECK(dm9051_register_write(emac, DM9051_MPTRCR, MPTRCR_RST_RX) == ESP_OK,
"write MPTRCR failed", err, ESP_FAIL); "write MPTRCR failed", err, ESP_FAIL);
ets_delay_us(10); ets_delay_us(10);
MAC_CHECK(dm9051_start(emac) == ESP_OK, "start dm9051 failed", err, ESP_FAIL); MAC_CHECK(mac->start(mac) == ESP_OK, "start dm9051 failed", err, ESP_FAIL);
MAC_CHECK(false, "reset rx fifo pointer", err, ESP_FAIL); MAC_CHECK(false, "reset rx fifo pointer", err, ESP_FAIL);
} else if (rxbyte) { } else if (rxbyte) {
MAC_CHECK(dm9051_memory_peek(emac, (uint8_t *)&header, sizeof(header)) == ESP_OK, MAC_CHECK(dm9051_memory_peek(emac, (uint8_t *)&header, sizeof(header)) == ESP_OK,
@ -698,7 +700,7 @@ static esp_err_t emac_dm9051_deinit(esp_eth_mac_t *mac)
{ {
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
esp_eth_mediator_t *eth = emac->eth; esp_eth_mediator_t *eth = emac->eth;
dm9051_stop(emac); mac->stop(mac);
gpio_isr_handler_remove(emac->int_gpio_num); gpio_isr_handler_remove(emac->int_gpio_num);
gpio_reset_pin(emac->int_gpio_num); gpio_reset_pin(emac->int_gpio_num);
eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL); eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL);
@ -731,6 +733,8 @@ esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config,
emac->parent.set_mediator = emac_dm9051_set_mediator; emac->parent.set_mediator = emac_dm9051_set_mediator;
emac->parent.init = emac_dm9051_init; emac->parent.init = emac_dm9051_init;
emac->parent.deinit = emac_dm9051_deinit; emac->parent.deinit = emac_dm9051_deinit;
emac->parent.start = emac_dm9051_start;
emac->parent.stop = emac_dm9051_stop;
emac->parent.del = emac_dm9051_del; emac->parent.del = emac_dm9051_del;
emac->parent.write_phy_reg = emac_dm9051_write_phy_reg; emac->parent.write_phy_reg = emac_dm9051_write_phy_reg;
emac->parent.read_phy_reg = emac_dm9051_read_phy_reg; emac->parent.read_phy_reg = emac_dm9051_read_phy_reg;

View file

@ -336,6 +336,20 @@ static esp_err_t emac_esp32_deinit(esp_eth_mac_t *mac)
return ESP_OK; return ESP_OK;
} }
static esp_err_t emac_esp32_start(esp_eth_mac_t *mac)
{
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
emac_hal_start(&emac->hal);
return ESP_OK;
}
static esp_err_t emac_esp32_stop(esp_eth_mac_t *mac)
{
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
emac_hal_stop(&emac->hal);
return ESP_OK;
}
static esp_err_t emac_esp32_del(esp_eth_mac_t *mac) static esp_err_t emac_esp32_del(esp_eth_mac_t *mac)
{ {
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent); emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
@ -410,6 +424,8 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config)
emac->parent.set_mediator = emac_esp32_set_mediator; emac->parent.set_mediator = emac_esp32_set_mediator;
emac->parent.init = emac_esp32_init; emac->parent.init = emac_esp32_init;
emac->parent.deinit = emac_esp32_deinit; emac->parent.deinit = emac_esp32_deinit;
emac->parent.start = emac_esp32_start;
emac->parent.stop = emac_esp32_stop;
emac->parent.del = emac_esp32_del; emac->parent.del = emac_esp32_del;
emac->parent.write_phy_reg = emac_esp32_write_phy_reg; emac->parent.write_phy_reg = emac_esp32_write_phy_reg;
emac->parent.read_phy_reg = emac_esp32_read_phy_reg; emac->parent.read_phy_reg = emac_esp32_read_phy_reg;

View file

@ -94,6 +94,11 @@ static esp_err_t dm9051_update_link_duplex_speed(phy_dm9051_t *dm9051)
eth_duplex_t duplex = ETH_DUPLEX_HALF; eth_duplex_t duplex = ETH_DUPLEX_HALF;
bmsr_reg_t bmsr; bmsr_reg_t bmsr;
dscsr_reg_t dscsr; dscsr_reg_t dscsr;
// BMSR is a latch low register
// after power up, the first latched value must be 0, which means down
// to speed up power up link speed, double read this register as a workaround
PHY_CHECK(eth->phy_reg_read(eth, dm9051->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK,
"read BMSR failed", err);
PHY_CHECK(eth->phy_reg_read(eth, dm9051->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK, PHY_CHECK(eth->phy_reg_read(eth, dm9051->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK,
"read BMSR failed", err); "read BMSR failed", err);
eth_link_t link = bmsr.link_status ? ETH_LINK_UP : ETH_LINK_DOWN; eth_link_t link = bmsr.link_status ? ETH_LINK_UP : ETH_LINK_DOWN;