33static const char*
s_tag =
"ETHGWC";
83 k_ra8_linkfix_ptr_upper_shift = 32U,
84 k_ra8_linkfix_ptr_upper_mask = 0xFFULL,
85 k_ra8_linkfix_ptr_lower_mask = 0xFFFFFFFFULL,
87 const uintptr_t head_addr = (uintptr_t)chain_head;
90 (uint8_t)((uint64_t)head_addr >> k_ra8_linkfix_ptr_upper_shift) & k_ra8_linkfix_ptr_upper_mask;
91 entry->
ptr_l = (uint32_t)head_addr & k_ra8_linkfix_ptr_lower_mask;
121 uint32_t queue_index,
128 k_ra8_gwdcc_dcp_max = 7U,
130 if (cfg->
priority > k_ra8_gwdcc_dcp_max) {
134 if (gwdcc ==
nullptr) {
173 if (gwdcc ==
nullptr) {
216 k_ra8_gwca_ring_min_depth = 2U,
217 k_ra8_gwca_ring_max_bytes = 2048U,
219 if (ring_depth < k_ra8_gwca_ring_min_depth || slot_bytes > k_ra8_gwca_ring_max_bytes) {
225 k_ra8_ds_byte_mask = 0xFFU,
226 k_ra8_ds_high_shift = 8U,
227 k_ra8_ds_high_mask = 0xFU,
229 for (uint32_t i = 0U; i < (ring_depth - 1U); ++i) {
232 chain[i].
ds_l = (uint8_t)(slot_bytes & k_ra8_ds_byte_mask);
233 chain[i].
ds_h = (uint8_t)((slot_bytes >> k_ra8_ds_high_shift) & k_ra8_ds_high_mask);
271 k_ra8_buf_ptr_upper_shift = 32U,
272 k_ra8_buf_ptr_upper_mask = 0xFFULL,
273 k_ra8_buf_ptr_lower_mask = 0xFFFFFFFFULL,
275 const uintptr_t addr = (uintptr_t)buffer;
276 desc->
ptr_h = (uint8_t)((uint64_t)addr >> k_ra8_buf_ptr_upper_shift) & k_ra8_buf_ptr_upper_mask;
277 desc->
ptr_l = (uint32_t)addr & k_ra8_buf_ptr_lower_mask;
314 if (ring_depth < 2U || slot_bytes == 0U) {
317 for (uint32_t i = 0U; i < (ring_depth - 1U); ++i) {
318 const size_t slot_offset = (size_t)i * (
size_t)slot_bytes;
352 k_ra8_gwca_max_tx_queues = 64U,
353 k_ra8_gwca_queues_per_reg = 32U,
355 if (queue_index >= k_ra8_gwca_max_tx_queues) {
358 const uintptr_t offset = (queue_index < k_ra8_gwca_queues_per_reg)
362 const uint32_t bit = 1U << (queue_index % k_ra8_gwca_queues_per_reg);
363 *gwtrc = *gwtrc | bit;
403 if (ring_depth < 2U) {
406 const uint32_t data_slot_count = ring_depth - 1U;
407 if (start_idx >= data_slot_count) {
411 for (uint32_t i = 0U; i < data_slot_count; ++i) {
412 const uint32_t slot = (start_idx + i) % data_slot_count;
413 if (chain[slot].dt == (uint8_t)match_dt) {
423 if (desc ==
nullptr) {
432 k_ra8_ptr_upper_shift = 32ULL,
433 k_ra8_ptr_low_mask = 0xFFFFFFFFULL,
435 const uint64_t addr64 =
436 ((uint64_t)desc->
ptr_h << k_ra8_ptr_upper_shift) | ((uint64_t)desc->
ptr_l & k_ra8_ptr_low_mask);
437 return (uint8_t*)(uintptr_t)addr64;
472 const uint8_t* frame,
479 if (frame_len == 0U || frame_len > slot_bytes) {
486 *tail_idx % (ring_depth - 1U),
492 if (buf ==
nullptr) {
495 (void)
memcpy(buf, frame, (
size_t)frame_len);
497 k_ra8_ds_low_byte_mask = 0xFFU,
498 k_ra8_ds_high_shift = 8U,
499 k_ra8_ds_high_nibble = 0xFU,
501 chain[slot].
ds_l = (uint8_t)(frame_len & k_ra8_ds_low_byte_mask);
502 chain[slot].
ds_h = (uint8_t)((frame_len >> k_ra8_ds_high_shift) & k_ra8_ds_high_nibble);
504 *tail_idx = (slot + 1U) % (ring_depth - 1U);
static const char * s_tag
Logging / check tag.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_no_data
No application data available (e.g.
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Ethernet CPU Agent (GWCA) driver.
Cross-TU shared surface for the ra8_eth_gwca driver split.
@ k_ra8_eth_gwca_balr_spin
GWDCCi.BALR self-clear poll budget.
uint8_t * priv_ra8_eth_gwca_decode_ptr(const ra8_gwca_basic_descriptor_t *desc)
Decode a descriptor's 40-bit PTR back to a host pointer.
ra8_err_t ra8_eth_gwca_kick_tx(uint32_t queue_index)
Kick a TX queue via GWTRC.
ra8_err_t ra8_eth_gwca_init_ring(ra8_gwca_basic_descriptor_t *chain, uint32_t ring_depth, uint32_t slot_bytes)
Initialise a descriptor chain as a ring of FEMPTY slots.
ra8_err_t ra8_eth_gwca_tx_frame(ra8_gwca_basic_descriptor_t *chain, uint32_t ring_depth, uint32_t *tail_idx, const uint8_t *frame, uint32_t frame_len, uint32_t slot_bytes)
Enqueue one frame on a TX queue's descriptor ring.
void priv_ra8_eth_gwca_set_linkfix_entry(ra8_gwca_basic_descriptor_t *entry, const void *chain_head)
Promote a LINKFIX entry from LEMPTY to LINKFIX with chain-head PTR.
static uint32_t internal_compose_gwdcc(const ra8_eth_gwca_queue_cfg_t *cfg)
Compose the GWDCC[i] 32-bit value from a queue config.
ra8_err_t ra8_eth_gwca_find_slot(const ra8_gwca_basic_descriptor_t *chain, uint32_t ring_depth, ra8_gwdcc_dt_t match_dt, uint32_t start_idx, uint32_t *out_index)
Find the next slot in a ring matching a target descriptor type.
ra8_err_t ra8_eth_gwca_reload_queue(uint32_t queue_index)
Reload a descriptor queue: pulse GWDCC[i].BALR, wait for clear.
ra8_err_t ra8_eth_gwca_configure_queue(ra8_gwca_basic_descriptor_t *linkfix_table, uint32_t queue_index, const ra8_eth_gwca_queue_cfg_t *cfg)
Wire a per-queue config into GWDCC[i] + LINKFIX[i].
ra8_err_t ra8_eth_gwca_set_descriptor_buffer(ra8_gwca_basic_descriptor_t *desc, void *buffer)
Set a descriptor's data-buffer pointer.
ra8_err_t ra8_eth_gwca_attach_buffers(ra8_gwca_basic_descriptor_t *chain, uint32_t ring_depth, uint32_t slot_bytes, uint8_t *pool)
Walk a ring and attach per-slot buffers from a static pool.
Ethernet controller base addresses for the Renesas RA8D2.
@ k_ra8_gwca_off_gwtrc0
TX Request Cfg, queues 0..31.
@ k_ra8_gwca_off_gwtrc1
TX Request Cfg, queues 32..63.
ra8_gwdcc_dt_t
Descriptor type field values (HUM Ch 34.5.1.2.2 "Descriptor Types").
@ k_ra8_gwdcc_dt_fsingle
FSINGLE – single-fragment frame.
@ k_ra8_gwdcc_dt_link
LINK – chain continuation.
@ k_ra8_gwdcc_dt_fempty
FEMPTY – empty, full frame slot.
@ k_ra8_gwdcc_dt_linkfix
LINKFIX – chain head pointer.
@ k_ra8_gwca0_base_addr
RA8 gwca0 base address.
@ k_ra8_gwdcc_dcp_shift
RA8 gwdcc dcp shift.
@ k_ra8_gwdcc_balr
RA8 gwdcc balr.
@ k_ra8_gwdcc_dqt
0 = RX queue, 1 = TX queue.
@ k_ra8_gwdcc_ede
RA8 gwdcc ede.
@ k_ra8_gwdcc_sl
RA8 gwdcc sl.
@ k_ra8_gwdcc_dcp_mask
RA8 gwdcc dcp mask.
static volatile uint32_t * ra8_gwca_gwdcc(uint32_t queue_index)
Get pointer to GWDCC[queue_index] (per-queue descriptor chain cfg).
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
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.
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_error(tag, message)
RA8 log error.
Per-queue configuration descriptor for ra8_eth_gwca_configure_queue.
bool stop_on_last
SL: stop processing on last.
bool extended
EDE: true = 16-byte extended descriptors.
bool is_tx
DQT: true = TX, false = RX.
void * chain_head
First descriptor in the queue (basic or extended).
uint8_t priority
DCP[2:0]: class priority (0..7).
8-byte basic descriptor (HUM Ch 34.5.1.2 "General Formats").
volatile uint8_t dt
20..23 Descriptor type (ra8_gwdcc_dt_t).
volatile uint8_t ds_h
8..11 Descriptor size (high nibble).
volatile uint32_t ptr_l
32..63 Pointer low 32 bits.
volatile uint8_t ds_l
0..7 Descriptor size (low byte).
volatile uint8_t ptr_h
24..31 Pointer high byte (PTR[39:32]).