diff --git a/components/esp_eth/include/esp_eth.h b/components/esp_eth/include/esp_eth.h index 480349d56d..d204b50898 100644 --- a/components/esp_eth/include/esp_eth.h +++ b/components/esp_eth/include/esp_eth.h @@ -86,6 +86,47 @@ typedef struct { */ esp_err_t (*on_lowlevel_deinit_done)(esp_eth_handle_t eth_handle); + /** + * @brief Read PHY register + * + * @note Usually the PHY register read/write function is provided by MAC (SMI interface), + * but if the PHY device is managed by other interface (e.g. I2C), then user needs to + * implement the corresponding read/write. + * Setting this to NULL means your PHY device is managed by MAC's SMI interface. + * + * @param[in] eth_handle: handle of Ethernet driver + * @param[in] phy_addr: PHY chip address (0~31) + * @param[in] phy_reg: PHY register index code + * @param[out] reg_value: PHY register value + * + * @return + * - ESP_OK: read PHY register successfully + * - ESP_ERR_INVALID_ARG: read PHY register failed because of invalid argument + * - ESP_ERR_TIMEOUT: read PHY register failed because of timeout + * - ESP_FAIL: read PHY register failed because some other error occurred + */ + esp_err_t (*read_phy_reg)(esp_eth_handle_t eth_handle, uint32_t phy_addr, uint32_t phy_reg, uint32_t *reg_value); + + /** + * @brief Write PHY register + * + * @note Usually the PHY register read/write function is provided by MAC (SMI interface), + * but if the PHY device is managed by other interface (e.g. I2C), then user needs to + * implement the corresponding read/write. + * Setting this to NULL means your PHY device is managed by MAC's SMI interface. + * + * @param[in] eth_handle: handle of Ethernet driver + * @param[in] phy_addr: PHY chip address (0~31) + * @param[in] phy_reg: PHY register index code + * @param[in] reg_value: PHY register value + * + * @return + * - ESP_OK: write PHY register successfully + * - ESP_ERR_INVALID_ARG: read PHY register failed because of invalid argument + * - ESP_ERR_TIMEOUT: write PHY register failed because of timeout + * - ESP_FAIL: write PHY register failed because some other error occurred + */ + esp_err_t (*write_phy_reg)(esp_eth_handle_t eth_handle, uint32_t phy_addr, uint32_t phy_reg, uint32_t reg_value); } esp_eth_config_t; /** @@ -100,6 +141,8 @@ typedef struct { .stack_input = NULL, \ .on_lowlevel_init_done = NULL, \ .on_lowlevel_deinit_done = NULL, \ + .read_phy_reg = NULL, \ + .write_phy_reg = NULL, \ } /** diff --git a/components/esp_eth/src/esp_eth.c b/components/esp_eth/src/esp_eth.c index 52d07c741c..6f9a65b28f 100644 --- a/components/esp_eth/src/esp_eth.c +++ b/components/esp_eth/src/esp_eth.c @@ -55,6 +55,8 @@ typedef struct { 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); + esp_err_t (*customized_read_phy_reg)(esp_eth_handle_t eth_handle, uint32_t phy_addr, uint32_t phy_reg, uint32_t *reg_value); + esp_err_t (*customized_write_phy_reg)(esp_eth_handle_t eth_handle, uint32_t phy_addr, uint32_t phy_reg, uint32_t reg_value); } esp_eth_driver_t; ////////////////////////////////Mediator Functions//////////////////////////////////////////// @@ -69,6 +71,11 @@ typedef struct { static esp_err_t eth_phy_reg_read(esp_eth_mediator_t *eth, uint32_t phy_addr, uint32_t phy_reg, uint32_t *reg_value) { esp_eth_driver_t *eth_driver = __containerof(eth, esp_eth_driver_t, mediator); + // invoking user customized PHY IO function if necessary + if (eth_driver->customized_read_phy_reg) { + return eth_driver->customized_read_phy_reg(eth_driver, phy_addr, phy_reg, reg_value); + } + // by default, PHY device is managed by MAC's SMI interface esp_eth_mac_t *mac = eth_driver->mac; return mac->read_phy_reg(mac, phy_addr, phy_reg, reg_value); } @@ -76,6 +83,11 @@ static esp_err_t eth_phy_reg_read(esp_eth_mediator_t *eth, uint32_t phy_addr, ui static esp_err_t eth_phy_reg_write(esp_eth_mediator_t *eth, uint32_t phy_addr, uint32_t phy_reg, uint32_t reg_value) { esp_eth_driver_t *eth_driver = __containerof(eth, esp_eth_driver_t, mediator); + // invoking user customized PHY IO function if necessary + if (eth_driver->customized_write_phy_reg) { + return eth_driver->customized_write_phy_reg(eth_driver, phy_addr, phy_reg, reg_value); + } + // by default, PHY device is managed by MAC's SMI interface esp_eth_mac_t *mac = eth_driver->mac; return mac->write_phy_reg(mac, phy_addr, phy_reg, reg_value); } @@ -184,6 +196,8 @@ esp_err_t esp_eth_driver_install(const esp_eth_config_t *config, esp_eth_handle_ eth_driver->stack_input = config->stack_input; eth_driver->on_lowlevel_init_done = config->on_lowlevel_init_done; eth_driver->on_lowlevel_deinit_done = config->on_lowlevel_deinit_done; + eth_driver->customized_read_phy_reg = config->read_phy_reg; + eth_driver->customized_write_phy_reg = config->write_phy_reg; eth_driver->mediator.phy_reg_read = eth_phy_reg_read; eth_driver->mediator.phy_reg_write = eth_phy_reg_write; eth_driver->mediator.stack_input = eth_stack_input;