mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-11-04 06:11:06 +00:00 
			
		
		
		
	feat(esp_eth): added ioctl option to read/write PHY registers
LAN87xx: Added extra delay after setting PHY speed
This commit is contained in:
		@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
 | 
			
		||||
 * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 */
 | 
			
		||||
@@ -121,6 +121,15 @@ typedef struct {
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Data structure to Read/Write PHY register via ioctl API
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint32_t reg_addr;              /*!< PHY register address */
 | 
			
		||||
    uint32_t *reg_value_p;          /*!< Pointer to a memory where the register value is read/written */
 | 
			
		||||
} esp_eth_phy_reg_rw_data_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @brief Command list for ioctl API
 | 
			
		||||
*
 | 
			
		||||
@@ -139,6 +148,8 @@ typedef enum {
 | 
			
		||||
    ETH_CMD_G_DUPLEX_MODE,            /*!< Get Duplex mode */
 | 
			
		||||
    ETH_CMD_S_DUPLEX_MODE,            /*!< Set Duplex mode */
 | 
			
		||||
    ETH_CMD_S_PHY_LOOPBACK,           /*!< Set PHY loopback */
 | 
			
		||||
    ETH_CMD_READ_PHY_REG,             /*!< Read PHY register */
 | 
			
		||||
    ETH_CMD_WRITE_PHY_REG,            /*!< Write PHY register */
 | 
			
		||||
 | 
			
		||||
    ETH_CMD_CUSTOM_MAC_CMDS = 0x0FFF, // Offset for start of MAC custom commands
 | 
			
		||||
    ETH_CMD_CUSTOM_PHY_CMDS = 0x1FFF, // Offset for start of PHY custom commands
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
 | 
			
		||||
 * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 */
 | 
			
		||||
@@ -466,7 +466,23 @@ esp_err_t esp_eth_ioctl(esp_eth_handle_t hdl, esp_eth_io_cmd_t cmd, void *data)
 | 
			
		||||
    case ETH_CMD_S_PHY_LOOPBACK:
 | 
			
		||||
        ESP_GOTO_ON_FALSE(data, ESP_ERR_INVALID_ARG, err, TAG, "can't set loopback to null");
 | 
			
		||||
        ESP_GOTO_ON_ERROR(phy->loopback(phy, *(bool *)data), err, TAG, "configuration of phy loopback mode failed");
 | 
			
		||||
 | 
			
		||||
        break;
 | 
			
		||||
    case ETH_CMD_READ_PHY_REG:
 | 
			
		||||
        uint32_t phy_addr;
 | 
			
		||||
        ESP_GOTO_ON_FALSE(data, ESP_ERR_INVALID_ARG, err, TAG, "invalid register read/write info");
 | 
			
		||||
        esp_eth_phy_reg_rw_data_t *phy_r_data = (esp_eth_phy_reg_rw_data_t *)data;
 | 
			
		||||
        ESP_GOTO_ON_FALSE(phy_r_data->reg_value_p, ESP_ERR_INVALID_ARG, err, TAG, "can't read registers to null");
 | 
			
		||||
        ESP_GOTO_ON_ERROR(phy->get_addr(phy, &phy_addr), err, TAG, "get phy address failed");
 | 
			
		||||
        ESP_GOTO_ON_ERROR(eth_driver->mediator.phy_reg_read(ð_driver->mediator,
 | 
			
		||||
                          phy_addr, phy_r_data->reg_addr, phy_r_data->reg_value_p), err, TAG, "failed to read PHY register");
 | 
			
		||||
        break;
 | 
			
		||||
    case ETH_CMD_WRITE_PHY_REG:
 | 
			
		||||
        ESP_GOTO_ON_FALSE(data, ESP_ERR_INVALID_ARG, err, TAG, "invalid register read/write info");
 | 
			
		||||
        esp_eth_phy_reg_rw_data_t *phy_w_data = (esp_eth_phy_reg_rw_data_t *)data;
 | 
			
		||||
        ESP_GOTO_ON_FALSE(phy_w_data->reg_value_p, ESP_ERR_INVALID_ARG, err, TAG, "can't write registers from null");
 | 
			
		||||
        ESP_GOTO_ON_ERROR(phy->get_addr(phy, &phy_addr), err, TAG, "get phy address failed");
 | 
			
		||||
        ESP_GOTO_ON_ERROR(eth_driver->mediator.phy_reg_write(ð_driver->mediator,
 | 
			
		||||
                          phy_addr, phy_w_data->reg_addr, *(phy_w_data->reg_value_p)), err, TAG, "failed to write PHY register");
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        if (phy->custom_ioctl != NULL && cmd >= ETH_CMD_CUSTOM_PHY_CMDS) {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,8 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
#include "freertos/FreeRTOS.h"
 | 
			
		||||
#include "freertos/task.h"
 | 
			
		||||
#include "esp_log.h"
 | 
			
		||||
#include "esp_check.h"
 | 
			
		||||
#include "esp_eth_phy_802_3.h"
 | 
			
		||||
@@ -317,6 +319,19 @@ err:
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static esp_err_t lan87xx_set_speed(esp_eth_phy_t *phy, eth_speed_t speed)
 | 
			
		||||
{
 | 
			
		||||
    esp_err_t ret = ESP_OK;
 | 
			
		||||
    phy_802_3_t *phy_802_3 = esp_eth_phy_into_phy_802_3(phy);
 | 
			
		||||
 | 
			
		||||
    /* It was observed that a delay needs to be introduced after setting speed and prior driver's start.
 | 
			
		||||
    Otherwise, the very first read of PHY registers is not valid data (0xFFFF's). */
 | 
			
		||||
    ESP_GOTO_ON_ERROR(esp_eth_phy_802_3_set_speed(phy_802_3, speed), err, TAG, "set speed failed");
 | 
			
		||||
    vTaskDelay(pdMS_TO_TICKS(10));
 | 
			
		||||
err:
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static esp_err_t lan87xx_init(esp_eth_phy_t *phy)
 | 
			
		||||
{
 | 
			
		||||
    esp_err_t ret = ESP_OK;
 | 
			
		||||
@@ -359,6 +374,7 @@ esp_eth_phy_t *esp_eth_phy_new_lan87xx(const eth_phy_config_t *config)
 | 
			
		||||
    lan87xx->phy_802_3.parent.get_link = lan87xx_get_link;
 | 
			
		||||
    lan87xx->phy_802_3.parent.autonego_ctrl = lan87xx_autonego_ctrl;
 | 
			
		||||
    lan87xx->phy_802_3.parent.loopback = lan87xx_loopback;
 | 
			
		||||
    lan87xx->phy_802_3.parent.set_speed = lan87xx_set_speed;
 | 
			
		||||
 | 
			
		||||
    return &lan87xx->phy_802_3.parent;
 | 
			
		||||
err:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user