Commit Graph
16 Commits
Author SHA1 Message Date
Rob Emery 1ebee4d6e9 Implementing basic LLDP server, should send port_id message
to each port once every 30 seconds.
* Additionally fixes the on-ward passing of LLDP frames through
the switch

The ports on the case are marked 1-8 so this should reflect that
rather than being 0-based

We can send the hostname as well, this can be dynamically allocated

Let's send the model as the system description as well
2026-10-10 09:49:24 +01:00
DrDoof 6e2701bc8c rtlplayground: receive on the NIC interrupt instead of polling the buffer
The receive interrupt was wired up but never used: EX1 was enabled, the
handler re-enabled itself and did nothing, and the mask bit for it in the
NIC stayed clear, so idle() read the receive buffer register on every
pass to find out whether a packet had arrived, and slept until the next
tick when none had. A packet that arrived during that sleep waited for
the tick: 2.2 ms on average, 5 ms at worst, for every frame the CPU
handles.

Now the handler latches rx_irq and masks itself, and idle() sleeps
unless a receive, a link change, a console command or the tick is
pending. On rx_irq the loop drains the buffer, clears the status bit and
re-enables EX1, in that order: the NIC holds the line as long as the
status bit is set, and the bit does not clear while the buffer still
holds a frame, so a frame that lands between the last read and EX1 = 1
raises the interrupt again rather than getting lost. The other order,
clearing before draining, left the line asserted and produced an
interrupt on every pass. The mask is written after nic_setup(), which
resets it.

Measured on an RTL8373 board with the same counters in both images,
clocked by the tick counter, traffic from a host behind an LACP trunk:

```
                          polling     interrupt
idle, register ops/s          788            79
25 pps, RTT avg/max     2.19/4.96     0.44/0.75 ms
500 pps, RTT avg/max    2.78/5.06     0.39/5.40 ms
500 pps, loss               0.08%         0.08%
```

The handler compiles to clr EX1 / setb rx_irq / reti.

The timer interrupt now raises a tick flag too, so idle() no longer works
out TICKS_DUE twice per pass, and cmd_available moves from xdata to a
bit. The four wake-up flags sit in the low bits of one byte at 0x20, so
the sleep test is a single read of that byte. tx_buf_empty deliberately
stays out: it is 1 when there is nothing to do, so including it would
keep the sleep test from ever firing.
2026-09-23 16:12:32 +02:00
d00f fa0eb91586 health: build the instrumentation only when asked for
The counters, the phase hooks in idle() and the "health" command are now
behind HEALTH, set from the command line with HEALTH=1. Without it the
hooks are empty macros and the command does not exist, so a default build
carries none of it: on SWTGW218AS that is 1065 bytes of bank 2, 101 of the
common segment and 28 of xdata, plus seven banked calls per main-loop pass.

It is a developer's tool. Reading the dump takes knowing the main loop, and
a user who needs it for a report can build with the flag on, which is how
the kernel treats its lock and latency instrumentation as well.
2026-09-21 22:25:32 +02:00
d00f d37ce07119 health: a CLI dump of where the main loop's time goes
Every probe of a misbehaving switch so far measured it from the
outside. This puts the witnesses inside.

Each idle() pass increments a loop counter and stamps a checkpoint
after every phase: link polling, SFP, RX, TX, STP and the command
dispatch. A phase spanning two or more system ticks counts as slow and
its worst time is kept, in 5 ms units. handle_rx counts frames, so the
dump separates a flooded CPU from a stalled loop.

At boot the free stack area is painted, preserving the interrupt state
around the painting, and the dump reports how much of the pattern
survives next to the live stack pointer. The TCP connection table is
printed whole: state, timers, retransmissions, ports and peer, next to
the httpd transfer state, so a permanently occupied slot names its
occupant. With more than one slot configured every slot is listed.

Everything is raw hex; two dumps a known time apart give the rates.
The implementation sits in cmd_parser next to the other command
handlers and needs no storage beyond its counters.
2026-09-21 22:25:32 +02: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
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 2e2529be27 syslog: print the server address with print_ip()
The status line built the dotted quad by hand, which is what
print_ip() from cmd_parser.c already does. Reusing it drops seven
calls to one and takes 48 bytes off BANK2.

The prototype is not __banked because cmd_parser.c and syslog.c are
both in BANK2; a plain call is what the compiler needs here. Should
either file move to another bank, this has to become __banked with it.
2026-09-03 21:27:02 +02:00
UAb5eSMn 2316ffd493 Support for executing multiple commands via /cmd 2026-05-15 13:27:09 +02:00
René van Dorst d2e79d4d80 Fix: In commit 8cbafaa cmd_tokenize() has changed. Missed that it also used
outside cmd_parser.c.
Fix the other location and headerfile.
2026-04-21 21:17:22 +02:00
logicog 94d4ace88b Add support for command line editing
The current code for entering commands via the serial CLI is completely
refactored and moved out of rtlplayground.c into a separate file cmd_edit.c
putting code into BANK2.
The serial ring buffer sbuf[] is now exclusively used for receiving
keys, including escape sequences (DEL will generate a 4-byte escape
sequence). The command is now held in cmd_buffer. This reduces
XMEM use, because the serial buffer can be much smaller.

Supported is only editing the current command line via backspace, del,
cursor left and right.

Because the code cannot distinguish escape sequences which are not yet
complete (because the serial isr has not yet put all characters into
the serial buffer) from the dozens of unsupported ones (F-keys/home,
Page up/down, cursor up/down...) they are ignored and remain in the
serial buffer until the ring-pointer overwrites them. This is standard
behaviour for consoles, which will print out garbage for unsupported
characters. In this implementation, the command line buffer and the
visible command line in the terminal are always synced, so garbage
can be removed again by ediing the line.

The code makes several redundant checks in order to prevent race-conditions
between the serial ISR and the comand-editing code.
2026-02-24 19:57:22 +01:00
chriz 5662285a3e Clear command log after saving. 2026-01-26 23:29:23 +01:00
René van Dorst f59be9cf2b Added software version + git short hash string to firmware.
The Makefile has the version number and generates a version.h which
has VERSION_SW define that looks like "v<VERSION>-g<GIT_SHORT_HASH>".

Software version shows at boot in the serial console.
And shown with command: `version`.

It can also be requested via `information.json`.
```
{
    "ip_address": "192.168.10.247",
    "ip_gateway": "192.168.10.1",
    "ip_netmask": "255.255.255.0",
    "mac_address": "1c:2a:a3:23:00:02",
    "sw_ver": "v0.1.0-gd48235f",
    "hw_ver": "SWGT024-V2.0"
}
```
2025-11-26 23:08:23 +01:00
logicog ba902a68d4 Defer cmd execution for console and via http POST 2025-10-21 18:05:33 +02:00
logicog 52f8366d03 Improve command parser to work with other than serial buffer 2025-08-21 16:11:22 +02:00
logicog 8b1b4aff68 Fix parsing of mirror command, fix parsing of serial buffer beyond wrap arond, add bulk reading of flash and start of config file parser 2025-07-28 23:04:08 +02:00
logicog 846494dc46 Move parsing to external module 2025-07-05 09:23:20 +02:00