Commit Graph
1112 Commits
Author SHA1 Message Date
René van Dorst 7cf0115182 httpd: scan_header() put argument on xdata
Saves 2 bytes
2026-08-26 20:51:32 +02:00
René van Dorst adfbead438 syslog: syslog_callback() put local variables on xdata.
Save atleast 2 bytes.
2026-08-26 20:51:32 +02:00
René van Dorst 301774040b uip: place some pointer in xdata.
Saves 2 bytes.
2026-08-26 20:51:32 +02:00
René van Dorst 683037f410 httpd: rename gen_random_bytes to gen_random_hex_chars
This reflexs the function better.
Moving `byte` arguments to __xdata which saves 1 SRAM byte.
2026-08-26 20:51:27 +02:00
René van Dorst 57b820c4e8 httpd: mark pointer variable as __xdata.
Otherwise it is put on SRAM location.

Saves 6 SRAM bytes
2026-08-26 20:49:58 +02:00
logicog 45d0aac118 Merge pull request #326 from vDorst/SRAM-cmd-parse-port-helper
Add/refactor helpers to parse IP, numbers and port arguments
2026-08-25 12:49:00 +02:00
René van Dorst ee05cd4000 Fix: send_counters(), port-argument have to be physical port number.
Not the physical port index!
2026-08-25 07:55:17 +02:00
René van Dorst 74013bb14f CMD: Treat port zero as CPU-port 2026-08-25 07:55:17 +02:00
René van Dorst beb14deba5 httpd: send_counter(): Validate phys_port_idx and better error handling 2026-08-25 07:55:17 +02:00
René van Dorst 1212def799 CMD: fixes many comments 2026-08-25 07:55:17 +02:00
René van Dorst 95b3bde822 Rename print_port() to print_phys_port() 2026-08-25 07:55:17 +02:00
René van Dorst f511453f79 CMD: refactor code 2026-08-25 07:55:17 +02:00
René van Dorst 8653216047 CMD: Fix some comments 2026-08-25 07:55:17 +02:00
René van Dorst e62e0fc8bd CMD: Isolate allow the CPU-port as a member. 2026-08-25 07:55:17 +02:00
René van Dorst 2ff418f80f Replace '\0' to NUL to make it more clear that it is a NUL-terminated string. 2026-08-25 07:55:06 +02:00
René van Dorst 5d42e8843e Rename cmd_is_space_or_null to cmd_is_space_or_nul 2026-08-25 07:54:15 +02:00
René van Dorst 3c183f73f8 Added print_port() helper to print physical port number. 2026-08-25 07:54:15 +02:00
René van Dorst 3776f12f5c Fix and refactor parse_bw() 2026-08-25 07:54:15 +02:00
René van Dorst 5ddec9710a CMD: Fix parse_lag_hash() 2026-08-25 07:54:15 +02:00
René van Dorst f627559005 fix CMD: pvid: remove atoi_results_u8 from check 2026-08-25 07:54:15 +02:00
René van Dorst dca92d7f45 cmd_parse_port_separator() cmd_parse_port() remove CPU-port support
Removing the CPU-port support, As stated in #334, it is not needed to
manual add the CPU-port to any command. Because the CPU-port should be
added automatilly when CPU-port is needed.

Refactor cmd_parse_port() because port number is only 1 byte.
This simplifies the parsing code.

Refactor cmd_parse_port_separator() to ensure the return size is correct.
2026-08-25 07:54:15 +02:00
René van Dorst 149dc8537f Rename cmd_parse_port_space() to cmd_parse_port_separator()
cmd_parse_port_separator() parse the full port number and checks that the
number end with a NUL of space.
Now this function can also be used to parse the last argument number
because this ends with a NUL.

Also refactor code.
2026-08-25 07:54:15 +02:00
René van Dorst 42f7b4fba1 Fix parse_isolate(), ensure spaces between arguments 2026-08-25 07:54:15 +02:00
René van Dorst 17642699d4 Improve parse_ingress() 2026-08-25 07:54:15 +02:00
René van Dorst 724fd1e061 Added print_ip() to print IPv4 addresses. 2026-08-25 07:54:15 +02:00
René van Dorst 3eb2dfe0c9 Change parse_ip() 2026-08-25 07:54:15 +02:00
René van Dorst 73df006d39 Replace all manual port parsing with cmd_parse_port_space() or cmd_parse_port().
Saves no SRAM but around 1k code size
2026-08-25 07:54:15 +02:00
René van Dorst 175f3bb185 Add cmd_parse_port() and cmd_parse_port_space() helper.
A lot of places we manual parse and translate the port.
These helper functions will do that for us.
2026-08-25 07:54:15 +02:00
René van Dorst 57061161b6 Refactor code to make use of new atoi_byte() 2026-08-25 07:54:15 +02:00
René van Dorst 80f97a50e0 Refactor atoi_byte() same as atoi_short() 2026-08-25 07:54:15 +02:00
René van Dorst c265a20d83 Refactor the code for the new atoi_short()
Free-up 1 SRAM-byte
2026-08-25 07:54:15 +02:00
René van Dorst 4937618684 Change atoi_short() so it returns number of bytes consumed. 2026-08-25 07:54:15 +02:00
logicog f582576b10 Merge pull request #345 from DrDoof/fix/sfp-i2c-error
sfp: notice when an I2C read fails
2026-08-25 05:13:47 +02:00
feelfree69 16b0f207ed Merge pull request #317 from bloqaudio/pr/swtgw218as-sfp-led
machine: add PCB SWTG018AS-V2.1.0 variant of the SWTGW218AS
2026-08-25 02:22:21 +02:00
René van Dorst fe2bcc7f2d Merge pull request #356 from bloqaudio/fix/config-post-race
httpd: buffer a configuration upload before touching the flash
2026-08-24 23:35:19 +00:00
d00f a0628c7df5 sfp: read the EEPROM in blocks instead of a byte at a time
The I2C controller transfers up to sixteen bytes per transaction and
page_impl.c already used that for sfp_send_data(), while sfp_read_reg()
asked for one byte and every caller looped. Reading a module therefore
cost one address phase per byte: 87 transactions when a module is
inserted, 52 for the sfp command, 36 for the vendor block in status.json.

sfp_read_block() replaces sfp_read_reg() and the callers that already
wanted a run of registers ask for it once: the vendor fields as three
16 byte pages, the diagnostics as one transfer, rate and encoding
together. That drops the three paths above to 8, 6 and 3 transactions,
and sfp_send_data() loses its copy of the transfer.

The vendor loops now run over 16..63 rather than 20..59 so the page base
is a multiple of sixteen and the index into the buffer is a single AND.
The four extra bytes at each end are read and discarded. The diagnostics
read asks for 16 bytes rather than the 15 it uses, because 16 is a width
the shipped firmware already exercises and 15 is not.

The device address, the bus selection and the start bit go into the
control register in one write now that the memory address is written
first, so a transfer touches that register once instead of three times.
The register reads take their result from the SFRs directly rather than
through the sfr_data mirror. The result is a bool and the destination is
sfp_buf, so a caller that cares about a failed transfer looks at the
return value instead of a flag.

Every caller gives up on the first failed read rather than carrying a
flag to the end, which is why the module read moved out of handle_sfp
into a function of its own. A module whose read fails is left marked as
absent, so the next poll retries it instead of configuring the SerDes
from bytes that never arrived.

BANK1 -194 bytes, BANK2 +382, common segment +44, xdata +15 for the
buffer, and one byte more of internal RAM free than before the series.
Built for all 25 machine definitions on sdcc 4.5.0; the tightest common
segment is 98 bytes free on SWTG024AS_V2_0, against 54 before this
series.
2026-08-25 01:09:20 +02:00
bloqaudio cefe48fe51 httpd: size the config upload buffer for a full config sector
CONFIG_UPLOAD_BUF at 2560 capped a configuration upload at about 2.2K
while the config sector holds 4K. Size the buffer as CONFIG_LEN plus
room for the multipart framing so the whole sector is usable.

config_take() wrote the payload without checking it against the sector:
safe before only because the buffer could not hold an oversized one.
Reject a payload that does not fit CONFIG_LEN, terminator included,
instead of writing past the erased sector.
2026-08-24 15:45:25 -05:00
bloqaudio e8e7fcbe7f httpd: send the config tail from the config sector, not a bare offset
send_config() streams a configuration larger than the TCP output buffer
through the cont_addr/cont_len continuation, but set cont_addr to the
offset within the config instead of a flash address, so the tail was read
from code space. The file server sets cont_addr absolute; do the same by
adding CONFIG_START.

The bug was unreachable while CONFIG_UPLOAD_BUF capped uploads below
TCP_OUTBUF_SIZE, but a stored config near the full sector exposes it.
2026-08-24 15:45:25 -05:00
d00f 9a96c80af2 sfp: move the I2C transfer to the banked pins module
sfp_read_reg() sat in rtlplayground.c, so it occupied the common 16 KB
window that every bank shares, even though nothing outside the SFP paths
calls it. That window is the tightest resource in the image:
SWTG024AS_V2_0 and SWTG024AS_A_2_0_1_5C_1SFP had 54 bytes left in it.

rtl837x_pins.c is already in BANK2 and already holds the I2C bus helpers
this function calls, so the transfer belongs there. The function moves
verbatim and becomes __banked; the prototype in rtl837x_common.h says so,
which is what keeps the callers in BANK1 and BANK2 honest.

No behaviour change. The common segment gains 200 bytes on every machine:
159 to 359 free on SWTGW218AS, 54 to 254 on the two variants above.
BANK1 +6 bytes, BANK2 +336. Built on sdcc 4.5.0.
2026-08-24 02:34:39 +02:00
bloqaudio 772e9dc526 httpd: parse a configuration upload once the whole request has arrived
Saving the configuration works in Chrome and fails in Firefox, and the
difference is only how each browser splits the request. The handler
erased the config sector as soon as the request started and then parsed
the multipart body one TCP segment at a time, which requires every
boundary and every part header to fall inside a single segment. Firefox
splits inside a part header, so the parser lost its place and the
erased sector was left holding a truncated body or nothing at all. A
single-burst scripted post lost the whole body the same way.

The configuration is limited to two kilobytes, so the whole request body
now accumulates in xdata and is parsed only after the closing boundary
has arrived. The parts are walked in one pass, the part carrying a
filename is written to a freshly erased sector, and the client receives
a 200 instead of the previous silent close. No segmentation can confuse
this, since the parser only ever sees a complete body.

Locating the closing boundary first also bounds the walk over the parts,
since none can lie beyond it, so the length of the buffer is no longer
the bound and the test for the two trailing dashes is unnecessary.

The walk matches at offsets inside a buffer that is not terminated, so
neither existing helper fits: strcmp() goes on to compare the byte after
the match and is_word_x() demands a separator there. Add strstart() and
strstart_x() for that case, and use strlen_x() for the boundary length.

The firmware upload path still streams, since a megabyte cannot be
buffered, and is untouched.
2026-08-23 18:11:46 -05:00
logicog 025f72c876 Merge pull request #258 from bennydiamond/newline-on-uip-serial-print
Automatically print newline on serial interface
2026-08-22 19:14:45 +02:00
logicog 52cf759bec Merge pull request #355 from bloqaudio/fix/l2-static-display
httpd: read the static flag of an L2 entry from the byte that holds it
2026-08-18 19:44:05 +02:00
René van Dorst cbbc6160f4 Merge pull request #357 from bloqaudio/fix/ingress-port-bound
cmd_parser: reject port 0 in the ingress command
2026-08-18 09:05:06 +02:00
bloqaudio a8d3b7d39a cmd_parser: reject port 0 in the ingress command
The single-digit arm of the ingress parser guards with p - '1' > 9,
which no digit can satisfy: the largest, '9', gives 8. The digit that
needed rejecting is '0', which gives -1 and indexes one byte before
phys_to_log_port, so "ingress 0 t" reads out of bounds and applies the
ingress mode to whatever port number that byte happens to contain.
Ports are 1-based, so reject anything below '1'; values above '9' are
already excluded by the isnumber check before this.
2026-08-17 17:19:46 -05:00
René van Dorst 80095ba617 Merge pull request #354 from DrDoof/fix/isolate-cpu-port
port: reject the CPU port in isolate instead of refusing it silently
2026-08-17 18:31:25 +00:00
bloqaudio a3d1a35e2f httpd: read the static flag of an L2 entry from the byte that holds it
The MAC table listing tests bit 0 of byte 2 of the third table data
word for the static flag, but the flag lives in bit 0 of byte 1: an
entry written with byte 1 bit 0 set survives the aging engine
indefinitely where an identical entry without it ages out, and reads
back with exactly that bit set through both the address and the
next-entry read methods. Byte 2 of that word reads zero for learned and
static entries alike, so every entry has always been listed as learned
and a static entry has never been visible as such in the table listing.
2026-08-17 12:17:42 -05:00
d00f 47b3ee60b6 port: reject the CPU port in isolate instead of refusing it silently
parse_isolate() accepted a two digit port and mapped it to logical port 9,
the CPU port, while port_isolate() and port_isolation_get() both refuse
anything above machine.max_port. Setting the isolation of the CPU port was
therefore declined without a word and reading it always answered no
members, whatever the hardware held.

Bound the port to the front panel, so the command says what it does. The
digit is checked before it indexes phys_to_log_port[], which a non numeric
argument used to read past.
2026-08-17 10:53:17 +02:00
logicog 59d20ed9b6 Merge pull request #339 from plaes/parallel-build
Fix parallel build
2026-08-17 08:11:25 +02:00
logicog f41ed2b943 Merge pull request #332 from DrDoof/fix/igmp-enable-gate
igmp: only hand reports to the CPU while snooping is on
2026-08-17 07:58:18 +02:00
d00f 56fa96c494 igmp: only hand reports to the CPU while snooping is on
handle_rx() dispatched to igmp_packet_handler() on the destination
address alone, so an ordinary IGMPv3 report off the wire reached the
handler and could write a table entry whether or not anyone had asked
for snooping. The STP branch right above it is gated on stpEnabled;
this brings the IGMP branch in line.

Snooping state lived only in the per-port registers, and the receive
path cannot afford to read one per packet, so the flag shadows it:
igmp_enable() sets it, igmp_setup() clears it, and igmp_setup() runs
from both the boot path and "igmp off".

While here, igmp off becomes an explicit subcommand instead of the
fall-through, and an unrecognised igmp subcommand prints the usage
line rather than silently turning snooping off.

Six bytes of BANK1 and one of xdata, no internal RAM.
2026-08-16 23:42:46 +02:00