From 6fda9fe2071aa0d999918334e6478516a7410259 Mon Sep 17 00:00:00 2001 From: Ondrej Kosta Date: Mon, 2 Oct 2023 12:37:19 +0200 Subject: [PATCH] fix(esp_eth): various Ethernet driver fixes ksz8851snl: enabled reception of multicast frames Internal EMAC: fixed APLL CLK deinitialization DM9051 and KSZ80xx: fixed speed configuration when not in loopback mode phy_802_3: added multiple attempts when autodetecting PHY address --- components/esp_eth/src/esp_eth_mac_esp.c | 1 - .../esp_eth/src/esp_eth_mac_ksz8851snl.c | 12 +++++------ components/esp_eth/src/esp_eth_phy_802_3.c | 20 ++++++++++--------- components/esp_eth/src/esp_eth_phy_dm9051.c | 20 +++++++------------ components/esp_eth/src/esp_eth_phy_ksz80xx.c | 4 +++- 5 files changed, 27 insertions(+), 30 deletions(-) diff --git a/components/esp_eth/src/esp_eth_mac_esp.c b/components/esp_eth/src/esp_eth_mac_esp.c index a1dd3c157f..e9d20d1ef0 100644 --- a/components/esp_eth/src/esp_eth_mac_esp.c +++ b/components/esp_eth/src/esp_eth_mac_esp.c @@ -628,7 +628,6 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_esp32_emac_config_t *esp32_config emac->smi_mdio_gpio_num = esp32_config->smi_mdio_gpio_num; emac->flow_control_high_water_mark = FLOW_CONTROL_HIGH_WATER_MARK; emac->flow_control_low_water_mark = FLOW_CONTROL_LOW_WATER_MARK; - emac->use_apll = false; emac->parent.set_mediator = emac_esp32_set_mediator; emac->parent.init = emac_esp32_init; emac->parent.deinit = emac_esp32_deinit; diff --git a/components/esp_eth/src/esp_eth_mac_ksz8851snl.c b/components/esp_eth/src/esp_eth_mac_ksz8851snl.c index b6aea4df90..f19600a59e 100644 --- a/components/esp_eth/src/esp_eth_mac_ksz8851snl.c +++ b/components/esp_eth/src/esp_eth_mac_ksz8851snl.c @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: MIT * - * SPDX-FileContributor: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2021-2023 Espressif Systems (Shanghai) CO LTD */ #include @@ -226,7 +226,7 @@ static esp_err_t init_set_defaults(emac_ksz8851snl_t *emac) ESP_GOTO_ON_ERROR(ksz8851_set_bits(emac, KSZ8851_RXDTTR, RXDTTR_INIT_VALUE), err, TAG, "RXDTTR write failed"); ESP_GOTO_ON_ERROR(ksz8851_set_bits(emac, KSZ8851_RXDBCTR, RXDBCTR_INIT_VALUE), err, TAG, "RXDBCTR write failed"); ESP_GOTO_ON_ERROR(ksz8851_set_bits(emac, KSZ8851_RXCR1, - RXCR1_RXUDPFCC | RXCR1_RXTCPFCC | RXCR1_RXIPFCC | RXCR1_RXPAFMA | RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME), err, TAG, "RXCR1 write failed"); + RXCR1_RXUDPFCC | RXCR1_RXTCPFCC | RXCR1_RXIPFCC | RXCR1_RXPAFMA | RXCR1_RXFCE | RXCR1_RXUE | RXCR1_RXME | RXCR1_RXMAFMA | RXCR1_RXAE), err, TAG, "RXCR1 write failed"); ESP_GOTO_ON_ERROR(ksz8851_set_bits(emac, KSZ8851_RXCR2, (4 << RXCR2_SRDBL_SHIFT) | RXCR2_IUFFP | RXCR2_RXIUFCEZ | RXCR2_UDPLFE | RXCR2_RXICMPFCC), err, TAG, "RXCR2 write failed"); ESP_GOTO_ON_ERROR(ksz8851_set_bits(emac, KSZ8851_RXQCR, RXQCR_RXFCTE | RXQCR_ADRFE), err, TAG, "RXQCR write failed"); @@ -599,13 +599,13 @@ static esp_err_t emac_ksz8851_set_promiscuous(esp_eth_mac_t *mac, bool enable) if (enable) { // NOTE(v.chistyakov): set promiscuous mode ESP_LOGD(TAG, "setting promiscuous mode"); - rxcr1 |= RXCR1_RXINVF | RXCR1_RXAE; + rxcr1 |= RXCR1_RXAE | RXCR1_RXINVF; rxcr1 &= ~(RXCR1_RXPAFMA | RXCR1_RXMAFMA); } else { // NOTE(v.chistyakov): set hash perfect (default) - ESP_LOGD(TAG, "setting hash perfect mode"); - rxcr1 |= RXCR1_RXPAFMA; - rxcr1 &= ~(RXCR1_RXINVF | RXCR1_RXAE | RXCR1_RXMAFMA); + ESP_LOGD(TAG, "setting perfect with multicast passed"); + rxcr1 |= RXCR1_RXAE| RXCR1_RXPAFMA | RXCR1_RXMAFMA; + rxcr1 &= ~RXCR1_RXINVF; } ESP_GOTO_ON_ERROR(ksz8851_write_reg(emac, KSZ8851_RXCR1, rxcr1), err, TAG, "RXCR1 write failed"); err: diff --git a/components/esp_eth/src/esp_eth_phy_802_3.c b/components/esp_eth/src/esp_eth_phy_802_3.c index 4157f02011..d8db761433 100644 --- a/components/esp_eth/src/esp_eth_phy_802_3.c +++ b/components/esp_eth/src/esp_eth_phy_802_3.c @@ -380,16 +380,18 @@ esp_err_t esp_eth_phy_802_3_detect_phy_addr(esp_eth_mediator_t *eth, int *detect } int addr_try = 0; uint32_t reg_value = 0; - for (; addr_try < 16; addr_try++) { - eth->phy_reg_read(eth, addr_try, ETH_PHY_IDR1_REG_ADDR, ®_value); - if (reg_value != 0xFFFF && reg_value != 0x00) { - *detected_addr = addr_try; - break; + for (int i = 0; i < 3; i++){ + for (addr_try = 0; addr_try < 32; addr_try++) { + eth->phy_reg_read(eth, addr_try, ETH_PHY_IDR1_REG_ADDR, ®_value); + if (reg_value != 0xFFFF && reg_value != 0x00) { + *detected_addr = addr_try; + break; + } + } + if (addr_try < 32) { + ESP_LOGD(TAG, "Found PHY address: %d", addr_try); + return ESP_OK; } - } - if (addr_try < 16) { - ESP_LOGD(TAG, "Found PHY address: %d", addr_try); - return ESP_OK; } ESP_LOGE(TAG, "No PHY device detected"); return ESP_ERR_NOT_FOUND; diff --git a/components/esp_eth/src/esp_eth_phy_dm9051.c b/components/esp_eth/src/esp_eth_phy_dm9051.c index d8f9bad9fc..6db49f8fad 100644 --- a/components/esp_eth/src/esp_eth_phy_dm9051.c +++ b/components/esp_eth/src/esp_eth_phy_dm9051.c @@ -95,7 +95,7 @@ static esp_err_t dm9051_update_link_duplex_speed(phy_dm9051_t *dm9051) eth_duplex_t duplex = ETH_DUPLEX_HALF; uint32_t peer_pause_ability = false; bmsr_reg_t bmsr; - dscsr_reg_t dscsr; + bmcr_reg_t bmcr; anlpar_reg_t anlpar; // BMSR is a latch low register // after power up, the first latched value must be 0, which means down @@ -108,17 +108,9 @@ static esp_err_t dm9051_update_link_duplex_speed(phy_dm9051_t *dm9051) if (dm9051->phy_802_3.link_status != link) { /* when link up, read negotiation result */ if (link == ETH_LINK_UP) { - ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_DSCSR_REG_ADDR, &(dscsr.val)), err, TAG, "read DSCSR failed"); - if (dscsr.fdx100 || dscsr.hdx100) { - speed = ETH_SPEED_100M; - } else { - speed = ETH_SPEED_10M; - } - if (dscsr.fdx100 || dscsr.fdx10) { - duplex = ETH_DUPLEX_FULL; - } else { - duplex = ETH_DUPLEX_HALF; - } + ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)), err, TAG, "read BMCR failed"); + speed = bmcr.speed_select == 1 ? ETH_SPEED_100M : ETH_SPEED_10M; + duplex = bmcr.duplex_mode == 1 ? ETH_DUPLEX_FULL : ETH_DUPLEX_HALF; ESP_GOTO_ON_ERROR(eth->on_state_changed(eth, ETH_STATE_SPEED, (void *)speed), err, TAG, "change speed failed"); ESP_GOTO_ON_ERROR(eth->on_state_changed(eth, ETH_STATE_DUPLEX, (void *)duplex), err, TAG, "change duplex failed"); /* if we're in duplex mode, and peer has the flow control ability */ @@ -231,7 +223,9 @@ static esp_err_t dm9051_set_speed(esp_eth_phy_t *phy, eth_speed_t speed) /* Check if loopback is enabled, and if so, can it work with proposed speed or not */ bmcr_reg_t bmcr; ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, phy_802_3->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)), err, TAG, "read BMCR failed"); - ESP_GOTO_ON_FALSE(bmcr.en_loopback & (speed == ETH_SPEED_100M), ESP_ERR_INVALID_STATE, err, TAG, "Speed must be 100M for loopback operation"); + if (bmcr.en_loopback) { + ESP_GOTO_ON_FALSE(speed == ETH_SPEED_100M, ESP_ERR_INVALID_STATE, err, TAG, "Speed must be 100M for loopback operation"); + } return esp_eth_phy_802_3_set_speed(phy_802_3, speed); err: diff --git a/components/esp_eth/src/esp_eth_phy_ksz80xx.c b/components/esp_eth/src/esp_eth_phy_ksz80xx.c index 0c61e3347c..2102acdf88 100644 --- a/components/esp_eth/src/esp_eth_phy_ksz80xx.c +++ b/components/esp_eth/src/esp_eth_phy_ksz80xx.c @@ -186,7 +186,9 @@ static esp_err_t ksz80xx_set_speed(esp_eth_phy_t *phy, eth_speed_t speed) /* Check if loopback is enabled, and if so, can it work with proposed speed or not */ bmcr_reg_t bmcr; ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, phy_802_3->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)), err, TAG, "read BMCR failed"); - ESP_GOTO_ON_FALSE(bmcr.en_loopback & (speed == ETH_SPEED_100M), ESP_ERR_INVALID_STATE, err, TAG, "Speed must be 100M for loopback operation"); + if (bmcr.en_loopback) { + ESP_GOTO_ON_FALSE(speed == ETH_SPEED_100M, ESP_ERR_INVALID_STATE, err, TAG, "Speed must be 100M for loopback operation"); + } return esp_eth_phy_802_3_set_speed(phy_802_3, speed); err: