Commit Graph
1383 Commits
Author SHA1 Message Date
d00f 83491bc9e3 test: let the shim compile sources that touch the SFRs and libc
Two things kept every register-driven module out of the host harness. The
SFR keywords were unknown, so rtl837x_sfr.h did not compile at all, and once
it did, each translation unit would have defined its own copy of the
registers. They map to extern declarations now; a mock emits the storage
once by re-including the header with the keywords redefined.

The other was memset. rtl837x_common.h hides the firmware's own prototypes
under RTLP_HOST_TEST so host builds use the C library, but nothing declared
the library versions, and the modules do call them. The shim pulls in
string.h ahead of everything, where nothing can clash with it.
2026-09-17 03:55:30 +02:00
René van Dorst 2f005d2993 Merge pull request #324 from bloqaudio/pr/host-test-harness
test: add host-side unit-test harness, covering cmd_editor
2026-09-14 21:59:07 +00:00
bloqaudio f65416f0d1 ci: run the host-side unit tests on every push
The harness builds with the gcc the workflow already installs and runs
in under a second, so it goes before the SDCC steps and fails the build
first when a host-visible regression lands.
2026-09-14 15:04:19 -05:00
bloqaudio c05d83132b test: drop the unused typedef keyword and make the gcc-only warning switch conditional
Building the firmware headers on the host showed two warnings from
machine.h: `typedef struct machine { ... };` and the same for
machine_runtime declare no alias, so the keyword only draws "useless
storage class specifier in empty declaration". Every user says
`struct machine`, so drop the keyword.

-Wno-builtin-declaration-mismatch is a gcc switch and clang reports it
as an unknown option on every build; add it only when the compiler is
not clang.
2026-09-14 14:05:33 -05:00
bloqaudio dcd3cd5a98 test: add host-side unit-test harness, covering cmd_editor
Compile selected firmware translation units unmodified under host gcc with
AddressSanitizer and UBSan, force-including a shim header that erases the
SDCC 8051 keywords, and link them against a mocked serial ring and console.
A first suite covers the CLI line editor: line entry, backspace editing,
and both long-input overflow cases (length cap and ring-pointer stall).

The only firmware-source change is one #ifndef RTLP_HOST_TEST block in
rtl837x_common.h grouping the libc-named prototypes (sleep/memcpy/memset/
strlen/strcpy/strcmp) so host builds take them from the C library instead;
on-target builds are unaffected.

Run with: make -C test
2026-09-14 14:02:35 -05:00
René van Dorst 9f107b6e60 Merge pull request #410 from DrDoof/fix/httpd-rexmit-cont
httpd: retransmit a continued chunk from where it was sent
2026-09-14 18:12:43 +00:00
René van Dorst 15b10d9ed0 Merge pull request #427 from bennydiamond/Flash_SingleIO_ReadStatus
Temporary revert to SingleIO for Flash operations (except data read)
2026-09-14 17:19:29 +00:00
René van Dorst abf1cd1344 Merge pull request #429 from bloqaudio/feat/webui-v2
web: replace the multi-page UI with a themed single-page app
2026-09-14 17:17:39 +00:00
René van Dorst b5b52776bc Merge pull request #449 from bloqaudio/fix/bank2-dhcp-bank3
Move DHCP out of BANK2 into BANK3
2026-09-14 16:55:24 +00:00
René van Dorst 0486c34bfd Merge pull request #448 from bloqaudio/fix/stp-port-keyword
stp: accept the documented port keyword again
2026-09-14 16:55:08 +00:00
bloqaudio 690092d564 Move DHCP out of BANK2 into BANK3
BANK2 outgrew its 48 KB window on PCB_SWTG018AS_V2_1_0 (49182 bytes, 30
over) once the spanning tree code learnt about link aggregation, and the
image builder refuses to link. Only KP_9000_6XHML_X2 is built in CI, so
the overflow was not caught there.

dhcp.c is self-contained: its three exports are __banked, the rest of
the module is only reached from inside it, it holds no __code pointers,
and its uip calls already crossed into BANK1. Moving the pragma is the
whole change. BANK2 49182 -> 43691 on PCB_SWTG018AS_V2_1_0, BANK3 5709
-> 11206, BANK1 +6 for the trampolines; the generated assembly shows no
plain lcall leaving the module's bank.
2026-09-14 08:29:39 -05:00
bloqaudio 115ea09ebb web: address a link aggregation group as one spanning tree entity
The firmware lists a LAG as its own entity in /stp.json (`lag` and `mbr`,
`p` 0) and drops the member ports from the list; its settings take
`stp lag <n>`. Give the group its own row in both spanning tree tables,
named with its members, key the cells by entity rather than port number,
and rebuild the tables whenever the entity set or a membership changes so
a group created on the LAG tab appears without a reload. The `stp lag`
commands are recognised for the unsaved-changes badge and the startup
config merge alongside `stp port`.
2026-09-14 08:14:53 -05:00
bloqaudio f3e1a393b5 stp: accept the documented port keyword again
The rename of the entity index turned `stp port <n>` into `stp ent <n>`
in the parser only. doc/stp.md, the web UI and every saved startup
config still spell it `stp port`, so per-port settings were rejected on
the console and silently dropped when the startup config was replayed at
boot. Restore the keyword; `stp lag <n>` is unchanged.
2026-09-14 08:05:57 -05:00
bloqaudio 206c72b5ef web: floor the optical power at -40 dBm
A dark receiver reports 0 mW, which printed as -Infinity dBm. The DOM
value has a resolution of 0.1 uW, so -40 dBm is the lowest reading the
module can express; clamp there.
2026-09-14 08:03:36 -05:00
bloqaudio 472811cc9a doc: add the single-page UI to the changelog 2026-09-14 08:03:36 -05:00
bloqaudio 80552816b9 web: move the language and theme selectors to the System section
The header carried the save button, the language selector and the theme
selector on every section, although the latter two are set once. They
now live in a Display card in the System section; the header keeps the
title, the unsaved-changes badge and Save to flash.
2026-09-14 08:03:36 -05:00
bloqaudio c1caf6f569 web: stop the MAC table walk when its section is left
The forwarding database is read a page at a time; leaving the MAC table
or ports section let the walk carry on through the request queue. Give
the walk a generation number that the leave hooks bump, and stop the
walk at the next page when it is stale.
2026-09-14 08:03:36 -05:00
bloqaudio ddad65fe90 web: keep a VLAN's row when its details cannot be read
The VLAN table is one /vlanlist plus one /vlan.json per VLAN. A failed
per-VLAN request rejected the chain, so every VLAN after it was missing
from the table, indistinguishable from VLANs that do not exist. Keep the
row with the id and name from the list and a ? in the port columns.
2026-09-14 08:03:36 -05:00
bloqaudio ff7b517491 web: let the merged config be edited before it is written
Save to flash showed the merged startup config read-only, so a stray line
had to be fixed afterwards in the System section. The preview is now a
textarea: the size and unknown-line notes follow the edits, the write
button is disabled above 2048 bytes, and what is written is the edited
text.
2026-09-14 08:03:36 -05:00
bloqaudio 65417433eb web: fit the hostname in the sidebar, widen the number fields and the page
The default hostname (RTLPlayground- plus six hex digits) overflows the
200 px sidebar; clip it with an ellipsis and keep the full name in the
title. The MTU and Mbit/s fields were 70 px, which leaves no room for five
digits next to a number spinner. The main column stops at 1400 px instead
of 1100 px so the dashboard cards sit side by side on a wide screen.
2026-09-14 08:03:36 -05:00
bloqaudio b7621fad31 web: keep the port detail view live and summarise each port in a tooltip
The old dashboard showed a hover tooltip per port with the link state and,
for SFP ports, the module and its DOM readings, and rewrote it on every
poll. The single-page app replaced it with a click-to-open dialog that was
a snapshot: the values did not change while it was open.

Build the rows once per port and use them for both: the dialog is
re-rendered on every status poll while it is open, and each port in the
strip carries the same rows as its title.
2026-09-14 08:03:36 -05:00
bloqaudio 82f78cb8f2 web: render the per-port tables in physical port order
The firmware emits every per-port array in logical port order, which on a
board with a remapped port table (SWGT024: phys_to_log = {4,5,6,7,8,3,...})
is 6, 1, 2, 3, 4, 5. The old pages iterated over physical port numbers and
looked each entry up; the single-page app rendered the arrays as received,
so the ports, spanning tree, EEE and bandwidth tables and the dashboard
strip came out in logical order, and the strip put the SFP marker and the
detail view on the wrong port.

Sort every array by portNum on receipt so index i is port i+1 throughout.
2026-09-14 08:03:36 -05:00
bloqaudio 75f2ade1a1 doc: describe the web UI files and translation table after the rewrite 2026-09-14 08:03:36 -05:00
bloqaudio 3e91b05a42 web: replace the multi-page UI with a themed single-page app
The pages become one index.html holding every section, one app.js and a
self-contained login.html. The layout is a sidebar with light, dark and
Selenized themes (or follow the OS), a live dashboard with per-port
packet rates, and confirmation dialogs in front of the actions that can
lock the operator out.

Behaviour changes against the previous pages:

- every request goes through one queue that waits for the previous
  response BODY rather than its headers: the firmware shares a single
  output buffer across connections and delimits responses by closing,
  so a second request in flight corrupts the first
- "Save to flash" merges the command log into the startup configuration
  with the grammar the console accepts, shows the result before writing,
  verifies the sector by reading it back and clears the command log only
  after that; the header shows an "unsaved changes" badge while the
  running configuration differs from flash
- the console section shows the output the firmware returns for a
  command, including the parser's explanation on a rejected one
- the firmware update section checks size, bank header and CRC16 of the
  image in the browser before uploading, shows upload progress and waits
  for the switch to come back after the reset
- the ports table shows the learned MAC of a port when there is exactly
  one and the count otherwise; the MAC table sorts per column, filters,
  and names the LAG a learned address sits behind
- the spanning tree section sends only the settings that changed on
  Apply instead of one command per control event
- link aggregation groups are numbered 1-4 like the command line, and
  applying an empty group clears it

The translation table is inline in app.js with English, Japanese and
Chinese. The language selector sits in the page header and reloads the
page so that dynamically built tables are rebuilt in the new language.

Only login.html and the favicon are served before authentication; the
stylesheet, the port images and the old script bundle no longer exist.
The simulator's allowlist follows the firmware's.
2026-09-14 08:03:36 -05:00
bloqaudio ec1cb4106d httpd: count every authenticated request as session activity
The session timer was refreshed only when a page from the file table was
served, so a client that loads its pages once and then talks to the JSON
endpoints alone is logged out SESSION_TIMEOUT seconds after the load,
however busy it is. A firmware upload started after that point is answered
with 401 instead of a verdict. Refresh the timer wherever the session
cookie validates, which covers every authenticated request, and drop the
file-serving refresh that this makes redundant.
2026-09-14 08:03:35 -05:00
René van Dorst 62c6c65f1c Merge pull request #435 from bennydiamond/Support_HYWS-SGT0108S
Support for Lianguo HYWS-SGT0108S 8 + 1 unmanaged
2026-09-14 09:46:20 +02:00
René van Dorst c691591295 Merge branch 'main' into Support_HYWS-SGT0108S 2026-09-14 09:40:16 +02:00
logicog 434acbcc13 Merge pull request #397 from DrDoof/feat/stp-lag-entity
stp: treat a link aggregation group as one entity
2026-09-14 09:32:36 +02:00
René van Dorst 1aae2fac30 Merge pull request #364 from dw4rren/add-mokerlink-poe-2g080110gs
add support for MokerLink POE-2G080110GS
2026-09-14 09:23:15 +02:00
David Warren 1f9b3df3e6 Add basic support for MokerLink POE-2G080110GS 2026-09-13 23:18:55 -04:00
bennydiamond 7908044a44 Rework flash_write_enable() 2026-09-13 17:32:46 -04:00
bennydiamond 0ec1a5e63f Proper mapping for phys_to_log_port array 2026-09-13 17:16:34 -04:00
bennydiamond 114af559c7 Add support for Lianguo HYWS-SGT0108S unmanaged 8+1 2026-09-13 12:08:20 -04:00
René van Dorst 5a2c4ca029 Merge pull request #421 from DrDoof/fix/fileadder-binary-safe-length
fileadder: track the data length instead of measuring it with strlen
2026-09-13 11:51:37 +00:00
René van Dorst 63e367d298 Merge pull request #424 from DrDoof/refactor/split-sfp-boot
Move the boot and SFP handling out of the common area into BANK3
2026-09-13 09:51:57 +00:00
René van Dorst 5e513daf17 Merge pull request #423 from DrDoof/fix/arp-refresh-from-ip
Refresh ARP entries from incoming IP traffic
2026-09-13 08:41:10 +00:00
bennydiamond 3ec9319d77 Fix flash driver for proper SIO ops
Set SPI peripheral to SIO mode for all operations except READ.
Set back SPI Peripheral to DIO after said operation.
2026-09-13 01:40:26 -04:00
d00f b42eace21d Declare flash_default_config() in rtl837x_common.h
boot.c calls it from BANK3 and only rtlplayground.c had a prototype, so
the compiler saw an implicit declaration. The call itself was fine, the
function lives in the common area, but the warning was real. Move the
prototype into the shared header.

Reported by vDorst.
2026-09-13 05:18:07 +02:00
d00f 3dfd6a88c7 Move the SFP handling out of the common area into BANK3
sfp.c takes handle_sfp, sfp_module_read, sfp_apply_quirks, sfp_get_info,
sfp_read_field, sfp_print_info, setup_sfp_gpio, the quirk table and the module
state that goes with them. Everything exported is __banked: handle_sfp() and
sfp_print_info() are reached from cmd_parser.c in BANK2, the rest from the
common area, and both are bank boundaries.

The quirk table needed checking rather than assuming. Its entries are __code
pointers, and a __code pointer carries no bank, so passing one to a function in
a different bank hands it an offset read through the wrong window. That is safe
here because strcmp() sits in the common segment at 0x51f and is reached with a
plain lcall, so the bank register still says 3 while it runs. Verified in the
built image: the table at 0x35580 holds 0x563c and 0x5644, which resolve to
"QSFPTEK" and "QT-SFP+-T" inside BANK3.

Common segment 13393 -> 8432 bytes, leaving 7492 free rather than 2531. BANK3
holds 5710, BANK1 is unchanged and BANK2 grows by 31 for the trampolines.
All 34 machines in machine.h build and link, and the same walk over the
generated assembly finds no plain lcall crossing a bank boundary.
2026-09-13 05:16:50 +02:00
d00f 7fa26e0ae3 Move the boot and SerDes setup out of the common area into BANK3
The common segment is the scarce one: sixteen kilobytes shared by every bank,
and before this it had about 2.5 kB left. Most of what moves here runs once at
startup and does not have to sit in it. The two SerDes helpers are the
exception: the link-change handler and the SFP polling both reach sds_config()
while the switch is running, so they are not startup-only. None of it is
reached from an interrupt.

boot.c takes setup_i2c, init_smi, nic_setup, rtl8373_revision, rtl8224_enable,
early_boot_handle_button, set_hostname_default and the two SerDes helpers.
BANK3 is enabled with the linker flag; nothing else in the build needed
changing.

Everything moved is declared __banked, since every caller is outside BANK3:
main() and friends run from the common area and rtl837x_init.c calls
sds_config() and sds_config_mac() from BANK2. The calls the moved code makes
outward were already banked, so that side needed no work.

Common segment 13393 -> 10137 bytes, leaving 5787 free rather than 2531.
BANK3 holds 3732. All 34 machines in machine.h build and link. Walking
the generated assembly for plain lcalls that cross a bank boundary finds none
among 2808 calls; those build cleanly and only fail at run time, so it seemed
worth checking by machine rather than by eye.
2026-09-13 05:16:50 +02:00
d00f 1c8cdab4bf arp: take the sender MAC from where a received frame keeps it
IPBUF is laid out for frames we send, with the 12 byte TX descriptor in
front of the Ethernet header. A received frame starts with the Ethernet
header at uip_buf[0] and carries the RTL and VLAN tags after the
addresses, so IPBUF->ethhdr.src read the port mask and both VLAN fields
as a MAC. Every IP packet from the local network then replaced the
sender's ARP entry with that, and our replies went to an address nobody
has. The IP source address sits at the same offset in both layouts,
which is why the rest looked right.

Use BUF, the receive view uip_arp_arpin() already works from.
2026-09-13 04:14:21 +02:00
René van Dorst f49ca0d6fe Merge pull request #366 from gnacho/fix/kp9000-v31-mac-offset
Add factory MAC flash offset for keepLink KP-9000-9XHML-X V3.1 + mac command
2026-09-12 07:58:54 +00:00
gnacho 12fb6fd809 cmd_parser: parse mac into a global result buffer
parse_mac() now writes to the global mac_parse_result[6] and takes only the
index, like the other parsers (ip[4]). This drops the local __xdata buffer
and the now-unused hexval() helper.

Build (KP_9000_9XHML_X_V3_1): ROM 110302 -> 110193 bytes, XSEG and internal
RAM unchanged.
2026-09-11 23:42:01 +02:00
René van Dorst dad65fd550 Merge pull request #426 from DrDoof/fix/igmp-port-shift
igmp: mask the port number before shifting by it
2026-09-11 20:22:34 +00:00
René van Dorst dc82e044bc Merge pull request #436 from mintsoft/fix_gh_build
Fix Github Build - Add zlib
2026-09-11 17:22:37 +00:00
Rob Emery 7daa9effe0 Fixing dependencies and also broken link 2026-09-11 11:21:05 +00:00
Rob Emery 950586135a Build seems to be breaking on zlib.h being missing? 2026-09-11 11:14:32 +00:00
d00f c1ad800fc5 stp: name the MSTP state bits and the entity index
The state literals were spread over eighteen places in the file, sixteen
of them older than this branch, so naming only the new ones would have
left it written half one way and half the other.

Naming them separates two roles the literal hid: 0b11 is the forwarding
state in a call and a two bit field mask in a read-modify-write, hence
both STP_ST_FORWARDING and STP_ST_MASK. The comment above stp_state_set()
said what the defines now say, so it goes.

stp_parse() holds an entity index, not a port. cmd_parse_port() has
already mapped the front panel digit through machine.phys_to_log_port[],
and the aggregates continue that same logical range above the CPU port,
so call the variable ent. Reading the two branches of the if no longer
means following the parser two functions down.

No change to the generated code: 5331 instructions before and after.
2026-09-10 15:17:53 +02:00
gnacho dc4fb5becc fix(parser): reject malformed MAC inputs and make print helpers banked
parse_mac now accepts only a strict aa:bb:cc:dd:ee:ff (or '-' separators)
form: each octet is exactly two hex digits, the 5 separators are a single
consistent character, and nothing is allowed after the 6th octet. This
rejects the malformed values the reviewer flagged (repeated separators,
missing digits, trailing characters). A new inline hexval() helper does the
digit-to-value conversion and can be reused by future commands.

print_mac and print_ip are marked __banked to match cmd_parser(), which
lives in codeseg BANK2 and is itself __banked, so callers across the code
bank work correctly. cmd_parser.h is updated with the new prototypes and
the __banked qualifier on print_ip.

Verified with make MACHINE=KP_9000_9XHML_X_V3_1: the build links cleanly
and the internal-RAM (DSEG) layout is unchanged against main; XSEG is
unchanged and ROM grows by 184 bytes. A host-side test confirms parse_mac
rejects the two malformed inputs from the review.
2026-09-10 00:14:58 +02:00
d00f 78ecef15e9 stp gui: address a link aggregation group as one entity
The web UI became one index.html plus one main.js while this branch was
open, so the STP page changes had no html/stp.js and html/config.js left to
live in. They are re-applied here against the new structure.

A row now carries two derived fields: the name the CLI expects for it
("port N" or "lag N") and the key its controls are keyed by (the port
number or "LN"). A group's row is labelled with its front panel members,
which /stp.json reports in the mbr field.

conf_cmds and conf_overwrite accept the "stp lag N ..." forms so the
startup config keeps them.
2026-09-09 21:01:15 +02:00