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

NetX Duo network driver bound to the ESP32-C6 link (ra8_c6link). More...

#include "nx_ether_driver_c6.h"
#include <stdint.h>
#include <string.h>
#include "nx_api.h"
#include "nx_arp.h"
#include "nx_ip.h"
#include "ra8_attributes.h"
#include "ra8_c6link.h"
#include "ra8_esp_hosted_port.h"
#include "tx_api.h"
#include "nx_rarp.h"
Include dependency graph for nx_ether_driver_c6.c:

Go to the source code of this file.

Data Structures

struct  nx_c6_diag
 Bench-visible counters for the C6 NetX bridge. More...

Typedefs

typedef struct nx_c6_diag nx_c6_diag_t

Enumerations

enum  nx_c6_const_t : uint16_t {
  k_nx_c6_max_frame = 1514U ,
  k_nx_c6_min_frame = 60U ,
  k_nx_c6_mac_len = 6U ,
  k_nx_c6_hdr_bytes = 14U ,
  k_nx_c6_etype_off = 12U ,
  k_nx_c6_mtu = 1500U ,
  k_nx_c6_rx_align = 2U
}
 Compile-time sizes and offsets for the NetX Duo <-> C6 bridge. More...
enum  nx_c6_shift_t : uint8_t {
  k_nx_c6_shift_8 = 8U ,
  k_nx_c6_shift_16 = 16U ,
  k_nx_c6_shift_24 = 24U
}
 Bit shifts for packing a six-octet MAC into NetX msw/lsw words. More...
enum  nx_c6_mask_t : uint32_t { k_nx_c6_byte_mask = 0xFFU }
 Octet mask used when packing and unpacking MAC words. More...
enum  nx_c6_mac_idx_t : uint8_t {
  k_nx_c6_mac_i0 = 0U ,
  k_nx_c6_mac_i1 = 1U ,
  k_nx_c6_mac_i2 = 2U ,
  k_nx_c6_mac_i3 = 3U ,
  k_nx_c6_mac_i4 = 4U ,
  k_nx_c6_mac_i5 = 5U
}
 Octet indices into a six-byte MAC address. More...
enum  nx_c6_ethertype_t : uint16_t {
  k_nx_c6_ethertype_ipv4 = 0x0800U ,
  k_nx_c6_ethertype_arp = 0x0806U ,
  k_nx_c6_ethertype_rarp = 0x8035U
}
 Ethernet II EtherType values in host byte order. More...
enum  nx_c6_worker_t : uint32_t {
  k_nx_c6_worker_stack_bytes = 4096U ,
  k_nx_c6_worker_priority = 4U ,
  k_nx_c6_worker_period_ticks = 1U ,
  k_nx_c6_poll_transactions = 1U
}
 Sizing constants for the RX-poll worker thread. More...

Functions

void nx_ether_driver_c6_set_mac (const uint8_t mac[6])
 Tell the driver the station MAC address to stamp on outgoing 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_unpack_mac (const NX_INTERFACE *iface, uint8_t *mac)
 Pull the six-octet station MAC out of a NetX interface descriptor.
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.
static void internal_dispatch_to_netx (NX_PACKET *pkt)
 Route a received frame into NetX by EtherType, stripping the header.
static bool internal_rx_acceptable (const uint8_t *frame, uint16_t len)
 Report whether a received frame is fit to deliver into NetX.
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_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 uint16_t internal_ethertype_for_cmd (UINT cmd)
 Map a NetX link-send command to the EtherType its frame carries.
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 void internal_write_eth_header (const NX_IP_DRIVER *req)
 Write the 14-byte Ethernet II header into the staging buffer.
static void internal_handle_init (NX_IP_DRIVER *req)
 Handle NX_LINK_INITIALIZE: adopt the MAC and spawn the RX worker.
static bool internal_send_blocked (const NX_PACKET *pkt)
 Report whether a transmit must be refused before touching the wire.
static void internal_handle_send (NX_IP_DRIVER *req)
 Handle NX_LINK_PACKET_SEND and its broadcast / ARP / RARP variants.
static void internal_handle_get_status (NX_IP_DRIVER *req)
 Handle NX_LINK_GET_STATUS: report the link state NetX asks for.
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.
void nx_ether_driver_c6 (NX_IP_DRIVER *driver_req)
 NetX Duo link driver entry point for the ESP32-C6 Wi-Fi station.

Variables

static nx_c6_diag_t s_nx_c6_diag
 Diagnostic counters for the C6 NetX bridge.
static ra8_c6link_ts_c6_link
 Bound C6 link handle.
static TX_MUTEX s_c6_mtx
 Wire-serialisation mutex.
static uint8_t s_c6_mtx_made
 Non-zero once the mutex exists.
static uint8_t s_open
 Non-zero after NX_LINK_INITIALIZE.
static uint8_t s_link_up
 NX_LINK_ENABLE mirror.
static uint8_t s_local_mac [k_nx_c6_mac_len]
 Station MAC stamped on transmitted frames.
static uint8_t s_mac_user_set
 Non-zero once _set_mac ran.
static uint8_t s_tx_staging [k_nx_c6_max_frame]
 Linear transmit frame buffer.
static NX_IP * s_rx_ip
 IP the receive path pushes frames into.
static NX_INTERFACE * s_rx_iface
 Interface the receive path tags frames with.

Detailed Description

NetX Duo network driver bound to the ESP32-C6 link (ra8_c6link).

Tag
[Ring 4 / PAL] {World: NS}

Implements nx_ether_driver_c6 – the single NetX Duo link-driver entry point for the wireless station – plus the three helpers the application wires up around it (_bind for the open link handle, _set_mac for the station address, _rx for the facade's receive callback).

The C6 link is a polled, single-consumer SPI transport, so all wire access is serialised behind s_c6_mtx: transmit takes it around ra8_c6link_eth_send, and the RX poll worker takes it around ra8_c6link_poll. The facade delivers received frames synchronously inside that poll (or inside a transmit pump) through nx_ether_driver_c6_rx, so the receive callback never re-enters the wire and never needs the mutex itself – the thread that calls the facade already holds it.

Definition in file nx_ether_driver_c6.c.

Typedef Documentation

◆ nx_c6_diag_t

typedef struct nx_c6_diag nx_c6_diag_t

Enumeration Type Documentation

◆ nx_c6_const_t

enum nx_c6_const_t : uint16_t

Compile-time sizes and offsets for the NetX Duo <-> C6 bridge.

The staging buffer covers the largest untagged 802.3 frame this driver ever hands to ra8_c6link_eth_send (1514 payload octets, no FCS), which is well within the facade's k_ra8_c6link_max_payload. The header and EtherType offsets are the fixed layout of an Ethernet II frame.

Invariant
k_nx_c6_max_frame does not exceed k_ra8_c6link_max_payload.
k_nx_c6_hdr_bytes is the Ethernet II header length.
Since
0.1.0
Enumerator
k_nx_c6_max_frame 

Largest 802.3 frame forwarded to the C6.

k_nx_c6_min_frame 

Smallest 802.3 frame; runts are zero-padded.

k_nx_c6_mac_len 

Length of an Ethernet MAC, in octets.

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_mtu 

IP MTU advertised on this interface.

k_nx_c6_rx_align 

Prepend slide so the IP header lands aligned.

Definition at line 58 of file nx_ether_driver_c6.c.

◆ nx_c6_ethertype_t

enum nx_c6_ethertype_t : uint16_t

Ethernet II EtherType values in host byte order.

Since
0.1.0
Enumerator
k_nx_c6_ethertype_ipv4 

IPv4 frame.

k_nx_c6_ethertype_arp 

ARP frame.

k_nx_c6_ethertype_rarp 

RARP frame.

Definition at line 113 of file nx_ether_driver_c6.c.

◆ nx_c6_mac_idx_t

enum nx_c6_mac_idx_t : uint8_t

Octet indices into a six-byte MAC address.

Named so the MAC packing / unpacking carries no bare subscripts.

Since
0.1.0
Enumerator
k_nx_c6_mac_i0 

First MAC octet.

k_nx_c6_mac_i1 

Second MAC octet.

k_nx_c6_mac_i2 

Third MAC octet.

k_nx_c6_mac_i3 

Fourth MAC octet.

k_nx_c6_mac_i4 

Fifth MAC octet.

k_nx_c6_mac_i5 

Sixth MAC octet.

Definition at line 99 of file nx_ether_driver_c6.c.

◆ nx_c6_mask_t

enum nx_c6_mask_t : uint32_t

Octet mask used when packing and unpacking MAC words.

Since
0.1.0
Enumerator
k_nx_c6_byte_mask 

Low-octet mask.

Definition at line 89 of file nx_ether_driver_c6.c.

◆ nx_c6_shift_t

enum nx_c6_shift_t : uint8_t

Bit shifts for packing a six-octet MAC into NetX msw/lsw words.

NetX stores a MAC as a 16-bit most-significant word (octets 0..1) and a 32-bit least-significant word (octets 2..5). These are the shifts that place each octet, matched by ::nx_c6_byte_mask.

Since
0.1.0
Enumerator
k_nx_c6_shift_8 

One-octet shift (msw octet 0, lsw octet 4).

k_nx_c6_shift_16 

Two-octet shift (lsw octet 3).

k_nx_c6_shift_24 

Three-octet shift (lsw octet 2).

Definition at line 78 of file nx_ether_driver_c6.c.

◆ nx_c6_worker_t

enum nx_c6_worker_t : uint32_t

Sizing constants for the RX-poll worker thread.

Without an interrupt from the SPI transport, NetX is never told a frame arrived. A dedicated ThreadX worker pumps ra8_c6link_poll at a short cadence; the facade's receive callback fires from inside that poll.

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

k_nx_c6_poll_transactions 

One DATA_READY frame per poll.

Definition at line 129 of file nx_ether_driver_c6.c.

Function Documentation

◆ internal_dispatch_to_netx()

void internal_dispatch_to_netx ( NX_PACKET * pkt)
static

Route a received frame into NetX by EtherType, stripping the header.

Reads the EtherType, strips the 14-byte Ethernet header, then hands the packet to the matching deferred-receive path (IP, ARP or RARP). An unknown EtherType or a runt frame is released rather than leaked.

Parameters
[in,out]pktPacket holding the raw Ethernet frame; must be non-null.
Returns
Nothing; pkt is consumed (queued to NetX) or released.
Precondition
s_rx_ip and s_rx_iface have been populated by INITIALIZE.
pkt holds a frame whose length includes the Ethernet header.
Postcondition
A well-formed frame is owned by NetX; anything else is released.
s_nx_c6_diag rx counters reflect the outcome.
Note
Not thread-safe; runs with the wire mutex held on the calling thread.
Since
0.1.0

Definition at line 281 of file nx_ether_driver_c6.c.

References k_nx_c6_ethertype_arp, k_nx_c6_ethertype_ipv4, k_nx_c6_ethertype_rarp, k_nx_c6_etype_off, k_nx_c6_hdr_bytes, k_nx_c6_shift_8, RA8_INTERNAL, s_nx_c6_diag, and s_rx_ip.

Referenced by nx_ether_driver_c6_rx().

◆ internal_ethertype_for_cmd()

uint16_t internal_ethertype_for_cmd ( UINT cmd)
static

Map a NetX link-send command to the EtherType its frame carries.

ARP and RARP sends carry their own EtherTypes; everything else this driver forwards is IPv4.

Parameters
[in]cmdNetX nx_ip_driver_command for a send.
Returns
uint16_t The Ethernet II EtherType in host byte order.
Return values
0x0806cmd is an ARP send or ARP response.
0x8035cmd is a RARP send.
0x0800Any other send (IPv4 and broadcast).
Precondition
cmd is one of the NX_LINK_*_SEND commands.
The caller writes the result into the frame header.
Postcondition
The returned value names the frame's protocol.
No state is modified.
Note
Pure; safe from any thread.
Since
0.1.0

Definition at line 503 of file nx_ether_driver_c6.c.

References k_nx_c6_ethertype_arp, k_nx_c6_ethertype_ipv4, k_nx_c6_ethertype_rarp, and RA8_INTERNAL.

Referenced by internal_write_eth_header().

◆ internal_handle_get_status()

void internal_handle_get_status ( NX_IP_DRIVER * req)
static

Handle NX_LINK_GET_STATUS: report the link state NetX asks for.

The C6 has no PHY status register to poll; association is reflected through NX_LINK_ENABLE, so this returns the s_link_up mirror.

Parameters
[in,out]reqNetX driver request with a return pointer; must be non-null.
Returns
Nothing; the state is written through req->nx_ip_driver_return_ptr.
Precondition
req->nx_ip_driver_return_ptr is non-null for a meaningful answer.
s_link_up reflects the most recent ENABLE / DISABLE.
Postcondition
The return pointer holds NX_TRUE or NX_FALSE.
req->nx_ip_driver_status names success or the null-pointer failure.
Note
Not thread-safe; NetX calls it on the IP thread.
Since
0.1.0

Definition at line 736 of file nx_ether_driver_c6.c.

References RA8_INTERNAL, and s_link_up.

Referenced by nx_ether_driver_c6().

◆ internal_handle_init()

void internal_handle_init ( NX_IP_DRIVER * req)
static

Handle NX_LINK_INITIALIZE: adopt the MAC and spawn the RX worker.

Prefers the app-supplied MAC (nx_ether_driver_c6_set_mac) over the interface's, stamps it back into the interface, advertises the MTU, marks the link open and starts the RX poll worker. The C6 link is already open, so no hardware is brought up here.

Parameters
[in,out]reqNetX driver request; must be non-null.
Returns
Nothing; the result is written to req->nx_ip_driver_status.
Precondition
nx_ether_driver_c6_bind has run with an open link.
req->nx_ip_driver_interface names the interface being initialised.
Postcondition
On success s_open is set and the RX worker is running.
On failure req->nx_ip_driver_status is NX_NOT_SUCCESSFUL.
Note
Not thread-safe; NetX issues INITIALIZE once, on the IP thread.
Since
0.1.0

Definition at line 612 of file nx_ether_driver_c6.c.

References internal_spawn_rx_worker(), internal_stamp_iface_mac(), internal_unpack_mac(), k_nx_c6_mtu, RA8_INTERNAL, s_c6_link, s_local_mac, s_mac_user_set, and s_open.

Referenced by nx_ether_driver_c6().

◆ internal_handle_send()

void internal_handle_send ( NX_IP_DRIVER * req)
static

Handle NX_LINK_PACKET_SEND and its broadcast / ARP / RARP variants.

Builds the Ethernet header, linearises the packet body after it, zero-pads a runt to the 802.3 minimum, and forwards the whole frame to ra8_c6link_eth_send under the wire mutex. The packet is always released.

Parameters
[in,out]reqNetX driver request carrying the packet; must be non-null.
Returns
Nothing; the result is written to req->nx_ip_driver_status.
Precondition
s_open and s_link_up are set and the mutex exists.
req->nx_ip_driver_packet is a valid packet chain.
Postcondition
The packet is released exactly once via nx_packet_transmit_release.
s_nx_c6_diag tx counters and the request status reflect the outcome.
Note
Not thread-safe against itself; NetX serialises sends on the IP thread.
Since
0.1.0

Definition at line 683 of file nx_ether_driver_c6.c.

References internal_packet_to_buffer(), internal_send_blocked(), internal_write_eth_header(), k_nx_c6_hdr_bytes, k_nx_c6_min_frame, k_ra8_ok, memset(), ra8_c6link_eth_send(), RA8_INTERNAL, s_c6_link, s_c6_mtx, s_nx_c6_diag, s_tx_staging, tx_mutex_get, tx_mutex_put, and TX_WAIT_FOREVER.

Referenced by nx_ether_driver_c6().

◆ internal_packet_to_buffer()

UCHAR internal_packet_to_buffer ( const NX_PACKET * packet,
uint8_t * dst,
uint32_t cap,
uint32_t * out_len )
static

Copy a (possibly chained) NX_PACKET body into a linear buffer.

Walks the packet chain, concatenating each fragment into dst; it refuses rather than overrun when the total exceeds cap.

Parameters
[in]packetPacket chain to flatten; must be non-null.
[out]dstDestination buffer; must be non-null.
[in]capCapacity of dst in octets.
[out]out_lenTotal octets written on success; must be non-null.
Returns
UCHAR Non-zero on success, zero when the body did not fit.
Return values
1The whole body was copied and out_len is set.
0The body exceeded cap; dst is partially written.
Precondition
dst has room for cap octets.
packet fragments are valid prepend..append ranges.
Postcondition
On success dst holds the frame body and out_len its length.
No packet is released; ownership stays with the caller.
Note
Not thread-safe with respect to dst (the shared staging buffer).
Since
0.1.0

Definition at line 537 of file nx_ether_driver_c6.c.

References memcpy().

Referenced by internal_handle_send().

◆ internal_rx_acceptable()

bool internal_rx_acceptable ( const uint8_t * frame,
uint16_t len )
static

Report whether a received frame is fit to deliver into NetX.

Sequential checks (no compound boolean) so this not-host-testable driver owes no MC/DC vector set: the interface must be up, the frame present, and its length between the Ethernet header size and the staging buffer.

Parameters
[in]frameThe frame the facade handed the receive callback; may be null.
[in]lenIts length in octets.
Returns
bool True when the frame may be delivered.
Return values
trueThe interface is up and frame / len are in range.
falseThe interface is not up or the frame is null / out of range.
Precondition
The driver statics reflect the current link state.
len is the length the facade reported for frame.
Postcondition
No state is modified.
The caller drops and counts the frame when this returns false.
Note
Not thread-safe; called only from the receive callback.
Since
0.1.0

Definition at line 331 of file nx_ether_driver_c6.c.

References k_nx_c6_hdr_bytes, k_nx_c6_max_frame, RA8_INTERNAL, s_open, and s_rx_ip.

Referenced by nx_ether_driver_c6_rx().

◆ internal_rx_worker_entry()

void internal_rx_worker_entry ( ULONG arg)
static

RX poll worker entry: pump the link so received frames reach NetX.

The SPI transport raises no interrupt, so this thread calls ra8_c6link_poll under the wire mutex only while the held DATA_READY signal says receive work exists; the facade fires nx_ether_driver_c6_rx from inside that poll. One transaction is clocked per wake and the worker sleeps one tick between checks so an idle C6 never blocks outbound traffic.

Parameters
[in]argThreadX entry argument; unused.
Returns
Never returns.
Precondition
The driver has been bound and the mutex created.
INITIALIZE has populated s_rx_ip and set s_open.
Postcondition
Received frames are delivered to NetX whenever the link is open.
::s_nx_c6_diag.poll_total counts every poll performed.
Note
Runs at k_nx_c6_worker_priority alongside the NetX IP thread.
Since
0.1.0

Definition at line 409 of file nx_ether_driver_c6.c.

References k_nx_c6_poll_transactions, k_nx_c6_worker_period_ticks, ra8_c6link_poll(), ra8_esp_hosted_port_rx_pending(), RA8_INTERNAL, s_c6_link, s_c6_mtx, s_c6_mtx_made, s_nx_c6_diag, s_open, tx_mutex_get, tx_mutex_put, tx_thread_sleep, and TX_WAIT_FOREVER.

Referenced by internal_spawn_rx_worker(), and internal_spawn_rx_worker().

◆ internal_send_blocked()

bool internal_send_blocked ( const NX_PACKET * pkt)
static

Report whether a transmit must be refused before touching the wire.

Sequential checks (no compound boolean) so this not-host-testable driver owes no MC/DC vector set: a null packet, a closed or down link, or a missing mutex each block the transmit.

Parameters
[in]pktThe packet NetX handed the send handler; may be null.
Returns
bool True when the send must be refused.
Return values
trueOne of the readiness conditions failed.
falseThe link is ready to transmit pkt.
Precondition
The driver statics reflect the current link state.
pkt is the request's packet, null or otherwise.
Postcondition
No state is modified.
The caller releases pkt when this returns true.
Note
Not thread-safe; called only from the send handler.
Since
0.1.0

Definition at line 651 of file nx_ether_driver_c6.c.

References RA8_INTERNAL, s_c6_mtx_made, s_link_up, and s_open.

Referenced by internal_handle_send().

◆ internal_set_link_state()

void internal_set_link_state ( NX_IP_DRIVER * req,
UCHAR link_up )
static

Apply an ENABLE / DISABLE change to the link mirror and NetX iface.

Caches the new state in s_link_up and, when NetX supplied an interface, mirrors it into nx_interface_link_up so the IP layer agrees with the driver about whether the link is up.

Parameters
[in,out]reqNetX driver request; must be non-null.
[in]link_up1 to bring the link up, 0 to bring it down.
Returns
Nothing; req->nx_ip_driver_status is set to NX_SUCCESS.
Precondition
link_up is 0 or 1.
req is the ENABLE or DISABLE request being handled.
Postcondition
s_link_up equals link_up.
Any NetX interface on req mirrors the new link state.
Note
Not thread-safe; serialised on the NetX IP thread.
Since
0.1.0

Definition at line 761 of file nx_ether_driver_c6.c.

References RA8_INTERNAL, and s_link_up.

Referenced by nx_ether_driver_c6().

◆ internal_spawn_rx_worker()

void internal_spawn_rx_worker ( NX_IP * ip,
NX_INTERFACE * iface )
static

Spawn the RX poll worker thread once; idempotent on later calls.

Called from INITIALIZE. Records the IP and interface the receive path pushes frames into, then creates the worker; a second call is a no-op.

Parameters
[in]ipNetX IP the worker pushes received frames into; non-null.
[in]ifaceNetX interface the worker tags frames with; non-null.
Returns
Nothing.
Precondition
The ThreadX kernel is running.
ip and iface are the objects INITIALIZE is bringing up.
Postcondition
On first call the worker is running and its one-shot spawn guard is set.
On later calls no thread is created.
Note
Not thread-safe; the NetX link dispatch serialises callers.
Since
0.1.0

Definition at line 456 of file nx_ether_driver_c6.c.

References internal_rx_worker_entry(), k_nx_c6_worker_priority, k_nx_c6_worker_stack_bytes, RA8_INTERNAL, s_rx_iface, s_rx_ip, s_rx_thread, s_rx_thread_made, s_rx_thread_stack, TX_AUTO_START, TX_NO_TIME_SLICE, TX_SUCCESS, and tx_thread_create.

Referenced by internal_handle_init().

◆ internal_stamp_iface_mac()

void internal_stamp_iface_mac ( NX_INTERFACE * iface,
const uint8_t * mac )
static

Write a six-octet MAC into a NetX interface's msw/lsw words.

The inverse of internal_unpack_mac, so NetX subsystems that read the address later (ARP, sender stamping) see the value INITIALIZE adopted.

Parameters
[in,out]ifaceInterface to update; must be non-null.
[in]macSix-octet address to install; must be non-null.
Returns
Nothing.
Precondition
mac points at k_nx_c6_mac_len readable octets.
iface is the interface INITIALIZE is bringing up.
Postcondition
iface's physical-address words hold mac.
No other NetX state is modified.
Note
Not thread-safe; called only from the INITIALIZE handler.
Since
0.1.0

Definition at line 257 of file nx_ether_driver_c6.c.

References k_nx_c6_mac_i0, k_nx_c6_mac_i1, k_nx_c6_mac_i2, k_nx_c6_mac_i3, k_nx_c6_mac_i4, k_nx_c6_mac_i5, k_nx_c6_shift_16, k_nx_c6_shift_24, k_nx_c6_shift_8, and RA8_INTERNAL.

Referenced by internal_handle_init().

◆ internal_unpack_mac()

void internal_unpack_mac ( const NX_INTERFACE * iface,
uint8_t * mac )
static

Pull the six-octet station MAC out of a NetX interface descriptor.

NetX stores the address as a 16-bit msw (octets 0..1) and a 32-bit lsw (octets 2..5); this splits them back into a byte array.

Parameters
[in]ifaceInterface whose physical address is read; must be non-null.
[out]macSix-octet buffer to fill; must be non-null.
Returns
Nothing.
Precondition
iface->nx_interface_physical_address_msw/lsw hold the address.
mac has room for k_nx_c6_mac_len octets.
Postcondition
mac holds the interface address, most-significant octet first.
No NetX state is modified.
Note
Not thread-safe; called only during single-threaded bring-up.
Since
0.1.0

Definition at line 231 of file nx_ether_driver_c6.c.

References k_nx_c6_byte_mask, k_nx_c6_mac_i0, k_nx_c6_mac_i1, k_nx_c6_mac_i2, k_nx_c6_mac_i3, k_nx_c6_mac_i4, k_nx_c6_mac_i5, k_nx_c6_shift_16, k_nx_c6_shift_24, k_nx_c6_shift_8, and RA8_INTERNAL.

Referenced by internal_handle_init().

◆ internal_write_eth_header()

void internal_write_eth_header ( const NX_IP_DRIVER * req)
static

Write the 14-byte Ethernet II header into the staging buffer.

Destination MAC comes from the NetX request (resolved by ARP, or the broadcast address), the source MAC from s_local_mac, and the EtherType from internal_ethertype_for_cmd. The body is appended after this by the caller.

Parameters
[in]reqNetX driver request carrying the destination and command; must be non-null.
Returns
Nothing.
Precondition
s_local_mac holds the station address.
The first k_nx_c6_hdr_bytes of s_tx_staging are writable.
Postcondition
s_tx_staging[0..13] holds a valid Ethernet II header.
No packet is consumed.
Note
Not thread-safe; s_tx_staging is shared and guarded by the send path.
Since
0.1.0

Definition at line 574 of file nx_ether_driver_c6.c.

References internal_ethertype_for_cmd(), k_nx_c6_byte_mask, k_nx_c6_etype_off, k_nx_c6_mac_i0, k_nx_c6_mac_i1, k_nx_c6_mac_i2, k_nx_c6_mac_i3, k_nx_c6_mac_i4, k_nx_c6_mac_i5, k_nx_c6_mac_len, k_nx_c6_shift_16, k_nx_c6_shift_24, k_nx_c6_shift_8, memcpy(), RA8_INTERNAL, s_local_mac, and s_tx_staging.

Referenced by internal_handle_send().

◆ nx_ether_driver_c6()

void nx_ether_driver_c6 ( NX_IP_DRIVER * driver_req)

NetX Duo link driver entry point for the ESP32-C6 Wi-Fi station.

Pass this symbol as the driver argument to nx_ip_create. NetX Duo calls it for every link command – INITIALIZE, ENABLE, PACKET_SEND, GET_STATUS and the rest – and it dispatches each to the matching handler. The transmit path builds the 14-byte Ethernet header from the destination MAC NetX resolved, the station MAC set by nx_ether_driver_c6_set_mac and the EtherType implied by the command, then forwards the whole frame to ra8_c6link_eth_send.

Parameters
[in,out]driver_reqNetX Duo driver request block; NetX never passes null, but a null is tolerated as a no-op.
Returns
Nothing; the outcome is written to driver_req->nx_ip_driver_status.
Precondition
nx_ether_driver_c6_bind has run with an open, associated link.
The caller is NetX Duo's IP thread (the dispatch is not re-entrant).
Postcondition
driver_req->nx_ip_driver_status is set to NX_SUCCESS or an error.
Any packet carried by a send command is released exactly once.
Note
Not thread-safe against itself; NetX serialises link commands on the IP thread. Wire access is serialised against the RX worker by a mutex.
Since
0.1.0

Definition at line 770 of file nx_ether_driver_c6.c.

References internal_handle_get_status(), internal_handle_init(), internal_handle_send(), internal_set_link_state(), and s_open.

Referenced by internal_c6_cam_net_create(), priv_net_create_ip(), and priv_net_create_ip().

◆ nx_ether_driver_c6_bind()

void nx_ether_driver_c6_bind ( ra8_c6link_t * link)

Bind an open C6 link handle to the driver and arm its mutex.

The driver reaches the co-processor only through this handle. Call it once, after the link is open and the station is associated, and before nx_ip_create. It also creates the ThreadX mutex that serialises transmit against the RX poll worker, so it must run after the ThreadX kernel is up.

Parameters
[in]linkOpen, associated C6 link handle; must be non-null and must outlive every NetX operation on this interface.
Returns
Nothing.
Precondition
The ThreadX kernel is running (tx_application_define has returned).
link is open and its receive callback is nx_ether_driver_c6_rx.
Postcondition
The driver forwards transmit and receive through link.
The transmit/receive serialisation mutex exists.
Note
Idempotent for the mutex: a second bind re-points the handle but does not recreate the mutex.
Since
0.1.0

Definition at line 198 of file nx_ether_driver_c6.c.

References s_c6_link, s_c6_mtx, s_c6_mtx_made, tx_mutex_create, and TX_SUCCESS.

Referenced by c6_cam_net_up(), c6_join_net_up(), and wifi_hal_ip_bind().

◆ nx_ether_driver_c6_rx()

void nx_ether_driver_c6_rx ( void * ctx,
const uint8_t * frame,
uint16_t len )

Receive callback the application registers with ra8_c6link_open.

The facade invokes this for every 802.3 frame the co-processor forwards from the associated AP, synchronously inside ra8_c6link_poll (or inside a transmit pump). It allocates an NX_PACKET from the IP's default pool, copies the frame in, and hands it to NetX Duo's deferred receive path, keyed by EtherType. Before the interface is up (NX_LINK_INITIALIZE has not run) it drops the frame, which is correct: no data frames flow before association and IP bring-up.

Parameters
[in]ctxUnused context pointer from the link configuration.
[in]frameWhole Ethernet II frame including the 14-byte header; must be non-null when len is non-zero.
[in]lenFrame length in octets.
Returns
Nothing; a frame that cannot be delivered is dropped and counted.
Precondition
The driver has been bound and, for delivery, NX_LINK_INITIALIZE ran.
len is at least the 14-byte Ethernet header for delivery.
Postcondition
A well-formed frame is queued to NetX or dropped with the drop count incremented; the packet pool is never leaked.
Runt or pre-initialise frames leave NetX state untouched.
Note
Runs on the RX worker (or the transmit caller) with the wire mutex held; it performs no further wire access, only NetX packet operations.
Since
0.1.0

Definition at line 351 of file nx_ether_driver_c6.c.

References internal_dispatch_to_netx(), internal_rx_acceptable(), k_nx_c6_max_frame, k_nx_c6_rx_align, memcpy(), s_nx_c6_diag, s_rx_iface, s_rx_ip, and s_rx_staging.

Referenced by c6_join_open_link(), internal_c6_cam_open_link(), and wifi_hal_make_cfg().

◆ nx_ether_driver_c6_set_mac()

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 learns the interface MAC from nx_ip_interface_physical_address_set, but nx_ip_create fires NX_LINK_INITIALIZE before the application can call that, so the driver would otherwise stamp a zero source MAC on the first frames. Read the station address with ra8_c6link_wifi_mac and hand it here before nx_ip_create so INITIALIZE has the real value.

Parameters
[in]macSix-octet station MAC; must be non-null.
Returns
Nothing.
Precondition
mac points at k_ra8_c6link_mac_bytes readable octets.
Called before nx_ip_create for deterministic INITIALIZE framing.
Postcondition
The driver stamps mac as the source MAC on every transmitted frame.
A later NX_LINK_INITIALIZE prefers this value over the interface.
Note
Not thread-safe; call it during single-threaded bring-up.
Since
0.1.0

Definition at line 189 of file nx_ether_driver_c6.c.

References k_nx_c6_mac_len, memcpy(), s_local_mac, and s_mac_user_set.

Referenced by c6_cam_net_up(), c6_join_net_up(), and wifi_hal_ip_bind().

Variable Documentation

◆ s_c6_link

ra8_c6link_t* s_c6_link
static

Bound C6 link handle.

Note
Set by bind.
Since
0.1.0

Definition at line 168 of file nx_ether_driver_c6.c.

Referenced by internal_handle_init(), internal_handle_send(), internal_rx_worker_entry(), and nx_ether_driver_c6_bind().

◆ s_c6_mtx

TX_MUTEX s_c6_mtx
static

Wire-serialisation mutex.

Note
Created by bind.
Since
0.1.0

Definition at line 170 of file nx_ether_driver_c6.c.

Referenced by internal_handle_send(), internal_rx_worker_entry(), and nx_ether_driver_c6_bind().

◆ s_c6_mtx_made

uint8_t s_c6_mtx_made
static

Non-zero once the mutex exists.

Since
0.1.0

Definition at line 172 of file nx_ether_driver_c6.c.

Referenced by internal_rx_worker_entry(), internal_send_blocked(), and nx_ether_driver_c6_bind().

◆ s_link_up

uint8_t s_link_up
static

◆ s_local_mac

uint8_t s_local_mac[k_nx_c6_mac_len]
static

◆ s_mac_user_set

uint8_t s_mac_user_set
static

Non-zero once _set_mac ran.

Since
0.1.0

Definition at line 180 of file nx_ether_driver_c6.c.

Referenced by internal_handle_init(), and nx_ether_driver_c6_set_mac().

◆ s_nx_c6_diag

nx_c6_diag_t s_nx_c6_diag
static

Diagnostic counters for the C6 NetX bridge.

File-scope and static; a debugger still watches it by symbol name, and nothing outside this translation unit reads it.

Note
Read-mostly; only this translation unit writes it.
Warning
Not synchronised; treat a torn read as advisory.
Since
0.1.0

Definition at line 165 of file nx_ether_driver_c6.c.

Referenced by internal_dispatch_to_netx(), internal_handle_send(), internal_rx_worker_entry(), and nx_ether_driver_c6_rx().

◆ s_open

uint8_t s_open
static

Non-zero after NX_LINK_INITIALIZE.

Since
0.1.0

Definition at line 174 of file nx_ether_driver_c6.c.

◆ s_rx_iface

NX_INTERFACE* s_rx_iface
static

Interface the receive path tags frames with.

Since
0.1.0

Definition at line 187 of file nx_ether_driver_c6.c.

Referenced by internal_rx_drain(), internal_spawn_rx_worker(), internal_spawn_rx_worker(), and nx_ether_driver_c6_rx().

◆ s_rx_ip

◆ s_tx_staging

uint8_t s_tx_staging[k_nx_c6_max_frame]
static

Linear transmit frame buffer.

Since
0.1.0

Definition at line 182 of file nx_ether_driver_c6.c.

Referenced by internal_handle_send(), internal_handle_send(), and internal_write_eth_header().