47#ifndef NX_DISABLE_IPV4
60typedef enum : uint16_t {
86typedef enum : uint8_t {
105typedef enum : uint8_t {
117typedef enum : uint8_t {
131typedef enum : uint8_t {
226 if (mac ==
nullptr) {
293typedef enum : uint32_t {
343 static CHAR s_thread_name[] = {
'r',
'a',
'8',
'_',
'e',
't',
'h',
'_',
'r',
'x',
'\0'};
371typedef enum : uint16_t {
378typedef enum : uint16_t {
406 (void)nx_packet_release(pkt);
409 const UCHAR* p = (
const UCHAR*)pkt->nx_packet_prepend_ptr;
415 _nx_ip_packet_deferred_receive(
s_rx_ip, pkt);
418#ifndef NX_DISABLE_IPV4
420 _nx_arp_packet_deferred_receive(
s_rx_ip, pkt);
424 _nx_rarp_packet_deferred_receive(
s_rx_ip, pkt);
428 (void)nx_packet_release(pkt);
447 NX_PACKET_POOL* pool =
s_rx_ip->nx_ip_default_packet_pool;
448 if (pool == NX_NULL) {
460 NX_PACKET* pkt = NX_NULL;
461 UINT a = nx_packet_allocate(pool, &pkt, NX_RECEIVE_PACKET, NX_NO_WAIT);
462 if (a != NX_SUCCESS) {
465 if (pkt == NX_NULL) {
472 pkt->nx_packet_prepend_ptr = pkt->nx_packet_prepend_ptr + 2U;
473 pkt->nx_packet_append_ptr = pkt->nx_packet_prepend_ptr;
475 if (app != NX_SUCCESS) {
476 (void)nx_packet_release(pkt);
516 ULONG msw = iface->nx_interface_physical_address_msw;
517 ULONG lsw = iface->nx_interface_physical_address_lsw;
535 const NX_PACKET* cur = packet;
536 while (cur != NX_NULL) {
537 const uint8_t* seg = (
const uint8_t*)cur->nx_packet_prepend_ptr;
538 uint32_t seg_len = (uint32_t)(cur->nx_packet_append_ptr - cur->nx_packet_prepend_ptr);
539 if ((total + seg_len) > cap) {
543 (void)
memcpy((
void*)(dst + total), (
const void*)seg, (
size_t)seg_len);
545#ifndef NX_DISABLE_PACKET_CHAIN
546 cur = cur->nx_packet_next;
558 NX_INTERFACE* iface = req->nx_ip_driver_interface;
559 if (iface == NX_NULL) {
561 req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
583 iface->nx_interface_physical_address_msw = msw;
584 iface->nx_interface_physical_address_lsw = lsw;
593 .mac_address = {0U, 0U, 0U, 0U, 0U, 0U},
595 .num_tx_descriptors = 0U,
596 .num_rx_descriptors = 0U,
604 req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
610 iface->nx_interface_address_mapping_needed = NX_TRUE;
613 req->nx_ip_driver_status = NX_SUCCESS;
624 req->nx_ip_driver_status = NX_SUCCESS;
649 if (cmd == NX_LINK_ARP_SEND) {
652 if (cmd == NX_LINK_ARP_RESPONSE_SEND) {
655 if (cmd == NX_LINK_RARP_SEND) {
683 NX_PACKET* pkt = req->nx_ip_driver_packet;
685 if (pkt != NX_NULL) {
686 (void)nx_packet_transmit_release(pkt);
688 req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
698 const ULONG msw = req->nx_ip_driver_physical_address_msw;
699 const ULONG lsw = req->nx_ip_driver_physical_address_lsw;
721 uint32_t body_len = 0U;
726 (void)nx_packet_transmit_release(pkt);
727 req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
739 (void)nx_packet_transmit_release(pkt);
740 req->nx_ip_driver_status = (err ==
k_ra8_ok) ? (
UINT)NX_SUCCESS : (
UINT)NX_NOT_SUCCESSFUL;
766 NX_IP* ip_ptr = req->nx_ip_driver_ptr;
768 req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
774 NX_PACKET_POOL* pool = ip_ptr->nx_ip_default_packet_pool;
775 if (pool == NX_NULL) {
776 req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
788 NX_PACKET* pkt = NX_NULL;
789 UINT a = nx_packet_allocate(pool, &pkt, NX_RECEIVE_PACKET, NX_NO_WAIT);
790 if (a != NX_SUCCESS || pkt == NX_NULL) {
796 if (app != NX_SUCCESS) {
797 (void)nx_packet_release(pkt);
800 pkt->nx_packet_ip_interface = req->nx_ip_driver_interface;
803 req->nx_ip_driver_status = NX_SUCCESS;
809 if (req->nx_ip_driver_return_ptr == NX_NULL) {
810 req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
813 ra8_eth_link_t link = {.link_up = 0U, .speed_mbps = 0U, .full_duplex = 0U, .bmsr = 0U};
815 *(req->nx_ip_driver_return_ptr) = (
ULONG)NX_FALSE;
816 req->nx_ip_driver_status = NX_SUCCESS;
821 *(req->nx_ip_driver_return_ptr) = (
ULONG)NX_FALSE;
822 req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
825 *(req->nx_ip_driver_return_ptr) = (link.
link_up != 0U) ? (
ULONG)NX_TRUE : (
ULONG)NX_FALSE;
826 req->nx_ip_driver_status = NX_SUCCESS;
854 driver_req->nx_ip_driver_status = NX_SUCCESS;
855 if (driver_req->nx_ip_driver_interface != NX_NULL) {
856 driver_req->nx_ip_driver_interface->nx_interface_link_up = (link_up != 0U) ? NX_TRUE : NX_FALSE;
865 if (driver_req == NX_NULL) {
872 switch (driver_req->nx_ip_driver_command) {
873 case NX_LINK_INITIALIZE:
876 g_nx_ether_diag.init_last_status = (uint32_t)driver_req->nx_ip_driver_status;
883 case NX_LINK_DISABLE:
887 case NX_LINK_PACKET_SEND:
888 case NX_LINK_PACKET_BROADCAST:
889 case NX_LINK_ARP_SEND:
890 case NX_LINK_ARP_RESPONSE_SEND:
891 case NX_LINK_RARP_SEND:
894 g_nx_ether_diag.send_last_status = (uint32_t)driver_req->nx_ip_driver_status;
896 case NX_LINK_DEFERRED_PROCESSING:
900 case NX_LINK_GET_STATUS:
904 case NX_LINK_UNINITIALIZE:
907 case NX_LINK_MULTICAST_JOIN:
908 case NX_LINK_MULTICAST_LEAVE:
909 case NX_LINK_INTERFACE_ATTACH:
910 case NX_LINK_INTERFACE_DETACH:
911 case NX_LINK_SET_PHYSICAL_ADDRESS:
912 driver_req->nx_ip_driver_status = NX_SUCCESS;
915 driver_req->nx_ip_driver_status = NX_NOT_SUCCESSFUL;
static CHAR s_thread_name[]
static uint8_t s_local_mac[k_nx_c6_mac_len]
Station MAC stamped on transmitted frames.
static void internal_rx_worker_entry(ULONG arg)
RX poll worker entry: pump the link so received frames reach NetX.
static uint8_t s_link_up
NX_LINK_ENABLE mirror.
static NX_INTERFACE * s_rx_iface
Interface the receive path tags frames with.
static NX_IP * s_rx_ip
IP the receive path pushes frames into.
static uint8_t s_tx_staging[k_nx_c6_max_frame]
Linear transmit frame buffer.
@ k_nx_ra8_eth_etype_off
Nx RA8 Ethernet etype off.
@ k_nx_ra8_eth_hdr_bytes
Nx RA8 Ethernet hdr bytes.
static void internal_handle_deferred_rx(NX_IP_DRIVER *req)
Handle NX_LINK_DEFERRED_PROCESSING: drain RX into NetX.
static void internal_rx_worker_entry(ULONG arg)
RX-poll worker entry.
nx_ra8_eth_worker_t
Sizing constants for the RX-poll worker thread.
@ k_nx_ra8_eth_worker_priority
Nx RA8 Ethernet worker priority.
@ k_nx_ra8_eth_worker_period_ticks
Nx RA8 Ethernet worker period ticks.
@ k_nx_ra8_eth_worker_stack_bytes
Nx RA8 Ethernet worker stack bytes.
static void internal_spawn_rx_worker(NX_IP *ip, NX_INTERFACE *iface)
Spawn the RX-poll worker thread once, idempotent.
static void internal_handle_get_status(NX_IP_DRIVER *req)
static void internal_handle_uninit(NX_IP_DRIVER *req)
nx_ra8_eth_ethertype_t
Ethernet II EtherType constants in host byte order.
@ k_nx_ra8_eth_ethertype_rarp
RARP frame.
@ k_nx_ra8_eth_ethertype_arp
ARP frame.
@ k_nx_ra8_eth_ethertype_ipv4
IPv4 frame.
@ k_nx_ra8_eth_ethertype_ipv6
IPv6 frame.
nx_ra8_eth_hdr_offset_t
Byte offsets of the fields in the 14-byte Ethernet header that internal_handle_send stages into s_tx_...
@ k_nx_ra8_eth_hdr_src_mac_byte3
Source MAC octet 3.
@ k_nx_ra8_eth_hdr_ethertype_lo
EtherType low octet.
@ k_nx_ra8_eth_hdr_ethertype_hi
EtherType high octet.
@ k_nx_ra8_eth_hdr_src_mac_byte1
Source MAC octet 1.
@ k_nx_ra8_eth_hdr_src_mac_byte4
Source MAC octet 4.
@ k_nx_ra8_eth_hdr_src_mac_byte5
Source MAC octet 5.
static void internal_set_link_state(NX_IP_DRIVER *driver_req, UCHAR link_up)
Apply an ENABLE/DISABLE state change to the link mirror and NetX iface.
nx_ra8_eth_constants_t
Compile-time constants for the NetX Duo <-> ra8_eth bridge.
@ k_nx_ra8_eth_max_frame
Largest 802.3 frame we forward.
@ k_nx_ra8_eth_mtu
Capped MTU.
@ k_nx_ra8_eth_min_frame
Smallest 802.3 frame.
@ k_nx_ra8_eth_phys_addr_len
Reported to NX_LINK_FACTORY_*.
@ k_nx_ra8_eth_phys_msw_shift
Bytes-per-byte shift for MAC msw.
@ k_nx_ra8_eth_mac_len
Length of an Ethernet MAC.
static void internal_rx_drain(void)
Drain the GWCA RX ring and push every frame into NetX.
static uint8_t s_rx_staging[k_nx_ra8_eth_max_frame]
Contiguous RX staging buffer.
static void internal_handle_send(NX_IP_DRIVER *req)
Handle NX_LINK_PACKET_SEND / ARP_SEND / ARP_RESPONSE_SEND / RARP_SEND.
nx_ra8_eth_byte_mask_t
Low-octet mask used when extracting bytes from packed words.
@ k_nx_ra8_eth_byte_mask
Keep the least-significant octet.
static uint8_t s_rx_thread_stack[k_nx_ra8_eth_worker_stack_bytes]
static void internal_handle_init(NX_IP_DRIVER *req)
nx_ra8_eth_mac_byte_idx_t
Indices into the local 6-byte MAC array.
@ k_nx_ra8_eth_mac_byte_2
Nx RA8 Ethernet MAC byte 2.
@ k_nx_ra8_eth_mac_byte_3
Nx RA8 Ethernet MAC byte 3.
@ k_nx_ra8_eth_mac_byte_4
Nx RA8 Ethernet MAC byte 4.
@ k_nx_ra8_eth_mac_byte_0
Nx RA8 Ethernet MAC byte 0.
@ k_nx_ra8_eth_mac_byte_5
Nx RA8 Ethernet MAC byte 5.
@ k_nx_ra8_eth_mac_byte_1
Nx RA8 Ethernet MAC byte 1.
static UCHAR s_ra8_eth_open
Latched flag: has ra8_eth_open been called for this interface?
static uint16_t internal_ethertype_for_cmd(UINT cmd)
Pick the ethernet ethertype for a NetX driver SEND command.
nx_ra8_eth_mac_word_shift_t
Bit shifts that pack the 6 MAC bytes into NetX's msw/lsw words.
@ k_nx_ra8_eth_lsw_shift_byte3
Nx RA8 Ethernet lsw shift byte3.
@ k_nx_ra8_eth_lsw_shift_byte2
Nx RA8 Ethernet lsw shift byte2.
@ k_nx_ra8_eth_lsw_shift_byte4
Nx RA8 Ethernet lsw shift byte4.
@ k_nx_ra8_eth_lsw_shift_byte5
Nx RA8 Ethernet lsw shift byte5.
@ k_nx_ra8_eth_msw_shift_byte0
Nx RA8 Ethernet msw shift byte0.
static UCHAR internal_packet_to_buffer(const NX_PACKET *packet, uint8_t *dst, uint32_t cap, uint32_t *out_len)
static uint8_t s_rx_thread_made
void nx_ether_driver_ra8_eth_set_mac(const uint8_t mac[6])
Install the local MAC address used by the driver at NX_LINK_INITIALIZE.
static void internal_dispatch_to_netx(NX_PACKET *pkt)
Dispatch a received frame into NetX by ethertype.
static TX_THREAD s_rx_thread
void nx_ether_driver_ra8_eth(NX_IP_DRIVER *driver_req)
NetX Duo network-driver entry point bridging onto ra8_eth_*.
static uint8_t s_local_mac_user_set
Flag indicating whether the app supplied a MAC via the pre-init seam.
volatile nx_ether_diag_t g_nx_ether_diag
Diagnostic counters readable via JLink.
static void internal_unpack_mac(const NX_INTERFACE *iface, uint8_t *mac)
NetX Duo network driver shim that bridges onto the RA8 ra8_eth HAL.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Error Code Definitions for ra8-firmware.
@ 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 Switch Module (ESWM) + frame TX/RX driver.
ra8_err_t ra8_eth_close(void)
Close the NIC: gate clocks and idle the descriptor rings.
ra8_err_t ra8_eth_write(const uint8_t *buf, uint32_t len)
Transmit a frame through the GWCA TX queue.
ra8_err_t ra8_eth_link_status(ra8_eth_link_t *out_status)
Query the PHY link state via MIIM (RMAC MDIO Clause-22).
ra8_err_t ra8_eth_open(const ra8_eth_cfg_t *cfg)
Open the NIC: bring up the controller stack and the descriptor rings.
ra8_err_t ra8_eth_read(uint8_t *buf, uint32_t max_len, uint32_t *got_len)
Pop the next received frame from the RX descriptor ring.
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).
char CHAR
ThreadX-compatible CHAR (host stub).
unsigned long ULONG
ThreadX-compatible unsigned long (host stub).
Opaque thread stand-in for the host build.
Bench-readable diagnostic counters for the NetX link driver.
uint32_t send_last_status
Last NetX status internal_handle_send set.
uint32_t last_cmd
Most recent driver command code.
uint32_t rx_total
NX_LINK_DEFERRED_PROCESSING dispatches.
uint32_t enable_last_link_up
1 = last set_link_state was UP.
uint32_t init_iface_null_hits
Times INITIALIZE saw a NULL interface.
uint32_t init_total
NX_LINK_INITIALIZE dispatches.
uint32_t enable_total
NX_LINK_ENABLE dispatches.
uint32_t init_ra8_eth_open_err
Last ra8_eth_open return code.
uint32_t send_total
NX_LINK_PACKET_SEND/_BROADCAST dispatches.
uint32_t init_last_status
Last NetX status internal_handle_init set.
uint32_t dispatch_total
total dispatches into the driver.
uint32_t status_total
NX_LINK_GET_STATUS dispatches.
Per-channel NIC configuration.
uint8_t mac_address[6]
Local MAC address (octets 0..5).
uint8_t link_up
1 if BMSR.LINK_STATUS asserted, else 0.