ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
nx_ether_driver_c6.c
Go to the documentation of this file.
1
25
26#include "nx_ether_driver_c6.h"
27
28#include <stdint.h>
29#include <string.h>
30
31#include "nx_api.h"
32#include "nx_arp.h"
33#include "nx_ip.h"
34#include "ra8_attributes.h"
35#include "ra8_c6link.h"
36#include "ra8_esp_hosted_port.h"
37#include "tx_api.h"
38
39#ifndef NX_DISABLE_IPV4
40#include "nx_rarp.h"
41#endif
42
67
78typedef enum : uint8_t {
83
89typedef enum : uint32_t {
92
107
113typedef enum : uint16_t {
118
135
148typedef struct nx_c6_diag {
149 uint32_t tx_total;
150 uint32_t tx_err;
151 uint32_t rx_total;
152 uint32_t rx_drop;
153 uint32_t poll_total;
155
166
172static uint8_t s_c6_mtx_made;
174static uint8_t s_open;
176static uint8_t s_link_up;
180static uint8_t s_mac_user_set;
183
185static NX_IP* s_rx_ip;
187static NX_INTERFACE* s_rx_iface;
188
189void nx_ether_driver_c6_set_mac(const uint8_t mac[6])
190{
191 if (mac == NX_NULL) {
192 return;
193 }
194 (void)memcpy((void*)s_local_mac, (const void*)mac, (size_t)k_nx_c6_mac_len);
195 s_mac_user_set = 1U;
196}
197
199{
200 /* ThreadX stores the name pointer, so the buffer must outlive the mutex:
201 * a block-scope static (MISRA 8.9) with static storage duration. It is a
202 * fully-braced, non-const char array -- braced so it is not a bare string
203 * literal assigned to CHAR* (MISRA 7.4), and fully initialised so no
204 * element is left unset (MISRA 9.2/9.3). */
205 static CHAR s_mutex_name[] = {'c', '6', '_', 'w', 'i', 'r', 'e', '\0'};
206 if (link == NX_NULL) {
207 return;
208 }
209 s_c6_link = link;
210 if (s_c6_mtx_made == 0U) {
211 if (tx_mutex_create(&s_c6_mtx, s_mutex_name, TX_INHERIT) == TX_SUCCESS) {
212 s_c6_mtx_made = 1U;
213 }
214 }
215}
216
231RA8_INTERNAL static void internal_unpack_mac(const NX_INTERFACE* iface, uint8_t* mac)
232{
233 ULONG msw = iface->nx_interface_physical_address_msw;
234 ULONG lsw = iface->nx_interface_physical_address_lsw;
235 mac[k_nx_c6_mac_i0] = (uint8_t)((msw >> (ULONG)k_nx_c6_shift_8) & (ULONG)k_nx_c6_byte_mask);
236 mac[k_nx_c6_mac_i1] = (uint8_t)(msw & (ULONG)k_nx_c6_byte_mask);
237 mac[k_nx_c6_mac_i2] = (uint8_t)((lsw >> (ULONG)k_nx_c6_shift_24) & (ULONG)k_nx_c6_byte_mask);
238 mac[k_nx_c6_mac_i3] = (uint8_t)((lsw >> (ULONG)k_nx_c6_shift_16) & (ULONG)k_nx_c6_byte_mask);
239 mac[k_nx_c6_mac_i4] = (uint8_t)((lsw >> (ULONG)k_nx_c6_shift_8) & (ULONG)k_nx_c6_byte_mask);
240 mac[k_nx_c6_mac_i5] = (uint8_t)(lsw & (ULONG)k_nx_c6_byte_mask);
241}
242
257RA8_INTERNAL static void internal_stamp_iface_mac(NX_INTERFACE* iface, const uint8_t* mac)
258{
263 iface->nx_interface_physical_address_msw = msw;
264 iface->nx_interface_physical_address_lsw = lsw;
265}
266
281RA8_INTERNAL static void internal_dispatch_to_netx(NX_PACKET* pkt)
282{
283 if (pkt->nx_packet_length < (ULONG)k_nx_c6_hdr_bytes) {
284 (void)nx_packet_release(pkt);
285 s_nx_c6_diag.rx_drop += 1U;
286 return;
287 }
288 const UCHAR* p = (const UCHAR*)pkt->nx_packet_prepend_ptr;
289 const uint16_t et = (uint16_t)(((uint16_t)p[k_nx_c6_etype_off] << (uint16_t)k_nx_c6_shift_8) |
290 (uint16_t)p[(uint16_t)k_nx_c6_etype_off + 1U]);
291 pkt->nx_packet_prepend_ptr = pkt->nx_packet_prepend_ptr + (ULONG)k_nx_c6_hdr_bytes;
292 pkt->nx_packet_length = pkt->nx_packet_length - (ULONG)k_nx_c6_hdr_bytes;
293 if (et == (uint16_t)k_nx_c6_ethertype_ipv4) {
294 _nx_ip_packet_deferred_receive(s_rx_ip, pkt);
295 s_nx_c6_diag.rx_total += 1U;
296 return;
297 }
298#ifndef NX_DISABLE_IPV4
299 if (et == (uint16_t)k_nx_c6_ethertype_arp) {
300 _nx_arp_packet_deferred_receive(s_rx_ip, pkt);
301 s_nx_c6_diag.rx_total += 1U;
302 return;
303 }
304 if (et == (uint16_t)k_nx_c6_ethertype_rarp) {
305 _nx_rarp_packet_deferred_receive(s_rx_ip, pkt);
306 s_nx_c6_diag.rx_total += 1U;
307 return;
308 }
309#endif
310 (void)nx_packet_release(pkt);
311 s_nx_c6_diag.rx_drop += 1U;
312}
313
331RA8_INTERNAL static bool internal_rx_acceptable(const uint8_t* frame, uint16_t len)
332{
333 if (s_rx_ip == NX_NULL) {
334 return false;
335 }
336 if (s_open == 0U) {
337 return false;
338 }
339 if (frame == NX_NULL) {
340 return false;
341 }
342 if (len < (uint16_t)k_nx_c6_hdr_bytes) {
343 return false;
344 }
345 if (len > (uint16_t)k_nx_c6_max_frame) {
346 return false;
347 }
348 return true;
349}
350
351void nx_ether_driver_c6_rx(void* ctx, const uint8_t* frame, uint16_t len)
352{
353 /* Non-const copy of the received frame for NetX's non-const append; a
354 * block-scope static (MISRA 8.9) whose static storage duration keeps this
355 * 1514-octet buffer off the RX worker's bounded stack. */
356 static uint8_t s_rx_staging[k_nx_c6_max_frame];
357 (void)ctx;
358 if (!internal_rx_acceptable(frame, len)) {
359 s_nx_c6_diag.rx_drop += 1U;
360 return;
361 }
362 NX_PACKET_POOL* pool = s_rx_ip->nx_ip_default_packet_pool;
363 if (pool == NX_NULL) {
364 s_nx_c6_diag.rx_drop += 1U;
365 return;
366 }
367 NX_PACKET* pkt = NX_NULL;
368 if (nx_packet_allocate(pool, &pkt, NX_RECEIVE_PACKET, NX_NO_WAIT) != NX_SUCCESS) {
369 s_nx_c6_diag.rx_drop += 1U;
370 return;
371 }
372 if (pkt == NX_NULL) {
373 s_nx_c6_diag.rx_drop += 1U;
374 return;
375 }
376 /* Copy into a non-const staging buffer so the const-correct callback frame is
377 * never cast away for NetX's non-const append parameter. */
378 (void)memcpy((void*)s_rx_staging, (const void*)frame, (size_t)len);
379 /* Slide prepend by two octets so the IP header lands word-aligned once the
380 * 14-byte Ethernet header is stripped; NetX drops misaligned frames on
381 * Cortex-M parts. */
382 pkt->nx_packet_prepend_ptr = pkt->nx_packet_prepend_ptr + (ULONG)k_nx_c6_rx_align;
383 pkt->nx_packet_append_ptr = pkt->nx_packet_prepend_ptr;
384 if (nx_packet_data_append(pkt, s_rx_staging, (ULONG)len, pool, (ULONG)NX_NO_WAIT) != NX_SUCCESS) {
385 (void)nx_packet_release(pkt);
386 s_nx_c6_diag.rx_drop += 1U;
387 return;
388 }
389 pkt->nx_packet_ip_interface = s_rx_iface;
391}
392
410{
411 (void)arg;
412 while (1) {
413 /* Sequential readiness checks rather than one compound boolean, so the driver
414 * needs no MC/DC vector set for a decision that cannot be host-tested. */
415 bool pumpable = true;
416 if (s_open == 0U) {
417 pumpable = false;
418 }
419 if (s_c6_link == NX_NULL) {
420 pumpable = false;
421 }
422 if (s_c6_mtx_made == 0U) {
423 pumpable = false;
424 }
425 if (pumpable) {
427 }
428 if (pumpable) {
430 /* Pass a null stats out-pointer: ra8_c6link_poll pumps the transport the
431 * same way and simply discards the per-call counters, which this worker
432 * never reads. That drops the throwaway C23 `= {}` aggregate cppcheck
433 * 2.13 misreads under Rule 9.2, with no change in behaviour. */
434 (void)ra8_c6link_poll(s_c6_link, (uint16_t)k_nx_c6_poll_transactions, nullptr);
435 (void)tx_mutex_put(&s_c6_mtx);
436 s_nx_c6_diag.poll_total += 1U;
437 }
439 }
440}
441
456RA8_INTERNAL static void internal_spawn_rx_worker(NX_IP* ip, NX_INTERFACE* iface)
457{
458 /* Worker-private state kept at block scope (MISRA 8.9). Each retains static
459 * storage duration because ThreadX keeps a pointer to the control block, the
460 * stack and the name for the life of the thread; the spawn guard makes a
461 * second call a no-op. The name is a fully-braced, non-const char array
462 * (avoids the 7.4 string-literal-to-CHAR* assignment and any partial init). */
463 static TX_THREAD s_rx_thread;
464 alignas(8) static uint8_t s_rx_thread_stack[k_nx_c6_worker_stack_bytes];
465 static uint8_t s_rx_thread_made;
466 static CHAR s_rx_name[] = {'c', '6', '_', 'n', 'x', '_', 'r', 'x', '\0'};
467 if (s_rx_thread_made != 0U) {
468 return;
469 }
470 s_rx_ip = ip;
471 s_rx_iface = iface;
473 s_rx_name,
475 0U,
476 (VOID*)s_rx_thread_stack,
482 if (t == TX_SUCCESS) {
483 s_rx_thread_made = 1U;
484 }
485}
486
504{
505 /* A switch rather than a compound boolean, so the driver carries no MC/DC-owing
506 * decision; the two ARP commands share one arm by fall-through. */
507 switch (cmd) {
508 case NX_LINK_ARP_SEND:
509 case NX_LINK_ARP_RESPONSE_SEND:
510 return (uint16_t)k_nx_c6_ethertype_arp;
511 case NX_LINK_RARP_SEND:
512 return (uint16_t)k_nx_c6_ethertype_rarp;
513 default:
514 return (uint16_t)k_nx_c6_ethertype_ipv4;
515 }
516}
517
536RA8_INTERNAL static UCHAR
537internal_packet_to_buffer(const NX_PACKET* packet, uint8_t* dst, uint32_t cap, uint32_t* out_len)
538{
539 uint32_t total = 0U;
540 const NX_PACKET* cur = packet;
541 while (cur != NX_NULL) {
542 const uint8_t* seg = (const uint8_t*)cur->nx_packet_prepend_ptr;
543 uint32_t seg_len = (uint32_t)(cur->nx_packet_append_ptr - cur->nx_packet_prepend_ptr);
544 if ((total + seg_len) > cap) {
545 return 0U;
546 }
547 (void)memcpy((void*)(dst + total), (const void*)seg, (size_t)seg_len);
548 total += seg_len;
549#ifndef NX_DISABLE_PACKET_CHAIN
550 cur = cur->nx_packet_next;
551#else
552 cur = NX_NULL;
553#endif
554 }
555 *out_len = total;
556 return 1U;
557}
558
574RA8_INTERNAL static void internal_write_eth_header(const NX_IP_DRIVER* req)
575{
576 const ULONG msw = req->nx_ip_driver_physical_address_msw;
577 const ULONG lsw = req->nx_ip_driver_physical_address_lsw;
578 const uint16_t et = internal_ethertype_for_cmd(req->nx_ip_driver_command);
580 (uint8_t)((msw >> (ULONG)k_nx_c6_shift_8) & (ULONG)k_nx_c6_byte_mask);
583 (uint8_t)((lsw >> (ULONG)k_nx_c6_shift_24) & (ULONG)k_nx_c6_byte_mask);
585 (uint8_t)((lsw >> (ULONG)k_nx_c6_shift_16) & (ULONG)k_nx_c6_byte_mask);
587 (uint8_t)((lsw >> (ULONG)k_nx_c6_shift_8) & (ULONG)k_nx_c6_byte_mask);
589 (void)memcpy((void*)(s_tx_staging + k_nx_c6_mac_len),
590 (const void*)s_local_mac,
591 (size_t)k_nx_c6_mac_len);
593 (uint8_t)((et >> (uint16_t)k_nx_c6_shift_8) & (uint16_t)k_nx_c6_byte_mask);
594 s_tx_staging[(uint16_t)k_nx_c6_etype_off + 1U] = (uint8_t)(et & (uint16_t)k_nx_c6_byte_mask);
595}
596
612RA8_INTERNAL static void internal_handle_init(NX_IP_DRIVER* req)
613{
614 NX_INTERFACE* iface = req->nx_ip_driver_interface;
615 /* Split guards (no compound boolean) so this driver owes no MC/DC vectors. */
616 if (iface == NX_NULL) {
617 req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
618 return;
619 }
620 if (s_c6_link == NX_NULL) {
621 req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
622 return;
623 }
624 if (s_mac_user_set == 0U) {
626 }
628 iface->nx_interface_ip_mtu_size = (ULONG)k_nx_c6_mtu;
629 iface->nx_interface_address_mapping_needed = NX_TRUE;
630 s_open = 1U;
631 internal_spawn_rx_worker(req->nx_ip_driver_ptr, iface);
632 req->nx_ip_driver_status = NX_SUCCESS;
633}
634
651RA8_INTERNAL static bool internal_send_blocked(const NX_PACKET* pkt)
652{
653 bool blocked = false;
654 if (pkt == NX_NULL) {
655 blocked = true;
656 }
657 if (s_open == 0U) {
658 blocked = true;
659 }
660 if (s_link_up == 0U) {
661 blocked = true;
662 }
663 if (s_c6_mtx_made == 0U) {
664 blocked = true;
665 }
666 return blocked;
667}
668
683RA8_INTERNAL static void internal_handle_send(NX_IP_DRIVER* req)
684{
685 NX_PACKET* pkt = req->nx_ip_driver_packet;
686 if (internal_send_blocked(pkt)) {
687 if (pkt != NX_NULL) {
688 (void)nx_packet_transmit_release(pkt);
689 }
690 s_nx_c6_diag.tx_err += 1U;
691 req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
692 return;
693 }
695 uint32_t body_len = 0U;
698 (uint32_t)sizeof(s_tx_staging) - (uint32_t)k_nx_c6_hdr_bytes,
699 &body_len) == 0U) {
700 (void)nx_packet_transmit_release(pkt);
701 s_nx_c6_diag.tx_err += 1U;
702 req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
703 return;
704 }
705 uint32_t len = body_len + (uint32_t)k_nx_c6_hdr_bytes;
706 if (len < (uint32_t)k_nx_c6_min_frame) {
707 (void)memset((void*)(s_tx_staging + len), 0, (size_t)((uint32_t)k_nx_c6_min_frame - len));
708 len = (uint32_t)k_nx_c6_min_frame;
709 }
712 (void)tx_mutex_put(&s_c6_mtx);
713 (void)nx_packet_transmit_release(pkt);
714 if (err == k_ra8_ok) {
715 s_nx_c6_diag.tx_total += 1U;
716 req->nx_ip_driver_status = NX_SUCCESS;
717 } else {
718 s_nx_c6_diag.tx_err += 1U;
719 req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
720 }
721}
722
736RA8_INTERNAL static void internal_handle_get_status(NX_IP_DRIVER* req)
737{
738 if (req->nx_ip_driver_return_ptr == NX_NULL) {
739 req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
740 return;
741 }
742 *(req->nx_ip_driver_return_ptr) = (s_link_up != 0U) ? (ULONG)NX_TRUE : (ULONG)NX_FALSE;
743 req->nx_ip_driver_status = NX_SUCCESS;
744}
745
761RA8_INTERNAL static void internal_set_link_state(NX_IP_DRIVER* req, UCHAR link_up)
762{
763 s_link_up = link_up;
764 req->nx_ip_driver_status = NX_SUCCESS;
765 if (req->nx_ip_driver_interface != NX_NULL) {
766 req->nx_ip_driver_interface->nx_interface_link_up = (link_up != 0U) ? NX_TRUE : NX_FALSE;
767 }
768}
769
770void nx_ether_driver_c6(NX_IP_DRIVER* driver_req)
771{
772 if (driver_req == NX_NULL) {
773 return;
774 }
775 switch (driver_req->nx_ip_driver_command) {
776 case NX_LINK_INITIALIZE:
777 internal_handle_init(driver_req);
778 break;
779 case NX_LINK_ENABLE:
780 internal_set_link_state(driver_req, 1U);
781 break;
782 case NX_LINK_DISABLE:
783 internal_set_link_state(driver_req, 0U);
784 break;
785 case NX_LINK_PACKET_SEND:
786 case NX_LINK_PACKET_BROADCAST:
787 case NX_LINK_ARP_SEND:
788 case NX_LINK_ARP_RESPONSE_SEND:
789 case NX_LINK_RARP_SEND:
790 internal_handle_send(driver_req);
791 break;
792 case NX_LINK_GET_STATUS:
793 internal_handle_get_status(driver_req);
794 break;
795 case NX_LINK_UNINITIALIZE:
796 s_open = 0U;
797 driver_req->nx_ip_driver_status = NX_SUCCESS;
798 break;
799 case NX_LINK_MULTICAST_JOIN:
800 case NX_LINK_MULTICAST_LEAVE:
801 case NX_LINK_INTERFACE_ATTACH:
802 case NX_LINK_INTERFACE_DETACH:
803 case NX_LINK_SET_PHYSICAL_ADDRESS:
804 driver_req->nx_ip_driver_status = NX_SUCCESS;
805 break;
806 default:
807 driver_req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
808 break;
809 }
810}
static void internal_stamp_iface_mac(NX_INTERFACE *iface, const uint8_t *mac)
Write a six-octet MAC into a NetX interface's msw/lsw words.
struct nx_c6_diag nx_c6_diag_t
nx_c6_const_t
Compile-time sizes and offsets for the NetX Duo <-> C6 bridge.
@ k_nx_c6_rx_align
Prepend slide so the IP header lands aligned.
@ k_nx_c6_mac_len
Length of an Ethernet MAC, in octets.
@ k_nx_c6_mtu
IP MTU advertised on this interface.
@ k_nx_c6_max_frame
Largest 802.3 frame forwarded to the C6.
@ k_nx_c6_hdr_bytes
Ethernet II header length.
@ k_nx_c6_etype_off
Offset of the EtherType field in the header.
@ k_nx_c6_min_frame
Smallest 802.3 frame; runts are zero-padded.
static uint8_t s_local_mac[k_nx_c6_mac_len]
Station MAC stamped on transmitted frames.
void nx_ether_driver_c6_bind(ra8_c6link_t *link)
Bind an open C6 link handle to the driver and arm its mutex.
static void internal_rx_worker_entry(ULONG arg)
RX poll worker entry: pump the link so received frames reach NetX.
static void internal_spawn_rx_worker(NX_IP *ip, NX_INTERFACE *iface)
Spawn the RX poll worker thread once; idempotent on later calls.
static ra8_c6link_t * s_c6_link
Bound C6 link handle.
static void internal_handle_get_status(NX_IP_DRIVER *req)
Handle NX_LINK_GET_STATUS: report the link state NetX asks for.
static bool internal_rx_acceptable(const uint8_t *frame, uint16_t len)
Report whether a received frame is fit to deliver into NetX.
nx_c6_mask_t
Octet mask used when packing and unpacking MAC words.
@ k_nx_c6_byte_mask
Low-octet mask.
void nx_ether_driver_c6(NX_IP_DRIVER *driver_req)
NetX Duo link driver entry point for the ESP32-C6 Wi-Fi station.
static uint8_t s_mac_user_set
Non-zero once _set_mac ran.
static uint8_t s_link_up
NX_LINK_ENABLE mirror.
nx_c6_shift_t
Bit shifts for packing a six-octet MAC into NetX msw/lsw words.
@ k_nx_c6_shift_8
One-octet shift (msw octet 0, lsw octet 4).
@ k_nx_c6_shift_24
Three-octet shift (lsw octet 2).
@ k_nx_c6_shift_16
Two-octet shift (lsw octet 3).
static void internal_handle_send(NX_IP_DRIVER *req)
Handle NX_LINK_PACKET_SEND and its broadcast / ARP / RARP variants.
static uint8_t s_c6_mtx_made
Non-zero once the mutex exists.
static void internal_write_eth_header(const NX_IP_DRIVER *req)
Write the 14-byte Ethernet II header into the staging buffer.
nx_c6_ethertype_t
Ethernet II EtherType values in host byte order.
@ k_nx_c6_ethertype_rarp
RARP frame.
@ k_nx_c6_ethertype_arp
ARP frame.
@ k_nx_c6_ethertype_ipv4
IPv4 frame.
static void internal_handle_init(NX_IP_DRIVER *req)
Handle NX_LINK_INITIALIZE: adopt the MAC and spawn the RX worker.
void nx_ether_driver_c6_rx(void *ctx, const uint8_t *frame, uint16_t len)
Receive callback the application registers with ra8_c6link_open.
static void internal_set_link_state(NX_IP_DRIVER *req, UCHAR link_up)
Apply an ENABLE / DISABLE change to the link mirror and NetX iface.
static TX_MUTEX s_c6_mtx
Wire-serialisation mutex.
nx_c6_mac_idx_t
Octet indices into a six-byte MAC address.
@ k_nx_c6_mac_i3
Fourth MAC octet.
@ k_nx_c6_mac_i1
Second MAC octet.
@ k_nx_c6_mac_i5
Sixth MAC octet.
@ k_nx_c6_mac_i2
Third MAC octet.
@ k_nx_c6_mac_i0
First MAC octet.
@ k_nx_c6_mac_i4
Fifth MAC octet.
static nx_c6_diag_t s_nx_c6_diag
Diagnostic counters for the C6 NetX bridge.
static uint16_t internal_ethertype_for_cmd(UINT cmd)
Map a NetX link-send command to the EtherType its frame carries.
static bool internal_send_blocked(const NX_PACKET *pkt)
Report whether a transmit must be refused before touching the wire.
static NX_INTERFACE * s_rx_iface
Interface the receive path tags frames with.
static UCHAR internal_packet_to_buffer(const NX_PACKET *packet, uint8_t *dst, uint32_t cap, uint32_t *out_len)
Copy a (possibly chained) NX_PACKET body into a linear buffer.
static NX_IP * s_rx_ip
IP the receive path pushes frames into.
static void internal_dispatch_to_netx(NX_PACKET *pkt)
Route a received frame into NetX by EtherType, stripping the header.
static uint8_t s_tx_staging[k_nx_c6_max_frame]
Linear transmit frame buffer.
nx_c6_worker_t
Sizing constants for the RX-poll worker thread.
@ k_nx_c6_poll_transactions
One DATA_READY frame per poll.
@ k_nx_c6_worker_stack_bytes
RX worker stack, in octets.
@ k_nx_c6_worker_priority
RX worker ThreadX priority.
@ k_nx_c6_worker_period_ticks
Sleep between polls, in ticks.
static void internal_unpack_mac(const NX_INTERFACE *iface, uint8_t *mac)
Pull the six-octet station MAC out of a NetX interface descriptor.
void nx_ether_driver_c6_set_mac(const uint8_t mac[6])
Tell the driver the station MAC address to stamp on outgoing frames.
NetX Duo network driver shim that bridges onto the ESP32-C6 link.
static uint8_t s_rx_staging[k_nx_ra8_eth_max_frame]
Contiguous RX staging buffer.
static uint8_t s_rx_thread_stack[k_nx_ra8_eth_worker_stack_bytes]
static uint8_t s_rx_thread_made
static TX_THREAD s_rx_thread
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ 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
Public entry point of the RA8D2 + ThreadX port of esp-hosted.
bool ra8_esp_hosted_port_rx_pending(void)
Report whether the co-processor has queued receive data.
static bool s_open
True between a successful open and its matching close.
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.
unsigned int UINT
ThreadX-compatible unsigned int (host stub).
#define TX_SUCCESS
#define tx_thread_create
#define tx_thread_sleep
#define TX_NO_TIME_SLICE
#define tx_mutex_create
#define tx_mutex_put
char CHAR
ThreadX-compatible CHAR (host stub).
#define TX_AUTO_START
#define TX_WAIT_FOREVER
unsigned long ULONG
ThreadX-compatible unsigned long (host stub).
#define tx_mutex_get
Opaque mutex stand-in for the host build.
Opaque thread stand-in for the host build.
Bench-visible counters for the C6 NetX bridge.
uint32_t tx_total
Frames handed to ra8_c6link_eth_send.
uint32_t poll_total
ra8_c6link_poll calls the worker made.
uint32_t rx_drop
Frames dropped (pre-init, runt, no packet).
uint32_t tx_err
Transmits the facade or link rejected.
uint32_t rx_total
Frames pushed into NetX from the receive path.