mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
esp_eth: restart negotiation in esp_eth_start
This commit is contained in:
parent
83f2d802ce
commit
0c25793b06
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user