Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ version at the top when it merges.
to an 11,680-byte ceiling when the setting is absent; other devices retain
the 50,176-byte port default. This changes ACK cadence, not the unresolved
cause of missing outbound frames (#89). The per-interface policy brings the
resident `bsdsocket.library` image to 365,468 bytes in CI; its budget is
resident `bsdsocket.library` image to 365,316 bytes; its budget is
366,000 bytes.

## 1.0.0-beta7
Expand Down
5 changes: 5 additions & 0 deletions include/aminetxduo/sana2.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ ULONG ami_sana2_retained_holds(const char *device, ULONG unit);
use that port default. Names are compared by basename, ignoring case. */
ULONG ami_sana2_default_tcp_ack_max(const char *device);

/* The pure device-name helpers behind those defaults (sana2_policy.c). */
BOOL ami_str_iequal(const char *a, const char *b);
const char *ami_sana2_basename(const char *device);
UWORD ami_sana2_default_ip_reads(const char *device);

/*
* Collect whatever the devices have given back since, without waiting, and
* CloseDevice() and free every interface nothing holds any more. Under
Expand Down
59 changes: 0 additions & 59 deletions src/sana2/sana2_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,24 +83,6 @@ static VOID ami_str_copy(char *dst, const char *src, ULONG size)
dst[i] = '\0';
}

/* The same, ignoring case: a device name is a file name. */
static BOOL ami_str_iequal(const char *a, const char *b)
{
while (*a != '\0' && *b != '\0')
{
char x = *a++;
char y = *b++;

if (x >= 'A' && x <= 'Z')
x = (char)(x + ('a' - 'A'));
if (y >= 'A' && y <= 'Z')
y = (char)(y + ('a' - 'A'));
if (x != y)
return FALSE;
}
return (BOOL)(*a == *b);
}

static BOOL ami_str_equal(const char *a, const char *b)
{
ULONG i = 0;
Expand Down Expand Up @@ -1542,22 +1524,6 @@ UWORD ami_sana2_retained_count(VOID)
return ami_sana2_retained_n;
}

/* The file name without its path: DEVS:Networks/x.device and x.device are
one driver. */
static const char *ami_sana2_basename(const char *device)
{
const char *base = device;
const char *p;

for (p = device; *p != '\0'; p++)
{
if (*p == '/' || *p == ':')
base = p + 1;
}

return base;
}

ULONG ami_sana2_retained_holds(const char *device, ULONG unit)
{
const AmiSana2If *iface;
Expand Down Expand Up @@ -1693,31 +1659,6 @@ ULONG ami_sana2_known_rx_bytes(const char *device)
return 0;
}

/* WiFiPi's receiver runs at Exec priority 5, above every ThreadX task, and
* delivers a whole wake's SDPCM frames (up to 64, each possibly a glom)
* before the reader can re-post one CMD_READ; a frame with no read queued is
* dropped into UnknownTypesReceived. Its fixed 100 Mbit/s device query lands
* on the 32-read LAN rung. Measured on the CM4 A1200 (#89): 128 reads, 59.0
* Mbit/s inbound, UnknownTypes 82 of 53,483 packets; 128 is also
* AMI_SANA2_RX_MAX_DEPTH. Over the 32 it replaces it holds 96 more pool
* packets (156,672 B of the pool at the 1,632 B stride, none allocated) and
* 11,904 B more slot RAM; an explicit IPREQUESTS still wins, and rx_plan()
* still caps it at the pool budget. */
UWORD ami_sana2_default_ip_reads(const char *device)
{
const char *base;

if (device == NULL)
return 0;

base = ami_sana2_basename(device);
if (ami_str_iequal(base, "anxwifipi.device") ||
ami_str_iequal(base, "wifipi.device"))
return 128;

return 0;
}

BOOL ami_sana2_is_online(const AmiSana2If *iface)
{
return (iface != NULL) ? iface->online : FALSE;
Expand Down
1 change: 0 additions & 1 deletion src/sana2/sana2_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -985,7 +985,6 @@ VOID ami_sana2_rx_filled(APTR ios2_data, ULONG len, ULONG sum, UBYTE summed);
ULONG ami_sana2_known_rx_bytes(const char *device);
/* Extra default IPv4 reads for a known burst-delivering driver, or 0 to use
the ordinary BPS ladder; explicit IPREQUESTS always takes precedence. */
UWORD ami_sana2_default_ip_reads(const char *device);
/* The IPv4 read depth an interface asks for: IPREQUESTS, else the above
(sana2_rx.c). */
UWORD ami_sana2_rx_ask_ip(const AmiSana2If *iface);
Expand Down
62 changes: 42 additions & 20 deletions src/sana2/sana2_policy.c
Original file line number Diff line number Diff line change
@@ -1,38 +1,60 @@
/* Pure device-name defaults shared by the driver and host netstack tests. */
/* Pure device-name policy shared by the driver and the host netstack tests. */
#include "aminetxduo/sana2.h"

static char lower_ascii(char c)
{
if (c >= 'A' && c <= 'Z')
return (char)(c + ('a' - 'A'));
return c;
}

static int name_equal(const char *a, const char *b)
/* Two strings the same, ignoring case: a device name is a file name. */
BOOL ami_str_iequal(const char *a, const char *b)
{
while (*a != '\0' && *b != '\0')
{
if (lower_ascii(*a++) != lower_ascii(*b++))
return 0;
char x = *a++;
char y = *b++;

if (x >= 'A' && x <= 'Z')
x = (char)(x + ('a' - 'A'));
if (y >= 'A' && y <= 'Z')
y = (char)(y + ('a' - 'A'));
if (x != y)
return FALSE;
}
return *a == *b;
return (BOOL)(*a == *b);
}

ULONG ami_sana2_default_tcp_ack_max(const char *device)
/* The file name without its path: DEVS:Networks/x.device and x.device are
one driver. */
const char *ami_sana2_basename(const char *device)
{
const char *base = device;
const char *p;

if (device == NULL)
return 0;

for (p = device; *p != '\0'; p++)
{
if (*p == '/' || *p == ':')
base = p + 1;
}

if (name_equal(base, "anxwifipi.device") ||
name_equal(base, "wifipi.device"))
return 11680UL;
return base;
}

return 0;
static BOOL ami_sana2_is_wifipi(const char *device)
{
const char *base;

if (device == NULL)
return FALSE;

base = ami_sana2_basename(device);
return (BOOL)(ami_str_iequal(base, "anxwifipi.device") ||
ami_str_iequal(base, "wifipi.device"));
}

/* WiFiPi wants 128 posted reads (#107); the pool budget still caps it. */
UWORD ami_sana2_default_ip_reads(const char *device)
{
return ami_sana2_is_wifipi(device) ? 128 : 0;
}

/* WiFiPi acknowledges once per GRO run (#89, #109); 0 = the NetX default. */
ULONG ami_sana2_default_tcp_ack_max(const char *device)
{
return ami_sana2_is_wifipi(device) ? 11680UL : 0UL;
}
4 changes: 2 additions & 2 deletions tools/check-image-size.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ BUDGETS=(
# and an abandoned request kept with its interface until the device
# replies (#90, 5473e26e), 2026-09-26 (micro 204,052, minimal 238,240).
# 365,468 with per-interface TCP ACK policy (#109): config parsing and
# publishing the WiFi/default-or-explicit ceiling into each NX_INTERFACE.
# This adds 468 bytes over the previous resident-image budget.
# publishing the WiFi/default-or-explicit ceiling into each NX_INTERFACE;
# 365,316 once the device-name helpers live once, in sana2_policy.c.
"default:src/bsdsocket/bsdsocket.library:366000"
# 41,412 after stateless receive-checksum verification was added to the
# EL3 and word/long NE2000 direct paths, 2026-09-15. 43,620 with
Expand Down
Loading