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

Ethernet Switch Module (ESWM) + frame TX/RX driver. More...

#include <stdint.h>
#include "ra8_err.h"
Include dependency graph for ra8_eth.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_eth_cfg_t
 Per-channel NIC configuration. More...
 PHY link state snapshot. More...
struct  ra8_eth_stats_t
 NIC software counters. More...

Typedefs

typedef void(* ra8_eth_event_fn_t) (void *ctx, uint32_t status_mask)
 Ethernet switch event callback.

Enumerations

enum  ra8_eth_mii_port_t : uint8_t {
  k_ra8_eth_mii_port_0 = 0U ,
  k_ra8_eth_mii_port_1 = 1U ,
  k_ra8_eth_mii_port_count = 2U
}
 ESWM media-interface port selector (m = 0, 1). More...
enum  ra8_eth_limits_t : uint16_t {
  k_ra8_eth_num_tx_desc = 8U ,
  k_ra8_eth_num_rx_desc = 8U ,
  k_ra8_eth_buf_size = 1536U ,
  k_ra8_eth_mac_len = 6U ,
  k_ra8_eth_desc_align = 16U ,
  k_ra8_eth_min_frame = 60U ,
  k_ra8_eth_max_frame = 1514U
}
 Compile-time NIC ring sizing constants. More...

Functions

ra8_err_t ra8_eth_init (void)
 Initialise the ESWM block (MSTP enable + reset regs).
ra8_err_t ra8_eth_deinit (void)
 Tear down the ESWM block.
ra8_err_t ra8_eth_get_status (uint32_t *out_mask)
 Read the ESWM_STS status register.
ra8_err_t ra8_eth_clear_status (uint32_t mask)
 Clear bits in ESWM_STS via ESWM_ICLR.
void ra8_eth_attach_handler (ra8_eth_event_fn_t fn, void *ctx)
 Replace the shared Ethernet event callback.
void ra8_eth_dispatch (void)
 Dispatch an ESWM event – snapshot + fire callback.
ra8_err_t ra8_eth_enter_stop (void)
 Put the ethernet switch into MSTP-gated stop.
ra8_err_t ra8_eth_exit_stop (void)
 Exit MSTP-gated stop.
ra8_err_t ra8_eth_rgmii_select (ra8_eth_mii_port_t port)
 Select RGMII on a port's ESWM media-interface mux and enable it.
ra8_err_t ra8_eth_open (const ra8_eth_cfg_t *cfg)
 Open the NIC: bring up the controller stack and the descriptor rings.
ra8_err_t ra8_eth_close (void)
 Close the NIC: gate clocks and idle the descriptor rings.
ra8_err_t ra8_eth_write (const uint8_t *buf, uint32_t len)
 Transmit a frame through the GWCA TX queue.
ra8_err_t ra8_eth_read (uint8_t *buf, uint32_t max_len, uint32_t *got_len)
 Pop the next received frame from the RX descriptor ring.
ra8_err_t ra8_eth_link_status (ra8_eth_link_t *out_status)
 Query the PHY link state via MIIM (RMAC MDIO Clause-22).
ra8_err_t ra8_eth_get_stats (ra8_eth_stats_t *out_stats)
 Read the NIC software counters.

Detailed Description

Ethernet Switch Module (ESWM) + frame TX/RX driver.

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

Driver for the RA8D2 Layer-3 ESWM block plus the polling-first frame TX / RX path that lifts this driver from "controller bring- up only" to "can move bytes on the wire".

The RA8D2 ethernet subsystem is split into five cooperating controller drivers:

  • ra8_eth (this file) – Layer 3 Ethernet Switch Module + NIC API
  • ra8_eth_mfwd – Message Forwarding Engine
  • ra8_eth_coma – Common Agent
  • ra8_eth_gwca – CPU Agent
  • ra8_eth_gptp – Generic PTP Timer

All five share the ra8_mstp gate k_ra8_mstp_eswm and follow the same lifecycle + status + IRQ + power-transition shape.

The frame-level surface (ra8_eth_open, ra8_eth_close, ra8_eth_write, ra8_eth_read, ra8_eth_link_status, ra8_eth_get_stats) mirrors the FSP r_ether API simplified for polling-first use: a fixed-size descriptor ring lives in this compilation unit, software bumps a write pointer (TX) and a read pointer (RX), and the EDMAC engine walks the ring on the silicon side. Hardware ownership is encoded by the descriptor TACT/RACT bit per FSP convention.

Definition in file ra8_eth.h.

Typedef Documentation

◆ ra8_eth_event_fn_t

typedef void(* ra8_eth_event_fn_t) (void *ctx, uint32_t status_mask)

Ethernet switch event callback.

Definition at line 53 of file ra8_eth.h.

Enumeration Type Documentation

◆ ra8_eth_limits_t

enum ra8_eth_limits_t : uint16_t

Compile-time NIC ring sizing constants.

The descriptor ring is statically allocated – there is no malloc anywhere in the driver. Defaults match the values requested by Sweep 2 / Task 1: 8 TX, 8 RX, 1536-byte buffers (jumbo frames are out of scope). Descriptors and buffers are aligned to 16 bytes per FSP requirement.

Enumerator
k_ra8_eth_num_tx_desc 

Number of TX descriptors in the ring.

k_ra8_eth_num_rx_desc 

Number of RX descriptors in the ring.

k_ra8_eth_buf_size 

Per-descriptor buffer size in bytes.

k_ra8_eth_mac_len 

Length of an Ethernet MAC address.

k_ra8_eth_desc_align 

Descriptor / buffer alignment in bytes.

k_ra8_eth_min_frame 

Minimum 802.3 frame (excl.

FCS).

k_ra8_eth_max_frame 

Maximum 802.3 untagged frame.

Definition at line 207 of file ra8_eth.h.

◆ ra8_eth_mii_port_t

enum ra8_eth_mii_port_t : uint8_t

ESWM media-interface port selector (m = 0, 1).

The RA8 ESWM wraps each MAC pin group with a media-interface mux. Port m maps 1:1 to RMACm / ETHAm and to the ESWM MIICRm control register plus the MIIRR.RGRSTm per-port enable bit. Passed to ra8_eth_rgmii_select to route a given port's pins to RGMII.

See also
ra8_eth_rgmii_select
Enumerator
k_ra8_eth_mii_port_0 

ESWM media port 0 (RMAC0 / ETHA0).

k_ra8_eth_mii_port_1 

ESWM media port 1 (RMAC1 / ETHA1).

k_ra8_eth_mii_port_count 

Number of media-interface ports.

Definition at line 137 of file ra8_eth.h.

Function Documentation

◆ ra8_eth_attach_handler()

void ra8_eth_attach_handler ( ra8_eth_event_fn_t fn,
void * ctx )

Replace the shared Ethernet event callback.

Stores one callback/context pair for ra8_eth_dispatch. Passing NULL for fn detaches the current callback. Slot replacement performs no fallible work; callers observe completion when this function returns.

Parameters
[in]fnCallback to install, or NULL to detach.
[in]ctxContext passed to fn; ignored while fn is NULL.
Precondition
Caller serializes this update with ra8_eth_dispatch.
ctx remains valid for as long as the installed callback uses it.
Postcondition
Subsequent dispatches observe the supplied callback/context pair.
Passing NULL for fn prevents subsequent callback invocation.
Note
Not thread-safe; update the slot with Ethernet IRQ delivery masked.
Since
0.1.0

Definition at line 532 of file ra8_eth.c.

References s_eth_ctx, and s_eth_fn.

Referenced by ra8_net_pal_deinit(), and ra8_net_pal_init().

◆ ra8_eth_clear_status()

ra8_err_t ra8_eth_clear_status ( uint32_t mask)
nodiscard

Clear bits in ESWM_STS via ESWM_ICLR.

Since
0.1.0

Definition at line 523 of file ra8_eth.c.

References r_eswm_regs_t::ESWM_ICLR, r_eswm_regs_t::ESWM_STS, k_ra8_ok, and ra8_eswm().

◆ ra8_eth_close()

ra8_err_t ra8_eth_close ( void )
nodiscard

Close the NIC: gate clocks and idle the descriptor rings.

Returns
ra8_err_t Error code.
Return values
k_ra8_okController idled.
k_ra8_err_not_initializedra8_eth_open was not called first.
Precondition
Driver previously brought up via ra8_eth_open.
No outstanding DMA against the ring.
Postcondition
EDMAC TX engine halted (EDTRR.TR=0).
EDMAC RX engine halted (EDRRR.RR=0).
Note
Stats are preserved; call ra8_eth_open to reset them.
See also
ra8_eth_open
Since
0.1.0

Definition at line 799 of file ra8_eth.c.

References g_eth_mac_speed_resynced, k_ra8_err_not_initialized, k_ra8_gwmc_opc_disable, k_ra8_mstp_eswm, priv_ra8_eth_channel_to_port(), ra8_eth_gwca_deinit(), ra8_eth_gwca_set_operation_mode(), ra8_mstp_disable(), ra8_rmac_deinit(), and s_eth_state.

Referenced by internal_handle_uninit().

◆ ra8_eth_deinit()

ra8_err_t ra8_eth_deinit ( void )
nodiscard

Tear down the ESWM block.

Since
0.1.0

Definition at line 504 of file ra8_eth.c.

References r_eswm_regs_t::ESWM_CTRL, r_eswm_regs_t::ESWM_IE, k_ra8_mstp_eswm, ra8_eswm(), ra8_mstp_disable(), s_eth_ctx, and s_eth_fn.

Referenced by ra8_net_pal_deinit().

◆ ra8_eth_dispatch()

void ra8_eth_dispatch ( void )

Dispatch an ESWM event – snapshot + fire callback.

Since
0.1.0

See implementation.

Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.

Definition at line 539 of file ra8_eth.c.

References r_eswm_regs_t::ESWM_ICLR, r_eswm_regs_t::ESWM_STS, ra8_eswm(), s_eth_ctx, and s_eth_fn.

◆ ra8_eth_enter_stop()

ra8_err_t ra8_eth_enter_stop ( void )
nodiscard

Put the ethernet switch into MSTP-gated stop.

Since
0.1.0

Definition at line 553 of file ra8_eth.c.

References r_eswm_regs_t::ESWM_CTRL, k_ra8_mstp_eswm, ra8_eswm(), and ra8_mstp_disable().

◆ ra8_eth_exit_stop()

ra8_err_t ra8_eth_exit_stop ( void )
nodiscard

Exit MSTP-gated stop.

Since
0.1.0

Definition at line 560 of file ra8_eth.c.

References k_ra8_mstp_eswm, and ra8_mstp_enable().

◆ ra8_eth_get_stats()

ra8_err_t ra8_eth_get_stats ( ra8_eth_stats_t * out_stats)
nodiscard

Read the NIC software counters.

Parameters
[out]out_statsDestination structure.
Returns
ra8_err_t Error code.
Return values
k_ra8_okCounter snapshot returned.
k_ra8_err_null_ptrout_stats is nullptr.
k_ra8_err_not_initializedra8_eth_open was not called first.
Precondition
Driver previously brought up via ra8_eth_open.
out_stats points to a writable structure.
Postcondition
out_stats fields reflect the live software counters.
Counters in the driver are NOT cleared.
Note
Counters saturate at UINT32_MAX rather than wrapping.
See also
ra8_eth_open
Since
0.1.0

Definition at line 869 of file ra8_eth.c.

References k_ra8_err_not_initialized, k_ra8_ok, RA8_CHECK_NULL_PTR, s_eth_state, and s_tag.

◆ ra8_eth_get_status()

ra8_err_t ra8_eth_get_status ( uint32_t * out_mask)
nodiscard

Read the ESWM_STS status register.

Since
0.1.0

Definition at line 515 of file ra8_eth.c.

References r_eswm_regs_t::ESWM_STS, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_eswm(), and s_tag.

◆ ra8_eth_init()

ra8_err_t ra8_eth_init ( void )
nodiscard

Initialise the ESWM block (MSTP enable + reset regs).

Since
0.1.0

Definition at line 486 of file ra8_eth.c.

References r_eswm_regs_t::ESWM_CTRL, r_eswm_regs_t::ESWM_ICLR, r_eswm_regs_t::ESWM_IE, r_eswm_regs_t::ESWM_STS, k_ra8_mstp_eswm, k_ra8_ok, ra8_eswm(), ra8_log_info, ra8_mstp_enable(), RA8_RETURN_ON_ERROR, and s_tag.

Referenced by ra8_net_pal_init(), and ra8_nsc_eth_init().

◆ ra8_eth_link_status()

ra8_err_t ra8_eth_link_status ( ra8_eth_link_t * out_status)
nodiscard

Query the PHY link state via MIIM (RMAC MDIO Clause-22).

Reads BMSR (PHY register 0x01) for link-status, then BMCR (0x00) to extract the configured speed and duplex. The PHY address is fixed at 0 (the EK-RA8D2 board's on-board PHY default).

Parameters
[out]out_statusDestination structure.
Returns
ra8_err_t Error code.
Return values
k_ra8_okLink snapshot returned.
k_ra8_err_null_ptrout_status is nullptr.
k_ra8_err_not_initializedra8_eth_open was not called first.
k_ra8_err_hw_timeoutMDIO transaction did not complete.
Precondition
Driver previously brought up via ra8_eth_open.
PHY MDC clock programmed by RMAC init (MPIC.PSMCS).
Postcondition
out_status->link_up reflects BMSR bit 2.
out_status->bmsr is the raw PHY register snapshot.
See also
ra8_eth_get_stats
Since
0.1.0

Definition at line 427 of file ra8_eth_link.c.

References g_eth_mac_speed_resynced, internal_phy_read_link(), internal_resync_mac_speed(), k_ra8_err_not_initialized, k_ra8_ok, ra8_eth_link_t::link_up, priv_ra8_eth_channel_to_port(), RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, s_eth_state, and s_tag.

Referenced by internal_handle_get_status(), and ra8_eth_open().

◆ ra8_eth_open()

ra8_err_t ra8_eth_open ( const ra8_eth_cfg_t * cfg)
nodiscard

Open the NIC: bring up the controller stack and the descriptor rings.

Sequence (mirrors FSP R_ETHER_Open):

  1. Enable the shared ESWM MSTP gate via ra8_eth_init.
  2. Capture cfg (MAC, channel, ring counts, buffer size).
  3. Reset the static descriptor ring – every TX descriptor is set software-owned (TACT=0); every RX descriptor is hardware-owned (RACT=1) so the EDMAC engine can fill it.
  4. Programme EDMAC TX / RX descriptor base addresses (TDLAR / RDLAR in FSP terms, GWCA_CTRL register set on this chip) and assert EDRR / EDTR via the GWCA control bits to start the engine.
  5. Reset the software statistics counters.
Parameters
[in]cfgNIC configuration. Must not be nullptr.
Returns
ra8_err_t Error code.
Return values
k_ra8_okController and rings ready for IO.
k_ra8_err_null_ptrcfg is nullptr.
k_ra8_err_invalid_argchannel or ring count out of range.
Precondition
Caller is single-threaded with respect to this driver.
ESWM MSTP gate is unrestricted (S/NS mapping permits it).
Postcondition
EDMAC TX engine running (EDTRR.TR=1) on the fake and on silicon.
EDMAC RX engine running (EDRRR.RR=1).
Note
Not thread-safe; gate with a mutex if shared between contexts.
Example:
static const ra8_eth_cfg_t cfg = {
.mac_address = { 0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE },
.channel = 0U,
.num_tx_descriptors = 0U, // use defaults
.num_rx_descriptors = 0U,
.buffer_size = 0U,
};
(void)ra8_eth_open(&cfg);
ra8_err_t ra8_eth_open(const ra8_eth_cfg_t *cfg)
Open the NIC: bring up the controller stack and the descriptor rings.
Definition ra8_eth.c:756
Per-channel NIC configuration.
Definition ra8_eth.h:228
See also
ra8_eth_close
Since
0.1.0

Definition at line 756 of file ra8_eth.c.

References g_eth_mac_speed_resynced, g_ra8_eth_open_step, internal_capture_state(), internal_open_gwca_path(), internal_open_prep(), internal_populate_gwca_state(), k_ra8_eth_step_fail_1, k_ra8_eth_step_ok_1, k_ra8_eth_step_ok_2, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_eth_link_status(), ra8_log_info, and s_tag.

Referenced by eop_run_once(), and internal_handle_init().

◆ ra8_eth_read()

ra8_err_t ra8_eth_read ( uint8_t * buf,
uint32_t max_len,
uint32_t * got_len )
nodiscard

Pop the next received frame from the RX descriptor ring.

Inspects the descriptor at the current RX read pointer. If it is software-owned (RACT=0, hardware released it), the buffer payload is copied into buf, *got_len is set to the frame length, and the descriptor is returned to hardware (RACT=1) before the read pointer advances. If the descriptor is still hardware-owned (RACT=1) the call returns k_ra8_err_no_data without side effects.

Parameters
[out]bufCaller buffer, at least max_len bytes.
[in]max_lenCapacity of buf in bytes.
[out]got_lenActual frame size written into buf.
Returns
ra8_err_t Error code.
Return values
k_ra8_okFrame copied into buf.
k_ra8_err_null_ptrbuf or got_len is nullptr.
k_ra8_err_no_dataNo frame released by hardware yet.
k_ra8_err_invalid_argmax_len is zero.
k_ra8_err_not_initializedra8_eth_open was not called first.
Precondition
Driver previously brought up via ra8_eth_open.
buf points to at least max_len writable bytes.
Postcondition
On k_ra8_ok the descriptor is RACT=1 again (handed back to HW).
On k_ra8_ok the read pointer advanced one slot.
Note
Drops bytes past max_len; *got_len reflects what was copied.
See also
ra8_eth_write
Since
0.1.0

Definition at line 845 of file ra8_eth.c.

References internal_stat_inc(), k_ra8_err_invalid_arg, k_ra8_err_no_data, k_ra8_err_not_initialized, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_eth_gwca_default_recv(), s_eth_state, s_gwca_state, and s_tag.

Referenced by internal_handle_deferred_rx(), and internal_rx_drain().

◆ ra8_eth_rgmii_select()

ra8_err_t ra8_eth_rgmii_select ( ra8_eth_mii_port_t port)
nodiscard

Select RGMII on a port's ESWM media-interface mux and enable it.

The chip-generic ESWM RGMII media-select every RA8 RGMII board runs once during Ethernet bring-up. After power-on reset MIICRm.MIISEL reads 0 (GMII/MII) and MIIRR.RGRSTm reads 0 (RGMII block held in reset), so the RGMII data path is dead until the driver explicitly:

  1. Sets MIICRm = MIISEL = RGMII (01b) | TXCIDE (on-chip TX clock delay), matching the FSP "RGMII + 2 ns TX skew" board profile.
  2. Sets MIIRR.RGRSTm = 1. HUM Ch 29.2.1.2: RGRSTm is 1 = Enable, 0 = Reset – an ENABLE bit, not an active-high reset. Without it TXC is never generated and the RMAC RX state machine is unclocked, so every RMAC RX counter stays at 0.

It previously lived open-coded in the EK-RA8D2 board Ethernet bring-up; the accesses are chip-generic, so they belong here in the HAL. Which port is wired, and any board TX/RX skew choices in the PHY, remain board concerns.

Parameters
[in]portESWM media-interface port to route to RGMII. Must be a valid ra8_eth_mii_port_t (< k_ra8_eth_mii_port_count).
Returns
ra8_err_t Result code.
Return values
k_ra8_okPort routed to RGMII and its block enabled.
k_ra8_err_invalid_argport is out of range.
Precondition
The ESWM module-stop gate (k_ra8_mstp_eswm) has been released.
COMA has been brought up (ra8_eth_coma_bringup) so the media window is accessible.
Postcondition
On success MIICRport = TXCIDE | RGMII and MIIRR.RGRSTport = 1.
On k_ra8_err_invalid_arg no register was written.
Note
Not thread-safe; call from a single-threaded init context.
eth is HW-blocked on silicon (issue #21); this path is host-tested and sim-modeled, not hardware-validated.
Example:
(void)ra8_eth_rgmii_select(k_ra8_eth_mii_port_1); // EK-RA8D2 RJ45 = port 1
@ k_ra8_eth_mii_port_1
ESWM media port 1 (RMAC1 / ETHA1).
Definition ra8_eth.h:139
ra8_err_t ra8_eth_rgmii_select(ra8_eth_mii_port_t port)
Select RGMII on a port's ESWM media-interface mux and enable it.
ra8_err_t ra8_eth_coma_bringup(void)
Bring the COMA switch out of reset, init the buffer pool, and fan every per-agent clock out.
See also
ra8_eth_coma_bringup
Since
0.1.0

Log tag – block scope: this is the only function here that logs.

Definition at line 26 of file ra8_eth_media.c.

References k_ra8_err_invalid_arg, k_ra8_eswm_miicr_miisel_rgmii, k_ra8_eswm_miicr_txcide, k_ra8_eswm_miirr_rgrst0, k_ra8_eswm_miirr_rgrst1, k_ra8_eth_mii_port_0, k_ra8_eth_mii_port_1, k_ra8_ok, RA8_CHECK_RANGE_TAG, ra8_eswm_miicr0(), ra8_eswm_miicr1(), ra8_eswm_miirr(), and ra8_log_info.

Referenced by ehb_run_once(), and ra8_board_ethernet_init().

◆ ra8_eth_write()

ra8_err_t ra8_eth_write ( const uint8_t * buf,
uint32_t len )
nodiscard

Transmit a frame through the GWCA TX queue.

Copies len bytes from buf into the driver-owned TX buffer, fills the slot-0 extended descriptor (direct format, destination vector = the bound MAC port), kicks the GWCA, and blocks until the GWCA writes the descriptor back. Every call reuses descriptor slot 0, so the send is synchronous: it returns only once the previous frame has left the queue.

Parameters
[in]bufPointer to frame bytes (MAC header + payload, no FCS).
[in]lenFrame length in bytes (60..1514).
Returns
ra8_err_t Error code.
Return values
k_ra8_okFrame transmitted.
k_ra8_err_null_ptrbuf is nullptr.
k_ra8_err_invalid_arglen is out of range.
k_ra8_err_hw_timeoutGWCA did not complete the descriptor.
k_ra8_err_not_initializedra8_eth_open was not called first.
Precondition
Driver previously brought up via ra8_eth_open.
len is between k_ra8_eth_min_frame and k_ra8_eth_max_frame.
Postcondition
On success, the frame has been handed to the GWCA TX queue.
On success, the tx_ok statistics counter has been incremented.
Note
Caller copies the data; buf may be released on return.
See also
ra8_eth_read
Since
0.1.0

Definition at line 825 of file ra8_eth.c.

References internal_stat_inc(), k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_eth_max_frame, k_ra8_eth_min_frame, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_eth_gwca_default_send(), ra8_log_error, s_eth_state, s_gwca_state, and s_tag.

Referenced by internal_handle_send().