ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_ether_phy.c File Reference

Generic Ethernet PHY abstraction (MDIO Clause-22). More...

#include "ra8_ether_phy.h"
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_log.h"
Include dependency graph for ra8_ether_phy.c:

Go to the source code of this file.

Data Structures

struct  ra8_ether_phy_internal_t

Enumerations

enum  ra8_ether_phy_priv_t : uint8_t {
  k_ra8_ether_phy_reg_max = 31U ,
  k_ra8_ether_phy_reset_poll_max = 32U
}
enum  ra8_ether_phy_bits_t : uint16_t {
  k_ra8_ether_phy_bmcr_reset = 0x8000U ,
  k_ra8_ether_phy_bmcr_an_enable = 0x1000U ,
  k_ra8_ether_phy_bmcr_an_restart = 0x0200U ,
  k_ra8_ether_phy_bmsr_link_up = 0x0004U ,
  k_ra8_ether_phy_bmsr_an_complete = 0x0020U ,
  k_ra8_ether_phy_anar_100full = 0x0100U ,
  k_ra8_ether_phy_anar_100half = 0x0080U ,
  k_ra8_ether_phy_anar_10full = 0x0040U ,
  k_ra8_ether_phy_anar_10half = 0x0020U
}

Functions

static ra8_err_t internal_reset_and_wait (void)
 Issue BMCR.RESET to the PHY and poll until it self-clears.
ra8_err_t ra8_ether_phy_open (const ra8_ether_phy_cfg_t *cfg)
 Open and reset a PHY.
ra8_err_t ra8_ether_phy_close (void)
 Close the driver.
ra8_err_t ra8_ether_phy_mdio_read (uint8_t reg_addr, uint16_t *out_data)
 Read a Clause-22 PHY register.
ra8_err_t ra8_ether_phy_mdio_write (uint8_t reg_addr, uint16_t data)
 Write a Clause-22 PHY register.
ra8_err_t ra8_ether_phy_auto_negotiate_start (void)
 Kick off auto-negotiation by re-arming BMCR.
ra8_err_t ra8_ether_phy_link_status_get (ra8_ether_phy_link_t *out)
 Poll the BMSR for auto-negotiation completion + link-up.

Variables

static const char * s_tag = "EPHY"
 Module log tag.
static ra8_ether_phy_internal_t s_state = {}

Detailed Description

Generic Ethernet PHY abstraction (MDIO Clause-22).

Tag
[Ring 3 / HAL] {World: NS}

Hardware-agnostic PHY driver. The MDIO bus itself is plugged in via ra8_ether_phy_io_t callbacks so the same code can drive the RA8D2 RMAC MIIM block, the legacy ETHER MIIM, an external SMI-over-GPIO bit-banger, or a host fake. State is kept in a single static control block; only one PHY is tracked at a time because the underlying MAC ports each use their own driver instance (ra8_ethercat_phy / ra8_rmac_phy).

Definition in file ra8_ether_phy.c.

Enumeration Type Documentation

◆ ra8_ether_phy_bits_t

enum ra8_ether_phy_bits_t : uint16_t
Enumerator
k_ra8_ether_phy_bmcr_reset 

RA8 ether PHY bmcr reset.

k_ra8_ether_phy_bmcr_an_enable 

RA8 ether PHY bmcr an enable.

k_ra8_ether_phy_bmcr_an_restart 

RA8 ether PHY bmcr an restart.

k_ra8_ether_phy_bmsr_link_up 

RA8 ether PHY bmsr link up.

k_ra8_ether_phy_bmsr_an_complete 

RA8 ether PHY bmsr an complete.

k_ra8_ether_phy_anar_100full 

RA8 ether PHY anar 100full.

k_ra8_ether_phy_anar_100half 

RA8 ether PHY anar 100half.

k_ra8_ether_phy_anar_10full 

RA8 ether PHY anar 10full.

k_ra8_ether_phy_anar_10half 

RA8 ether PHY anar 10half.

Definition at line 38 of file ra8_ether_phy.c.

◆ ra8_ether_phy_priv_t

enum ra8_ether_phy_priv_t : uint8_t
Enumerator
k_ra8_ether_phy_reg_max 

RA8 ether PHY register maximum.

k_ra8_ether_phy_reset_poll_max 

RA8 ether PHY reset poll maximum.

Definition at line 33 of file ra8_ether_phy.c.

Function Documentation

◆ internal_reset_and_wait()

ra8_err_t internal_reset_and_wait ( void )
static

Issue BMCR.RESET to the PHY and poll until it self-clears.

IEEE 802.3 Clause 22 requires BMCR bit 15 (RESET) to self-clear once the PHY has re-initialized its internal state. Polls up to k_ra8_ether_phy_reset_poll_max MDIO reads before giving up.

Returns
ra8_err_t error code.
Return values
k_ra8_okBMCR.RESET observed clear.
k_ra8_err_hw_timeoutBMCR.RESET still set after the poll budget.
Precondition
s_state.io.read and s_state.io.write are non-NULL.
s_state.phy_address names the PHY being opened.
Postcondition
On success the PHY is back in its post-reset default state.
On error the PHY may be partway through reset; the caller rolls the driver state back to closed.
Note
Not thread-safe; called from open under single-threaded init.
Since
0.1.0

Definition at line 83 of file ra8_ether_phy.c.

References k_ra8_err_hw_timeout, k_ra8_ether_phy_bmcr_reset, k_ra8_ether_phy_reg_control, k_ra8_ether_phy_reset_poll_max, k_ra8_ok, and s_state.

Referenced by ra8_ether_phy_open(), and ra8_rmac_phy_open().

◆ ra8_ether_phy_auto_negotiate_start()

ra8_err_t ra8_ether_phy_auto_negotiate_start ( void )
nodiscard

Kick off auto-negotiation by re-arming BMCR.

Returns
ra8_err_t.
Return values
k_ra8_okAuto-neg restarted.
k_ra8_err_not_initializedNot opened.
Precondition
ra8_ether_phy_open succeeded.
Postcondition
BMCR.AUTONEG_RESTART was written.
Note
Not thread-safe.
Since
0.1.0

Definition at line 165 of file ra8_ether_phy.c.

References k_ra8_err_not_initialized, k_ra8_ether_phy_bmcr_an_enable, k_ra8_ether_phy_bmcr_an_restart, k_ra8_ether_phy_reg_control, and s_state.

◆ ra8_ether_phy_close()

ra8_err_t ra8_ether_phy_close ( void )
nodiscard

Close the driver.

Returns
ra8_err_t.
Return values
k_ra8_okClosed.
k_ra8_err_invalid_stateNot opened.
Precondition
Driver is open.
Postcondition
Subsequent ops return k_ra8_err_not_initialized.
Note
Not thread-safe.
Since
0.1.0

Definition at line 133 of file ra8_ether_phy.c.

References k_ra8_err_invalid_state, k_ra8_ok, and s_state.

◆ ra8_ether_phy_link_status_get()

ra8_err_t ra8_ether_phy_link_status_get ( ra8_ether_phy_link_t * out)
nodiscard

◆ ra8_ether_phy_mdio_read()

ra8_err_t ra8_ether_phy_mdio_read ( uint8_t reg_addr,
uint16_t * out_data )
nodiscard

Read a Clause-22 PHY register.

Parameters
[in]reg_addrRegister index (0..31).
[out]out_dataReceives the value.
Returns
ra8_err_t.
Return values
k_ra8_okRead completed.
k_ra8_err_null_ptrout_data was NULL.
k_ra8_err_invalid_argreg_addr > 31.
k_ra8_err_not_initializedNot opened.
Precondition
ra8_ether_phy_open succeeded.
Postcondition
*out_data is defined on success.
Note
Not thread-safe.
Since
0.1.0

Definition at line 142 of file ra8_ether_phy.c.

References k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_ether_phy_reg_max, RA8_CHECK_NULL_PTR, s_state, and s_tag.

◆ ra8_ether_phy_mdio_write()

ra8_err_t ra8_ether_phy_mdio_write ( uint8_t reg_addr,
uint16_t data )
nodiscard

Write a Clause-22 PHY register.

Parameters
[in]reg_addrRegister index (0..31).
[in]data16-bit value.
Returns
ra8_err_t.
Return values
k_ra8_okWrite completed.
k_ra8_err_invalid_argreg_addr > 31.
k_ra8_err_not_initializedNot opened.
Precondition
ra8_ether_phy_open succeeded.
Postcondition
Register at reg_addr holds data (driver perspective).
Note
Not thread-safe.
Since
0.1.0

Definition at line 154 of file ra8_ether_phy.c.

References k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_ether_phy_reg_max, and s_state.

◆ ra8_ether_phy_open()

ra8_err_t ra8_ether_phy_open ( const ra8_ether_phy_cfg_t * cfg)
nodiscard

Open and reset a PHY.

Issues a Clause-22 BMCR.RESET to the PHY at cfg->phy_address and waits until the bit self-clears (or reset_wait_us elapses, whichever is sooner). Mirrors R_ETHER_PHY_Open.

Parameters
[in]cfgConfiguration. Must not be nullptr.
Returns
ra8_err_t.
Return values
k_ra8_okPHY responded to reset.
k_ra8_err_null_ptrcfg, or any required IO callback NULL.
k_ra8_err_invalid_argphy_address > 31.
k_ra8_err_existsAlready opened.
k_ra8_err_hw_timeoutReset bit never cleared.
Precondition
Single-threaded init context.
Postcondition
Driver is in the open state.
ra8_ether_phy_close will succeed.
Note
Not thread-safe.
Since
0.1.0

Definition at line 105 of file ra8_ether_phy.c.

References internal_reset_and_wait(), ra8_ether_phy_cfg_t::io, k_ra8_err_exists, k_ra8_err_invalid_arg, k_ra8_ether_phy_addr_max, k_ra8_ok, ra8_ether_phy_cfg_t::mii_type, ra8_ether_phy_cfg_t::phy_address, RA8_CHECK_NULL_PTR, ra8_log_info_val, ra8_ether_phy_io_t::read, ra8_ether_phy_cfg_t::reset_wait_us, s_state, s_tag, and ra8_ether_phy_io_t::write.

Variable Documentation

◆ s_state

ra8_ether_phy_internal_t s_state = {}
static

Definition at line 59 of file ra8_ether_phy.c.

◆ s_tag

const char* s_tag = "EPHY"
static

Module log tag.

Definition at line 31 of file ra8_ether_phy.c.