diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 31a94891..7097ef48 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,6 +5,11 @@ on: branches: ['**'] pull_request: +permissions: + contents: read + pull-requests: write + issues: write + jobs: build: runs-on: ubuntu-latest @@ -13,18 +18,33 @@ jobs: steps: - uses: actions/checkout@v6 + with: + path: branch + + - uses: actions/checkout@v6 + with: + path: main + ref: main - name: Install dependencies run: | apt update apt install make gcc sdcc xxd python-is-python3 libjson-c-dev zlib1g-dev -y - name: Run the host-side unit tests - run: make -C test + run: cd branch && make -C test - name: Check that every machine definition can be compiled - run: make machine_check + run: cd branch && make machine_check - name: Make project (4x2/RTL8372) - run: make CI=1 MACHINE="KP_9000_6XHML_X2" + run: cd branch && make CI=1 MACHINE="KP_9000_6XHML_X2" && cp output/KP_9000_6XHML_X2/rtlplayground.map /tmp/branch.map - name: Make project (8x1/RTL8373) - run: make CI=1 MACHINE="KP_9000_9XHML_X_V3_1" + run: cd branch && make CI=1 MACHINE="KP_9000_9XHML_X_V3_1" - name: Make project with the health instrumentation - run: make clean && make CI=1 MACHINE="KP_9000_6XHML_X2" HEALTH=1 + run: cd branch && make clean && make CI=1 MACHINE="KP_9000_6XHML_X2" HEALTH=1 + - name: Make main + run: cd main && make CI=1 MACHINE="KP_9000_6XHML_X2" && cp output/KP_9000_6XHML_X2/rtlplayground.map /tmp/main.map + - name: Calculate bank growth + run: | + sed -rn 's/^([XCD]SEG|(BANK[0-9])).*=\s+([0-9]+)\. bytes.*$/MAIN_\1=\3/p' /tmp/main.map | sort -u >> "$GITHUB_ENV" + sed -rn 's/^([XCD]SEG|(BANK[0-9])).*=\s+([0-9]+)\. bytes.*$/BRANCH_\1=\3/p' /tmp/branch.map | sort -u >> "$GITHUB_ENV" + du -sb main/output/KP_9000_6XHML_X2/html_min | awk '{print "MAIN_WEB="$1}' >> "$GITHUB_ENV" + du -sb branch/output/KP_9000_6XHML_X2/html_min | awk '{print "BRANCH_WEB="$1}' >>"$GITHUB_ENV" diff --git a/.gitignore b/.gitignore index 11f5c4ed..9f544835 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .gitignore .idea/ output/ +output-main/ html_data.c html_data.h version.h @@ -12,3 +13,4 @@ build/ # host-test stand-ins for the two generated headers !test/stub/html_data.h !test/stub/version.h +.vscode diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f019c10..879a6682 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,9 @@ - Accept firmware uploads regardless of the file part's MIME type, including `application/macbinary` sent by Chrome on macOS for `.bin` files. +- Health + - `HEALTH=1` builds no longer write past the phase timing arrays at the LLDP checkpoint, which + corrupted the `link` slow counter and the DHCP client state. #658 - Config - A startup configuration line longer than the command buffer no longer stops the replay: the offending line is skipped and the following lines are still applied. diff --git a/Makefile b/Makefile index c95f12af..5754ee08 100644 --- a/Makefile +++ b/Makefile @@ -15,11 +15,10 @@ SUBDIRS := tools SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS)) # $MACHINE selects machine/$(MACHINE).c as the board definition and is passed -# on as -DMACHINE_$(MACHINE), which the rest of the firmware tests with -# #if defined(MACHINE_...), and as -DMACHINE_NAME, which machine.h uses to -# include machine/$(MACHINE).h. Both take the same value, so they cannot drift. +# on as -DMACHINE_NAME, which machine.h uses to include machine/$(MACHINE).h. +# Board selection itself needs no MACHINE_* symbol for #if chains, so the +# definition is all the compiler has to know. ifneq ($(MACHINE),) - CC_FLAGS += -DMACHINE_$(MACHINE) CC_FLAGS += -DMACHINE_NAME=$(MACHINE) endif # Health instrumentation and the "health" console command: HEALTH=1 gmake ... @@ -34,7 +33,16 @@ endif # The board definition being built: one file per MACHINE_* symbol in machine.h. MACHINE_SRC = machine/$(MACHINE).c -BUILDDIR = output/$(MACHINE) +MACHINE_INIT_DEFAULT := machine/default_machine_init.c +MACHINE_INIT_SRC := $(wildcard machine/$(MACHINE)_init.c) +ifeq ($(MACHINE_INIT_SRC),) + MACHINE_INIT_SRC := $(MACHINE_INIT_DEFAULT) +endif + +ifndef BUILDDIR + BUILDDIR = output/$(MACHINE) +endif + VERSION_HEADER := version.h GIT_VERSION := $(shell git rev-parse --short HEAD) @@ -61,6 +69,9 @@ endif # is built, including the tools/ subdirectory. all: create_build_dir $(VERSION_HEADER) $(MACHINE_SRC) $(SUBDIRS) $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin +bank_size: + tools/bank_occupancy.sh "$(MACHINE)" + create_build_dir: mkdir -p "$(BUILDDIR)" mkdir -p "$(BUILDDIR)/uip" @@ -81,7 +92,7 @@ $(MACHINE_SRC): # invalid $MACHINE value SRCS = \ $(MACHINE_SRC) \ - machine_init.c \ + $(MACHINE_INIT_SRC) \ cmd_editor.c \ cmd_parser.c \ dhcp.c \ @@ -133,7 +144,7 @@ HTML := $(shell find html -name '*.js' -or -name '*.html' -or -name '*.svg' -or # Minified copy of the web UI sources, used as the fileadder input. # The raw html/ sources stay untouched for development; the minified # copy is a build artifact under output/. -HTML_MIN := output/html_min +HTML_MIN := $(BUILDDIR)/html_min .PHONY: html_min html_min: $(HTML) rm -rf $(HTML_MIN) @@ -141,7 +152,7 @@ html_min: $(HTML) @for f in $(HTML); do python3 tools/minify.py $$f $(HTML_MIN)/$$(basename $$f) || exit 1; done html_data.c html_data.h &: $(HTML) | tools html_min - tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -z -d $(HTML_MIN) -p html_data + tools/$(BUILDDIR)/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -z -d $(HTML_MIN) -p html_data $(VERSION_HEADER): FORCE @printf '%s\n' "#ifndef VERSION_H" "#define VERSION_H" \ @@ -155,7 +166,7 @@ $(VERSION_HEADER): FORCE httpd: html_data.h $(SUBDIRS): - $(MAKE) -C $@ + $(MAKE) -C $@ BUILDDIR=$(BUILDDIR) clean: $(SUBDIRSCLEAN) -rm -f html_data.c html_data.h $(VERSION_HEADER) @@ -193,31 +204,35 @@ $(BUILDDIR)/rtlplayground.img: $(BUILDDIR)/rtlplayground.ihx $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.img | tools if [ -e $@ ]; then rm $@; fi - tools/output/imagebuilder -i $^ $@ - tools/output/fileadder -a $(DEFAULT_CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@ - tools/output/fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@ - tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -z -d $(HTML_MIN) -b BANK1 $@ - tools/output/crc_calculator -u $@ - ln -sf $(MACHINE)/rtlplayground-$(FILENAME_EXTENSION).bin output/rtlplayground.bin + tools/$(BUILDDIR)/imagebuilder -i $^ $@ + tools/$(BUILDDIR)/fileadder -a $(DEFAULT_CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@ + tools/$(BUILDDIR)/fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@ + tools/$(BUILDDIR)/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -z -d $(HTML_MIN) -b BANK1 $@ + tools/$(BUILDDIR)/crc_calculator -u $@ + ln -sf $(MACHINE)/rtlplayground-$(FILENAME_EXTENSION).bin $(BUILDDIR)/../rtlplayground.bin .PHONY: clean distclean all $(SUBDIRS) $(SUBDIRSCLEAN) create_build_dir # Every machine/ definition is compiled, so a machine added to machine/ is -# covered without registering it anywhere. The machine-specific defines are +# covered without registering it anywhere. The _init.c files are excluded here: +# they are the boot hooks, compiled separately below (the board's own if it +# exists, otherwise default_machine_init.c). The machine-specific defines are # filtered out of $(CC_FLAGS) and supplied per iteration instead, so this also # works as "make machine_check MACHINE=...". -MACHINE_DEFS := $(sort $(patsubst machine/%.c,%,$(wildcard machine/*.c))) +MACHINE_DEFS := $(sort $(patsubst machine/%.c,%,$(filter-out machine/%_init.c,$(wildcard machine/*.c)))) MACHINE_LESS_CC_FLAGS = $(filter-out -DMACHINE_%,$(CC_FLAGS)) -.PHONY: +.PHONY: machine_check machine_check: @mkdir -p $(BUILDDIR)/tmp @set -eo pipefail; \ for MACHINE in $(MACHINE_DEFS); \ do \ echo "Checking $${MACHINE}"; \ - $(CC) $(MACHINE_LESS_CC_FLAGS) -DMACHINE_$${MACHINE} -DMACHINE_NAME=$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine/$${MACHINE}.c; \ - $(CC) $(MACHINE_LESS_CC_FLAGS) -DMACHINE_$${MACHINE} -DMACHINE_NAME=$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine_init.c; \ + $(CC) $(MACHINE_LESS_CC_FLAGS) -DMACHINE_NAME=$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine/$${MACHINE}.c; \ + INIT=machine/$${MACHINE}_init.c; \ + if [ ! -e $$INIT ] && [ ! -L $$INIT ]; then INIT=$(MACHINE_INIT_DEFAULT); fi; \ + $(CC) $(MACHINE_LESS_CC_FLAGS) -DMACHINE_NAME=$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c $$INIT; \ done @rm -rf $(BUILDDIR)/tmp diff --git a/cmd_parser.c b/cmd_parser.c index afc7831a..f7b1f5cb 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -266,7 +266,7 @@ uint8_t cmd_parse_port(uint8_t idx) { return 0; port = machine.phys_to_log_port[port]; - if (port < machine.min_port || port > machine.max_port) + if (!MACHINE_PORT_VALID(port)) return 0; atoi_results_u8 = port; @@ -743,7 +743,7 @@ void parse_isolate(void) } if (cmd_compare(2, "off")) { - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) members |= ((uint16_t)1) << i; members |= PMASK_CPU; // CPU-port port_isolate(port_configured, members); @@ -797,7 +797,7 @@ void parse_ingress(void) if (!cmd_is_space_or_nul(idx)) goto err; // Setting mode for all ports at once - for (log_port = machine.min_port; log_port <= machine.max_port; log_port++) { + for (log_port = MACHINE_MIN_PORT; log_port <= MACHINE_MAX_PORT; log_port++) { if (!port_ingress_filter(log_port, mode)) { cmd_error("cannot set the ingress filter for port "); print_phys_port(log_port); write_char('\n'); return; @@ -1019,7 +1019,7 @@ void parse_mtu(void) uint8_t p; if (cmd_compare(1, "show")) { - for (p = machine.min_port; p <= machine.max_port; p++) { + for (p = MACHINE_MIN_PORT; p <= MACHINE_MAX_PORT; p++) { reg_read_m(RTL8373_REG_MAC_L2_PORT_MAX_LEN + ((uint16_t) p << 8)); uint16_t mtu = SFR_DATA_U16 & 0x3fff; print_string("Port "); print_phys_port(p); @@ -2329,6 +2329,7 @@ void health_show(void) __banked ph_line("tx ", HEALTH_PH_TX); ph_line("stp ", HEALTH_PH_STP); ph_line("cmd ", HEALTH_PH_CMD); + ph_line("lldp", HEALTH_PH_LLDP); /* Stack: current depth plus how much of the painted area is untouched */ print_string("sp "); diff --git a/cmd_parser.h b/cmd_parser.h index 2359eb16..e6a073ab 100644 --- a/cmd_parser.h +++ b/cmd_parser.h @@ -19,8 +19,8 @@ extern __xdata uint8_t err_status; #define HEALTH_PH_TX 3 #define HEALTH_PH_STP 4 #define HEALTH_PH_CMD 5 -#define HEALTH_PHASES 6 -#define HEALTH_LLDP 7 +#define HEALTH_PH_LLDP 6 +#define HEALTH_PHASES (HEALTH_PH_LLDP + 1) /* last id + 1: sizes the arrays in cmd_parser.c */ extern __xdata uint16_t health_rx_frames; #define health_rx_frame() health_rx_frames++ diff --git a/doc/adding-a-device.md b/doc/adding-a-device.md index 312f318f..7e2aa150 100644 --- a/doc/adding-a-device.md +++ b/doc/adding-a-device.md @@ -15,6 +15,7 @@ make MACHINE= |------|---------| | `machine/.c` | the `struct machine machine` board definition | | `machine/.h` | `MACHINE_MODEL` (the model string shown in the UI and the CLI) and `MACHINE_CHIPSET` (`RTL8372` or `RTL8373`) | +| `machine/_init.c` | optional `machine_custom_init()` boot hook, for registers the machine definition cannot express | | `doc/devices/.md` + `doc/supported_devices.md` | (only if the board is verified and you want to support it publicly) user-facing documentation | `` is the machine symbol without its `MACHINE_` prefix, so `MACHINE` is @@ -37,8 +38,8 @@ existing files as the template: ``` `MACHINE_CHIPSET` is `RTL8373` or `RTL8372`; a build without it will fail. It selects the default -logical port range: `min_port` is `0` for RTL8373 and `3` for RTL8372, while `max_port` is `8`, -the highest logical port index. A board with a different range defines +logical port range: `MACHINE_MIN_PORT` is `0` for RTL8373 and `3` for RTL8372, while +`MACHINE_MAX_PORT` is `8`, the highest logical port index. A board with a different range defines `MACHINE_MIN_PORT` and/or `MACHINE_MAX_PORT` in its header to override the defaults. @@ -93,16 +94,16 @@ __code const struct machine machine = { }; ``` -`MACHINE_COMMON_SETTING` (from `machine_defs.h`) initializes `machine_name`, -`isRTL8373`, `min_port` and `max_port` from the header's `MACHINE_MODEL` and -`MACHINE_CHIPSET`. Keep it as the first initializer and list the -board-specific fields after it. +`MACHINE_COMMON_SETTING` (from `machine_defs.h`) initializes `machine_name` and +`isRTL8373` from the header's `MACHINE_MODEL` and `MACHINE_CHIPSET`. The logical +port range comes from `MACHINE_MIN_PORT` and `MACHINE_MAX_PORT` in `machine.h`. +Keep it as the first initializer and list the board-specific fields after it. ### Fields | Field | Meaning | |-------|---------| -| `MACHINE_COMMON_SETTING` | expands to `machine_name` (`MACHINE_MODEL`), `isRTL8373` (`1` for `RTL8373`, `0` for `RTL8372`), `min_port` and `max_port`; all are derived from the header's `MACHINE_CHIPSET` (see Step 1) | +| `MACHINE_COMMON_SETTING` | expands to `machine_name` (`MACHINE_MODEL`) and `isRTL8373` (`1` for `RTL8373`, `0` for `RTL8372`); both are derived from the header's `MACHINE_CHIPSET` (see Step 1) | | `n_sfp` | number of SFP+ cages | | `n_10g` | SerDes 10G capability used by the RTL837xN init: `0` none, `1` one, `2` two 10G-capable SerDes | | `log_to_phys_port[9]` | logical port (0-based index) → physical front-panel port number | @@ -147,6 +148,20 @@ and the six `KP_9000_*` revision variants. Two files that differ only in whitespace or comments are duplicates and should be collapsed this way. +### Optional custom init hook + +If the board needs custom initialization, add +`machine/_init.c` defining `machine_custom_init()`. The Makefile picks the +file up by name and compiles it. + +Boards that need the same hook share one file: keep the code in a single +`machine/_init.c` whose `machine/.c` is a real file (not a symlink), +and make the other boards' `_init.c` symlinks to it, for example: + +``` +ln -s KP_9000_6XH_X2_init.c machine/MY_BOARD_1_0_init.c +``` + ## Step 3: build and verify ``` @@ -160,7 +175,7 @@ file, before anything is compiled. Then run the checks CI runs: ``` -make machine_check # compiles machine/.c and machine_init.c for every machine +make machine_check # compiles machine/.c and its optional _init.c for every machine make -C test # host-side unit tests ``` diff --git a/doc/health.md b/doc/health.md index 736d52b7..af6b8a28 100644 --- a/doc/health.md +++ b/doc/health.md @@ -14,6 +14,7 @@ rx max 00 slow 0x0000 tx max 00 slow 0x0000 stp max 04 slow 0x0001 cmd max 02 slow 0x0001 +lldp max 00 slow 0x0000 sp 80 untouched 62 tcp st 00 tmr 00 rtx 00 rto 00 len 0x0000 mss 0x05b4 lport 0x0000 rport 0x0000 rip 0x0000 0x0000 @@ -46,7 +47,7 @@ a flooded CPU port from a stalled loop, which look identical from outside. ## Phases Each line is one section of the main loop: the link poll, SFP handling, -frame reception, TCP transmission, the STP timers and the command dispatch. +frame reception, TCP transmission, the STP timers, the LLDP timer and the command dispatch. `max` is the worst time that section has taken, in ticks of 5 ms; `slow` counts the passes that took two ticks or more. A misbehaving subsystem names itself here, which is the difference between knowing that the loop is diff --git a/httpd/page_impl.c b/httpd/page_impl.c index 006d2dbe..7f107b7d 100644 --- a/httpd/page_impl.c +++ b/httpd/page_impl.c @@ -341,7 +341,7 @@ void send_vlan(uint16_t vlan) } slen += strtox(outbuf + slen, "\",\"pvid\":\"0x"); uint16_t pvid_mask = 0; - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { if (port_pvid_get(i) == vlan) pvid_mask |= (1 << i); } @@ -357,7 +357,7 @@ void send_vlan(uint16_t vlan) bool send_counters(uint8_t phys_port) { uint8_t phys_port_idx = phys_port - 1; - if (phys_port_idx > (machine.max_port - machine.min_port)) + if (phys_port_idx > (MACHINE_MAX_PORT - MACHINE_MIN_PORT)) goto err; uint8_t log_port = machine.phys_to_log_port[phys_port_idx]; @@ -676,7 +676,7 @@ void send_stp(void) slen += strtox(outbuf + slen, "\",\"ports\":["); reg_read_m(RTL837X_MSTP_STATES); for (i = 0; i < STP_ENTITIES; i++) { - if (i < STP_LAG_BASE && (i < machine.min_port || i > machine.max_port)) + if (i < STP_LAG_BASE && !MACHINE_PORT_VALID(i)) continue; if (i < STP_LAG_BASE && stp_ent_of[i] != i) continue; @@ -761,7 +761,7 @@ void send_lacp(void) } slen -= 1; // remove comma slen += strtox(outbuf + slen, "],\"ports\":["); - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { slen += strtox(outbuf + slen, "{\"p\":"); itoa_html(machine.log_to_phys_port[i]); slen += strtox(outbuf + slen, ",\"lag\":"); @@ -793,7 +793,7 @@ void send_lldp(void) bool_to_html(lldp_enabled); slen += strtox(outbuf + slen, ",\"portStatus\":["); - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { slen += strtox(outbuf + slen, "{\"portNum\":"); itoa_html(machine.log_to_phys_port[i]); @@ -808,7 +808,7 @@ void send_lldp(void) bool_to_html(1 & (lldp_logical_port_status >> i)); slen += strtox(outbuf + slen, "}"); - if (i < machine.max_port) + if (i < MACHINE_MAX_PORT) char_to_html(','); else char_to_html(']'); @@ -825,7 +825,7 @@ void send_eee(void) uint8_t eee_ablty = sfr_data[3]; char_to_html('['); - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { slen += strtox(outbuf + slen, "{\"portNum\":"); itoa_html(machine.log_to_phys_port[i]); @@ -857,7 +857,7 @@ void send_eee(void) bool_to_html(eee_ablty & (1 << i)); } char_to_html('}'); - if (i < machine.max_port) + if (i < MACHINE_MAX_PORT) char_to_html(','); else char_to_html(']'); @@ -870,7 +870,7 @@ void send_bandwidth(void) dbg_string("send_bandwidth called\n"); slen = strtox(outbuf, HTTP_RESPONCE_JSON); char_to_html('['); - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { slen += strtox(outbuf + slen, "{\"portNum\":"); itoa_html(machine.log_to_phys_port[i]); slen += strtox(outbuf + slen, ",\"iLimited\":"); @@ -900,7 +900,7 @@ void send_bandwidth(void) byte_to_html(sfr_data[3]); char_to_html('"'); char_to_html('}'); - if (i < machine.max_port) + if (i < MACHINE_MAX_PORT) char_to_html(','); else char_to_html(']'); @@ -914,7 +914,7 @@ void send_storm(void) slen = strtox(outbuf, HTTP_RESPONCE_JSON); char_to_html('['); - for (i = machine.min_port; i <= machine.max_port; i++) { + for (i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { slen += strtox(outbuf + slen, "{\"portNum\":"); itoa_html(machine.log_to_phys_port[i]); slen += strtox(outbuf + slen, ",\"en\":\""); @@ -934,7 +934,7 @@ void send_storm(void) } char_to_html('"'); char_to_html('}'); - if (i < machine.max_port) + if (i < MACHINE_MAX_PORT) char_to_html(','); else char_to_html(']'); @@ -949,7 +949,7 @@ void send_isolation(void) dbg_string("send_isolation called\n"); slen = strtox(outbuf, HTTP_RESPONCE_JSON); char_to_html('['); - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { slen += strtox(outbuf + slen, "{\"portNum\":"); itoa_html(machine.log_to_phys_port[i]); slen += strtox(outbuf + slen, ",\"allow\":\""); @@ -958,7 +958,7 @@ void send_isolation(void) byte_to_html(allow & 0xff); char_to_html('"'); char_to_html('}'); - if (i < machine.max_port) + if (i < MACHINE_MAX_PORT) char_to_html(','); } char_to_html(']'); @@ -970,7 +970,7 @@ void send_mtu(void) dbg_string("send_mtu called\n"); slen = strtox(outbuf, HTTP_RESPONCE_JSON); char_to_html('['); - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { slen += strtox(outbuf + slen, "{\"portNum\":"); itoa_html(machine.log_to_phys_port[i]); slen += strtox(outbuf + slen, ",\"mtu\":\"0x"); @@ -980,7 +980,7 @@ void send_mtu(void) byte_to_html(mtu & 0xff); char_to_html('"'); char_to_html('}'); - if (i < machine.max_port) + if (i < MACHINE_MAX_PORT) char_to_html(','); else char_to_html(']'); @@ -994,7 +994,7 @@ void send_status(void) dbg_string("sending status\n"); char_to_html('['); - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { slen += strtox(outbuf + slen, "{\"portNum\":"); itoa_html(machine.log_to_phys_port[i]); slen += strtox(outbuf + slen, ",\"logPort\":"); @@ -1115,7 +1115,7 @@ void send_status(void) slen += strtox(outbuf + slen, "\",\"macs\":\"0x"); reg_to_html(RTL837X_L2_LRN_PORT_CONSTRT_CNT + (i << 2)); slen += strtox(outbuf + slen, "\"}"); - if (i < machine.max_port) + if (i < MACHINE_MAX_PORT) char_to_html(','); else char_to_html(']'); diff --git a/machine.h b/machine.h index 70d75e8b..78dfd77a 100644 --- a/machine.h +++ b/machine.h @@ -42,6 +42,9 @@ #endif #endif +#define MACHINE_PORT_VALID(p) \ + ((uint8_t)((p) - MACHINE_MIN_PORT) <= (MACHINE_MAX_PORT - MACHINE_MIN_PORT)) + // auto derive SOC_FAMILY #define RTL836X 6 #define RTL837X 7 @@ -81,10 +84,6 @@ struct sfp_port struct machine { char machine_name[30]; uint8_t isRTL8373; - // Lowest logical port number - uint8_t min_port; - // Highest logical port number - uint8_t max_port; uint8_t n_sfp; uint8_t n_10g; uint8_t log_to_phys_port[9]; diff --git a/machine/2G5F4_10G2_V1_01.c b/machine/2G5F4_10G2_V1_01.c index e4a78ad1..caca361d 100644 --- a/machine/2G5F4_10G2_V1_01.c +++ b/machine/2G5F4_10G2_V1_01.c @@ -41,8 +41,8 @@ __code const struct machine machine = { * at 2.5G only) and LED-ID2 carries the SFP single LED. The "solid" * conditions (LINK/speed) barely drive the LEDs here and ACT is what * actually lights them, which is why the white LED used to glow faintly at - * non-2.5G speeds; the fix for that is LED_GLB_IO_EN bit 6, set in - * machine_init.c. */ + * non-2.5G speeds; the fix for that is LED_GLB_IO_EN bit 6, set in the + * shared machine_custom_init() hook (machine/2G5F4_10G2_V1_01_init.c). */ .led_sets = { { LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G, LEDS_2G5 | LEDS_LINK | LEDS_10G, LEDS_1G | LEDS_LINK, diff --git a/machine/2G5F4_10G2_V1_01_init.c b/machine/2G5F4_10G2_V1_01_init.c new file mode 120000 index 00000000..37370e2a --- /dev/null +++ b/machine/2G5F4_10G2_V1_01_init.c @@ -0,0 +1 @@ +KP_9000_6XH_X2_init.c \ No newline at end of file diff --git a/machine/FG_4GT_2SX_V2_0_init.c b/machine/FG_4GT_2SX_V2_0_init.c new file mode 100644 index 00000000..c9b9ddab --- /dev/null +++ b/machine/FG_4GT_2SX_V2_0_init.c @@ -0,0 +1,6 @@ +#include "machine_init_defs.h" + +void machine_custom_init(void) __banked +{ + REG_SET(RTL837X_REG_LED_GLB_IO_EN, 0x7624155b); +} diff --git a/machine/FNS1200P_init.c b/machine/FNS1200P_init.c new file mode 120000 index 00000000..37370e2a --- /dev/null +++ b/machine/FNS1200P_init.c @@ -0,0 +1 @@ +KP_9000_6XH_X2_init.c \ No newline at end of file diff --git a/machine/HI_K0402WS_init.c b/machine/HI_K0402WS_init.c new file mode 120000 index 00000000..37370e2a --- /dev/null +++ b/machine/HI_K0402WS_init.c @@ -0,0 +1 @@ +KP_9000_6XH_X2_init.c \ No newline at end of file diff --git a/machine/KP_9000_6XHML_X2_V2_1_init.c b/machine/KP_9000_6XHML_X2_V2_1_init.c new file mode 120000 index 00000000..37370e2a --- /dev/null +++ b/machine/KP_9000_6XHML_X2_V2_1_init.c @@ -0,0 +1 @@ +KP_9000_6XH_X2_init.c \ No newline at end of file diff --git a/machine/KP_9000_6XH_X2_V2_1_init.c b/machine/KP_9000_6XH_X2_V2_1_init.c new file mode 120000 index 00000000..37370e2a --- /dev/null +++ b/machine/KP_9000_6XH_X2_V2_1_init.c @@ -0,0 +1 @@ +KP_9000_6XH_X2_init.c \ No newline at end of file diff --git a/machine/KP_9000_6XH_X2_init.c b/machine/KP_9000_6XH_X2_init.c new file mode 100644 index 00000000..394f71ef --- /dev/null +++ b/machine/KP_9000_6XH_X2_init.c @@ -0,0 +1,6 @@ +#include "machine_init_defs.h" + +void machine_custom_init(void) __banked +{ + reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6); +} diff --git a/machine/PCB_K0402WS_V2_init.c b/machine/PCB_K0402WS_V2_init.c new file mode 120000 index 00000000..37370e2a --- /dev/null +++ b/machine/PCB_K0402WS_V2_init.c @@ -0,0 +1 @@ +KP_9000_6XH_X2_init.c \ No newline at end of file diff --git a/machine/PCB_K0402WS_V3_init.c b/machine/PCB_K0402WS_V3_init.c new file mode 120000 index 00000000..37370e2a --- /dev/null +++ b/machine/PCB_K0402WS_V3_init.c @@ -0,0 +1 @@ +KP_9000_6XH_X2_init.c \ No newline at end of file diff --git a/machine/PCB_SWTG018AS_V2_1_0_init.c b/machine/PCB_SWTG018AS_V2_1_0_init.c new file mode 100644 index 00000000..bce0b814 --- /dev/null +++ b/machine/PCB_SWTG018AS_V2_1_0_init.c @@ -0,0 +1,18 @@ +#include "machine_init_defs.h" + +static __code const struct { uint16_t reg; uint32_t val; } custom_init_regs[] = { + { RTL837X_REG_LED3_0_SET1, 0x00100000UL }, + { RTL837X_REG_LED1_0_SET1, 0x01400155UL }, + { RTL837X_REG_LED1_0_SET0, 0x01740141UL }, + { RTL837X_REG_LED_GLB_IO_EN, 0x7f24977fUL }, + { RTL837X_PIN_MUX_0, 0x20db6880UL }, +}; + +void machine_custom_init(void) __banked +{ + uint8_t i; + // REG_SET is a multi-statement macro without a do-while wrapper: braces required + for (i = 0; i < sizeof(custom_init_regs) / sizeof(custom_init_regs[0]); i++) { + REG_SET(custom_init_regs[i].reg, custom_init_regs[i].val); + } +} diff --git a/machine/PCB_SWTG024AS_A_2_0_1_init.c b/machine/PCB_SWTG024AS_A_2_0_1_init.c new file mode 100644 index 00000000..311bda3e --- /dev/null +++ b/machine/PCB_SWTG024AS_A_2_0_1_init.c @@ -0,0 +1,9 @@ +#include "machine_init_defs.h" + +void machine_custom_init(void) __banked +{ + reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6); + reg_bit_set(RTL837X_REG_LED_MODE, 17); + reg_bit_clear(RTL837X_REG_LED_MODE, 9); + reg_bit_clear(RTL837X_REG_LED_MODE, 7); +} diff --git a/machine/SWTG024AS_A_2_0_1_5C_1SFP_init.c b/machine/SWTG024AS_A_2_0_1_5C_1SFP_init.c new file mode 120000 index 00000000..6297e789 --- /dev/null +++ b/machine/SWTG024AS_A_2_0_1_5C_1SFP_init.c @@ -0,0 +1 @@ +SWTG024AS_V2_0_init.c \ No newline at end of file diff --git a/machine/SWTG024AS_V2_0_init.c b/machine/SWTG024AS_V2_0_init.c new file mode 100644 index 00000000..98d2f0c6 --- /dev/null +++ b/machine/SWTG024AS_V2_0_init.c @@ -0,0 +1,20 @@ +#include "machine_init_defs.h" + +void machine_custom_init(void) __banked +{ + uint16_t pval; + + reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6); + reg_bit_set(RTL837X_REG_LED_MODE, 17); + reg_bit_clear(RTL837X_REG_LED_MODE, 9); + reg_bit_clear(RTL837X_REG_LED_MODE, 7); + + // OEM firmware sets these companion SDS0 polarity bits for the RTL8221B. + sds_read(0, 0, 0); + pval = SFR_DATA_U16; + sds_write_v(0, 0, 0, pval | 0x100); + + sds_read(0, 6, 2); + pval = SFR_DATA_U16; + sds_write_v(0, 6, 2, pval | 0x4000); +} diff --git a/machine/ZX310S_4T2XT_init.c b/machine/ZX310S_4T2XT_init.c new file mode 100644 index 00000000..38a96e25 --- /dev/null +++ b/machine/ZX310S_4T2XT_init.c @@ -0,0 +1,8 @@ +#include "machine_init_defs.h" + +void machine_custom_init(void) __banked +{ + // For this device, the reset value of RTL837X_PIN_MUX_0 is 0x30000000, + // which would disables all LEDS, enable them manually: + REG_SET(RTL837X_PIN_MUX_0, 0x30db68bf); +} diff --git a/machine/default_machine_init.c b/machine/default_machine_init.c new file mode 100644 index 00000000..1ee200f5 --- /dev/null +++ b/machine/default_machine_init.c @@ -0,0 +1,6 @@ +/* + * Fallback boot hook for boards without a machine/_init.c. + */ +#include "machine_init_defs.h" + +void machine_custom_init(void) __banked { } diff --git a/machine/machine_defs.h b/machine/machine_defs.h index 4775a58f..be77636d 100644 --- a/machine/machine_defs.h +++ b/machine/machine_defs.h @@ -43,8 +43,6 @@ #define MACHINE_COMMON_SETTING \ .machine_name = MACHINE_MODEL, \ - .isRTL8373 = MACHINE_CHIPSET == RTL8373, \ - .min_port = MACHINE_MIN_PORT, \ - .max_port = MACHINE_MAX_PORT + .isRTL8373 = MACHINE_CHIPSET == RTL8373 #endif diff --git a/machine/machine_init_defs.h b/machine/machine_init_defs.h new file mode 100644 index 00000000..b3507d25 --- /dev/null +++ b/machine/machine_init_defs.h @@ -0,0 +1,10 @@ +#ifndef _MACHINE_INIT_DEFS_H_ +#define _MACHINE_INIT_DEFS_H_ + + +#include "machine_defs.h" + +#pragma codeseg BANK2 +#pragma constseg BANK2 + +#endif diff --git a/machine_init.c b/machine_init.c deleted file mode 100644 index efb16e61..00000000 --- a/machine_init.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Per-machine one-shot boot hooks, hosted in BANK2 so board-specific - * tables and code do not consume the common bank. - */ -#include -#include "machine.h" -#include "rtl837x_pins.h" -#include "rtl837x_leds.h" -#include "rtl837x_sfr.h" -#include "rtl837x_regs.h" -#include "rtl837x_common.h" - -#pragma codeseg BANK2 -#pragma constseg BANK2 - -#if defined(MACHINE_KP_9000_6XH_X2) || \ - defined(MACHINE_KP_9000_6XH_X2_V2_1) || \ - defined(MACHINE_KP_9000_6XHML_X2_V2_1) || \ - defined(MACHINE_HI_K0402WS) || \ - defined(MACHINE_PCB_K0402WS_V2) || \ - defined(MACHINE_PCB_K0402WS_V3) || \ - defined(MACHINE_2G5F4_10G2_V1_01) || \ - defined(MACHINE_FNS1200P) -void machine_custom_init(void) __banked -{ - reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6); -} - -#elif defined MACHINE_PCB_SWTG018AS_V2_1_0 -// Stock-firmware values for what the LED-set encoding cannot express: the -// bi-color SFP LED (blue pin at 10G) and the PIN_MUX_0 routing of that pin -// to the LED controller. Runs after leds_setup(), which covers the rest. -static __code const struct { uint16_t reg; uint32_t val; } custom_init_regs[] = { - { RTL837X_REG_LED3_0_SET1, 0x00100000UL }, - { RTL837X_REG_LED1_0_SET1, 0x01400155UL }, - { RTL837X_REG_LED1_0_SET0, 0x01740141UL }, - { RTL837X_REG_LED_GLB_IO_EN, 0x7f24977fUL }, - { RTL837X_PIN_MUX_0, 0x20db6880UL }, -}; - -void machine_custom_init(void) __banked -{ - uint8_t i; - // REG_SET is a multi-statement macro without a do-while wrapper: braces required - for (i = 0; i < sizeof(custom_init_regs) / sizeof(custom_init_regs[0]); i++) { - REG_SET(custom_init_regs[i].reg, custom_init_regs[i].val); - } -} - -#elif defined MACHINE_PCB_SWTG024AS_A_2_0_1 -void machine_custom_init(void) __banked -{ - reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6); - reg_bit_set(RTL837X_REG_LED_MODE, 17); - reg_bit_clear(RTL837X_REG_LED_MODE, 9); - reg_bit_clear(RTL837X_REG_LED_MODE, 7); -} - -#elif defined(MACHINE_SWTG024AS_A_2_0_1_5C_1SFP) || \ - defined(MACHINE_SWTG024AS_V2_0) -void machine_custom_init(void) __banked -{ - uint16_t pval; - - reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6); - reg_bit_set(RTL837X_REG_LED_MODE, 17); - reg_bit_clear(RTL837X_REG_LED_MODE, 9); - reg_bit_clear(RTL837X_REG_LED_MODE, 7); - - // OEM firmware sets these companion SDS0 polarity bits for the RTL8221B. - sds_read(0, 0, 0); - pval = SFR_DATA_U16; - sds_write_v(0, 0, 0, pval | 0x100); - - sds_read(0, 6, 2); - pval = SFR_DATA_U16; - sds_write_v(0, 6, 2, pval | 0x4000); -} - -#elif defined MACHINE_ZX310S_4T2XT -void machine_custom_init(void) __banked -{ - // For this device, the reset value of RTL837X_PIN_MUX_0 is 0x30000000, - // which would disables all LEDS, enable them manually: - REG_SET(RTL837X_PIN_MUX_0, 0x30db68bf); -} - -#elif defined MACHINE_FG_4GT_2SX_V2_0 -void machine_custom_init(void) __banked -{ - REG_SET(RTL837X_REG_LED_GLB_IO_EN, 0x7624155b); -} - -#else -void machine_custom_init(void) __banked { } -#endif diff --git a/rtl837x_igmp.c b/rtl837x_igmp.c index 35940446..f996cd3f 100644 --- a/rtl837x_igmp.c +++ b/rtl837x_igmp.c @@ -126,7 +126,7 @@ void igmp_setup(void) __banked * For now the IGMP protocols are flooded (01), MLD which MAC-based is handled by ASIC * All messages are allowed and maximum MC group is 0xff */ - for (i = machine.min_port; i <= machine.max_port; i++) + for (i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) REG_SET(RTL837X_IGMP_PORT_CFG + (i << 2), IGMP_MAX_GROUP | IGMP_PROTOCOL_ENABLE | IGMP_FLOOD); /* // Allow all physical ports to be dynamic router ports @@ -155,7 +155,7 @@ void igmp_enable(void) __banked // Configure per-port IGMP configuration, bits 0-10 enable MC protocol snooping, // bits 16-24 configure max MC group used by that port. Trap to CPU (10) - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { REG_SET(RTL837X_IGMP_PORT_CFG + (i << 2), IGMP_MAX_GROUP | IGMP_PROTOCOL_ENABLE | IGMP_TRAP); } } @@ -180,7 +180,7 @@ void igmp_router_port_set(uint16_t pmask) __banked void igmp_show(void) __banked { print_string("igmp_show called\n"); - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { write_char('0' + i); write_char(':'); reg_read_m(RTL837X_IGMP_PORT_CFG + (i << 2)); print_sfr_data(); diff --git a/rtl837x_init.c b/rtl837x_init.c index c7b7e71e..73498642 100644 --- a/rtl837x_init.c +++ b/rtl837x_init.c @@ -246,7 +246,7 @@ void rtl8372_init(void) __banked // [...] /// uint16_t reg = 0x1238 + 0x300; // Port base register for the bits we set - for (char i = machine.min_port; i <= machine.max_port; i++) { + for (char i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { // Bit 7 (0x40) enables replacement of the RTL-VLAN tag with an 802.1Q VLAN tag REG_SET(reg, 0xe77); reg += 0x100; diff --git a/rtl837x_lacp.c b/rtl837x_lacp.c index 2573bc34..c8d6b1d6 100644 --- a/rtl837x_lacp.c +++ b/rtl837x_lacp.c @@ -165,7 +165,7 @@ void lacp_mux_update(void) __banked if (!lacp_lag_ports[lag]) continue; lacp_scratch_mask = 0; - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { if (lacp_port_lag[i] != lag) continue; if ((lacp_actor_state[i] & LACP_STATE_FULL) == LACP_STATE_FULL @@ -248,7 +248,7 @@ void lacp_in(void) __banked return; port = ((uint8_t)HTONS(LACP_H->rtl_tag.pmask)) & 0x0f; - if (port < machine.min_port || port > machine.max_port) + if (!MACHINE_PORT_VALID(port)) return; lag = lacp_port_lag[port]; @@ -298,7 +298,7 @@ void lacp_in(void) __banked static void lacp_step(void) { - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { if (lacp_port_lag[i] == LACP_LAG_NONE) continue; @@ -328,7 +328,7 @@ static void lacp_step(void) if (!lacp_agg_valid[lag]) continue; - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { if (lacp_port_lag[i] == lag && lacp_rx_state[i] == LACP_RX_CURRENT && lacp_sys_eq(lacp_partner_sys[i], lacp_agg_sys[lag])) { any_current = 1; @@ -422,7 +422,7 @@ void lacp_lag_set(uint8_t lag, __xdata uint16_t ports) __banked return; lacp_scratch_flag = lacp_any_lag(); - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { if (lacp_port_lag[i] == lag && !(ports & PORT_BIT(i))) { lacp_port_lag[i] = LACP_LAG_NONE; lacp_port_release(i); @@ -438,7 +438,7 @@ void lacp_lag_set(uint8_t lag, __xdata uint16_t ports) __banked if (ports && !lacp_scratch_flag) lacp_engine_on(); - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { if (!(ports & PORT_BIT(i))) continue; lacp_scratch_lag = lacp_port_lag[i]; @@ -490,7 +490,7 @@ void lacp_show(void) __banked print_string(" members "); print_short(lacp_members_last[l]); write_char('\n'); } - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { print_string("port "); print_byte(machine.log_to_phys_port[i]); print_string(" actor "); print_byte(lacp_actor_state[i]); print_string(" partner "); print_byte(lacp_partner_state[i]); diff --git a/rtl837x_leds.c b/rtl837x_leds.c index d1b8cf91..5757060c 100644 --- a/rtl837x_leds.c +++ b/rtl837x_leds.c @@ -37,10 +37,10 @@ void leds_setup(void) __banked // Set up all Port-LEDs to belong to RLDP sfr_data[3] = sfr_data[2] = sfr_data[1] = sfr_data[0] = 0; - for (uint8_t i = machine.min_port; i <= (machine.max_port > 7 ? 7 : machine.max_port); i++) + for (uint8_t i = MACHINE_MIN_PORT; i <= (MACHINE_MAX_PORT > 7 ? 7 : MACHINE_MAX_PORT); i++) sfr_data[3 - (i >> 2)] |= i & 1 ? 0xf0 : 0x0f; reg_write_m(RTL837X_REG_LED_RLDP_2); - if (machine.max_port == 8) + if (MACHINE_MAX_PORT == 8) REG_SET(RTL837X_REG_LED_RLDP_3, 0x0000000f); // Port 8 // Configure high LEDs 27-29: mux and LED enable @@ -110,7 +110,7 @@ void leds_setup(void) __banked // Configure the LED-set of a port sfr_data[3] = sfr_data[2] = sfr_data[1] = sfr_data[0] = 0; - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) sfr_data[3 - (i >> 2)] |= machine.port_led_set[i] << ((i & 3) << 1); reg_write_m(RTL837X_LED_PORT_SET_SEL); diff --git a/rtl837x_leds_dump.c b/rtl837x_leds_dump.c index 8a820e3a..5bf04d0f 100644 --- a/rtl837x_leds_dump.c +++ b/rtl837x_leds_dump.c @@ -87,7 +87,7 @@ void leds_dump(void) __banked } write_char('\n'); } - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { reg_read_m(RTL837X_LED_PORT_SET_SEL); __xdata uint8_t set = sfr_data[3 - (i >> 2)]; set = (set >> ((i & 3) << 1)); diff --git a/rtl837x_lldp.c b/rtl837x_lldp.c index 84208433..441e7eb4 100644 --- a/rtl837x_lldp.c +++ b/rtl837x_lldp.c @@ -108,7 +108,7 @@ void lldp_send(void) __banked __reentrant */ uip_len = MAC_ADDR_LEN + MAC_ADDR_LEN + sizeof(struct rtl_tag) + LLDP_ETHERTYPE_LENGTH + (p - LLDP_O->payload); - for (uint8_t port = machine.min_port; port <= machine.max_port; port++) { + for (uint8_t port = MACHINE_MIN_PORT; port <= MACHINE_MAX_PORT; port++) { if ((1 << port) & lldp_logical_port_status) { LLDP_O->payload[port_position] = '0' + machine.log_to_phys_port[port]; diff --git a/rtl837x_port.c b/rtl837x_port.c index d4a5b9f5..6874685f 100644 --- a/rtl837x_port.c +++ b/rtl837x_port.c @@ -271,7 +271,7 @@ void vlan_setup(void) __banked wait_table_ready(); // Set PVID 1 for every port. TODO: Skip unused ports! - for (uint8_t i = machine.min_port; i <= machine.max_port + 1; i++) { // Do this also for the CPU port (+1) + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT + 1; i++) { // Do this also for the CPU port (+1) uint16_t reg = RTL837x_PVID_BASE_REG + ((i >> 1) << 2); #ifdef DEBUG print_byte(i); write_char(':'); write_char(' '); print_short(reg); write_char('='); @@ -459,7 +459,7 @@ void port_l2_setup(void) __banked port_l2_forget(); - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { // Limit the number of automatically learned MAC-Entries per port to 0x1040 uint8_t idx = (i << 2); REG_SET(RTL837X_L2_LRN_PORT_CONSTRAINT + idx, 0x00001040); @@ -511,7 +511,7 @@ void port_media_show(uint8_t port) __banked void port_stats_print(void) __banked { print_string("\nPort\tState\tLink\tTxGood\t\tTxBad\t\tRxGood\t\tRxBad\t\tMACs\n"); - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { print_phys_port(i); write_char('\t'); if (!machine.is_sfp[i]) { @@ -594,14 +594,14 @@ void port_stats_print(void) __banked void port_isolate(uint8_t port, __xdata uint16_t pmask) __banked { - if (port <= machine.max_port) + if (port <= MACHINE_MAX_PORT) REG_SET(RTL837X_PORT_ISOLATION_BASE + (port << 2), pmask); } uint16_t port_isolation_get(uint8_t port) __banked { - if (port > machine.max_port) + if (port > MACHINE_MAX_PORT) return 0; reg_read_m(RTL837X_PORT_ISOLATION_BASE + (port << 2)); @@ -775,7 +775,7 @@ void port_eee_status(uint8_t port) __banked void port_eee_enable_all(__xdata uint8_t speed) __banked { - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { if (i == 3 && machine.n_10g) { port_eee_enable(i, speed); } else if (i == 8 && machine.n_10g == 2) { @@ -792,7 +792,7 @@ void port_eee_enable_all(__xdata uint8_t speed) __banked void port_eee_disable_all(void) __banked { - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { port_eee_disable(i); } } @@ -800,7 +800,7 @@ void port_eee_disable_all(void) __banked void port_eee_status_all(void) __banked { - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { port_eee_status(i); } } @@ -908,7 +908,7 @@ void vlan_dump(void) __banked { print_string("Ingress VLAN configuration:\n"); print_string("Port\tPVID\tType\tFiltering\n"); - for (uint8_t port = machine.min_port; port <= machine.max_port; port++) { + for (uint8_t port = MACHINE_MIN_PORT; port <= MACHINE_MAX_PORT; port++) { print_vlan_ingress_port(port); } print_vlan_ingress_port(9); @@ -923,7 +923,7 @@ void vlan_dump(void) __banked /** Set the ingress VLAN filtering */ bool port_ingress_vlan_filter_set(uint8_t port, __xdata bool enabled) __banked { - if (port < machine.min_port || (port > machine.max_port && port != CPU_PORT)) { + if (!MACHINE_PORT_VALID(port) && port != CPU_PORT) { return false; } if (enabled) @@ -937,7 +937,7 @@ bool port_ingress_vlan_filter_set(uint8_t port, __xdata bool enabled) __banked /** Get the ingress VLAN filtering status */ bool port_ingress_vlan_filter_get(uint8_t port) __banked { - if (port < machine.min_port || (port > machine.max_port && port != CPU_PORT)) { + if (!MACHINE_PORT_VALID(port) && port != CPU_PORT) { return false; } diff --git a/rtl837x_storm.c b/rtl837x_storm.c index 2308b210..23cfc83a 100644 --- a/rtl837x_storm.c +++ b/rtl837x_storm.c @@ -67,7 +67,7 @@ void storm_show(void) __banked { uint8_t i, t, idx; - for (i = machine.min_port; i <= machine.max_port; i++) { + for (i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) { print_string("port "); write_char('0' + machine.log_to_phys_port[i]); for (t = 0; t < STORM_TYPES; t++) { diff --git a/rtl837x_stp.c b/rtl837x_stp.c index bc810d96..118e265c 100644 --- a/rtl837x_stp.c +++ b/rtl837x_stp.c @@ -335,7 +335,7 @@ static uint8_t stp_ent_active(uint8_t e) __reentrant return 0; if (e >= STP_LAG_BASE) return stp_lag_mask[e - STP_LAG_BASE] != 0; - return e >= machine.min_port && e <= machine.max_port && stp_ent_of[e] == e; + return MACHINE_PORT_VALID(e) && stp_ent_of[e] == e; } @@ -410,7 +410,7 @@ static void stp_topology_change(uint8_t port) __reentrant stp_tc_count++; stp_tc_while = ((uint16_t)stp_maxage_s + stp_fwddelay_s) * STP_HZ; if (port >= STP_LAG_BASE) { - for (uint8_t i = machine.min_port; i <= machine.max_port; i++) + for (uint8_t i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) if (stp_ent_has(port, i)) port_l2_forget_port(i); } else { @@ -565,7 +565,7 @@ void stp_in(void) __banked /* Ingress port: low nibble of the CPU tag's pmask on RX */ stp_scratch = ((uint8_t)HTONS(STP_H->rtl_tag.pmask)) & 0x0f; - if (stp_scratch < machine.min_port || stp_scratch > machine.max_port) + if (!MACHINE_PORT_VALID(stp_scratch)) return; port = stp_ent_of[stp_scratch]; @@ -658,7 +658,7 @@ void stp_in(void) __banked if (!stp_tc_while) { uint8_t i; stp_tc_count++; - for (i = machine.min_port; i <= machine.max_port; i++) + for (i = MACHINE_MIN_PORT; i <= MACHINE_MAX_PORT; i++) if (!stp_ent_has(port, i) && (stp_pflags[stp_ent_of[i]] & STP_PF_ENABLED) && !(stp_pflags[stp_ent_of[i]] & STP_PF_OPEREDGE)) @@ -714,7 +714,7 @@ void stp_timers(void) __banked if (stp_map_dirty) { stp_map_dirty = 0; for (stp_i = 0; stp_i < STP_LAG_BASE; stp_i++) { - if (stp_i < machine.min_port || stp_i > machine.max_port) + if (!MACHINE_PORT_VALID(stp_i)) continue; if (stp_ent_of[stp_i] != stp_i) { stp_loop_held[stp_i] = 0; @@ -747,14 +747,14 @@ void stp_timers(void) __banked { __xdata static uint16_t eff; eff = 0; - for (stp_i = machine.min_port; stp_i <= machine.max_port; stp_i++) + for (stp_i = MACHINE_MIN_PORT; stp_i <= MACHINE_MAX_PORT; stp_i++) if ((stp_link_now >> stp_i) & 1) eff |= (uint16_t)1 << stp_ent_of[stp_i]; stp_link_now = eff; } if (stp_link_now != stp_link_prev) { for (stp_i = 0; stp_i < STP_ENTITIES; stp_i++) { - if (stp_i < STP_PORTS && (stp_i < machine.min_port || stp_i > machine.max_port)) + if (stp_i < STP_PORTS && !MACHINE_PORT_VALID(stp_i)) continue; if (stp_i < STP_PORTS && stp_ent_of[stp_i] != stp_i) continue; @@ -890,7 +890,7 @@ static void stp_fdb_update(__xdata uint16_t pmask) continue; port_l2mc_set(0x00, stp_fdb_vid, pmask); } - for (stp_fdb_i = machine.min_port; stp_fdb_i <= machine.max_port; stp_fdb_i++) { + for (stp_fdb_i = MACHINE_MIN_PORT; stp_fdb_i <= MACHINE_MAX_PORT; stp_fdb_i++) { stp_fdb_vid = port_pvid_get(stp_fdb_i); port_l2mc_set(0x00, stp_fdb_vid, pmask); } @@ -910,7 +910,7 @@ void stp_setup(void) __banked stp_tx_count[stp_i] = 0; port_timers[stp_i] = 0; port_hello[stp_i] = (uint16_t)stp_hello_s * STP_HZ; - if (stp_i < STP_PORTS && (stp_i < machine.min_port || stp_i > machine.max_port)) + if (stp_i < STP_PORTS && !MACHINE_PORT_VALID(stp_i)) continue; if (stp_i >= STP_LAG_BASE && !stp_lag_mask[stp_i - STP_LAG_BASE]) continue; @@ -939,7 +939,7 @@ void stp_setup(void) __banked reg_read_m(RTL837X_REG_LINKS_STS); stp_link_now = (uint16_t)sfr_data[1] | ((uint16_t)sfr_data[2] << 8); stp_link_prev = 0; - for (stp_i = machine.min_port; stp_i <= machine.max_port; stp_i++) + for (stp_i = MACHINE_MIN_PORT; stp_i <= MACHINE_MAX_PORT; stp_i++) if ((stp_link_now >> stp_i) & 1) stp_link_prev |= (uint16_t)1 << stp_ent_of[stp_i]; @@ -952,7 +952,7 @@ void stp_setup(void) __banked void stp_off(void) __banked { sfr_data[0] = sfr_data[1] = sfr_data[2] = sfr_data[3] = 0; - for (stp_i = machine.min_port; stp_i <= machine.max_port; stp_i++) { + for (stp_i = MACHINE_MIN_PORT; stp_i <= MACHINE_MAX_PORT; stp_i++) { // Set STP port state to forwarding // States are: 00 disable, 01 blocking, 10 learning, 11 forwarding sfr_data[3 - (stp_i >> 2)] |= (uint8_t)(STP_ST_FORWARDING << ((stp_i << 1) & 0x7)); diff --git a/rtlplayground.c b/rtlplayground.c index 0afa93c8..fbb94d76 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -1203,7 +1203,7 @@ static void handle_tick(void) lacp_timers(); health_phase(HEALTH_PH_STP); lldp_tick(); - health_phase(HEALTH_LLDP); + health_phase(HEALTH_PH_LLDP); cabletest_tick(); } diff --git a/test/env_tables.c b/test/env_tables.c index 719e045a..e4d23c37 100644 --- a/test/env_tables.c +++ b/test/env_tables.c @@ -59,8 +59,6 @@ uint8_t *hex = (uint8_t *)hex_chars; /* ---- a 9-port RTL8373 whose logical ports map to themselves ---- */ const struct machine machine = { .machine_name = "HOSTTEST", - .min_port = 0, - .max_port = 8, .n_sfp = 0, .log_to_phys_port = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, .phys_to_log_port = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, diff --git a/test/test_lacp.c b/test/test_lacp.c index 160c773e..56b8e56f 100644 --- a/test/test_lacp.c +++ b/test/test_lacp.c @@ -14,8 +14,11 @@ uint8_t uip_buf[UIP_CONF_BUFFER_ALLOC_SIZE]; uint16_t uip_len; struct uip_eth_addr uip_ethaddr = { .addr = {0x02,0x11,0x22,0x33,0x44,0x55} }; -const struct machine machine = { .min_port = 0, .max_port = 7, +const struct machine machine = { .log_to_phys_port = {5, 1, 2, 3, 4, 6, 7, 8, 9} }; +/* Logical ports of the mock machine above */ +#define TEST_MIN_PORT 0 +#define TEST_MAX_PORT 7 struct machine_runtime machine_detected = { .isRTL8373 = 1 }; uint8_t lacpEnabled; uint16_t management_vlan; /* mocked; slow-protocol path zeroes it per-frame */ @@ -216,7 +219,7 @@ int main(int argc, char **argv) lacp_lag_set(0, 0x00ff); step(8); int all_tx = 1, sane = 1; - for (int i = machine.min_port; i <= machine.max_port; i++) { + for (int i = TEST_MIN_PORT; i <= TEST_MAX_PORT; i++) { if (!tx_count[i]) all_tx = 0; if (last_tx[i].ethertype != HTONS(0x8809) || last_tx[i].subtype != 1 || last_tx[i].dst[5] != 0x02 diff --git a/tools/Makefile b/tools/Makefile index 1b1c6685..80ac9743 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,6 +1,8 @@ CC = gcc CCFLAGS = -Wall -o -BUILDDIR = output +ifndef BUILDDIR + BUILDDIR = output +endif all: create_build_dir $(BUILDDIR)/injector $(BUILDDIR)/fileadder $(BUILDDIR)/httpd_sim\ $(BUILDDIR)/crc_calculator $(BUILDDIR)/imagebuilder diff --git a/tools/bank_occupancy.sh b/tools/bank_occupancy.sh new file mode 100755 index 00000000..8638d390 --- /dev/null +++ b/tools/bank_occupancy.sh @@ -0,0 +1,31 @@ +#!/bin/bash +MACHINE="$1" +if [[ ! -s output-main/rtlplayground.map ]]; then + original_branch=$(git branch --show-current) + #trap 'git switch "$original_branch"' EXIT + git switch main && make CI=1 MACHINE="$MACHINE" BUILDDIR=output-main + git switch "$original_branch" +fi +source <(sed -rn 's/^([XCD]SEG|(BANK[0-9])).*=\s+([0-9]+)\. bytes.*$/main_\1=\3/p' output-main/rtlplayground.map | sort -u) + +main_WEB=$(du -sb output-main/html_min | awk '{print $1}') +if [[ ! -s "output/$MACHINE/rtlplayground.map" ]]; then + make CI=1 MACHINE="$MACHINE" +fi +source <(sed -rn 's/^([XCD]SEG|(BANK[0-9])).*=\s+([0-9]+)\. bytes.*$/branch_\1=\3/p' output/"$MACHINE"/rtlplayground.map | sort -u) +branch_WEB=$(du -sb output/html_min | awk '{print $1}') + +print_line() { + local name=$1 main=$2 branch=$3 + printf '%-20s %-20s %-20s %-20s\n' "$name" "$main" "$branch" "$((branch - main))" +} + +printf '%-20s %-20s %-20s %-20s\n' "segment" "main" "branch" "change" + +print_line "BANK1" "$main_BANK1" "$branch_BANK1" +print_line "BANK2" "$main_BANK2" "$branch_BANK2" +print_line "BANK3" "$main_BANK3" "$branch_BANK3" +print_line "CSEG" "$main_CSEG" "$branch_CSEG" +print_line "DSEG" "$main_DSEG" "$branch_DSEG" +print_line "XSEG" "$main_XSEG" "$branch_XSEG" +print_line "WEB" "$main_WEB" "$branch_WEB"