diff --git a/rtl837x_lacp.c b/rtl837x_lacp.c index f03ef8ef..276e80d5 100644 --- a/rtl837x_lacp.c +++ b/rtl837x_lacp.c @@ -270,6 +270,8 @@ void lacp_send(uint8_t port) __banked */ void lacp_in(void) __banked { + __xdata uint8_t port, lag; + lacp_rxbody = TRAP_RX_BODY(); if (uip_len < lacp_rxbody + sizeof(struct lacpdu_in)) { uip_len = 0; @@ -284,12 +286,12 @@ void lacp_in(void) __banked /* Per rtl837x_common.h, pmask carries a 4-bit port number on RX * (hardware-verified on RTL8373: per-port rx counters track the actual * ingress port through full LACP convergence). */ - __xdata uint8_t port = ((uint8_t)HTONS(LACP_H->rtl_tag.pmask)) & 0x0f; + port = ((uint8_t)HTONS(LACP_H->rtl_tag.pmask)) & 0x0f; if (port < machine.min_port || port > machine.max_port) return; /* Only ports assigned to a LACP-mode LAG participate in the protocol. */ - __xdata uint8_t lag = lacp_port_lag[port]; + lag = lacp_port_lag[port]; if (lag == LACP_LAG_NONE) return; if (lacp_sys_eq(LACP_I->actor.sys, uip_ethaddr.addr)) diff --git a/test/Makefile b/test/Makefile index e47cbf4e..cdb27355 100644 --- a/test/Makefile +++ b/test/Makefile @@ -28,7 +28,8 @@ TESTS = $(BUILDDIR)/test_cmd_editor \ $(BUILDDIR)/test_port_tables \ $(BUILDDIR)/test_page_json \ $(BUILDDIR)/test_httpd_tx \ - $(BUILDDIR)/test_tick_gate + $(BUILDDIR)/test_tick_gate \ + $(BUILDDIR)/test_lacp # The table tests link the register mock and one environment file; stub/ # stands in for the two headers a firmware build generates. @@ -54,29 +55,24 @@ $(BUILDDIR)/test_tick_gate: test_tick_gate.c support.c $(SRCROOT)/cmd_editor.c | $(BUILDDIR)/test_page_json: test_page_json.c $(TABLE_ENV) hw_mock.h | $(BUILDDIR) $(CC) $(CFLAGS) $(filter %.c,$^) -o $@ $(LDFLAGS) +# rtl837x_lacp.c is compiled UNMODIFIED from the firmware tree. +$(BUILDDIR)/test_lacp: test_lacp.c $(SRCROOT)/rtl837x_lacp.c | $(BUILDDIR) + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) + # httpd/httpd.c and uip/uip.c are compiled UNMODIFIED from the firmware tree; # this test carries the environment below them itself. $(BUILDDIR)/test_httpd_tx: test_httpd_tx.c $(SRCROOT)/httpd/httpd.c $(SRCROOT)/uip/uip.c | $(BUILDDIR) $(CC) $(CFLAGS) $(filter %.c,$^) -o $@ $(LDFLAGS) -# Sandboxes with a Makefile of their own; each fails the run when it fails. -SUBTESTS = lacp port_hash - run: $(TESTS) @fail=0; for t in $(TESTS); do \ echo "=== $$t ==="; \ $$t || fail=1; \ echo; \ done; \ - for d in $(SUBTESTS); do \ - echo "=== $$d ==="; \ - $(MAKE) -C $$d test || fail=1; \ - echo; \ - done; \ if [ $$fail -ne 0 ]; then echo "TESTS FAILED"; exit 1; else echo "ALL TESTS PASSED"; fi clean: rm -rf $(BUILDDIR) - @for d in $(SUBTESTS); do $(MAKE) -C $$d clean; done .PHONY: all run clean diff --git a/test/README.md b/test/README.md index 4f040d5a..a79b3242 100644 --- a/test/README.md +++ b/test/README.md @@ -48,8 +48,7 @@ fires — so it drops straight into CI. | `test_port_tables` | `rtl837x_port.c` | VLAN entry layout and round trip, PVID register sharing, static multicast and management entries, per-port flush, trunk membership and hash seed | | `test_page_json` | `httpd/page_impl.c` + `rtl837x_port.c` | `/vlan.json`, `/vlanlist`, `/l2.json` (walk, wrap marker, paging inside `outbuf`), 64-bit counters in `/status.json` and `/counters.json` | | `test_httpd_tx` | `httpd/httpd.c` + `uip/uip.c` | a GET of a static file against a client that moves its receive window: ACK accounting, continuation chunks out of flash, retransmission | -| `lacp/` | `rtl837x_lacp.c` | state machines against a simulated 802.3ad partner: convergence, mis-cabling, expiry, re-election, two groups, LACPDU containment entries | -| `port_hash/` | `port_lag_members_set()` | a LAG seeds its own hash register | +| `test_lacp` | `rtl837x_lacp.c` | state machines against a simulated 802.3ad partner: convergence, mis-cabling, expiry, re-election, two groups, delivery by trap | ## Adding a test for another module 1. Write `test_.c` with `main()` driving the module's entry points and diff --git a/test/lacp/.gitignore b/test/lacp/.gitignore deleted file mode 100644 index 567609b1..00000000 --- a/test/lacp/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build/ diff --git a/test/lacp/Makefile b/test/lacp/Makefile deleted file mode 100644 index 856f21e5..00000000 --- a/test/lacp/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# Host-side sandbox for the firmware LACP state machines. -# -# Compiles the UNMODIFIED ../../rtl837x_lacp.c against shim headers: SDCC -# storage-class keywords are blanked via -D, and the module copy lives in -# build/ so quote-includes resolve to shim/ (its own directory has no real -# platform headers) instead of the firmware tree. rtl837x_trap.h is copied -# alongside it for the same reason: TRAP_RX_BODY() is what delivery by trap -# rests on, so the test must use the real macro, not a shim restating it. -CC ?= cc -CFLAGS = -std=c11 -Wall -Wextra -Wno-unknown-pragmas \ - -D__xdata= -D__code= -D__banked= -D__reentrant= \ - -Ishim -I../.. - -all: test - -test: build/lacp_sim - ./build/lacp_sim - -verbose: build/lacp_sim - ./build/lacp_sim -v - -build/lacp_sim: lacp_sim.c ../../rtl837x_lacp.c ../../rtl837x_lacp.h ../../rtl837x_trap.h shim/*.h - mkdir -p build - cp ../../rtl837x_lacp.c build/lacp_under_test.c - cp ../../rtl837x_trap.h build/rtl837x_trap.h - $(CC) $(CFLAGS) -o $@ lacp_sim.c build/lacp_under_test.c - -clean: - rm -rf build - -.PHONY: all test verbose clean diff --git a/test/lacp/shim/machine.h b/test/lacp/shim/machine.h deleted file mode 100644 index 7f6612fb..00000000 --- a/test/lacp/shim/machine.h +++ /dev/null @@ -1,12 +0,0 @@ -/* Host-build shim: rtl837x_lacp.c reads min_port/max_port and, for the - * console dump, the front-panel numbering. The real map is not the identity - * on any machine, so the harness uses a shuffled one to keep a logical index - * from passing as a physical port by accident. */ -#ifndef _SHIM_MACHINE_H_ -#define _SHIM_MACHINE_H_ -#include -struct machine { uint8_t min_port; uint8_t max_port; uint8_t log_to_phys_port[9]; }; -extern const struct machine machine; -struct machine_runtime { uint8_t isRTL8373; }; -extern struct machine_runtime machine_detected; -#endif diff --git a/test/lacp/shim/rtl837x_common.h b/test/lacp/shim/rtl837x_common.h deleted file mode 100644 index b21c7141..00000000 --- a/test/lacp/shim/rtl837x_common.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Host-build shim for rtl837x_common.h - just enough for rtl837x_lacp.c. - * Layouts of rtl_tag/vlan_tag and the frame-desc size mirror the real header; - * the harness static-asserts the resulting on-wire struct sizes. - */ -#ifndef _SHIM_RTL837X_COMMON_H_ -#define _SHIM_RTL837X_COMMON_H_ - -#include -#include /* memcpy/memset - firmware provides its own */ - -struct rtl_tag { - uint16_t tag; - uint8_t version; - uint8_t reason; - uint16_t flags; - uint16_t pmask; /* TX: port bitmask; RX: 4-bit port number */ -}; - -struct vlan_tag { - uint16_t svlan; - uint16_t vlan; -}; - -#define RTL_TAG_SIZE (sizeof (struct rtl_tag)) -#define VLAN_TAG_SIZE (sizeof (struct vlan_tag)) -#define RTL_FRAME_TAG_ID 0x8899 -#define RTL_FRAME_TAG_VERSION 0x04 -#define RTL_FRAME_DESC_SIZE 12 -#define ETHER_HEADER_SIZE 14 - -#define HTONS(n) ((uint16_t)((((uint16_t)(n)) << 8) | (((uint16_t)(n)) >> 8))) - -/* Console output - provided by the harness */ -void print_string(char *s); -void print_byte(uint8_t b); -void print_short(uint16_t v); -void write_char(char c); - -#endif - -/* Host-build shim: port masks used by lacp_isolation_update() */ -#ifndef PMASK_CPU -#define CPU_PORT 9 -#define PMASK_9 0x1ff -#define PMASK_6 0x1f8 -#define PMASK_CPU 0x200 -#endif - -/* Host-build shim: directed-egress/strip-tag bit (bit15 of TX pmask word) */ -#ifndef RTL_TAG_ALLOW -#define RTL_TAG_ALLOW 0x8000 -#endif - -/* Host-build shim: tag flags word bits (tag_rtl8_4) */ -#ifndef RTL_TAG_LEARN_DIS -#define RTL_TAG_LEARN_DIS 0x0020 -#define RTL_TAG_KEEP 0x0080 -#define SYS_TICK_HZ 200 -extern volatile uint32_t ticks; -#define TICKS_DUE(last, period) ((uint8_t)((uint8_t)ticks - (last)) >= (period)) - -#endif diff --git a/test/lacp/shim/rtl837x_port.h b/test/lacp/shim/rtl837x_port.h deleted file mode 100644 index 646d5253..00000000 --- a/test/lacp/shim/rtl837x_port.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Host-build shim: the harness mocks trunk programming and records calls */ -#ifndef _SHIM_RTL837X_PORT_H_ -#define _SHIM_RTL837X_PORT_H_ -#include -void port_lag_members_set(uint8_t lag, uint16_t members); -void port_isolate(uint8_t port, uint16_t pmask); -#endif diff --git a/test/lacp/shim/rtl837x_regs.h b/test/lacp/shim/rtl837x_regs.h deleted file mode 100644 index 2dc92d8d..00000000 --- a/test/lacp/shim/rtl837x_regs.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Host-build shim for rtl837x_regs.h - the register numbers rtl837x_lacp.c - * touches, with the values from the real header so a wrong constant shows up - * as a failing expectation rather than as a silent no-op. - */ -#ifndef _SHIM_RTL837X_REGS_H_ -#define _SHIM_RTL837X_REGS_H_ - -#include - -#define RTL837X_RMA2_CONF 0x4ed4 -#define RTL837X_RMA_ACT_TRAP 0x10 -#define RTL837X_RMA_ACT_DROP 0x20 - -/* Registers touched by lacp_send's CPU-port targeting */ -#define RTL837X_PORT_ISOLATION_BASE 0x50c0 -#define RTL837X_REG_NIC_TXCMD 0x7850 - -#endif diff --git a/test/lacp/shim/uip.h b/test/lacp/shim/uip.h deleted file mode 100644 index 0d5a51ec..00000000 --- a/test/lacp/shim/uip.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Host-build shim for uip.h - frame buffer + TX hook used by rtl837x_lacp.c */ -#ifndef _SHIM_UIP_H_ -#define _SHIM_UIP_H_ -#include -#define UIP_CONF_BUFFER_SIZE 600 -struct uip_eth_addr { uint8_t addr[6]; }; -extern uint16_t uip_len; -void tcpip_output(void); -#endif diff --git a/test/port_hash/.gitignore b/test/port_hash/.gitignore deleted file mode 100644 index cf8f788c..00000000 --- a/test/port_hash/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -test_lag_hash -port_lag_members_set.inc diff --git a/test/port_hash/Makefile b/test/port_hash/Makefile deleted file mode 100644 index feeee940..00000000 --- a/test/port_hash/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -test: port_lag_members_set.inc - gcc -Wall -Wextra -O1 -o test_lag_hash test_lag_hash.c && ./test_lag_hash -port_lag_members_set.inc: ../../rtl837x_port.c - awk '/^void port_lag_members_set/,/^}/' $< > $@ -clean: - rm -f test_lag_hash port_lag_members_set.inc diff --git a/test/port_hash/test_lag_hash.c b/test/port_hash/test_lag_hash.c deleted file mode 100644 index 205d3fc8..00000000 --- a/test/port_hash/test_lag_hash.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Host test for port_lag_members_set(): the default load-balancing hash must be - * seeded into the CURRENT trunk's register (BASE + lag*4), never trunk 0's, and - * must not overwrite a hash that is already set. Compiles the REAL function - * (extracted verbatim from rtl837x_port.c) against register-recording shims. */ -#include -#include -#include - -#define __banked -#define __xdata -#define __code - -/* register defs (mirror rtl837x_regs.h) */ -#define RTL837X_TRK_MBR_CTRL_BASE 0x4f38 -#define RTL837X_TRK_HASH_CTRL_BASE 0x4f48 -#define LAG_HASH_SOURCE_PORT_NUMBER 0x01 -#define LAG_HASH_L2_SMAC 0x02 -#define LAG_HASH_L2_DMAC 0x04 -#define LAG_HASH_L3_SIP 0x08 -#define LAG_HASH_L3_DIP 0x10 -#define LAG_HASH_L4_SPORT 0x20 -#define LAG_HASH_L4_DPORT 0x40 -#define LAG_HASH_DEFAULT (LAG_HASH_L2_SMAC|LAG_HASH_L2_DMAC|LAG_HASH_L3_SIP|LAG_HASH_L3_DIP|LAG_HASH_L4_SPORT|LAG_HASH_L4_DPORT) -#define LAG_HASH_RESET (LAG_HASH_SOURCE_PORT_NUMBER|LAG_HASH_L2_SMAC|LAG_HASH_L2_DMAC|LAG_HASH_L3_SIP|LAG_HASH_L3_DIP|LAG_HASH_L4_SPORT) - -uint8_t SFR_DATA_24, SFR_DATA_16, SFR_DATA_8, SFR_DATA_0; -uint8_t sfr_data[4]; -static uint32_t reg_store[0x10000]; - -void reg_read_m(uint16_t r){ uint32_t v=reg_store[r]; - sfr_data[0]=(v>>24)&0xff; sfr_data[1]=(v>>16)&0xff; sfr_data[2]=(v>>8)&0xff; sfr_data[3]=v&0xff; } -void reg_write(uint16_t r){ reg_store[r]=((uint32_t)SFR_DATA_24<<24)|((uint32_t)SFR_DATA_16<<16)|((uint32_t)SFR_DATA_8<<8)|SFR_DATA_0; } -void print_string(char*s){(void)s;} void print_byte(uint8_t b){(void)b;} -void print_short(uint16_t s){(void)s;} void write_char(char c){(void)c;} - -#define REG_SET(r,v) do{ SFR_DATA_24=((uint32_t)(v)>>24)&0xff; SFR_DATA_16=((uint32_t)(v)>>16)&0xff; \ - SFR_DATA_8=((uint32_t)(v)>>8)&0xff; SFR_DATA_0=(v)&0xff; reg_write(r); }while(0) -#define REG_WRITE(r,a,b,c,d) do{ SFR_DATA_24=(a); SFR_DATA_16=(b); SFR_DATA_8=(c); SFR_DATA_0=(d); reg_write(r); }while(0) - -/* THE REAL FUNCTION (extracted from rtl837x_port.c at build time) */ -#include "port_lag_members_set.inc" - -static int fails; -#define CK(cond,msg,...) do{ if(cond){printf("PASS " msg "\n",##__VA_ARGS__);} else {printf("FAIL " msg "\n",##__VA_ARGS__); fails++;} }while(0) - -int main(void){ - for(int lag=0; lag<4; lag++){ - memset(reg_store,0,sizeof(reg_store)); - port_lag_members_set(lag, 0x0180); - uint16_t h = RTL837X_TRK_HASH_CTRL_BASE + (lag<<2); - uint16_t m = RTL837X_TRK_MBR_CTRL_BASE + (lag<<2); - CK(reg_store[h]==LAG_HASH_DEFAULT, "lag%d: default 0x%02x -> hash reg 0x%04x", lag, LAG_HASH_DEFAULT, h); - CK(reg_store[m]==0x0180, "lag%d: members 0x0180 -> mbr reg 0x%04x", lag, m); - if(lag) CK(reg_store[RTL837X_TRK_HASH_CTRL_BASE]==0, "lag%d: trunk-0 hash NOT clobbered", lag); - } - /* guard: existing hash must survive a later member change */ - memset(reg_store,0,sizeof(reg_store)); - reg_store[RTL837X_TRK_HASH_CTRL_BASE+(1<<2)] = 0x06; /* lag1 already L2 */ - port_lag_members_set(1, 0x00c0); - CK(reg_store[RTL837X_TRK_HASH_CTRL_BASE+(1<<2)]==0x06, "guard: preset lag1 hash 0x06 preserved"); - /* the chip's reset value counts as unset and is replaced by the default */ - memset(reg_store,0,sizeof(reg_store)); - reg_store[RTL837X_TRK_HASH_CTRL_BASE+(2<<2)] = LAG_HASH_RESET; - port_lag_members_set(2, 0x0003); - CK(reg_store[RTL837X_TRK_HASH_CTRL_BASE+(2<<2)]==LAG_HASH_DEFAULT, "reset value 0x%02x replaced by default on lag2", LAG_HASH_RESET); - printf(fails? "\n=== FAIL (%d) ===\n" : "\n=== ALL PASS ===\n", fails); - return fails?1:0; -} diff --git a/test/lacp/lacp_sim.c b/test/test_lacp.c similarity index 97% rename from test/lacp/lacp_sim.c rename to test/test_lacp.c index 13d571cd..f0ab5f3f 100644 --- a/test/lacp/lacp_sim.c +++ b/test/test_lacp.c @@ -1,13 +1,3 @@ -/* - * Host-side sandbox for the RTL837x LACP implementation. - * - * Compiles the UNMODIFIED rtl837x_lacp.c against shim headers (see shim/) and - * drives it with synthetic LACPDUs from a simulated partner switch/bond. This - * exercises the real state machines that ship in the firmware image - only - * the platform below them (frame I/O, trunk registers, console) is mocked. - * - * Run: make -C test/lacp (exit code 0 = all scenarios pass) - */ #include #include #include @@ -31,7 +21,7 @@ uint8_t lacpEnabled; uint16_t management_vlan; /* mocked; slow-protocol path zeroes it per-frame */ static int verbose = 0; -void print_string(char *s) { if (verbose) fputs(s, stdout); } +void print_string(const char *s) { if (verbose) fputs(s, stdout); } void print_byte(uint8_t b) { if (verbose) printf("%02x", b); } void print_short(uint16_t v) { if (verbose) printf("%04x", v); } void write_char(char c) { if (verbose) putchar(c); }