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

Per-port Ethernet MAC (RMAC) driver implementation – HUM Ch 33. More...

#include "ra8_rmac.h"
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_ether_regs.h"
#include "ra8_hal_internal.h"
#include "ra8_hw_err.h"
#include "ra8_hw_intrinsics.h"
#include "ra8_log.h"
#include "ra8_mstp.h"
#include "ra8_mstp_regs.h"
#include "ra8_rmac_regs.h"
Include dependency graph for ra8_rmac.c:

Go to the source code of this file.

Data Structures

struct  ra8_rmac_slot_t
 Per-port runtime state. More...

Enumerations

enum  rmac_field_t : uint32_t {
  k_rmac_pipp_pos = 9U ,
  k_rmac_pfrlv_mask = 0x1FU
}
 RMAC field constants. More...
enum  ra8_rmac_internal_t : uint32_t { k_ra8_rmac_mdio_poll_budget = 100000UL }
 Driver-private constants (poll budgets, sentinel values). More...
enum  ra8_rmac_bit_pos_t : uint8_t {
  k_ra8_rmac_shift_mpfc_te0 = 16U ,
  k_ra8_rmac_shift_mpfc_te1 = 17U ,
  k_ra8_rmac_shift_mtpfc_pfrlv = 27U ,
  k_ra8_rmac_shift_mtpfc2_pfm = 26U
}
 Bit positions for register fields not covered by the register-header enum file. More...

Functions

static bool internal_pis_ok (ra8_rmac_pis_t iface)
 Validate an MPIC.PIS interface selector.
static uint32_t internal_calc_psmcs (uint32_t eswclk_hz, uint32_t mdc_hz)
 Compute the MPIC.PSMCS divider code for a target MDC rate.
static uint32_t internal_make_mpic (ra8_rmac_pis_t iface, ra8_rmac_lsc_t speed, ra8_rmac_duplex_t duplex, uint32_t psmcs)
 Build the MPIC value from interface / speed / duplex inputs.
static ra8_err_t internal_mdio_drain (volatile r_rmac_regs_t *reg)
 Drain any in-flight MDIO transaction (poll MPSM.PSME -> 0).
static ra8_err_t internal_mdio_wait (volatile r_rmac_regs_t *reg, uint32_t mask)
 Wait for an MDIO transaction to complete, with a bounded poll budget.
static void internal_mpsm_issue (volatile r_rmac_regs_t *reg, uint8_t pda_5bit, uint8_t pra_5bit, ra8_rmac_mdio_op_t op, uint16_t prd_16bit, bool mff)
 Issue a raw MPSM transaction.
static void internal_program_mac_config (volatile r_rmac_regs_t *reg, const ra8_rmac_config_t *cfg)
 Reset every per-MAC config register to its post-init baseline.
static void internal_program_irq_block (volatile r_rmac_regs_t *reg, const ra8_rmac_config_t *cfg)
 Reset/disable every IRQ status + enable register.
ra8_err_t ra8_rmac_init (ra8_rmac_port_t port, const ra8_rmac_config_t *cfg)
 Initialise an RMAC port (MSTP gate + reset regs + filter mode).
ra8_err_t ra8_rmac_deinit (ra8_rmac_port_t port)
 Tear down an RMAC port.
ra8_err_t ra8_rmac_enter_stop (ra8_rmac_port_t port)
 Enter low-power "stop" by disabling RX address filtering.
ra8_err_t ra8_rmac_exit_stop (ra8_rmac_port_t port)
 Exit low-power "stop" by reasserting the saved RX filter.
ra8_err_t ra8_rmac_set_mac_address (ra8_rmac_port_t port, const uint8_t mac[k_ra8_rmac_mac_byte_count])
 Program the reception MAC address (MRMAC0 / MRMAC1).
ra8_err_t ra8_rmac_set_rx_filter (ra8_rmac_port_t port, ra8_rmac_mrafc_t filter)
 Program the RX address filter mask (MRAFC).
ra8_err_t ra8_rmac_set_ptp_filter (ra8_rmac_port_t port, uint8_t index, uint8_t byte_offset, uint8_t value, bool tef0, bool tef1)
 Program a PTP-frame filter table entry (MPFCt, t = 0..15).
ra8_err_t ra8_rmac_set_frame_size (ra8_rmac_port_t port, bool is_pframe, uint16_t min_size, uint16_t max_size)
 Configure jumbo-frame minimum / maximum sizes.
ra8_err_t ra8_rmac_set_vlan_framing (ra8_rmac_port_t port, bool disable_pad, bool use_mcrc)
 Configure VLAN double-tagging behaviour via MTFFC.
ra8_err_t ra8_rmac_set_pause_frame (ra8_rmac_port_t port, ra8_rmac_pause_mode_t mode, uint16_t pause_time, uint8_t retry_time, uint8_t retry_level)
 Program a TX pause / PFC frame template.
ra8_err_t ra8_rmac_set_pfc_group (ra8_rmac_port_t port, ra8_rmac_pfc_group_t group, uint8_t pcp_mask)
 Configure a PFC (802.1Qbb) priority group bitmap.
ra8_err_t ra8_rmac_set_lpi (ra8_rmac_port_t port, bool enable)
 Enable / disable Energy Efficient Ethernet LPI request.
ra8_err_t ra8_rmac_set_magic_packet (ra8_rmac_port_t port, bool enable)
 Enable / disable magic-packet wake-on-LAN detection.
ra8_err_t ra8_rmac_set_loopback (ra8_rmac_port_t port, bool enable)
 Enable / disable internal MAC loopback.
ra8_err_t ra8_rmac_set_link (ra8_rmac_port_t port, ra8_rmac_pis_t iface, ra8_rmac_lsc_t speed, ra8_rmac_duplex_t duplex)
 Configure the link layer (interface, speed, duplex) atomically.
ra8_err_t ra8_rmac_mdio_c22_read (ra8_rmac_port_t port, uint8_t phy_addr, uint8_t reg_addr, uint16_t *out_value)
 Trigger an MDIO Clause-22 register read on the off-chip PHY.
ra8_err_t ra8_rmac_mdio_c22_write (ra8_rmac_port_t port, uint8_t phy_addr, uint8_t reg_addr, uint16_t value)
 Trigger an MDIO Clause-22 register write on the off-chip PHY.
ra8_err_t ra8_rmac_mdio_c45_read (ra8_rmac_port_t port, uint8_t phy_addr, uint8_t dev_addr, uint16_t reg_addr, uint16_t *out_value)
 Trigger an MDIO Clause-45 register read.
ra8_err_t ra8_rmac_mdio_c45_write (ra8_rmac_port_t port, uint8_t phy_addr, uint8_t dev_addr, uint16_t reg_addr, uint16_t value)
 Trigger an MDIO Clause-45 register write.
ra8_err_t ra8_rmac_attach_handler (ra8_rmac_port_t port, ra8_rmac_event_fn_t cb, void *ctx)
 Attach a per-port IRQ handler for RMAC events.
void ra8_rmac_dispatch (ra8_rmac_port_t port)
 Dispatch a pending RMAC IRQ.

Variables

static const char * s_tag = "RMAC"
 Logger tag used by every ra8_rmac_* call.
static ra8_rmac_slot_t s_slots [k_ra8_rmac_port_count]
 Per-port handler / cache table; index = ra8_rmac_port_t.

Detailed Description

Per-port Ethernet MAC (RMAC) driver implementation – HUM Ch 33.

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

Full HAL coverage of the RA8D2 RMAC block (HUM Ch 33, p 1703-1786). The driver owns the per-port MAC layer: lifecycle, MAC-address program, RX address-filter table (perfect-match + multicast hash via MRAFC), VLAN double-tagging (MTFFC), jumbo frame MTU (MRFSCE/MRFSCP), 802.3x pause / 802.1Qbb PFC (MTPFC/MTPFC2/MTPFC3t), Energy Efficient Ethernet / LPI (MEEEC + MMIS2 LPI bits), magic- packet WoL (MRGC.MPDE + MMIS2.MPDIS), MAC-side loopback (MLBC), link config across all interfaces / speeds / duplex modes (MPIC.PIS / .LSC / .PIPP), Clause-22 + Clause-45 PHY MDIO (MPSM driven by MMIS1 completion), the full statistic counter block (MMPFTCT..MTXBCPL), and IRQ management of MEIS / MMIS0 / MMIS1 / MMIS2.

The shared MSTP gate k_ra8_mstp_eswm is reference-counted by ra8_mstp, so init/deinit interleave safely with the other ethernet sub-drivers.

Every register access carries a HUM Ch 33 citation.

State Machine

Definition in file ra8_rmac.c.

Enumeration Type Documentation

◆ ra8_rmac_bit_pos_t

enum ra8_rmac_bit_pos_t : uint8_t

Bit positions for register fields not covered by the register-header enum file.

HUM Ch 33.4 "MPFC", "MTPFC", "MTPFC2" p 1707. The header file exposes the data-byte mask/shift but leaves these single-bit / wide field positions inline in the driver. Naming them avoids readability-magic-numbers warnings and documents intent.

Enumerator
k_ra8_rmac_shift_mpfc_te0 

MPFC.TEF0 (PTP table entry 0 enable).

k_ra8_rmac_shift_mpfc_te1 

MPFC.TEF1 (PTP table entry 1 enable).

k_ra8_rmac_shift_mtpfc_pfrlv 

MTPFC.PFRLV[31:27] retry-level field.

k_ra8_rmac_shift_mtpfc2_pfm 

MTPFC2.PFM (1 = PFC frame, 0 = pause).

Definition at line 105 of file ra8_rmac.c.

◆ ra8_rmac_internal_t

enum ra8_rmac_internal_t : uint32_t

Driver-private constants (poll budgets, sentinel values).

Enumerator
k_ra8_rmac_mdio_poll_budget 

Bounded MDIO poll loop.

Definition at line 90 of file ra8_rmac.c.

◆ rmac_field_t

enum rmac_field_t : uint32_t

RMAC field constants.

Enumerator
k_rmac_pipp_pos 

PIPP (in-pause) bit position.

k_rmac_pfrlv_mask 

5-bit pause-frame retry level.

Definition at line 81 of file ra8_rmac.c.

Function Documentation

◆ internal_calc_psmcs()

uint32_t internal_calc_psmcs ( uint32_t eswclk_hz,
uint32_t mdc_hz )
inlinestatic

Compute the MPIC.PSMCS divider code for a target MDC rate.

HUM Ch 33.4.1.2 "MPIC.PSMCS" + FSP r_rmac_phy_calculate_mpic: PSMCS = ((eswclk_hz / mdc_hz) / 2) - 1

Clamps to the 7-bit field width. Returns the conservative ceiling (slowest MDC) on a divide-by-zero or absurdly slow ESWCLK so the PHY has the best chance of latching the frame.

Parameters
[in]eswclk_hzLive ESWCLK frequency in Hz (caller-provided).
[in]mdc_hzDesired MDC frequency in Hz (e.g. 1 MHz).
Returns
PSMCS divider code, clamped to k_ra8_rmac_mdc_psmcs_max.
Return values
0..0x7FValid PSMCS divider code.
Precondition
eswclk_hz > 0.
mdc_hz > 0.
Postcondition
Returned value fits in the 7-bit PSMCS field.
Pure function: no state changes.
Note
Pure function.
Since
0.1.0

Definition at line 188 of file ra8_rmac.c.

References k_ra8_rmac_mdc_psmcs_max.

Referenced by internal_program_mac_config().

◆ internal_make_mpic()

uint32_t internal_make_mpic ( ra8_rmac_pis_t iface,
ra8_rmac_lsc_t speed,
ra8_rmac_duplex_t duplex,
uint32_t psmcs )
inlinestatic

Build the MPIC value from interface / speed / duplex inputs.

Parameters
[in]ifacePHY interface.
[in]speedLink speed.
[in]duplexDuplex mode.
[in]psmcsMPIC.PSMCS clock-divider code (see internal_calc_psmcs).
Returns
32-bit MPIC value with PIS / LSC / PIPP / PSMCS fields packed.

Packs every MPIC field the driver owns:

  • PIS [2:0] – physical interface selector.
  • LSC [5:3] – link-speed selector.
  • PIPP [9] – 1 = full duplex, 0 = half.
  • PSMCS[22:16]– PHY-station-management clock divider (MDC rate).
Return values
k_ra8_okOperation succeeded.
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.
Since
0.1.0

Definition at line 240 of file ra8_rmac.c.

References k_ra8_rmac_duplex_full, k_ra8_rmac_mask_mpic_lsc, k_ra8_rmac_mask_mpic_pis, k_ra8_rmac_mask_mpic_psmcs, k_ra8_rmac_shift_mpic_lsc, k_ra8_rmac_shift_mpic_pis, k_ra8_rmac_shift_mpic_psmcs, and k_rmac_pipp_pos.

Referenced by internal_program_mac_config(), and ra8_rmac_set_link().

◆ internal_mdio_drain()

ra8_err_t internal_mdio_drain ( volatile r_rmac_regs_t * reg)
static

Drain any in-flight MDIO transaction (poll MPSM.PSME -> 0).

HUM Ch 33.4.1.1 "MPSM" p 1707-1708, Note 2: "Accessing to MPSM register while this [PSME] bit is asserted has no effect." So the driver MUST confirm PSME == 0 BEFORE issuing a new transaction – otherwise the issuing write is silently swallowed, the post-wait polls the previous transaction, and the caller reads stale PRD.

Call this immediately before every internal_mpsm_issue.

Parameters
[in]regRMAC register window.
Returns
ra8_err_t Error code.
Return values
k_ra8_okPSME is 0; the bus is idle.
k_ra8_err_hw_timeoutPSME never cleared within the budget.
Precondition
reg points at a live RMAC register window.
MPIC.PSMCS != 0 (MDC clock running).
Postcondition
On k_ra8_ok no MDIO transaction is in flight.
Side-effect free apart from the bounded busy-wait.
Note
Not thread-safe.
Since
0.1.0

Definition at line 283 of file ra8_rmac.c.

References k_ra8_rmac_mdio_poll_budget, k_ra8_rmac_mpsm_psme, r_rmac_regs_t::MPSM, and ra8_hw_wait_flag_clear32().

Referenced by ra8_rmac_mdio_c22_read(), ra8_rmac_mdio_c22_write(), ra8_rmac_mdio_c45_read(), and ra8_rmac_mdio_c45_write().

◆ internal_mdio_wait()

ra8_err_t internal_mdio_wait ( volatile r_rmac_regs_t * reg,
uint32_t mask )
static

Wait for an MDIO transaction to complete, with a bounded poll budget.

The HUM-canonical completion signal is MPSM.PSME self-clearing to 0 (HUM Ch 33.4.1.1 p 1708: "When PHY register access is completed, this bit returns automatically to 0"). The MMIS1 status bits are RW1C and a stale MMIS1.PRACS left over from the previous transaction caused spurious immediate returns on real silicon – the caller then read PRD before the new transaction had even started, observing 0. Production therefore polls only PSME.

The real PSME poll runs on every build. On the host unit-test build each poll's loop-exit decision is routed through the ra8_fake_mmio fault seam keyed on MPSM: first-poll success when no fault is armed, or a test-armed retry / timeout leg (T1-01). The drain in internal_mdio_drain polls the same MPSM address, so a test isolates THIS wait with ra8_fake_mmio_fail_nth_wait.

Parameters
[in]regRMAC register window.
[in]maskMMIS1 completion bit this op sets; cleared via MMID1 on completion so a stale latch cannot outlive the op.
Returns
ra8_err_t Error code.
Return values
k_ra8_okTransaction completed (PSME == 0).
k_ra8_err_hw_timeoutPSME never cleared within the budget.
Precondition
internal_mpsm_issue launched a transaction on this window.
The bus was drained via internal_mdio_drain before issuing.
Postcondition
On k_ra8_ok PRD holds the completed transaction's data.
The matching MMIS1 status bit is cleared via MMID1.
Note
Not thread-safe.
Since
0.1.0

Definition at line 331 of file ra8_rmac.c.

References k_ra8_err_hw_timeout, k_ra8_ok, k_ra8_rmac_mdio_poll_budget, k_ra8_rmac_mpsm_psme, r_rmac_regs_t::MMID1, and r_rmac_regs_t::MPSM.

Referenced by ra8_rmac_mdio_c22_read(), ra8_rmac_mdio_c22_write(), ra8_rmac_mdio_c45_read(), and ra8_rmac_mdio_c45_write().

◆ internal_mpsm_issue()

void internal_mpsm_issue ( volatile r_rmac_regs_t * reg,
uint8_t pda_5bit,
uint8_t pra_5bit,
ra8_rmac_mdio_op_t op,
uint16_t prd_16bit,
bool mff )
static

Issue a raw MPSM transaction.

Parameters
[in]regRMAC register window.
[in]pda_5bit5-bit PDA field (PHY address for C22; same for C45).
[in]pra_5bit5-bit PRA field (register address for C22; device address for C45 – the on-the-wire MMD selector).
[in]opMPSM.POP encoding.
[in]prd_16bit16-bit PRD payload (ignored on read; for C45 this carries the 16-bit register address on the c45_address op and the data word on c45_write).
[in]mffMPSM.MFF (0 for C22, 1 for C45).

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.
Since
0.1.0

Definition at line 377 of file ra8_rmac.c.

References k_ra8_rmac_mask_all, k_ra8_rmac_mask_mpsm_data, k_ra8_rmac_mask_mpsm_op, k_ra8_rmac_mask_mpsm_phy_reg, k_ra8_rmac_mpsm_psme, k_ra8_rmac_shift_mpsm_pda, k_ra8_rmac_shift_mpsm_pop, k_ra8_rmac_shift_mpsm_pra, k_ra8_rmac_shift_mpsm_prd, r_rmac_regs_t::MMID1, r_rmac_regs_t::MPSM, and ra8_hw_dsb().

Referenced by ra8_rmac_mdio_c22_read(), ra8_rmac_mdio_c22_write(), ra8_rmac_mdio_c45_read(), and ra8_rmac_mdio_c45_write().

◆ internal_pis_ok()

bool internal_pis_ok ( ra8_rmac_pis_t iface)
inlinestatic

Validate an MPIC.PIS interface selector.

HUM Ch 33.4.1.2 p 1707: MPIC.PIS has only two defined encodings – MII (000b) and GMII (010b). Everything else is Reserved. The enum is non-contiguous so this is an explicit two-value check rather than an upper-bound comparison.

Parameters
[in]ifaceCandidate interface selector.
Returns
true if iface is MII or GMII; false otherwise.
Return values
trueiface == k_ra8_rmac_pis_mii or k_ra8_rmac_pis_gmii.
falseiface is a Reserved encoding.
Precondition
None.
iface holds a value of the ra8_rmac_pis_t underlying type.
Postcondition
Return value reflects whether iface is a defined PIS code.
No state is modified.
Note
Pure function; thread-safe.
Since
0.1.0

Definition at line 152 of file ra8_rmac.c.

References k_ra8_rmac_pis_gmii, and k_ra8_rmac_pis_mii.

Referenced by ra8_rmac_init(), and ra8_rmac_set_link().

◆ internal_program_irq_block()

void internal_program_irq_block ( volatile r_rmac_regs_t * reg,
const ra8_rmac_config_t * cfg )
static

Reset/disable every IRQ status + enable register.

HUM Ch 33.4 "MEID/MMID0..2" p 1706 – write 1 to clear, then load the caller's enable masks into MEIE / MMIE0..2.

Parameters
[in,out]regRMAC register window.
[in]cfgValidated init config.
Precondition
Module clock ungated.
Postcondition
Status bits cleared, enable masks programmed.
Note
Internal helper, not thread-safe.
Precondition
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Since
0.1.0

Definition at line 468 of file ra8_rmac.c.

References ra8_rmac_config_t::err_irq_enable, k_ra8_rmac_mask_all, r_rmac_regs_t::MEID, r_rmac_regs_t::MEIE, r_rmac_regs_t::MMID0, r_rmac_regs_t::MMID1, r_rmac_regs_t::MMID2, r_rmac_regs_t::MMIE0, r_rmac_regs_t::MMIE1, r_rmac_regs_t::MMIE2, ra8_rmac_config_t::mon0_irq_enable, ra8_rmac_config_t::mon1_irq_enable, and ra8_rmac_config_t::mon2_irq_enable.

Referenced by ra8_rmac_init().

◆ internal_program_mac_config()

void internal_program_mac_config ( volatile r_rmac_regs_t * reg,
const ra8_rmac_config_t * cfg )
static

Reset every per-MAC config register to its post-init baseline.

HUM Ch 33.4 "MIOC ... MEEEC" p 1707. Splits ra8_rmac_init so it stays under the function-size threshold.

Parameters
[in,out]regRMAC register window.
[in]cfgValidated init config.
Precondition
Module clock ungated.
Postcondition
All listed registers reflect cfg.
Note
Internal helper, not thread-safe.
Precondition
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Since
0.1.0

Definition at line 433 of file ra8_rmac.c.

References ra8_rmac_config_t::duplex, ra8_rmac_config_t::eswclk_hz, internal_calc_psmcs(), internal_make_mpic(), k_ra8_rmac_mdc_default_hz, ra8_rmac_config_t::link_speed, ra8_rmac_config_t::mdc_hz, r_rmac_regs_t::MEEEC, r_rmac_regs_t::MIOC, r_rmac_regs_t::MLBC, r_rmac_regs_t::MPIC, r_rmac_regs_t::MRAFC, r_rmac_regs_t::MRGC, r_rmac_regs_t::MRMAC0, r_rmac_regs_t::MRMAC1, r_rmac_regs_t::MTFFC, ra8_rmac_config_t::phy_interface, and ra8_rmac_config_t::rx_filter.

Referenced by ra8_rmac_init().

◆ ra8_rmac_attach_handler()

ra8_err_t ra8_rmac_attach_handler ( ra8_rmac_port_t port,
ra8_rmac_event_fn_t cb,
void * ctx )
nodiscard

Attach a per-port IRQ handler for RMAC events.

Parameters
[in]portPort identifier.
[in]cbCallback (nullptr to detach).
[in]ctxOpaque cookie passed back to cb.
Returns
ra8_err_t Error code.
Precondition
Port previously brought up via ra8_rmac_init.
Caller is single-threaded with respect to attach/dispatch.
Postcondition
Subsequent calls to ra8_rmac_dispatch invoke cb.
See also
ra8_rmac_dispatch
Since
0.1.0

Definition at line 934 of file ra8_rmac.c.

References internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, ra8_log_error, s_slots, and s_tag.

◆ ra8_rmac_deinit()

ra8_err_t ra8_rmac_deinit ( ra8_rmac_port_t port)
nodiscard

Tear down an RMAC port.

Parameters
[in]portPort identifier.
Returns
ra8_err_t Error code.
Return values
k_ra8_okPort stopped, regs cleared.
k_ra8_err_invalid_argport out of range.
Precondition
Port previously brought up via ra8_rmac_init.
No outstanding TX/RX traffic on this port.
Postcondition
MRAFC, MRGC, MTFFC, MLBC, MEEEC cleared.
MEIE, MMIE0, MMIE1, MMIE2 cleared.
Note
Does NOT drop the shared ESWM MSTP gate; ra8_eth_deinit owns the final reference.
See also
ra8_rmac_init
Since
0.1.0

Definition at line 515 of file ra8_rmac.c.

References internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, r_rmac_regs_t::MEEEC, r_rmac_regs_t::MEIE, r_rmac_regs_t::MLBC, r_rmac_regs_t::MMIE0, r_rmac_regs_t::MMIE1, r_rmac_regs_t::MMIE2, r_rmac_regs_t::MRAFC, r_rmac_regs_t::MRGC, r_rmac_regs_t::MTFFC, ra8_log_error, ra8_rmac(), s_slots, and s_tag.

Referenced by ra8_eth_close().

◆ ra8_rmac_dispatch()

void ra8_rmac_dispatch ( ra8_rmac_port_t port)

Dispatch a pending RMAC IRQ.

Parameters
[in]portPort identifier.

Reads MEIS / MMIS0..2 atomically, clears every observed bit through the matching MEID / MMID register, then invokes the attached callback with the snapshot. Designed to be called from the NVIC ISR registered for the RMAC error / monitor interrupt vectors.

Precondition
Port previously brought up via ra8_rmac_init.
Called from ISR context or a host-test driver.
Postcondition
All four status registers are cleared.
Callback (if any) has run with the snapshot.
Note
Not thread-safe; pair with NVIC masking. See HUM Ch 41 "Reduced Media Access Controller (RMAC)" pp 1893-2018.
See also
ra8_rmac_attach_handler
Since
0.1.0

Definition at line 946 of file ra8_rmac.c.

References internal_port_ok(), r_rmac_regs_t::MEID, r_rmac_regs_t::MEIS, r_rmac_regs_t::MMID0, r_rmac_regs_t::MMID1, r_rmac_regs_t::MMID2, r_rmac_regs_t::MMIS0, r_rmac_regs_t::MMIS1, r_rmac_regs_t::MMIS2, ra8_rmac(), and s_slots.

◆ ra8_rmac_enter_stop()

ra8_err_t ra8_rmac_enter_stop ( ra8_rmac_port_t port)
nodiscard

Enter low-power "stop" by disabling RX address filtering.

Parameters
[in]portPort identifier.
Returns
ra8_err_t Error code.
Precondition
Port has been brought up via ra8_rmac_init.
No PHY MDIO transaction outstanding.
Postcondition
MRAFC = 0 (no frame class accepted).
Existing IRQ enables preserved so wake events still fire.
Note
Pair with ra8_rmac_exit_stop. Magic-packet WoL stays armed if MRGC.MPDE was set before this call.
Since
0.1.0

Definition at line 551 of file ra8_rmac.c.

References internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, r_rmac_regs_t::MRAFC, ra8_log_error, ra8_rmac(), and s_tag.

◆ ra8_rmac_exit_stop()

ra8_err_t ra8_rmac_exit_stop ( ra8_rmac_port_t port)
nodiscard

Exit low-power "stop" by reasserting the saved RX filter.

Parameters
[in]portPort identifier.
Returns
ra8_err_t Error code.
Precondition
Caller previously invoked ra8_rmac_enter_stop on this port.
Port still has its MSTP gate held by ra8_eth.
Postcondition
MRAFC restored to the value cached by ra8_rmac_init / set_filter.
Counters reset to zero so the new accounting window starts clean.
See also
ra8_rmac_enter_stop
Since
0.1.0

Definition at line 562 of file ra8_rmac.c.

References internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, r_rmac_regs_t::MRAFC, ra8_log_error, ra8_rmac(), s_slots, and s_tag.

◆ ra8_rmac_init()

ra8_err_t ra8_rmac_init ( ra8_rmac_port_t port,
const ra8_rmac_config_t * cfg )
nodiscard

Initialise an RMAC port (MSTP gate + reset regs + filter mode).

Parameters
[in]portPort identifier (k_ra8_rmac_port_0 or _1).
[in]cfgPer-port configuration. Must not be nullptr.
Returns
ra8_err_t Error code.
Return values
k_ra8_okPort brought up.
k_ra8_err_null_ptrcfg is nullptr.
k_ra8_err_invalid_argport out of range or cfg field invalid.
Precondition
Caller is single-threaded with respect to this port.
Ethernet subsystem MSTP gate may already be enabled by ra8_eth.
Postcondition
MRAFC = cfg->rx_filter.
MEIE = cfg->err_irq_enable; MMIE0/1/2 set; status regs cleared.
MPIC.PIS / .LSC / .PIPP programmed from cfg.
Note
Per-port; safe to call concurrently for distinct ports.
See also
ra8_rmac_deinit
Since
0.1.0

Definition at line 481 of file ra8_rmac.c.

References internal_pis_ok(), internal_port_ok(), internal_program_irq_block(), internal_program_mac_config(), k_ra8_err_invalid_arg, k_ra8_mstp_eswm, k_ra8_ok, k_ra8_rmac_lsc_count, ra8_rmac_config_t::link_speed, ra8_rmac_config_t::phy_interface, RA8_CHECK_NULL_PTR, ra8_log_error, ra8_log_info, ra8_mstp_enable(), RA8_RETURN_ON_ERROR, ra8_rmac(), ra8_rmac_config_t::rx_filter, s_slots, and s_tag.

Referenced by internal_eth_rmac_program().

◆ ra8_rmac_mdio_c22_read()

ra8_err_t ra8_rmac_mdio_c22_read ( ra8_rmac_port_t port,
uint8_t phy_addr,
uint8_t reg_addr,
uint16_t * out_value )
nodiscard

Trigger an MDIO Clause-22 register read on the off-chip PHY.

Parameters
[in]portPort identifier.
[in]phy_addr5-bit PHY address (0..31).
[in]reg_addr5-bit register address (0..31).
[out]out_value16-bit register value on success.
Returns
ra8_err_t Error code.
Return values
k_ra8_okRead complete, *out_value populated.
k_ra8_err_null_ptrout_value is nullptr.
k_ra8_err_hw_timeoutMMIS1.PRACS never set within the bounded poll.
Precondition
Port previously brought up via ra8_rmac_init.
MPIC.PSMCS programmed for the chosen MDC clock.
Postcondition
MPSM transaction issued; MMIS1.PRACS cleared.
PHY register snapshot in *out_value when k_ra8_ok is returned.
Since
0.1.0

Definition at line 811 of file ra8_rmac.c.

References internal_mdio_drain(), internal_mdio_wait(), internal_mpsm_issue(), internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_rmac_mask_mpsm_data, k_ra8_rmac_mdio_op_c22_read, k_ra8_rmac_mmis1_pracs, k_ra8_rmac_shift_mpsm_prd, r_rmac_regs_t::MPSM, RA8_CHECK_NULL_PTR, ra8_log_error, ra8_rmac(), and s_tag.

Referenced by internal_eth_phy_set_rgmii_skew(), internal_eth_phy_soft_reset(), internal_phy_read_link(), internal_query_negotiated_speed(), internal_wait_for_autoneg(), ra8_rmac_phy_auto_neg_wait(), ra8_rmac_phy_link_status(), and ra8_rmac_phy_reset().

◆ ra8_rmac_mdio_c22_write()

ra8_err_t ra8_rmac_mdio_c22_write ( ra8_rmac_port_t port,
uint8_t phy_addr,
uint8_t reg_addr,
uint16_t value )
nodiscard

Trigger an MDIO Clause-22 register write on the off-chip PHY.

Parameters
[in]portPort identifier.
[in]phy_addr5-bit PHY address.
[in]reg_addr5-bit register address.
[in]value16-bit value to drive into the PHY register.
Returns
ra8_err_t Error code.
Precondition
Port previously brought up via ra8_rmac_init.
MPIC.PSMCS programmed for the chosen MDC clock.
Postcondition
MPSM transaction issued; MMIS1.PWACS cleared.
Since
0.1.0

Definition at line 842 of file ra8_rmac.c.

References internal_mdio_drain(), internal_mdio_wait(), internal_mpsm_issue(), internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_rmac_mdio_op_c22_write, k_ra8_rmac_mmis1_pwacs, ra8_log_error, ra8_rmac(), and s_tag.

Referenced by internal_eth_phy_set_rgmii_skew(), internal_eth_phy_soft_reset(), internal_eth_phy_start_autoneg(), ra8_rmac_phy_auto_neg_start(), ra8_rmac_phy_reset(), and ra8_rmac_phy_set_advertise().

◆ ra8_rmac_mdio_c45_read()

ra8_err_t ra8_rmac_mdio_c45_read ( ra8_rmac_port_t port,
uint8_t phy_addr,
uint8_t dev_addr,
uint16_t reg_addr,
uint16_t * out_value )
nodiscard

Trigger an MDIO Clause-45 register read.

Parameters
[in]portPort identifier.
[in]phy_addr5-bit PHY address.
[in]dev_addr5-bit MMD device address.
[in]reg_addr16-bit MMD register address.
[out]out_value16-bit register value on success.
Returns
ra8_err_t Error code.
Return values
k_ra8_okRead complete.
k_ra8_err_null_ptrout_value is nullptr.
k_ra8_err_hw_timeoutMMIS1 completion bit never asserted.
Precondition
Port previously brought up via ra8_rmac_init.
MPIC.PSMHT configured for Clause-45 hold time.
Postcondition
Address frame followed by read frame both completed.
Since
0.1.0

Definition at line 859 of file ra8_rmac.c.

References internal_mdio_drain(), internal_mdio_wait(), internal_mpsm_issue(), internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_rmac_mask_mpsm_data, k_ra8_rmac_mdio_op_c45_address, k_ra8_rmac_mdio_op_c45_read, k_ra8_rmac_mmis1_paacs, k_ra8_rmac_mmis1_pracs, k_ra8_rmac_shift_mpsm_prd, r_rmac_regs_t::MPSM, RA8_CHECK_NULL_PTR, ra8_log_error, ra8_rmac(), and s_tag.

◆ ra8_rmac_mdio_c45_write()

ra8_err_t ra8_rmac_mdio_c45_write ( ra8_rmac_port_t port,
uint8_t phy_addr,
uint8_t dev_addr,
uint16_t reg_addr,
uint16_t value )
nodiscard

Trigger an MDIO Clause-45 register write.

Parameters
[in]portPort identifier.
[in]phy_addr5-bit PHY address.
[in]dev_addr5-bit MMD device address.
[in]reg_addr16-bit MMD register address.
[in]value16-bit value to drive into the MMD register.
Returns
ra8_err_t Error code.
Precondition
Port previously brought up via ra8_rmac_init.
MPIC.PSMHT configured for Clause-45 hold time.
Postcondition
Address frame followed by write frame both completed.
Since
0.1.0

Definition at line 902 of file ra8_rmac.c.

References internal_mdio_drain(), internal_mdio_wait(), internal_mpsm_issue(), internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_rmac_mdio_op_c45_address, k_ra8_rmac_mdio_op_c45_write, k_ra8_rmac_mmis1_paacs, k_ra8_rmac_mmis1_pwacs, ra8_log_error, ra8_rmac(), and s_tag.

◆ ra8_rmac_set_frame_size()

ra8_err_t ra8_rmac_set_frame_size ( ra8_rmac_port_t port,
bool is_pframe,
uint16_t min_size,
uint16_t max_size )
nodiscard

Configure jumbo-frame minimum / maximum sizes.

Parameters
[in]portPort identifier.
[in]is_pframetrue for P-frames (MRFSCP), false for E-frames (MRFSCE).
[in]min_sizeMinimum accepted frame size (bytes).
[in]max_sizeMaximum accepted frame size (bytes, up to 16383).
Returns
ra8_err_t Error code.
Precondition
Port is in CONFIG mode.
min_size <= max_size.
Postcondition
MRFSCE / MRFSCP packed with min and max in the right halves.
Frames outside the window count toward MRGUEFC / MRBUEFC / MRGOEFC / MRBOEFC depending on size and FCS validity.
Since
0.1.0

Definition at line 652 of file ra8_rmac.c.

References internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_rmac_mask_mrfsc, k_ra8_rmac_shift_mrfsce_max, k_ra8_rmac_shift_mrfsce_min, r_rmac_regs_t::MRFSCE, r_rmac_regs_t::MRFSCP, ra8_log_error, ra8_rmac(), and s_tag.

◆ ra8_rmac_set_link()

ra8_err_t ra8_rmac_set_link ( ra8_rmac_port_t port,
ra8_rmac_pis_t iface,
ra8_rmac_lsc_t speed,
ra8_rmac_duplex_t duplex )
nodiscard

Configure the link layer (interface, speed, duplex) atomically.

Parameters
[in]portPort identifier.
[in]ifacePHY-side interface (GMII / MII / RMII / RGMII / XGMII).
[in]speedLink speed (10 / 100 / 1000 / 2500 / 10000 Mbit/s).
[in]duplexHalf / full duplex.
Returns
ra8_err_t Error code.
Precondition
Port is in CONFIG mode.
iface, speed, duplex are within their respective enums.
Postcondition
MPIC.PIS = iface; MPIC.LSC = speed; MPIC.PIPP = duplex.
Since
0.1.0

Definition at line 782 of file ra8_rmac.c.

References internal_make_mpic(), internal_pis_ok(), internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_rmac_lsc_count, k_ra8_rmac_mask_mpic_psmcs, k_ra8_rmac_shift_mpic_psmcs, r_rmac_regs_t::MPIC, ra8_log_error, ra8_rmac(), and s_tag.

Referenced by internal_program_mpic().

◆ ra8_rmac_set_loopback()

ra8_err_t ra8_rmac_set_loopback ( ra8_rmac_port_t port,
bool enable )
nodiscard

Enable / disable internal MAC loopback.

Parameters
[in]portPort identifier.
[in]enabletrue to short TX -> RX inside the MAC.
Returns
ra8_err_t Error code.
Precondition
Port is in CONFIG mode.
PHY pulled into electrical loopback or detached for cleanest test.
Postcondition
MLBC.LBME set / cleared.
Note
Some PHYs also offer line-side loopback configured via MDIO; this driver only manages the on-chip MAC-side path.
Since
0.1.0

Definition at line 767 of file ra8_rmac.c.

References internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_rmac_mlbc_lbme, r_rmac_regs_t::MLBC, ra8_log_error, ra8_rmac(), and s_tag.

◆ ra8_rmac_set_lpi()

ra8_err_t ra8_rmac_set_lpi ( ra8_rmac_port_t port,
bool enable )
nodiscard

Enable / disable Energy Efficient Ethernet LPI request.

Parameters
[in]portPort identifier.
[in]enabletrue to assert TX LPI; false to clear.
Returns
ra8_err_t Error code.
Precondition
Port previously brought up via ra8_rmac_init.
PHY supports IEEE 802.3az LPI (caller responsibility).
Postcondition
MEEEC.LPITR set / cleared accordingly.
Subsequent TX traffic enters / leaves LPI; MMIS2.LPIAIS / LPIDIS fires at the transition.
See also
ra8_rmac_get_status to observe MPIM.LPIA bit.
Since
0.1.0

Definition at line 734 of file ra8_rmac.c.

References internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_rmac_meeec_lpitr, r_rmac_regs_t::MEEEC, ra8_log_error, ra8_rmac(), and s_tag.

◆ ra8_rmac_set_mac_address()

ra8_err_t ra8_rmac_set_mac_address ( ra8_rmac_port_t port,
const uint8_t mac[k_ra8_rmac_mac_byte_count] )
nodiscard

Program the reception MAC address (MRMAC0 / MRMAC1).

Parameters
[in]portPort identifier.
[in]mac6-byte network-byte-order MAC address (mac[0] = OUI hi).
Returns
ra8_err_t Error code.
Return values
k_ra8_okMAC address programmed.
k_ra8_err_null_ptrmac is nullptr.
k_ra8_err_invalid_argport out of range.
Precondition
Port is in CONFIG mode (MRMAC0/1 are CONFIG-only writes per Table 33.4).
mac points to a 6-byte readable buffer.
Postcondition
MRMAC0.MAU = mac[0..1] big-endian (MSB in bits [15:8]).
MRMAC1.MAL = mac[2..5] big-endian (mac[2] in bits [31:24]).
Note
Caller is responsible for switching to/from CONFIG mode via the ETHA EAMC.OPC field; see ra8_etha_init.
Since
0.1.0

Definition at line 573 of file ra8_rmac.c.

References internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_rmac_mac_byte_0, k_ra8_rmac_mac_byte_1, k_ra8_rmac_mac_byte_2, k_ra8_rmac_mac_byte_3, k_ra8_rmac_mac_byte_4, k_ra8_rmac_mac_byte_5, k_ra8_rmac_mac_byte_count, k_ra8_rmac_mask_byte, k_ra8_rmac_mask_mrmac0_mau, k_ra8_rmac_shift_byte0, k_ra8_rmac_shift_byte1, k_ra8_rmac_shift_byte2, k_ra8_rmac_shift_byte3, k_ra8_rmac_shift_high16, k_ra8_rmac_shift_high24, r_rmac_regs_t::MRMAC0, r_rmac_regs_t::MRMAC1, RA8_CHECK_NULL_PTR, ra8_log_error, ra8_rmac(), and s_tag.

Referenced by internal_bring_up_rmac().

◆ ra8_rmac_set_magic_packet()

ra8_err_t ra8_rmac_set_magic_packet ( ra8_rmac_port_t port,
bool enable )
nodiscard

Enable / disable magic-packet wake-on-LAN detection.

Parameters
[in]portPort identifier.
[in]enabletrue arms detection; false disarms.
Returns
ra8_err_t Error code.
Precondition
Port previously brought up via ra8_rmac_init.
RX path is otherwise quiesced (only WoL frames expected).
Postcondition
MRGC.MPDE set / cleared.
On magic-packet arrival, MMIS2.MPDIS asserts and the IRQ handler fires if MMIE2.MPDIE is set.
Since
0.1.0

Definition at line 749 of file ra8_rmac.c.

References internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_rmac_mrgc_mpde, r_rmac_regs_t::MRGC, ra8_log_error, ra8_rmac(), and s_tag.

◆ ra8_rmac_set_pause_frame()

ra8_err_t ra8_rmac_set_pause_frame ( ra8_rmac_port_t port,
ra8_rmac_pause_mode_t mode,
uint16_t pause_time,
uint8_t retry_time,
uint8_t retry_level )
nodiscard

Program a TX pause / PFC frame template.

Parameters
[in]portPort identifier.
[in]modePause-vs-PFC (MTPFC2.PFM).
[in]pause_time16-bit pause quanta (MTPFC.PT).
[in]retry_time8-bit retry threshold (MTPFC.PFRT).
[in]retry_level5-bit retry-level (MTPFC.PFRLV).
Returns
ra8_err_t Error code.
Precondition
Port is in CONFIG mode.
Postcondition
MTPFC packed with pause_time + retry_time + retry_level.
MTPFC2.PFM written from mode.
Since
0.1.0

Definition at line 692 of file ra8_rmac.c.

References internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_rmac_mask_mtpfc_pfrt, k_ra8_rmac_mask_mtpfc_pt, k_ra8_rmac_pause_mode_pfc, k_ra8_rmac_shift_mtpfc2_pfm, k_ra8_rmac_shift_mtpfc_pfrlv, k_ra8_rmac_shift_mtpfc_pfrt, k_ra8_rmac_shift_mtpfc_pt, k_rmac_pfrlv_mask, r_rmac_regs_t::MTPFC, r_rmac_regs_t::MTPFC2, ra8_log_error, ra8_rmac(), and s_tag.

◆ ra8_rmac_set_pfc_group()

ra8_err_t ra8_rmac_set_pfc_group ( ra8_rmac_port_t port,
ra8_rmac_pfc_group_t group,
uint8_t pcp_mask )
nodiscard

Configure a PFC (802.1Qbb) priority group bitmap.

Parameters
[in]portPort identifier.
[in]groupPriority group index (0..1).
[in]pcp_mask8-bit PCP-priority bitmap.
Returns
ra8_err_t Error code.
Precondition
Port is in CONFIG mode.
group < k_ra8_rmac_pfc_group_count.
Postcondition
MTPFC3[group] = pcp_mask & 0xFF.
Since
0.1.0

Definition at line 719 of file ra8_rmac.c.

References internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_rmac_mask_pfc_priority, k_ra8_rmac_pfc_group_count, r_rmac_regs_t::MTPFC3, ra8_log_error, ra8_rmac(), and s_tag.

◆ ra8_rmac_set_ptp_filter()

ra8_err_t ra8_rmac_set_ptp_filter ( ra8_rmac_port_t port,
uint8_t index,
uint8_t byte_offset,
uint8_t value,
bool tef0,
bool tef1 )
nodiscard

Program a PTP-frame filter table entry (MPFCt, t = 0..15).

Parameters
[in]portPort identifier.
[in]indexSlot index (0..15).
[in]byte_offsetOffset into the frame payload to test.
[in]valueReference byte value to compare.
[in]tef0true to flag GPTP TX-event-frame trigger 0.
[in]tef1true to flag GPTP TX-event-frame trigger 1.
Returns
ra8_err_t Error code.
Precondition
Port is in CONFIG mode.
index < k_ra8_rmac_ptp_filter_count.
Postcondition
MPFC[index] = encoded slot.
Subsequent matching frames raise the requested GPTP trigger.
Note
Pair with ra8_eth_gptp to consume the timestamp.
Since
0.1.0

Definition at line 621 of file ra8_rmac.c.

References internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_rmac_mask_byte, k_ra8_rmac_ptp_filter_count, k_ra8_rmac_shift_mpfc_te0, k_ra8_rmac_shift_mpfc_te1, k_ra8_rmac_shift_mpfc_val, r_rmac_regs_t::MPFC, ra8_log_error, ra8_rmac(), and s_tag.

◆ ra8_rmac_set_rx_filter()

ra8_err_t ra8_rmac_set_rx_filter ( ra8_rmac_port_t port,
ra8_rmac_mrafc_t filter )
nodiscard

Program the RX address filter mask (MRAFC).

Parameters
[in]portPort identifier.
[in]filterBitwise OR of ra8_rmac_mrafc_t values.
Returns
ra8_err_t Error code.
Precondition
Port has been brought up via ra8_rmac_init.
filter only sets bits documented in ra8_rmac_mrafc_t.
Postcondition
MRAFC = filter.
Driver caches filter for ra8_rmac_exit_stop restore.
Note
Filter writes are CONFIG/OPERATION-mode safe per HUM Table 33.4 ("MRAFC -- C, O").
Since
0.1.0

Definition at line 609 of file ra8_rmac.c.

References internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, r_rmac_regs_t::MRAFC, ra8_log_error, ra8_rmac(), s_slots, and s_tag.

◆ ra8_rmac_set_vlan_framing()

ra8_err_t ra8_rmac_set_vlan_framing ( ra8_rmac_port_t port,
bool disable_pad,
bool use_mcrc )
nodiscard

Configure VLAN double-tagging behaviour via MTFFC.

Parameters
[in]portPort identifier.
[in]disable_padtrue to disable TX pad (DPAD).
[in]use_mcrctrue to use mCRC framing instead of standard CRC (FCM).
Returns
ra8_err_t Error code.
Precondition
Port is in CONFIG mode.
Postcondition
MTFFC = (DPAD?1) | (FCM<<1).
Note
802.1Q double-tagging itself is honoured by the chip when both outer and inner Ethertypes are recognised; this call only toggles the framing mode that the rest of the pipeline uses.
Since
0.1.0

Definition at line 674 of file ra8_rmac.c.

References internal_port_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_rmac_mtffc_dpad, k_ra8_rmac_mtffc_fcm, r_rmac_regs_t::MTFFC, ra8_log_error, ra8_rmac(), and s_tag.

Variable Documentation

◆ s_slots

Per-port handler / cache table; index = ra8_rmac_port_t.

Definition at line 127 of file ra8_rmac.c.

◆ s_tag

const char* s_tag = "RMAC"
static

Logger tag used by every ra8_rmac_* call.

Definition at line 78 of file ra8_rmac.c.