ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_rmac.c
Go to the documentation of this file.
1
57
58#include "ra8_rmac.h"
59
60#include <stdint.h>
61
62#include "ra8_attributes.h"
63#include "ra8_check.h"
64#include "ra8_err.h"
65#include "ra8_ether_regs.h"
66#include "ra8_hal_internal.h"
67#include "ra8_hw_err.h"
68#include "ra8_hw_intrinsics.h"
69#include "ra8_log.h"
70#include "ra8_mstp.h"
71#include "ra8_mstp_regs.h"
72#include "ra8_rmac_regs.h"
73
78static const char* s_tag = "RMAC";
79
81typedef enum : uint32_t {
85
90typedef enum : uint32_t {
93
111
122
128
152static inline bool internal_pis_ok(ra8_rmac_pis_t iface)
153{
154 if (iface == k_ra8_rmac_pis_mii) {
155 return true;
156 }
157 if (iface == k_ra8_rmac_pis_gmii) {
158 return true;
159 }
160 return false;
161}
162
188static inline uint32_t internal_calc_psmcs(uint32_t eswclk_hz, uint32_t mdc_hz)
189{
190 /* Defensive clamp: ESWCLK = 0 means the chip's CGC has not been
191 * configured; pick the slowest MDC the field can encode so the PHY
192 * has the best chance of latching. ``mdc_hz`` is guaranteed non-zero
193 * by the only caller (``internal_program_mac_config`` substitutes
194 * ``k_ra8_rmac_mdc_default_hz`` when ``cfg->mdc_hz`` is 0), so a
195 * single early-return on eswclk_hz==0 is sufficient. */
196 if (eswclk_hz == 0U) {
197 return (uint32_t)k_ra8_rmac_mdc_psmcs_max;
198 }
199 /* Same defensive clamp on mdc_hz to avoid undefined integer div if
200 * a future caller bypasses the substitution above. */
201 if (mdc_hz == 0U) {
202 return (uint32_t)k_ra8_rmac_mdc_psmcs_max;
203 }
204 uint32_t psmcs = ((eswclk_hz / mdc_hz) / 2U);
205 if (psmcs == 0U) {
206 psmcs = 1U;
207 }
208 psmcs -= 1U;
209 if (psmcs > (uint32_t)k_ra8_rmac_mdc_psmcs_max) {
210 psmcs = (uint32_t)k_ra8_rmac_mdc_psmcs_max;
211 }
212 return psmcs;
213}
214
240static inline uint32_t internal_make_mpic(ra8_rmac_pis_t iface,
241 ra8_rmac_lsc_t speed,
242 ra8_rmac_duplex_t duplex,
243 uint32_t psmcs)
244{
245 /* HUM Ch 33.4 "MPIC : PHY Interfaces Configuration Register" p 1709 */
246 const uint32_t pis = ((uint32_t)iface & k_ra8_rmac_mask_mpic_pis)
247 << (uint32_t)k_ra8_rmac_shift_mpic_pis;
248 const uint32_t lsc = ((uint32_t)speed & k_ra8_rmac_mask_mpic_lsc)
249 << (uint32_t)k_ra8_rmac_shift_mpic_lsc;
250 const uint32_t pipp = (duplex == k_ra8_rmac_duplex_full) ? (1U << k_rmac_pipp_pos) : 0U;
251 const uint32_t psmcs_field = (psmcs & k_ra8_rmac_mask_mpic_psmcs)
252 << (uint32_t)k_ra8_rmac_shift_mpic_psmcs;
253 return pis | lsc | pipp | psmcs_field;
254}
255
284{
285 /* Bounded wait for MPSM.PSME to self-clear to 0 (HUM Note 2: a write
286 * to MPSM while PSME=1 has no effect, so the bus must be idle first).
287 * ra8_hw_wait_flag_clear32 runs the same real poll/timeout loop on the
288 * host unit-test build, where each iteration is routed through the
289 * ra8_fake_mmio seam so a test can drive PSME clearing or a timeout. */
290 return ra8_hw_wait_flag_clear32(&reg->MPSM,
291 (uint32_t)k_ra8_rmac_mpsm_psme,
293}
294
331static ra8_err_t internal_mdio_wait(volatile r_rmac_regs_t* reg, uint32_t mask)
332{
333 for (uint32_t i = 0; i < k_ra8_rmac_mdio_poll_budget; ++i) {
334 /* HUM Ch 33.4.1.1 "MPSM : PHY Station Management Register" p 1708 */
335 const bool done = ((reg->MPSM & (uint32_t)k_ra8_rmac_mpsm_psme) == 0U);
336#if defined(RA8_OFF_TARGET) && defined(UNIT_TEST)
337 /* Host MMIO fault seam, keyed on MPSM (the polled register). */
338 if (ra8_fake_mmio_wait_eval(&reg->MPSM, i, done)) {
339 /* HUM Ch 33 "MMID1 / MMIS1" p 1707 */
340 reg->MMID1 = mask;
341 return k_ra8_ok;
342 }
343#else
344 if (done) {
345 /* HUM Ch 33 "MMID1 / MMIS1" p 1707 */
346 reg->MMID1 = mask;
347 return k_ra8_ok;
348 }
349#endif
350 }
352}
353
377static void internal_mpsm_issue(volatile r_rmac_regs_t* reg,
378 uint8_t pda_5bit,
379 uint8_t pra_5bit,
381 uint16_t prd_16bit,
382 bool mff)
383{
384 /* HUM Ch 33.4.1.1 "MPSM : PHY Station Management Register" p 1707 */
385 const uint32_t pda = ((uint32_t)pda_5bit & k_ra8_rmac_mask_mpsm_phy_reg)
386 << (uint32_t)k_ra8_rmac_shift_mpsm_pda;
387 const uint32_t pra = ((uint32_t)pra_5bit & k_ra8_rmac_mask_mpsm_phy_reg)
388 << (uint32_t)k_ra8_rmac_shift_mpsm_pra;
389 const uint32_t pop = ((uint32_t)op & k_ra8_rmac_mask_mpsm_op)
390 << (uint32_t)k_ra8_rmac_shift_mpsm_pop;
391 const uint32_t prd = ((uint32_t)prd_16bit & k_ra8_rmac_mask_mpsm_data)
392 << (uint32_t)k_ra8_rmac_shift_mpsm_prd;
393 uint32_t mff_bit = 0UL;
394 if (mff) {
395 mff_bit = (1UL << 2U);
396 }
397 /* Clear any stale MMIS1 completion bits from the previous
398 * transaction BEFORE launching this one, so the post-wait can
399 * never short-circuit on a leftover status bit. MMID1 is the
400 * write-1-to-clear alias of MMIS1. */
401 /* HUM Ch 33 "MMID1 / MMIS1" p 1707 */
403 /* PSME = bit 0 -- starts the transaction. The caller has already
404 * drained PSME to 0 via internal_mdio_drain, so this write is
405 * honoured (HUM Note 2: a write while PSME=1 has no effect). */
406 /* HUM Ch 33.4.1.1 "MPSM : PHY Station Management Register" p 1707 */
407 reg->MPSM = pda | pra | pop | prd | mff_bit | (uint32_t)k_ra8_rmac_mpsm_psme;
408 /* Ensure the issuing write reaches the peripheral before the post-wait
409 * starts polling MPSM (host no-op via the ra8_hw_intrinsics seam). */
410 ra8_hw_dsb();
411}
412
433static void internal_program_mac_config(volatile r_rmac_regs_t* reg, const ra8_rmac_config_t* cfg)
434{
435 reg->MIOC = 0U;
436 reg->MTFFC = 0U;
437 reg->MRMAC0 = 0U;
438 reg->MRMAC1 = 0U;
439 reg->MRGC = 0U;
440 reg->MRAFC = (uint32_t)cfg->rx_filter;
441 reg->MLBC = 0U;
442 reg->MEEEC = 0U;
443 const uint32_t mdc_hz = (cfg->mdc_hz != 0U) ? cfg->mdc_hz : (uint32_t)k_ra8_rmac_mdc_default_hz;
444 const uint32_t psmcs = internal_calc_psmcs(cfg->eswclk_hz, mdc_hz);
445 reg->MPIC = internal_make_mpic(cfg->phy_interface, cfg->link_speed, cfg->duplex, psmcs);
446}
447
468static void internal_program_irq_block(volatile r_rmac_regs_t* reg, const ra8_rmac_config_t* cfg)
469{
474
475 reg->MEIE = cfg->err_irq_enable;
476 reg->MMIE0 = cfg->mon0_irq_enable;
477 reg->MMIE1 = cfg->mon1_irq_enable;
478 reg->MMIE2 = cfg->mon2_irq_enable;
479}
480
482{
483 RA8_CHECK_NULL_PTR(cfg, s_tag, "rmac_init: cfg must not be nullptr");
484 if (!internal_port_ok(port)) {
485 ra8_log_error(s_tag, "rmac_init: port out of range");
487 }
488 if (!internal_pis_ok(cfg->phy_interface)) {
489 ra8_log_error(s_tag, "rmac_init: phy_interface out of range");
491 }
492 if ((uint8_t)cfg->link_speed >= k_ra8_rmac_lsc_count) {
493 ra8_log_error(s_tag, "rmac_init: link_speed out of range");
495 }
496
497 /* HUM Ch 11.2.8 "MSTPCRC : Module Stop Control Register C" p 446 */
499 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
500 RA8_RETURN_ON_ERROR(mst_err, s_tag, "rmac_init: mstp enable");
501 /* GCOVR_EXCL_BR_STOP */
502
503 volatile r_rmac_regs_t* reg = ra8_rmac(port);
506
507 s_slots[(uint8_t)port].cb = nullptr;
508 s_slots[(uint8_t)port].ctx = nullptr;
509 s_slots[(uint8_t)port].cached_filter = cfg->rx_filter;
510 s_slots[(uint8_t)port].in_use = 1U;
511 ra8_log_info(s_tag, "rmac_init");
512 return k_ra8_ok;
513}
514
516{
517 if (!internal_port_ok(port)) {
518 ra8_log_error(s_tag, "rmac_deinit: port out of range");
520 }
521
522 volatile r_rmac_regs_t* reg = ra8_rmac(port);
523
524 /* HUM Ch 33.4 "MRAFC : MAC Reception Address Filter Configuration Register" p 1717 */
525 reg->MRAFC = 0U;
526 /* HUM Ch 33.4 "MRGC : MAC Reception General Configuration Register" p 1715 */
527 reg->MRGC = 0U;
528 /* HUM Ch 33.4 "MTFFC : MAC Transmission Frame Format Configuration Register" p 1711 */
529 reg->MTFFC = 0U;
530 /* HUM Ch 33.4 "MLBC : MAC Loopback Configuration Register" p 1726 */
531 reg->MLBC = 0U;
532 /* HUM Ch 33.4 "MEEEC : MAC Energy Efficient Ethernet Configuration Register" p 1726 */
533 reg->MEEEC = 0U;
534 /* HUM Ch 33.4 "MEIE : MAC Error Interrupt Enable Register" p 1751 */
535 reg->MEIE = 0U;
536 /* HUM Ch 33.4 "MMIE0 : MAC Monitoring Interrupt Enable Register 0" p 1757 */
537 reg->MMIE0 = 0U;
538 /* HUM Ch 33.4 "MMIE1 : MAC Monitoring Interrupt Enable Register 1" p 1759 */
539 reg->MMIE1 = 0U;
540 /* HUM Ch 33.4 "MMIE2 : MAC Monitoring Interrupt Enable Register 2" p 1762 */
541 reg->MMIE2 = 0U;
542
543 s_slots[(uint8_t)port].cb = nullptr;
544 s_slots[(uint8_t)port].ctx = nullptr;
545 s_slots[(uint8_t)port].in_use = 0U;
546 /* MSTP gate is shared with the rest of the Ethernet subsystem; do
547 * NOT drop it here. ra8_eth_deinit owns the final reference. */
548 return k_ra8_ok;
549}
550
552{
553 if (!internal_port_ok(port)) {
554 ra8_log_error(s_tag, "rmac_enter_stop: port out of range");
556 }
557 /* HUM Ch 33.4 "MRAFC : MAC Reception Address Filter Configuration Register" p 1717 */
558 ra8_rmac(port)->MRAFC = 0U;
559 return k_ra8_ok;
560}
561
563{
564 if (!internal_port_ok(port)) {
565 ra8_log_error(s_tag, "rmac_exit_stop: port out of range");
567 }
568 /* HUM Ch 33.4 "MRAFC : MAC Reception Address Filter Configuration Register" p 1717 */
569 ra8_rmac(port)->MRAFC = (uint32_t)s_slots[(uint8_t)port].cached_filter;
570 return k_ra8_ok;
571}
572
574 const uint8_t mac[k_ra8_rmac_mac_byte_count])
575{
576 RA8_CHECK_NULL_PTR(mac, s_tag, "set_mac_address: mac must not be nullptr");
577 if (!internal_port_ok(port)) {
578 ra8_log_error(s_tag, "set_mac_address: port out of range");
580 }
581
582 /* MRMAC0.MAU holds the upper 16 bits (bytes 0..1, MSB at bit 15);
583 * MRMAC1.MAL holds the lower 32 bits (bytes 2..5, mac[2] in [31:24]).
584 * Source: HUM Ch 33.4 "MRMAC0/MRMAC1 : MAC Reception MAC Address
585 * Configuration Registers" p 1707, cross-checked against FSP
586 * R_RMAC0_Type.MRMAC0_b.MAU and .MRMAC1_b.MAL. */
587 const uint32_t b0 = (uint32_t)mac[k_ra8_rmac_mac_byte_0] & k_ra8_rmac_mask_byte;
588 const uint32_t b1 = (uint32_t)mac[k_ra8_rmac_mac_byte_1] & k_ra8_rmac_mask_byte;
589 const uint32_t b2 = (uint32_t)mac[k_ra8_rmac_mac_byte_2] & k_ra8_rmac_mask_byte;
590 const uint32_t b3 = (uint32_t)mac[k_ra8_rmac_mac_byte_3] & k_ra8_rmac_mask_byte;
591 const uint32_t b4 = (uint32_t)mac[k_ra8_rmac_mac_byte_4] & k_ra8_rmac_mask_byte;
592 const uint32_t b5 = (uint32_t)mac[k_ra8_rmac_mac_byte_5] & k_ra8_rmac_mask_byte;
593
594 const uint32_t mrmac0 =
595 ((b0 << (uint32_t)k_ra8_rmac_shift_high24) | (b1 << (uint32_t)k_ra8_rmac_shift_high16)) &
597 const uint32_t mrmac1 =
598 (b2 << (uint32_t)k_ra8_rmac_shift_byte3) | (b3 << (uint32_t)k_ra8_rmac_shift_byte2) |
599 (b4 << (uint32_t)k_ra8_rmac_shift_byte1) | (b5 << (uint32_t)k_ra8_rmac_shift_byte0);
600
601 volatile r_rmac_regs_t* reg = ra8_rmac(port);
602 /* HUM Ch 33.4 "MRMAC0 : MAC Reception MAC Address Configuration Register 0" p 1716 */
603 reg->MRMAC0 = mrmac0;
604 /* HUM Ch 33.4 "MRMAC1 : MAC Reception MAC Address Configuration Register 1" p 1717 */
605 reg->MRMAC1 = mrmac1;
606 return k_ra8_ok;
607}
608
610{
611 if (!internal_port_ok(port)) {
612 ra8_log_error(s_tag, "set_rx_filter: port out of range");
614 }
615 /* HUM Ch 33.4 "MRAFC : MAC Reception Address Filter Configuration Register" p 1717 */
616 ra8_rmac(port)->MRAFC = (uint32_t)filter;
617 s_slots[(uint8_t)port].cached_filter = filter;
618 return k_ra8_ok;
619}
620
622 uint8_t index,
623 uint8_t byte_offset,
624 uint8_t value,
625 bool tef0,
626 bool tef1)
627{
628 if (!internal_port_ok(port)) {
629 ra8_log_error(s_tag, "set_ptp_filter: port out of range");
631 }
632 if (index >= k_ra8_rmac_ptp_filter_count) {
633 ra8_log_error(s_tag, "set_ptp_filter: index out of range");
635 }
636 /* HUM Ch 33.4 "MPFCt : MAC PTP Filtering Register Configuration t" p 1724 */
637 const uint32_t pfbn = (uint32_t)byte_offset & k_ra8_rmac_mask_byte;
638 const uint32_t pfbv = ((uint32_t)value & k_ra8_rmac_mask_byte)
639 << (uint32_t)k_ra8_rmac_shift_mpfc_val;
640 uint32_t te = 0UL;
641 if (tef0) {
642 te |= (1UL << (uint32_t)k_ra8_rmac_shift_mpfc_te0);
643 }
644 if (tef1) {
645 te |= (1UL << (uint32_t)k_ra8_rmac_shift_mpfc_te1);
646 }
647 ra8_rmac(port)->MPFC[index] = pfbn | pfbv | te;
648 return k_ra8_ok;
649}
650
652ra8_rmac_set_frame_size(ra8_rmac_port_t port, bool is_pframe, uint16_t min_size, uint16_t max_size)
653{
654 if (!internal_port_ok(port)) {
655 ra8_log_error(s_tag, "set_frame_size: port out of range");
657 }
658 if (min_size > max_size) {
659 ra8_log_error(s_tag, "set_frame_size: min > max");
661 }
662 /* HUM Ch 33.4 "MRFSCE / MRFSCP : MAC Reception Frame Size Configuration" p 1707 */
663 const uint32_t v =
664 (((uint32_t)max_size & k_ra8_rmac_mask_mrfsc) << (uint32_t)k_ra8_rmac_shift_mrfsce_max) |
665 (((uint32_t)min_size & k_ra8_rmac_mask_mrfsc) << (uint32_t)k_ra8_rmac_shift_mrfsce_min);
666 if (is_pframe) {
667 ra8_rmac(port)->MRFSCP = v;
668 } else {
669 ra8_rmac(port)->MRFSCE = v;
670 }
671 return k_ra8_ok;
672}
673
674ra8_err_t ra8_rmac_set_vlan_framing(ra8_rmac_port_t port, bool disable_pad, bool use_mcrc)
675{
676 if (!internal_port_ok(port)) {
677 ra8_log_error(s_tag, "set_vlan_framing: port out of range");
679 }
680 /* HUM Ch 33.4 "MTFFC : MAC Transmission Frame Format Configuration" p 1711 */
681 uint32_t v = 0UL;
682 if (disable_pad) {
684 }
685 if (use_mcrc) {
687 }
688 ra8_rmac(port)->MTFFC = v;
689 return k_ra8_ok;
690}
691
694 uint16_t pause_time,
695 uint8_t retry_time,
696 uint8_t retry_level)
697{
698 if (!internal_port_ok(port)) {
699 ra8_log_error(s_tag, "set_pause_frame: port out of range");
701 }
702 /* HUM Ch 33.4 "MTPFC : MAC Transmission Pause or PFC Frame Configuration" p 1712 */
703 const uint32_t pt = ((uint32_t)pause_time & k_ra8_rmac_mask_mtpfc_pt)
704 << (uint32_t)k_ra8_rmac_shift_mtpfc_pt;
705 const uint32_t pfrt = ((uint32_t)retry_time & k_ra8_rmac_mask_mtpfc_pfrt)
706 << (uint32_t)k_ra8_rmac_shift_mtpfc_pfrt;
707 const uint32_t pfrlv = ((uint32_t)retry_level & k_rmac_pfrlv_mask)
708 << (uint32_t)k_ra8_rmac_shift_mtpfc_pfrlv;
709 /* HUM Ch 33.4 "MTPFC2 : MAC Transmission Pause or PFC Frame Cfg 2" p 1713 */
710 uint32_t pfm = 0UL;
711 if (mode == k_ra8_rmac_pause_mode_pfc) {
712 pfm = (1UL << (uint32_t)k_ra8_rmac_shift_mtpfc2_pfm);
713 }
714 ra8_rmac(port)->MTPFC = pt | pfrt | pfrlv;
715 ra8_rmac(port)->MTPFC2 = pfm;
716 return k_ra8_ok;
717}
718
720{
721 if (!internal_port_ok(port)) {
722 ra8_log_error(s_tag, "set_pfc_group: port out of range");
724 }
725 if ((uint8_t)group >= k_ra8_rmac_pfc_group_count) {
726 ra8_log_error(s_tag, "set_pfc_group: group out of range");
728 }
729 /* HUM Ch 33.4 "MTPFC3t : MAC Transmission PFC Frame Configuration 3" p 1715 */
730 ra8_rmac(port)->MTPFC3[(uint8_t)group] = (uint32_t)pcp_mask & k_ra8_rmac_mask_pfc_priority;
731 return k_ra8_ok;
732}
733
735{
736 if (!internal_port_ok(port)) {
737 ra8_log_error(s_tag, "set_lpi: port out of range");
739 }
740 /* HUM Ch 33.4 "MEEEC : MAC Energy Efficient Ethernet Configuration" p 1726 */
741 uint32_t meeec = 0UL;
742 if (enable) {
744 }
745 ra8_rmac(port)->MEEEC = meeec;
746 return k_ra8_ok;
747}
748
750{
751 if (!internal_port_ok(port)) {
752 ra8_log_error(s_tag, "set_magic_packet: port out of range");
754 }
755 /* HUM Ch 33.4 "MRGC : MAC Reception General Configuration" p 1715 */
756 volatile r_rmac_regs_t* reg = ra8_rmac(port);
757 uint32_t v = reg->MRGC;
758 if (enable) {
760 } else {
762 }
763 reg->MRGC = v;
764 return k_ra8_ok;
765}
766
768{
769 if (!internal_port_ok(port)) {
770 ra8_log_error(s_tag, "set_loopback: port out of range");
772 }
773 /* HUM Ch 33.4 "MLBC : MAC Loopback Configuration Register" p 1726 */
774 uint32_t mlbc = 0UL;
775 if (enable) {
777 }
778 ra8_rmac(port)->MLBC = mlbc;
779 return k_ra8_ok;
780}
781
783 ra8_rmac_pis_t iface,
784 ra8_rmac_lsc_t speed,
785 ra8_rmac_duplex_t duplex)
786{
787 if (!internal_port_ok(port)) {
788 ra8_log_error(s_tag, "set_link: port out of range");
790 }
791 if (!internal_pis_ok(iface)) {
792 ra8_log_error(s_tag, "set_link: iface out of range");
794 }
795 if ((uint8_t)speed >= k_ra8_rmac_lsc_count) {
796 ra8_log_error(s_tag, "set_link: speed out of range");
798 }
799 /* HUM Ch 33.4 "MPIC : PHY Interfaces Configuration Register" p 1709
800 * Preserve the existing PSMCS (MDC divider) field -- ra8_rmac_init
801 * programmed it from cfg->eswclk_hz / mdc_hz; a runtime ra8_rmac_set_link
802 * call must NOT clobber the MDC clock the PHY is already using to ack
803 * the very transaction that is updating PIS/LSC/PIPP. */
804 volatile r_rmac_regs_t* reg = ra8_rmac(port);
805 const uint32_t existing_psmcs =
806 (reg->MPIC >> (uint32_t)k_ra8_rmac_shift_mpic_psmcs) & (uint32_t)k_ra8_rmac_mask_mpic_psmcs;
807 reg->MPIC = internal_make_mpic(iface, speed, duplex, existing_psmcs);
808 return k_ra8_ok;
809}
810
812 uint8_t phy_addr,
813 uint8_t reg_addr,
814 uint16_t* out_value)
815{
816 RA8_CHECK_NULL_PTR(out_value, s_tag, "mdio_c22_read: out_value must not be nullptr");
817 if (!internal_port_ok(port)) {
818 ra8_log_error(s_tag, "mdio_c22_read: port out of range");
820 }
821
822 volatile r_rmac_regs_t* reg = ra8_rmac(port);
823 /* Pre-wait: a write to MPSM while PSME=1 has no effect (HUM Note 2). */
824 const ra8_err_t drain_err = internal_mdio_drain(reg);
825 if (drain_err != k_ra8_ok) {
826 ra8_log_error(s_tag, "mdio_c22_read: pre-drain timeout");
827 return drain_err;
828 }
829 internal_mpsm_issue(reg, phy_addr, reg_addr, k_ra8_rmac_mdio_op_c22_read, 0U, false);
831 if (wait_err != k_ra8_ok) {
832 ra8_log_error(s_tag, "mdio_c22_read: timeout"); /* GCOVR_EXCL_BR_LINE -- MDIO status no stuck */
833 return wait_err;
834 }
835 /* HUM Ch 33.4.1.1 "MPSM : PHY Station Management Register" p 1707 */
836 *out_value =
837 (uint16_t)((reg->MPSM >> (uint32_t)k_ra8_rmac_shift_mpsm_prd) & k_ra8_rmac_mask_mpsm_data);
838 return k_ra8_ok;
839}
840
842ra8_rmac_mdio_c22_write(ra8_rmac_port_t port, uint8_t phy_addr, uint8_t reg_addr, uint16_t value)
843{
844 if (!internal_port_ok(port)) {
845 ra8_log_error(s_tag, "mdio_c22_write: port out of range");
847 }
848 volatile r_rmac_regs_t* reg = ra8_rmac(port);
849 /* Pre-wait: a write to MPSM while PSME=1 has no effect (HUM Note 2). */
850 const ra8_err_t drain_err = internal_mdio_drain(reg);
851 if (drain_err != k_ra8_ok) {
852 ra8_log_error(s_tag, "mdio_c22_write: pre-drain timeout");
853 return drain_err;
854 }
855 internal_mpsm_issue(reg, phy_addr, reg_addr, k_ra8_rmac_mdio_op_c22_write, value, false);
857}
858
860 uint8_t phy_addr,
861 uint8_t dev_addr,
862 uint16_t reg_addr,
863 uint16_t* out_value)
864{
865 RA8_CHECK_NULL_PTR(out_value, s_tag, "mdio_c45_read: out_value must not be nullptr");
866 if (!internal_port_ok(port)) {
867 ra8_log_error(s_tag, "mdio_c45_read: port out of range");
869 }
870
871 volatile r_rmac_regs_t* reg = ra8_rmac(port);
872 /* C45 step 1: address frame loads the 16-bit MMD register address. */
874 if (err != k_ra8_ok) {
875 ra8_log_error(s_tag, "mdio_c45_read: addr pre-drain timeout"); /* GCOVR_EXCL_BR_LINE -- stuck */
876 return err;
877 }
878 internal_mpsm_issue(reg, phy_addr, dev_addr, k_ra8_rmac_mdio_op_c45_address, reg_addr, true);
880 if (err != k_ra8_ok) {
881 ra8_log_error(s_tag, "mdio_c45_read: address timeout"); /* GCOVR_EXCL_BR_LINE -- MDIO timeout */
882 return err;
883 }
884 /* C45 step 2: read frame fetches the 16-bit data. */
885 err = internal_mdio_drain(reg);
886 if (err != k_ra8_ok) {
887 ra8_log_error(s_tag, "mdio_c45_read: read pre-drain timeout");
888 return err;
889 }
890 internal_mpsm_issue(reg, phy_addr, dev_addr, k_ra8_rmac_mdio_op_c45_read, 0U, true);
892 if (err != k_ra8_ok) {
893 ra8_log_error(s_tag, "mdio_c45_read: read timeout"); /* GCOVR_EXCL_BR_LINE -- no stuck-status */
894 return err;
895 }
896 /* HUM Ch 33.4.1.1 "MPSM : PHY Station Management Register" p 1707 */
897 *out_value =
898 (uint16_t)((reg->MPSM >> (uint32_t)k_ra8_rmac_shift_mpsm_prd) & k_ra8_rmac_mask_mpsm_data);
899 return k_ra8_ok;
900}
901
903 uint8_t phy_addr,
904 uint8_t dev_addr,
905 uint16_t reg_addr,
906 uint16_t value)
907{
908 if (!internal_port_ok(port)) {
909 ra8_log_error(s_tag, "mdio_c45_write: port out of range");
911 }
912 volatile r_rmac_regs_t* reg = ra8_rmac(port);
913 /* Address frame followed by write frame -- both must complete. */
915 if (err != k_ra8_ok) {
916 ra8_log_error(s_tag, "mdio_c45_write: addr pre-drain timeout"); /* GCOVR_EXCL_BR_LINE -- MDIO */
917 return err;
918 }
919 internal_mpsm_issue(reg, phy_addr, dev_addr, k_ra8_rmac_mdio_op_c45_address, reg_addr, true);
921 if (err != k_ra8_ok) {
922 ra8_log_error(s_tag, "mdio_c45_write: address timeout"); /* GCOVR_EXCL_BR_LINE -- timeout */
923 return err;
924 }
925 err = internal_mdio_drain(reg);
926 if (err != k_ra8_ok) {
927 ra8_log_error(s_tag, "write pre-drain timeout"); /* GCOVR_EXCL_BR_LINE -- MDIO never stalls */
928 return err;
929 }
930 internal_mpsm_issue(reg, phy_addr, dev_addr, k_ra8_rmac_mdio_op_c45_write, value, true);
932}
933
935{
936 if (!internal_port_ok(port)) {
937 ra8_log_error(s_tag, "attach_handler: port out of range");
939 }
940 s_slots[(uint8_t)port].cb = cb;
941 s_slots[(uint8_t)port].ctx = ctx;
942 return k_ra8_ok;
943}
944
947{
948 if (!internal_port_ok(port)) {
949 return;
950 }
951 volatile r_rmac_regs_t* reg = ra8_rmac(port);
952 /* HUM Ch 33.4 "MEIS / MMIS0 / MMIS1 / MMIS2" p 1706 */
953 const uint32_t err = reg->MEIS;
954 const uint32_t m0 = reg->MMIS0;
955 const uint32_t m1 = reg->MMIS1;
956 const uint32_t m2 = reg->MMIS2;
957 const ra8_rmac_event_fn_t fn = s_slots[(uint8_t)port].cb;
958 void* const ctx = s_slots[(uint8_t)port].ctx;
959 /* HUM Ch 33.4 "MEID / MMID0 / MMID1 / MMID2" p 1706 */
960 reg->MEID = err;
961 reg->MMID0 = m0;
962 reg->MMID1 = m1;
963 reg->MMID2 = m2;
964 reg->MEIS = 0U;
965 reg->MMIS0 = 0U;
966 reg->MMIS1 = 0U;
967 reg->MMIS2 = 0U;
968 if (fn != nullptr) {
969 fn(ctx, port, err, m0, m1, m2);
970 }
971}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_ISR_SAFE
The function is callable from interrupt context.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
Definition ra8_check.h:184
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_hw_timeout
Hardware timed out waiting for a flag or handshake.
Definition ra8_err.h:304
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
static bool internal_port_ok(ra8_etha_port_t port)
Range-check a port argument.
Ethernet controller base addresses for the Renesas RA8D2.
Cross-translation-unit private helpers shared inside ra8_hal.
Bounded wait-flag primitives for RA8D2 HAL drivers.
static ra8_err_t ra8_hw_wait_flag_clear32(volatile const uint32_t *reg, uint32_t mask, uint32_t budget)
Spin until (*reg & mask) == 0 or budget runs out.
Definition ra8_hw_err.h:351
Shared CPU-intrinsic seam for the HAL drivers (host/target split).
static void ra8_hw_dsb(void)
Data Synchronisation Barrier (full system).
static ra8_isr_slot_t s_slots[k_ra8_isr_slot_count]
Per-slot dispatch table.
Definition ra8_isr.c:77
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info(tag, message)
RA8 log info.
Definition ra8_log.h:364
#define ra8_log_error(tag, message)
RA8 log error.
Definition ra8_log.h:335
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_enable(ra8_mstp_t id)
Reference-counted "ungate this peripheral" request.
Definition ra8_mstp.c:343
Module Stop Control (MSTP) register layout for the Renesas RA8D2.
@ k_ra8_mstp_eswm
MSTPC30 ESWM.
ra8_rmac_bit_pos_t
Bit positions for register fields not covered by the register-header enum file.
Definition ra8_rmac.c:105
@ k_ra8_rmac_shift_mpfc_te1
MPFC.TEF1 (PTP table entry 1 enable).
Definition ra8_rmac.c:107
@ k_ra8_rmac_shift_mtpfc2_pfm
MTPFC2.PFM (1 = PFC frame, 0 = pause).
Definition ra8_rmac.c:109
@ k_ra8_rmac_shift_mpfc_te0
MPFC.TEF0 (PTP table entry 0 enable).
Definition ra8_rmac.c:106
@ k_ra8_rmac_shift_mtpfc_pfrlv
MTPFC.PFRLV[31:27] retry-level field.
Definition ra8_rmac.c:108
ra8_rmac_internal_t
Driver-private constants (poll budgets, sentinel values).
Definition ra8_rmac.c:90
@ k_ra8_rmac_mdio_poll_budget
Bounded MDIO poll loop.
Definition ra8_rmac.c:91
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.
Definition ra8_rmac.c:859
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.
Definition ra8_rmac.c:240
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.
Definition ra8_rmac.c:674
ra8_err_t ra8_rmac_enter_stop(ra8_rmac_port_t port)
Enter low-power "stop" by disabling RX address filtering.
Definition ra8_rmac.c:551
ra8_err_t ra8_rmac_set_magic_packet(ra8_rmac_port_t port, bool enable)
Enable / disable magic-packet wake-on-LAN detection.
Definition ra8_rmac.c:749
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.
Definition ra8_rmac.c:468
ra8_err_t ra8_rmac_exit_stop(ra8_rmac_port_t port)
Exit low-power "stop" by reasserting the saved RX filter.
Definition ra8_rmac.c:562
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.
Definition ra8_rmac.c:934
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.
Definition ra8_rmac.c:902
rmac_field_t
RMAC field constants.
Definition ra8_rmac.c:81
@ k_rmac_pfrlv_mask
5-bit pause-frame retry level.
Definition ra8_rmac.c:83
@ k_rmac_pipp_pos
PIPP (in-pause) bit position.
Definition ra8_rmac.c:82
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).
Definition ra8_rmac.c:609
static ra8_err_t internal_mdio_drain(volatile r_rmac_regs_t *reg)
Drain any in-flight MDIO transaction (poll MPSM.PSME -> 0).
Definition ra8_rmac.c:283
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.
Definition ra8_rmac.c:692
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.
Definition ra8_rmac.c:331
ra8_err_t ra8_rmac_set_lpi(ra8_rmac_port_t port, bool enable)
Enable / disable Energy Efficient Ethernet LPI request.
Definition ra8_rmac.c:734
ra8_err_t ra8_rmac_deinit(ra8_rmac_port_t port)
Tear down an RMAC port.
Definition ra8_rmac.c:515
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.
Definition ra8_rmac.c:433
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.
Definition ra8_rmac.c:842
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.
Definition ra8_rmac.c:377
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.
Definition ra8_rmac.c:188
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.
Definition ra8_rmac.c:782
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.
Definition ra8_rmac.c:652
static bool internal_pis_ok(ra8_rmac_pis_t iface)
Validate an MPIC.PIS interface selector.
Definition ra8_rmac.c:152
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.
Definition ra8_rmac.c:811
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).
Definition ra8_rmac.c:621
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).
Definition ra8_rmac.c:481
ra8_err_t ra8_rmac_set_loopback(ra8_rmac_port_t port, bool enable)
Enable / disable internal MAC loopback.
Definition ra8_rmac.c:767
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.
Definition ra8_rmac.c:719
void ra8_rmac_dispatch(ra8_rmac_port_t port)
Dispatch a pending RMAC IRQ.
Definition ra8_rmac.c:946
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).
Definition ra8_rmac.c:573
Per-port Ethernet MAC (RMAC) driver – HUM Ch 33.
void(* ra8_rmac_event_fn_t)(void *ctx, ra8_rmac_port_t port, uint32_t err_msk, uint32_t mon0_msk, uint32_t mon1_msk, uint32_t mon2_msk)
Per-port RMAC IRQ callback.
Definition ra8_rmac.h:290
@ k_ra8_rmac_mdc_default_hz
1 MHz MDC – well below the 2.5 MHz ceiling.
Definition ra8_rmac.h:106
@ k_ra8_rmac_mdc_psmcs_max
MPIC.PSMCS[22:16] is 7 bits wide.
Definition ra8_rmac.h:108
Ethernet MAC (RMAC) per-port register layout for the RA8D2.
@ k_ra8_rmac_mac_byte_count
Bytes in a unicast MAC.
ra8_rmac_pfc_group_t
PFC priority group index (MTPFC3t, t = 0..1).
@ k_ra8_rmac_pfc_group_count
RA8 rmac pfc group count.
ra8_rmac_mrafc_t
MRAFC reception address filter mode bits (HUM Ch 33.4).
@ k_ra8_rmac_ptp_filter_count
16 filter entries total.
@ k_ra8_rmac_mtffc_fcm
Frame-check mode (mCRC vs CRC).
@ k_ra8_rmac_mtffc_dpad
Disable padding.
@ k_ra8_rmac_meeec_lpitr
LPI transmit request.
ra8_rmac_pis_t
Physical interface selector for MPIC.PIS[2:0].
@ k_ra8_rmac_pis_mii
MII (000b) – internal xMII for 10/100 Mbps.
@ k_ra8_rmac_pis_gmii
GMII (010b) – internal xMII for 1 Gbps.
@ k_ra8_rmac_mac_byte_0
First byte (high octet, OUI).
@ k_ra8_rmac_mac_byte_2
RA8 rmac MAC byte 2.
@ k_ra8_rmac_mac_byte_4
RA8 rmac MAC byte 4.
@ k_ra8_rmac_mac_byte_3
RA8 rmac MAC byte 3.
@ k_ra8_rmac_mac_byte_1
RA8 rmac MAC byte 1.
@ k_ra8_rmac_mac_byte_5
Last byte (low octet).
@ k_ra8_rmac_mrgc_mpde
Magic-packet detect enable.
ra8_rmac_lsc_t
Link-speed selector for MPIC.LSC[5:3] (HUM Ch 33.4).
@ k_ra8_rmac_lsc_count
Sentinel.
ra8_rmac_pause_mode_t
Selects PFM bit in MTPFC2 – pause vs PFC frame.
@ k_ra8_rmac_pause_mode_pfc
IEEE 802.1Qbb PFC frame.
ra8_rmac_mdio_op_t
MPSM.POP[14:13] PHY MDIO operation selector.
@ k_ra8_rmac_mdio_op_c45_write
01 – C45 write.
@ k_ra8_rmac_mdio_op_c45_read
11 – C45 read.
@ k_ra8_rmac_mdio_op_c22_read
10 – C22 read.
@ k_ra8_rmac_mdio_op_c22_write
01 – C22 write.
@ k_ra8_rmac_mdio_op_c45_address
00 – C45 address.
@ k_ra8_rmac_mlbc_lbme
Loopback mode enable.
static volatile r_rmac_regs_t * ra8_rmac(ra8_rmac_port_t port)
Compile-time check that the RMAC register window matches FSP.
ra8_rmac_port_t
RMAC port index (m = 0, 1).
@ k_ra8_rmac_port_count
Number of RMAC ports.
ra8_rmac_duplex_t
Duplex selection (programmed via MPIC.PIPP / MPIC.PIP).
@ k_ra8_rmac_duplex_full
Full duplex.
@ k_ra8_rmac_mask_mtpfc_pfrt
MTPFC.PFRT[23:16].
@ k_ra8_rmac_mask_all
Wildcard write.
@ k_ra8_rmac_mask_mpsm_data
MPSM.PRD[31:16].
@ k_ra8_rmac_mask_mrfsc
16-bit frame size.
@ k_ra8_rmac_mask_mpsm_phy_reg
5-bit PHY reg/dev.
@ k_ra8_rmac_mask_mpic_lsc
MPIC.LSC[5:3].
@ k_ra8_rmac_mask_mpic_pis
MPIC.PIS[2:0].
@ k_ra8_rmac_mask_mrmac0_mau
MRMAC0.MAU valid.
@ k_ra8_rmac_mask_mpsm_op
MPSM.POP[14:13].
@ k_ra8_rmac_mask_pfc_priority
8-bit prio bitmap.
@ k_ra8_rmac_mask_mtpfc_pt
MTPFC.PT[15:0].
@ k_ra8_rmac_mask_mpic_psmcs
MPIC.PSMCS[22:16].
@ k_ra8_rmac_mask_byte
One MAC octet.
@ k_ra8_rmac_mpsm_psme
PHY Station Management Enable / busy.
@ k_ra8_rmac_mmis1_pwacs
PHY write access complete.
@ k_ra8_rmac_mmis1_paacs
PHY address access cmpl.
@ k_ra8_rmac_mmis1_pracs
PHY read access complete.
@ k_ra8_rmac_shift_mpic_pis
MPIC.PIS[2:0].
@ k_ra8_rmac_shift_byte2
Third byte position.
@ k_ra8_rmac_shift_mrfsce_max
MRFSCE.EMXS[15:0].
@ k_ra8_rmac_shift_byte1
Second byte position.
@ k_ra8_rmac_shift_mpsm_pda
MPSM.PDA[7:3].
@ k_ra8_rmac_shift_mtpfc_pfrt
MTPFC.PFRT[23:16].
@ k_ra8_rmac_shift_high16
MRMAC0.MAU low half.
@ k_ra8_rmac_shift_mrfsce_min
MRFSCE.EMNS[31:16].
@ k_ra8_rmac_shift_mpfc_val
MPFCt.PFBV[15:8].
@ k_ra8_rmac_shift_mpic_psmcs
MPIC.PSMCS[22:16].
@ k_ra8_rmac_shift_byte0
First byte position.
@ k_ra8_rmac_shift_mtpfc_pt
MTPFC.PT[15:0].
@ k_ra8_rmac_shift_mpsm_prd
MPSM.PRD[31:16].
@ k_ra8_rmac_shift_mpic_lsc
MPIC.LSC[5:3].
@ k_ra8_rmac_shift_mpsm_pra
MPSM.PRA[12:8].
@ k_ra8_rmac_shift_high24
MRMAC0.MAU high half.
@ k_ra8_rmac_shift_mpsm_pop
MPSM.POP[14:13].
@ k_ra8_rmac_shift_byte3
Fourth byte position.
Full RMAC per-port register window (HUM Ch 33.3, FSP R_RMAC0_Type).
volatile uint32_t MMID0
+0x0218 Monitor Disable 0.
volatile uint32_t MMIE2
+0x0234 Monitor Enable 2.
volatile uint32_t MMIS0
+0x0210 Monitor Status 0.
volatile uint32_t MMID2
+0x0238 Monitor Disable 2.
volatile uint32_t MTPFC
+0x0024 TX Pause/PFC Frame Cfg.
volatile uint32_t MTFFC
+0x0020 TX Frame Format Cfg.
volatile uint32_t MEEEC
+0x0184 EEE Configuration.
volatile uint32_t MRGC
+0x0080 RX General Cfg.
volatile uint32_t MEIS
+0x0200 Error IRQ Status.
volatile uint32_t MMIE0
+0x0214 Monitor Enable 0.
volatile uint32_t MPFC[k_ra8_rmac_ptp_filter_count]
+0x0100..0x013C
volatile uint32_t MRFSCP
+0x00A0 RX Frame Size Cfg P.
volatile uint32_t MRMAC1
+0x0088 RX MAC Address 1.
volatile uint32_t MEID
+0x0208 Error IRQ Disable.
volatile uint32_t MPSM
+0x0000 PHY Station Mgmt.
volatile uint32_t MLBC
+0x0188 Loopback Cfg.
volatile uint32_t MMIS2
+0x0230 Monitor Status 2.
volatile uint32_t MMIS1
+0x0220 Monitor Status 1.
volatile uint32_t MTPFC2
+0x0028 TX Pause/PFC Frame Cfg2.
volatile uint32_t MMID1
+0x0228 Monitor Disable 1.
volatile uint32_t MRAFC
+0x008C RX Address Filter Cfg.
volatile uint32_t MMIE1
+0x0224 Monitor Enable 1.
volatile uint32_t MRMAC0
+0x0084 RX MAC Address 0.
volatile uint32_t MTPFC3[k_ra8_rmac_pfc_group_count]
+0x0030..0x0034
volatile uint32_t MIOC
+0x0010 I/O Configuration.
volatile uint32_t MEIE
+0x0204 Error IRQ Enable.
volatile uint32_t MRFSCE
+0x009C RX Frame Size Cfg E.
volatile uint32_t MPIC
+0x0004 PHY Interfaces Cfg.
Per-port RMAC configuration knobs.
Definition ra8_rmac.h:120
uint32_t mon0_irq_enable
Bits to OR into MMIE0.
Definition ra8_rmac.h:123
uint32_t mon2_irq_enable
Bits to OR into MMIE2.
Definition ra8_rmac.h:125
ra8_rmac_lsc_t link_speed
Initial MPIC.LSC encoding.
Definition ra8_rmac.h:127
uint32_t eswclk_hz
Live ESWCLK frequency in Hz (input to the MDC divider).
Definition ra8_rmac.h:138
ra8_rmac_mrafc_t rx_filter
Initial MRAFC mask.
Definition ra8_rmac.h:121
ra8_rmac_duplex_t duplex
Initial MPIC.PIPP encoding.
Definition ra8_rmac.h:128
uint32_t mdc_hz
Target MDC (PHY station-management clock) frequency in Hz.
Definition ra8_rmac.h:147
uint32_t mon1_irq_enable
Bits to OR into MMIE1.
Definition ra8_rmac.h:124
ra8_rmac_pis_t phy_interface
Initial MPIC.PIS encoding.
Definition ra8_rmac.h:126
uint32_t err_irq_enable
Bits to OR into MEIE on init.
Definition ra8_rmac.h:122
Per-port runtime state.
Definition ra8_rmac.c:116
void * ctx
Opaque cookie passed to cb.
Definition ra8_rmac.c:118
uint8_t in_use
1 once init succeeds, 0 after deinit
Definition ra8_rmac.c:120
ra8_rmac_event_fn_t cb
Attached callback (nullptr).
Definition ra8_rmac.c:117
ra8_rmac_mrafc_t cached_filter
Last filter for stop/exit.
Definition ra8_rmac.c:119