36 Commits
Author SHA1 Message Date
logicog 018eab9810 Also display RTL837X_REG_LED_MODE 2026-06-10 05:45:19 +02:00
logicog ec36658ab9 Add ZX310S-4T2XT device photos 2026-06-10 05:45:19 +02:00
logicog eeded0f788 Add (Horaco) ZX310S-4T2XT
The ZX310S-4T2XT is a managed device with 2x2.5GBit and 2x10GBit Ethernet.
It is sold, among others, by Horaco as an unbranded device.

CPU: RTL8372
Flash: 2MByte Winbond W25Q16DV (U3)
PHY 2x RTL8261BE
2026-06-10 05:45:19 +02:00
logicog 8f3b738e59 Merge pull request #257 from logicog/revert-252-main
Revert "Don't disable flash DIO operation before flashing"
2026-06-07 10:47:10 +02:00
TylerDurden-23 62065875e3 Revert "Don't disable flash DIO operation before flashing" 2026-06-07 10:42:39 +02:00
René van Dorst 94e34a5991 Merge pull request #251 from feelfree69/make
make: seperate output directories by MACHINE
2026-06-05 19:16:04 +00:00
René van Dorst b58b1dfb35 Merge pull request #252 from feelfree69/main
Don't disable flash DIO operation before flashing
2026-06-05 19:13:30 +00:00
feelfree69 4ca5b4e87a Don't disable flash DIO operation before flashing - it works fine with DIO 2026-06-01 15:07:37 +02:00
logicog 5a8a8ed91b Merge pull request #237 from Erdnusschokolade/fix/config-persistence
Fix config persistence: missing commands, delete handling, multipart upload
2026-06-01 06:46:11 +02:00
René van Dorst ad64e450e1 Merge pull request #246 from logicog/sfp_speed
Add support for configuring SFP modules speeds via CLI
2026-05-31 18:33:05 +00:00
feelfree69 cfeffc434d Merge pull request #248 from zectaiga/swtg024as-a-2-0-1-fixes
Fix SWTG024AS-A 2.0.1 port and LED mapping
2026-05-31 10:42:01 +02:00
feelfree69 8670709b6e make: seperate output directories by MACHINE 2026-05-31 01:17:33 +02:00
logicog ce496ab25f Merge pull request #249 from vDorst/fix_led_settings
Fix SFP led for 2.5gbit for MACHINE_SWGT024_V2_0
2026-05-30 22:07:56 +02:00
René van Dorst 964ef2da7a Fix SFP led for 2.5gbit for MACHINE_SWGT024_V2_0
While testing #246, I noticd that SFP did not light-up while forcing
2.5gbit link. This is because RJ45 and SFP share the same LED-settings.
But RJ45 has two leds-settings.
Solution is to add settings for SFP for both managed and unmanaged
variant.
2026-05-30 21:02:42 +02:00
Taiga Ogawa 053dbe286e Fix SWTG024AS-A 2.0.1 port and LED mapping 2026-05-30 03:44:15 +09:00
feelfree69 e68e5cef46 Merge pull request #244 from kekopop/main
Add PCB-SWTG024AS-A-V2.0.1
2026-05-26 22:15:21 +02:00
kekopop b5543b6aeb Update machine.c 2026-05-26 22:04:26 +02:00
kekopop a51fcf1478 Update machine.h 2026-05-26 22:03:42 +02:00
kekopop 247cb4dd2f Add files via upload 2026-05-26 19:44:31 +02:00
logicog 394fc99485 Merge pull request #242 from tofurky/fix_xgspon_rates
Broaden range of SFP+ rates mapped to SDS_10GR
2026-05-26 05:32:54 +02:00
logicog cf0707475d Merge pull request #241 from tofurky/regset_arg_count
Correct argument count for regset command
2026-05-26 05:25:22 +02:00
Matt Merhar 73b99b2f08 Broaden range of SFP+ rates mapped to SDS_10GR
A commonly used SFP+ form-factor XGS-PON ONT (WAS-110) reports 0x63 at
power on and then switches to 0x64 after booting up.

0x63 -> 9.9gbps
0x64 -> 10gbps

These are outside of the previous 0x66-0x69 range which prevented the
link from ever being brought up.
2026-05-25 21:45:42 -04:00
Matt Merhar 005eaa3248 Correct argument count for regset command
Fixes: 2cdab5f9d9 ("parse_reg{set,get}() make use cmd_words_len.")
2026-05-25 20:24:27 -04:00
feelfree69 98f1e9443a Merge pull request #239 from amstan/ztyuav
doc: Describe other PCB-K0402WS-V3.0 devices
2026-05-25 23:23:16 +02:00
feelfree69 4c2be334d5 Merge pull request #233 from Erdnusschokolade/feature/vlan-overview
Add VLAN selector dropdown and overview table to vlan.html
2026-05-25 12:30:30 +02:00
Alexandru M Stan 073cc1e4a4 doc: Describe other PCB-K0402WS-V3.0 devices
I recently brought a "Ztyuav Z-QWYT0402", the insides looked identical to the
existing supported "Hisource Hi-K0402WS". Both of them have the
"PCB-K0402-V3.0" silkscreen.

I flashed the vanilla image and it seems to work great.

I changed the documentation to be more inclusive of other devices (including
adding a picture of mine). I suspect more devices might fall into this
"PCB-K0402-V3.0" bucket, for example the "YuanLey YS25-0402" with
the vlan switch also looks suspiciously identical from the outside.

I also added some details I noticed while flashing mine:
teardown, flash padding, how the selector switch actually works.
2026-05-24 18:33:23 -07:00
Erdnusschokolade ba919280ac Address PR #233 review feedback
- itoa16_html: add comment that the function is sufficient for VLAN
  IDs (<=4094); generalization not needed.
- send_vlanlist: replace post-write bounds check with a pre-write
  guard using worst-case entry size (138 bytes + 1 for closing
  bracket). Old comment claimed ~45 bytes per entry, which only
  held for short names. With a 117-char name (the actual bound from
  CMD_BUF_SIZE) entries can reach 138 bytes, and the post-check
  would not have prevented an overflow.
- Document the 0x02 check in sfr_data[0] as the VLAN table entry
  valid flag.
2026-05-24 23:31:18 +02:00
Erdnusschokolade dcc60c3824 Fix conf_overwrite vlan/mgmt conflict
The pattern /^vlan\s+\d{1,4}\b/ matched both VLAN membership entries
(vlan N <ports>) and management entries (vlan N mgmt), causing them
to overwrite each other in configuration[]. When saving, whichever
form came last in the cmd_log would dedupe the other out of the
final config — resulting in either lost membership or a stale mgmt
setting.

Split into two patterns using negative lookahead:
- /^vlan\s+\d{1,4}\s+mgmt$/      matches only mgmt entries
- /^vlan\s+\d{1,4}(?!\s+mgmt\b)/  matches everything else

Both dedup independently. Discovered via hardware test on 6XH-X
where 'vlan 44 mgmt' silently dropped 'vlan 44 management 2t 5u'
from saved config, locking out web UI on next boot.
2026-05-24 11:26:04 +02:00
Erdnusschokolade caad366b3b Fix config persistence: missing commands, delete handling, multipart
Multiple related bugs in the Save-to-Flash path:

1. Multipart upload was missing the required filename argument,
   causing the backend parser to fail. Added 'config.txt' to the
   form.append call. This was likely the primary reason Save-to-Flash
   was unreliable.

2. Web UI was not pausing its polling interval during flash write,
   causing CPU contention and intermittent crashes. Added isSaving
   lock and clearInterval before sendConfig.

3. conf_cmds whitelist was incomplete. Added: syslog, passwd, pvid,
   ingress, port name, lag, laghash, isolate, stp, igmp, mtu, bw,
   vlan N mgmt, vlan N d.

4. VLAN regex blocked named VLANs. New pattern allows optional name
   (starts with letter, matching CLI parser semantics).

5. vlan N d (delete) was not persisted. parseConf now removes the
   matching vlan N ... entry from configuration[] when seeing a
   delete command, without storing the delete itself. Result: the
   saved config describes the end state.

6. configuration[] was not cleared between flashSave invocations,
   leading to stale entries from prior interactions.

7. conf_overwrite boundary fix: 'pvid 1' no longer matches 'pvid 10'
   etc. Added trailing space in startsWith check.

8. All conf_cmds patterns now anchored with ^...$ for full-line
   match. parseConf normalizes whitespace before testing.

9. Port range widened to \d{1,2} so ports 11+ are accepted.

Structural fixes (1, 2, 6, 7, 8) ported from mcaptur's closed PR #219;
remaining fixes (3, 4, 5, 9) and overall regex strategy are new.
2026-05-24 11:26:04 +02:00
Erdnusschokolade ce0ee859d6 Fix: Untagged Ports column included non-member ports
The hardware bitmask format encodes both "untagged members" and
"non-members" in the upper 10 bits (per doc/vlan.md). The existing
fetchVLAN() correctly masks this with the membership bitmask before
display, but loadVlanTable() did not, causing non-member ports to
appear in the Untagged Ports column.

Tested on KeepLiNK KP-9000-6XH-X.
2026-05-24 11:20:57 +02:00
Erdnusschokolade a369e46fe6 Add VLAN overview table to VLAN configuration page
Below the configuration form, a new table lists all configured VLANs
with their port memberships: Member, Tagged, Untagged, and PVID
columns. Port ranges are formatted compactly (e.g. "1-2,5").

Port-to-bit mapping uses the existing physToLogPort[] array populated
by /status.json, so the table is consistent with the icon view in
fetchVLAN() and works on any supported machine.

Each row has a delete button that sends "vlan N d" via /cmd, with
a confirmation dialog. VLAN 1 cannot be deleted (no button shown).

Table and dropdown both refresh automatically after Update/Create
and after delete via a new refreshVlanViews() helper.

The N+1 request pattern (1x /vlanlist + Nx /vlan.json) keeps the
backend simple and avoids buffer overflow risks for systems with
many VLANs. For typical configurations (<50 VLANs), page load
remains under one second.
2026-05-24 11:20:57 +02:00
Erdnusschokolade defb37c06a Add VLAN selector dropdown to VLAN configuration page
A new <select> element above the VLAN ID input lets users pick an
existing VLAN by name instead of typing the ID. Options are loaded
from /vlanlist on page load and re-loaded after successful
Update/Create operations.

Selection triggers the existing fetchVLAN() flow.

Falls back gracefully if /vlanlist returns an empty list or fails:
the dropdown is hidden and the existing ID input remains functional.
2026-05-24 11:20:57 +02:00
Erdnusschokolade a5f77e4caf Add /vlanlist HTTP endpoint
Returns a JSON array of all configured VLANs with their IDs and names,
e.g. [{"id":1,"name":""},{"id":20,"name":"IoT"}].

The endpoint iterates VLAN IDs 1..4094 and filters by the validity bit
in sfr_data[0] (0x02), following the same pattern as vlan_create() and
vlan_setup() in rtl837x_port.c.

Also adds a small itoa16_html() helper for emitting decimal numbers
up to 4 digits (analogous to the existing 8-bit itoa_html()), used
for VLAN IDs which can reach 4094. Response builder uses the existing
vlan_name() helper for the name lookup, consistent with send_vlan().

Buffer overflow is prevented by breaking out of the iteration loop at
TCP_OUTBUF_SIZE - 60.

This endpoint is the foundation for upcoming UI improvements
(VLAN selector dropdown and overview table).
2026-05-24 11:20:57 +02:00
logicog 1311cb9ea9 Merge pull request #232 from Erdnusschokolade/fix/vlan-name-rename
Fix VLAN name persistence across rename and delete operations
2026-05-23 12:47:06 +02:00
Erdnusschokoladeandlogicog 7d0d8525d2 Fix two OOB reads in parse_vlan()
1. While loop scanning VLAN name terminated only on ' ', not '\0'.
   When the name is the last token in cmd_buffer, the loop reads past
   the buffer into adjacent XRAM.

2. Entering 'vlan' without arguments causes parse_vlan() to read
   cmd_words_b[1] which points to undefined memory, causing atoi_short()
   to interpret residual bytes from previous commands as a VLAN ID.
   Bug found and fix proposed by logicog during review of PR #232.

Co-Authored-By: logicog <logicog@users.noreply.github.com>
2026-05-23 11:19:42 +02:00
Erdnusschokolade 21f33abfa7 Fix VLAN name persistence across rename and delete operations
Previously, renaming a VLAN or deleting and recreating it with a
different name did not update the displayed name. The vlan_names[]
array is an append-only buffer where vlan_name() returns the first
matching entry, so stale entries kept winning.

This commit adds vlan_name_remove(), which locates an entry by
VLAN ID and removes it via array compaction. The function is called
in two places:

  - parse_vlan() in cmd_parser.c, before appending a new name entry,
    to remove any pre-existing entry for the same VLAN ID
  - vlan_delete() in rtl837x_port.c, to clean up the name when a
    VLAN is removed

The implementation reuses the existing vlan_name() lookup, scans for
the trailing space of the matched entry, then shifts remaining bytes
left. Locals are declared as static __xdata to avoid the SDCC
overlay segment limit on banked functions.

Tested on KeepLiNK KP-9000-6XH-X:
  - vlan 99 AAA p1u; vlan 99 BBB -> name updated to BBB
  - vlan 99 d; vlan 99 CCC p1u   -> name correctly CCC, not stale AAA

Note: This fix addresses the runtime XMEM state. Persistence of
renamed VLAN names across reboot requires the user to download and
re-upload /config, as is the existing pattern for all configuration
changes in this firmware.
2026-05-21 17:39:29 +02:00
28 changed files with 597 additions and 122 deletions
+11 -11
View File
@@ -12,15 +12,15 @@ AFLAGS= -plosgff
SUBDIRS := tools
SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS))
BUILDDIR = output
VERSION_HEADER := version.h
ifeq ($(MACHINE),)
MACHINE:= $(shell grep "^\s*#define MACHINE_" machine.h | sed "s/^\s*#define MACHINE_//")
else
CC_FLAGS += -DMACHINE_$(MACHINE)
endif
BUILDDIR = output/$(MACHINE)
VERSION_HEADER := version.h
GIT_VERSION := $(shell git rev-parse --short HEAD)
ifeq ($(shell git status --porcelain --untracked-files=no),)
else
@@ -45,8 +45,8 @@ OBJS = ${SRCS:%.c=$(BUILDDIR)/%.rel}
DEPS := ${SRCS:%.c=$(BUILDDIR)/%.d}
HTML := $(shell find $(html) -name '*.js' -or -name '*.html' -or -name '*.svg')
html_data.c html_data.h: $(HTML) tools/$(BUILDDIR)/fileadder
tools/$(BUILDDIR)/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -d html -p html_data
html_data.c html_data.h: $(HTML) tools/output/fileadder
tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -d html -p html_data
$(VERSION_HEADER):
@echo "#ifndef VERSION_H" > $(VERSION_HEADER)
@@ -83,12 +83,12 @@ $(BUILDDIR)/rtlplayground.img: $(BUILDDIR)/rtlplayground.ihx
$(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.img
if [ -e $@ ]; then rm $@; fi
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) -d html -p html_data -b BANK1 $@
tools/$(BUILDDIR)/crc_calculator -u $@
ln -sf rtlplayground-$(FILENAME_EXTENSION).bin $(BUILDDIR)/rtlplayground.bin
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) -d html -p html_data -b BANK1 $@
tools/output/crc_calculator -u $@
ln -sf $(MACHINE)/rtlplayground-$(FILENAME_EXTENSION).bin output/rtlplayground.bin
.PHONY: clean all $(SUBDIRS) $(VERSION_HEADER)
+5 -2
View File
@@ -333,6 +333,8 @@ void parse_vlan(void)
vlan_settings.vlan = 0;
vlan_settings.members = 0;
vlan_settings.tagged = 0;
if (cmd_words_len < 2)
goto err;
if (!atoi_short(&vlan_settings.vlan, cmd_words_b[1])) {
if (cmd_words_len == 3 && cmd_buffer[cmd_words_b[2]] == 'd') {
vlan_delete(vlan_settings.vlan);
@@ -349,10 +351,11 @@ void parse_vlan(void)
uint8_t w = 2;
if (cmd_words_len > w && isletter(cmd_buffer[cmd_words_b[w]])) {
register uint8_t i = 0;
vlan_name_remove(vlan_settings.vlan);
vlan_names[vlan_ptr++] = hex[(vlan_settings.vlan >> 8) & 0xf];
vlan_names[vlan_ptr++] = hex[(vlan_settings.vlan >> 4) & 0xf] ;
vlan_names[vlan_ptr++] = hex[vlan_settings.vlan & 0xf];
while(cmd_buffer[cmd_words_b[w] + i] != ' ') {
while(cmd_buffer[cmd_words_b[w] + i] != ' ' && cmd_buffer[cmd_words_b[w] + i] != '\0') {
write_char(cmd_buffer[cmd_words_b[w] + i]);
vlan_names[vlan_ptr++] = cmd_buffer[cmd_words_b[w] + i++];
}
@@ -847,7 +850,7 @@ void parse_regset(void)
{
uint16_t reg = 0;
if (cmd_words_len != 2) {
if (cmd_words_len != 3) {
goto err;
}
-62
View File
@@ -1,62 +0,0 @@
# Hisource Hi-K0402WS
Following is documentation for unmanaged switch marked as `Hi-K0402WS`.
Original software is running UART on 9600 baud rate.
Using SPI clamp in-board is the only method for initial installation.
The board has two flash chips `BY25Q16BS` with 16M-bit size. The front switch, switches between the two flash chips.
These can be programed independently by using said switch - so it is e.g. possible to run the original and new firmware in parallel.
### Label specifications
- **Name**: 2.5G Ethernet Switch
- **Model**: Hi-K0402WS
- **Ports**:
- 4 × RJ45: 10/100/1000/2500 Mbps
- 2 × SFP: 1000 / 2500 / 10000 Mbps
### What works (expected from label + similar devices)
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
- Both SFP ports supporting 1G, 2.5G and 10G modules
- LEDs
### PCB overview
**Board markings**
- Top silkscreen: PCB-KO4022W-V3.0 / DIP-KO4022WS-V3.0
Top side
<img src="photos/K0402W-V3.0-unmanaged\PCB-top.jpg" width="300" />
Bottom
<img src="photos/K0402W-V3.0-unmanaged\PCB-bottom.jpg" width="300" />
### T2, serial console
| `J2` pin | Signal |
| -------- | ----------- |
| 1 | 3V3 |
| 2 | RX (Input) |
| 3 | TX (Output) |
| 4 | GND |
## Power supply
Input power is delivered via barell plug, `12V 1A` adapter was provided.
Board has two supply rails. `0.95` and `3.3` volt.
### `0.95` Core Voltage
Voltage is made by a `Techcode TD1720` .
### `3.3` Voltage
Voltage is created by chip marked as `Techcode TD1720`.
**There seems to have been a miscalculation when choosing the inductor and the device is ~25% more efficient with an 5V power supply.**
+76
View File
@@ -0,0 +1,76 @@
# PCB-K0402WS-V3.0
Following is documentation for a variety of unmanaged switch internally marked as `PCB-K0402WS-V3.0`. They are sold under many brands.
Original software is running UART on 9600 baud rate.
Note during opening the device: there might be a hidden 5th screw on the back
of the device just above the big label, might be covered by a QC sticker.
### Brands
* Hisource Hi-K0402WS
<img src="photos/PCB-K0402WS-V3.0/HiSource_HI-K0402WS.jpg" width="300" />
* Ztyuav Z-QWYT0402
<img src="photos/PCB-K0402WS-V3.0/Ztyuav_Z-QWYT0402.jpg" width="300" />
<img src="photos/PCB-K0402WS-V3.0/Ztyuav_Z-QWYT0402_label.jpg" width="300" />
### Programming
Using SPI clamp in-board is the only method for initial installation.
The board has two flash chips `BY25Q16BS` with 16M-bit size. The front switch, switches between the two flash chips.
These can be programed independently by using said switch - so it is e.g. possible to run the original and new firmware in parallel.
The switch actually controls the HOLD line of each flash chip, and toggling the switch results in a reboot.
If the programming clip keeps HOLD not connected, the flashing will commence on whatever the switch selected, regardless on which chip was clipped.
For the initial flash (at least with flashrom), the bin file produced by the build is much smaller than the flash chip, it is suggested to pad the file to keep flashrom happy: `truncate -s 2097152 rtlplayground-*-PCB_K0402WS_V3.bin`. Note: do not then proceed to use this resulting padded file for the web flashing (as it bricks the device), use the original unpadded .bin.
### What works (expected from label + similar devices)
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
- Both SFP ports supporting 1G, 2.5G and 10G modules
- LEDs
### PCB overview
**Board markings**
- Top silkscreen: PCB-KO4022W-V3.0 / DIP-KO4022WS-V3.0
Top side
<img src="photos/PCB-K0402WS-V3.0/PCB-top.jpg" width="300" />
Bottom
<img src="photos/PCB-K0402WS-V3.0/PCB-bottom.jpg" width="300" />
### T2, serial console
| `J2` pin | Signal |
| -------- | ----------- |
| 1 | 3V3 |
| 2 | RX (Input) |
| 3 | TX (Output) |
| 4 | GND |
## Power supply
Input power is delivered via barell plug, `12V 1A` adapter was provided.
Board has two supply rails. `0.95` and `3.3` volt.
### `0.95` Core Voltage
Voltage is made by a `Techcode TD1720` .
### `3.3` Voltage
Voltage is created by chip marked as `Techcode TD1720`.
**There seems to have been a miscalculation when choosing the inductor and the device is ~25% more efficient with an 5V power supply.**
+53
View File
@@ -0,0 +1,53 @@
# ZX310S-4T2XT
The following is a documentation for the managed switch marked as
`ZX310S-4T2XT` and sold by Horaco.
The original software is running UART on 57600 baud rate 8N1.
CPU: RTL8372
Flash: 2MByte Winbond W25Q16DV (U3)
PHY 2x RTL8261BE
### Label specifications
- **Name**:
- **Ports**:
- 4 × RJ45: 10/100/1000/2500 Mbps
- 2 x RJ45: 10/100/1000/2500/5000/10000 Mbps
- **Power**: 12V DC, 2A barrel connector
<img src="photos/ZX310S-4T2XT/label.jpg" width="300" />
### What works
The device is fully supported:
- All 4 2.5GBASE-T RJ45 ports work at 10/100/1000/2500 Mbps, including EEE
- The 10GBit ports works, including EEE.
- LEDs work with the same indiciations as the OEM firmware
### PCB overview
**Board markings**
- Top silkscreen: PCB-SL310S-4T2XT-V1.0.0-22273
Top side
<img src="photos/ZX310S-4T2XT/pcb_top.jpg" width="300" />
Bottom
<img src="photos/ZX310S-4T2XT/pcb_bottom.jpg" width="300" />
### J1, serial console
| `J1` pin | Signal |
| -------- | ----------- |
| 1 | TX (Output) |
| 2 | RX (Input) |
| 3 | GND |
| 4 | 3V3 |
## Power supply
Input power is delivered via barell plug, `12V 2A` adapter was provided.

Before

Width:  |  Height:  |  Size: 2.6 MiB

After

Width:  |  Height:  |  Size: 2.6 MiB

Before

Width:  |  Height:  |  Size: 3.1 MiB

After

Width:  |  Height:  |  Size: 3.1 MiB

Before

Width:  |  Height:  |  Size: 2.8 MiB

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

+61 -12
View File
@@ -1,32 +1,81 @@
var configInterval = Number();
var configuration = [];
const conf_cmds = [
/ip\s+(\d{1,3}\.){3}\d{1,3}/, /gw\s+(\d{1,3}\.){3}\d{1,3}/, /netmask\s+(\d{1,3}\.){3}\d{1,3}/,
/eee(\s+\d)?\s+(on|off)/, /mirror(\s+(\d|10))(\s+(\d|10)(t|r)?)+/, /vlan\s+(\d{1,4})(\s+(\d|10)(t|u)?)+/
/^ip\s+(\d{1,3}\.){3}\d{1,3}$/,
/^ip\s+dhcp$/,
/^gw\s+(\d{1,3}\.){3}\d{1,3}$/,
/^netmask\s+(\d{1,3}\.){3}\d{1,3}$/,
/^syslog\s+(on|off)$/,
/^syslog\s+ip\s+(\d{1,3}\.){3}\d{1,3}$/,
/^passwd\s+\S+$/,
/^vlan\s+\d{1,4}\s+d$/,
/^vlan\s+\d{1,4}\s+mgmt$/,
/^vlan\s+\d{1,4}(\s+[a-zA-Z]\w*)?(\s+\d{1,2}[tu]?)+$/,
/^pvid\s+\d{1,2}\s+\d{1,4}$/,
/^ingress(\s+\d{1,2}[tua])+$/,
/^ingress\s+[tua]$/,
/^port\s+\d{1,2}\s+name\s+\S+$/,
/^eee(\s+\d{1,2})?\s+(on|off)$/,
/^mirror(\s+\d{1,2})(\s+\d{1,2}[tr]?)+$/,
/^lag\s+\d(\s+\d{1,2})+$/,
/^laghash\s+\d(\s+\w+)+$/,
/^isolate\s+\d{1,2}(\s+(off|\d{1,2}))+$/,
/^stp\s+(on|off)$/,
/^igmp\s+(on|off)$/,
/^mtu\s+\d{1,2}\s+\d+$/,
/^bw\s+(in|out)\s+\d{1,2}\s+\S+$/,
];
const conf_overwrite = [
/ip/, /gw/, /netmask/, /eee\s+\w+/, /eee(\s+\w)/, /mirror/, /vlan\s+(\d{1,4})/
/^ip\b/,
/^gw\b/,
/^netmask\b/,
/^syslog\s+ip\b/,
/^syslog\b/,
/^passwd\b/,
/^vlan\s+\d{1,4}\s+mgmt$/,
/^vlan\s+\d{1,4}(?!\s+mgmt\b)/,
/^pvid\s+\d{1,2}\b/,
/^ingress\b/,
/^port\s+\d{1,2}\s+name\b/,
/^eee\s+\d{1,2}\b/,
/^eee\b/,
/^mirror\b/,
/^lag\s+\d+\b/,
/^laghash\b/,
/^isolate\s+\d{1,2}\b/,
/^stp\b/,
/^igmp\b/,
/^mtu\s+\d{1,2}\b/,
/^bw\s+(in|out)\s+\d{1,2}\b/,
];
function parseConf(s){
var a = s.split(/\r\n|\n/);
for (var l = 0; l < a.length; l++) {
if (!a[l].length || a[l] == "\n" || a[l] == "\r\n")
var line = a[l].trim().replace(/\s+/g, ' ');
if (!line.length) continue;
const deleteMatch = line.match(/^vlan\s+(\d{1,4})\s+d$/);
if (deleteMatch) {
const prefix = "vlan " + deleteMatch[1] + " ";
configuration = configuration.filter(c =>
c !== "vlan " + deleteMatch[1] && !c.startsWith(prefix));
continue;
console.log(l + ' --> ' + a[l]);
}
console.log(l + ' --> ' + line);
var ignore = true;
for (const x of conf_cmds)
if (x.test(a[l])) ignore = false;
if (x.test(line)) { ignore = false; break; }
if (ignore) continue;
for (const x of conf_overwrite) {
if (x.test(a[l])) {
console.log("Match ", x, " to ", a[l]);
m = a[l].match(x);
console.log("Starts with ", m[0]);
configuration = configuration.filter(item => !(item.startsWith(m[0])));
if (x.test(line)) {
let m = line.match(x);
let matchStr = m[0];
configuration = configuration.filter(item =>
!(item === matchStr || item.startsWith(matchStr + " ")));
break;
}
}
configuration.push(a[l]);
configuration.push(line);
}
console.log("Configuration now:");
for (const x of configuration) { console.log(x); }
+1
View File
@@ -163,3 +163,4 @@ margin: 30px 0;
}
select { text-align-last: right; font-family: monospace}
option { direction: rtl; font-family: sans-serif}
#vlanTable td { text-align: left; }
+18 -13
View File
@@ -1,4 +1,5 @@
var systemInterval = Number();
var isSaving = false;
const ips = ["ip", "netmask", "gw"];
function checkIp(ip) {
@@ -43,35 +44,39 @@ async function cmdSub() {
async function sendConfig(c) {
if (isSaving) return;
isSaving = true;
clearInterval(systemInterval);
const form = new FormData();
form.append("MAX_FILE_SIZE", "4096");
form.append("configuration", new Blob([c], {type: "application/octet-stream"}));
form.append("configuration", new Blob([c], {type: "application/octet-stream"}), "config.txt");
try {
const response = await fetch('/config', {
method: 'POST',
body: form
});
console.log('Completed!', response);
try {
await fetch('/cmd_log_clear', { method: 'GET' });
} catch(e) {}
} catch(err) {
console.error(`Error: ${err}`);
} finally {
isSaving = false;
systemInterval = setInterval(fetchIP, 1000);
}
}
async function flashSave() {
fetchConfig().then((s) => {
parseConf(s);
fetchCmdLog().then((s) => {
parseConf(s);
var body = "";
for (const x of configuration) { body = body + x + "\n"; }
configuration = [];
const savedConfig = await fetchConfig();
const cmdLog = await fetchCmdLog();
if (savedConfig) parseConf(savedConfig);
if (cmdLog) parseConf(cmdLog);
const body = configuration.join('\n') + '\n';
console.log("CONFIGURATION to save: ", body);
sendConfig(body);
});
});
setTimeout(() => {
fetchIP();
}, 500);
await sendConfig(body);
}
async function flashStartupSave() {
+23
View File
@@ -10,6 +10,13 @@
<div id="ports"></div>
<h1>VLAN Configuration</h1>
<form id="vform" action="/vlan.html">
<div>
<label for="vlanSelect">VLAN auswählen:</label>
<select id="vlanSelect" style="margin: 0 0 0 8px">
<option value="" disabled selected>— VLAN wählen —</option>
</select>
</div>
<br/>
<div>
<label for="vid">VLAN ID:</label>
<input type="number" min="1" max="4094" id="vid" name="vid">
@@ -29,6 +36,22 @@
<br/> <input style="width:40%;" class="action" id="vlan_sub" onclick="vlanSub();" type="button" value="Update / Create">
<script src="/vlan_sub.js"></script>
</form>
<h2>Configured VLANs</h2>
<table id="vlanTable" style="width:90%">
<thead>
<tr>
<th>VLAN</th>
<th>Name</th>
<th>Member Ports</th>
<th>Tagged Ports</th>
<th>Untagged Ports</th>
<th>PVID Ports</th>
<th>Delete</th>
</tr>
</thead>
<tbody id="vlanTableBody">
</tbody>
</table>
</div>
<script src="/navigation.js"></script>
</body>
+120
View File
@@ -83,9 +83,129 @@ function fetchVLAN() {
sendXHTTP(xhttp);
}
function portsToRange(mask, nPorts) {
var parts = [];
var start = -1, prev = -1;
for (var p = 1; p <= nPorts; p++) {
var bit = physToLogPort[p - 1];
if ((mask >> bit) & 1) {
if (start < 0) start = p;
prev = p;
} else {
if (start >= 0) {
parts.push(start === prev ? String(start) : start + '-' + prev);
start = -1; prev = -1;
}
}
}
if (start >= 0)
parts.push(start === prev ? String(start) : start + '-' + prev);
return parts.length ? parts.join(',') : '-';
}
async function loadVlanTable() {
var tbody = document.getElementById('vlanTableBody');
if (!tbody) return;
tbody.innerHTML = '';
var resp;
try { resp = await fetch('/vlanlist'); } catch(e) { return; }
if (!resp.ok) return;
var vlans = await resp.json();
for (var i = 0; i < vlans.length; i++) {
var v = vlans[i];
var vresp;
try { vresp = await fetch('/vlan.json?vid=' + v.id); } catch(e) { continue; }
if (!vresp.ok) continue;
var s = await vresp.json();
var m = parseInt(s.members, 16);
var members = m & 0x3FF;
var untag = ((m >> 10) & 0x3FF) & members;
var tagged = members & ~untag;
var pvid = parseInt(s.pvid, 16) & 0x3FF;
var tr = document.createElement('tr');
var td, a, btn;
td = document.createElement('td');
a = document.createElement('a');
a.href = '#';
a.textContent = v.id;
(function(vid) {
a.onclick = function(e) {
e.preventDefault();
document.getElementById('vid').value = vid;
fetchVLAN();
};
})(v.id);
td.appendChild(a); tr.appendChild(td);
td = document.createElement('td');
td.textContent = v.name || ''; tr.appendChild(td);
td = document.createElement('td');
td.textContent = portsToRange(members, numPorts); tr.appendChild(td);
td = document.createElement('td');
td.textContent = portsToRange(tagged, numPorts); tr.appendChild(td);
td = document.createElement('td');
td.textContent = portsToRange(untag, numPorts); tr.appendChild(td);
td = document.createElement('td');
td.textContent = portsToRange(pvid, numPorts); tr.appendChild(td);
td = document.createElement('td');
if (v.id !== 1) {
btn = document.createElement('button');
btn.textContent = '✕';
(function(vid) {
btn.onclick = function() { deleteVlan(vid); };
})(v.id);
td.appendChild(btn);
}
tr.appendChild(td);
tbody.appendChild(tr);
}
}
function deleteVlan(id) {
if (!confirm('Delete VLAN ' + id + '?')) return;
fetch('/cmd', { method: 'POST', body: 'vlan ' + id + ' d' })
.then(function() { refreshVlanViews(); })
.catch(function(err) { console.error('Delete failed:', err); });
}
function refreshVlanViews() {
loadVlanList();
loadVlanTable();
}
function loadVlanList() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState !== 4) return;
var sel = document.getElementById('vlanSelect');
if (this.status !== 200) {
sel.style.display = 'none';
return;
}
var vlans = JSON.parse(this.responseText);
if (!vlans.length) {
sel.style.display = 'none';
return;
}
sel.options.length = 1;
for (var i = 0; i < vlans.length; i++) {
var opt = document.createElement('option');
opt.value = vlans[i].id;
opt.text = vlans[i].name ? vlans[i].id + ' — ' + vlans[i].name : String(vlans[i].id);
sel.appendChild(opt);
}
};
xhttp.open('GET', '/vlanlist', true);
sendXHTTP(xhttp);
}
window.addEventListener("load", function() {
update( () => {
vlanForm();
refreshVlanViews();
document.getElementById('vlanSelect').onchange = function() {
document.getElementById('vid').value = this.value;
fetchVLAN();
};
const interval = setInterval(update, 2000);
});
});
+1
View File
@@ -28,6 +28,7 @@ async function vlanSub() {
});
console.log('Completed!', response);
}
refreshVlanViews();
} catch(err) {
console.error(`Error: ${err}`);
}
+2
View File
@@ -682,6 +682,8 @@ void httpd_appcall(void)
send_mtu();
} else if (is_word(q, "/lag.json")) {
send_lag();
} else if (is_word(q, "/vlanlist")) {
send_vlanlist();
} else if (is_word(q, "/config")) {
send_config();
} else if (is_word(q, "/cmd_log")) {
+56
View File
@@ -97,6 +97,19 @@ void itoa_html(uint8_t v)
char_to_html('0' + (v % 10));
}
void itoa16_html(uint16_t v) /* sufficient for VLAN IDs (max 4094) */
{
uint8_t print_zeros = 0;
uint8_t d;
d = v / 1000;
if (d) { char_to_html('0' + d); print_zeros = 1; }
d = (v / 100) % 10;
if (d || print_zeros) { char_to_html('0' + d); print_zeros = 1; }
d = (v / 10) % 10;
if (d || print_zeros) char_to_html('0' + d);
char_to_html('0' + (v % 10));
}
void string_to_html(__code char *s)
{
while (*s) char_to_html(*s++);
@@ -825,3 +838,46 @@ void send_cmd_log(void)
p = (p + 1) & CMD_HISTORY_MASK;
}
}
void send_vlanlist(void)
{
/* Worst case per entry: {"id":4094,"name":"<117-char name>"} = 138 bytes
* (name bound: CMD_BUF_SIZE=128 minus command prefix); +1 for closing ']'.
* At worst case ~18 VLANs fit; typical configs with short names fit many more. */
__xdata uint16_t i;
__xdata uint16_t n;
uint8_t first = 1;
slen = strtox(outbuf, HTTP_RESPONCE_JSON);
char_to_html('[');
for (i = 1; i < 4095; i++) {
if (vlan_get(i) < 0)
continue;
if (!(sfr_data[0] & 0x02)) /* bit 1: VLAN table entry valid */
continue;
if (slen + 139 > TCP_OUTBUF_SIZE) /* 138 bytes worst-case entry + 1 byte for closing ']' */
break;
if (!first)
char_to_html(',');
first = 0;
slen += strtox(outbuf + slen, "{\"id\":");
itoa16_html(i);
slen += strtox(outbuf + slen, ",\"name\":\"");
n = vlan_name(i);
if (n != 0xffff) {
while (vlan_names[n] && vlan_names[n] != ' ')
char_to_html(vlan_names[n++]);
}
slen += strtox(outbuf + slen, "\"}");
}
char_to_html(']');
}
+1
View File
@@ -14,6 +14,7 @@ void send_mtu(void);
void send_config(void);
void send_cmd_log(void);
void send_lag(void);
void send_vlanlist(void);
/* Convert only the lower nibble to ascii HEX char.
For convenience the upper nibble is masked out.
+117 -8
View File
@@ -1,6 +1,7 @@
#include "machine.h"
#include "rtl837x_pins.h"
#include "rtl837x_leds.h"
#include "rtl837x_sfr.h"
#include "rtl837x_regs.h"
#include "rtl837x_common.h"
@@ -266,15 +267,19 @@ __code const struct machine machine = {
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 40 */
.reset_pin = GPIO54_ACL_BIT2_EN,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
.led_sets = {
{
/* Green LED */
{ /* RJ45: Green LED */
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
0,
/* Amber LED */
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
0
}, { /* SFP PORT: SINGLE GREEN LED */
LEDS_10M | LEDS_100M | LEDS_1G | LEDS_2G5 | LEDS_10G | LEDS_LINK | LEDS_ACT,
0,
0,
0,
},
},
};
@@ -305,15 +310,19 @@ __code const struct machine machine = {
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 40 */
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
.led_sets = {
{
/* Green LED */
{ /* RJ45: Green LED */
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
0,
/* Amber LED */
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
0
}, { /* SFP PORT: SINGLE GREEN LED */
LEDS_10M | LEDS_100M | LEDS_1G | LEDS_2G5 | LEDS_10G | LEDS_LINK | LEDS_ACT,
0,
0,
0,
},
},
};
@@ -536,9 +545,9 @@ __code const struct machine machine = {
void machine_custom_init(void) { }
#elif defined MACHINE_HI_K0402WS
#elif defined(MACHINE_PCB_K0402WS_V3) || defined(MACHINE_HI_K0402WS) // Sold as a variety of devices, see doc/
__code const struct machine machine = {
.machine_name = "HiSource HI-K0402WS",
.machine_name = "PCB-K0402WS-V3.0",
.isRTL8373 = 0,
.min_port = 3,
.max_port = 8,
@@ -778,6 +787,106 @@ void machine_custom_init(void)
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
}
#elif defined MACHINE_PCB_SWTG024AS_A_2_0_1
__code const struct machine machine = {
.machine_name = "PCB-SWTG024AS-A-2.0.1",
.isRTL8373 = 0,
.min_port = 3,
.max_port = 8,
.n_sfp = 2,
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
.is_sfp = {0, 0, 0, 1, 0, 0, 0, 0, 2},
// SFP port on SDS0 / logical port 3
.sfp_port[0].pin_detect = GPIO37,
.sfp_port[0].pin_los = GPIO_NA,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 0,
.sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
// SFP port on SDS1 / logical port 8
.sfp_port[1].pin_detect = GPIO38,
.sfp_port[1].pin_los = GPIO_NA,
.sfp_port[1].pin_tx_disable = GPIO_NA,
.sfp_port[1].sds = 1,
.sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
.led_sets = {
{
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
LEDS_DUPLEX,
LEDS_2G5 | LEDS_LINK | LEDS_ACT
},
{
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT,
LEDS_10G | LEDS_LINK | LEDS_ACT,
LEDS_2G5 | LEDS_LINK,
LEDS_COL | LEDS_DUPLEX
},
},
.led_mux_custom = 1,
.led_mux = {
0x00,0x01,0x04,0x05,0x08,0x09,0x0c,0x3f,0x0d,0x10,0x11,0x0e,0x14,0x11,0x12,0x15,0x15,0x16,0x18,0x19,0x1a,0x19,0x1d,0x1e,0x1c,0x1d,0x20,0x21
},
};
void machine_custom_init(void)
{
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_ZX310S_4T2XT
__code const struct machine machine = {
.machine_name = "ZX310S_4T2XT",
.isRTL8373 = 0,
.min_port = 3,
.max_port = 8,
.n_sfp = 0,
.n_10g = 2,
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 0},
.reset_pin = GPIO48_I2C_SCL1,
.high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 },
.led_mux_custom = 1,
.led_mux = { 0x00, 0x01, 0x04, 0x05, 0x08, // 65e0
0x09, 0x0c, 0x3f, 0x0d, 0x10, // 65e4
0x11, 0x0e, 0x14, 0x11, 0x12, // 65e8
0x15, 0x15, 0x16, 0x18, 0x19, // 65ec
0x1a, 0x19, 0x1d, 0x1e, 0x1c, // 65f0
0x1d, 0x20, 0x21 },
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
/* Ports 1-4: Green: 2.5GBit, Orange: 10/100/1000MBit
* Ports 5-6: Green: 10GBit, Orange: <= 5GBit
*/
.led_sets = { { LEDS_2G5 | LEDS_LINK | LEDS_ACT,
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
LEDS_DUPLEX,
LEDS_2G5 | LEDS_LINK | LEDS_ACT },
{
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT,
LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_5G,
LEDS_2G5 | LEDS_LINK,
LEDS_COL | LEDS_DUPLEX
}
},
};
void machine_custom_init(void) {
// 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);
}
#else
#error "Please select a machine type in machine.h"
#endif
+3 -1
View File
@@ -18,13 +18,15 @@
// #define MACHINE_HG0402XG_V1_1
// #define MACHINE_SWTG018AS_A_V_2_0
// #define MACHINE_SWTGW218AS
// #define MACHINE_HI_K0402WS
// #define MACHINE_PCB_K0402WS_V3
// #define MACHINE_K0501W_V2_0
// #define MACHINE_LIANGUO_ZX_SWTGW215AS
// #define MACHINE_ZX310S_4T2XH
// #define MACHINE_ZX310S_4T2XT
// #define MACHINE_DEFAULT_8C_1SFP
// #define MACHINE_HI_K0801WS
// #define MACHINE_FNS1200P
// #define MACHINE_PCB_SWTG024AS_A_2_0_1
typedef struct {
// GPIO pins for SDA/SCL
+1
View File
@@ -46,6 +46,7 @@ void leds_dump(void) __banked
print_string("RTL837X_REG_LED_GLB_MUX_5: "); print_reg(RTL837X_REG_LED_GLB_MUX_5); write_char('\n');
print_string("RTL837X_REG_LED_GLB_MUX_6: "); print_reg(RTL837X_REG_LED_GLB_MUX_6); write_char('\n');
print_string("RTL837X_REG_LED_GLB_ACTIVE: "); print_reg(RTL837X_REG_LED_GLB_ACTIVE); write_char('\n');
print_string("RTL837X_REG_LED_MODE: "); print_reg(RTL837X_REG_LED_MODE); write_char('\n');
print_string("LED pad Configuration:\n");
for (uint8_t i = 0; i < 28; i++) {
print_byte(i);
+34
View File
@@ -116,11 +116,45 @@ uint16_t port_pvid_get(uint8_t port) __banked
void vlan_delete(uint16_t vlan) __banked
{
print_string("\nvlan_delete called \n"); print_short(vlan);
vlan_name_remove(vlan);
REG_WRITE(RTL837x_TBL_DATA_IN_A, 0, 0, 0, 0);
REG_WRITE(RTL837X_TBL_CTRL, vlan >> 8, vlan, TBL_VLAN, TBL_WRITE | TBL_EXECUTE);
}
void vlan_name_remove(uint16_t vlan) __banked
{
static __xdata uint16_t name_pos;
static __xdata uint16_t entry_start;
static __xdata uint16_t pos;
static __xdata uint16_t entry_len;
static __xdata uint16_t move_count;
static __xdata uint16_t j;
name_pos = vlan_name(vlan);
if (name_pos == 0xffff)
return;
entry_start = name_pos - 3;
pos = entry_start;
while (pos < vlan_ptr && vlan_names[pos] != ' ')
pos++;
if (pos >= vlan_ptr)
return;
pos++;
entry_len = pos - entry_start;
move_count = vlan_ptr - pos;
for (j = 0; j < move_count; j++)
vlan_names[entry_start + j] = vlan_names[pos + j];
vlan_ptr -= entry_len;
vlan_names[vlan_ptr] = 0;
}
/*
* Reads VLAN information from VLAN table
* Returns data in sfr_data
+1
View File
@@ -50,6 +50,7 @@ void port_l2_learned(void) __banked;
void port_stats_print(void) __banked;
int8_t vlan_get(register uint16_t vlan) __banked;
__xdata uint16_t vlan_name(register uint16_t vlan) __banked;
void vlan_name_remove(uint16_t vlan) __banked;
void vlan_setup(void) __banked;
void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked;
uint16_t port_pvid_get(uint8_t port) __banked;
+1 -1
View File
@@ -1180,7 +1180,7 @@ static inline uint8_t sfp_rate_to_sds_config(register uint8_t rate)
return SDS_1000BX_FIBER;
if (rate >= 0x19 && rate <= 0x20) // Ethernet 2.5 GBit
return SDS_HSG;
if (rate > 0x65 && rate < 0x70)
if (rate >= 0x63 && rate < 0x70)
return SDS_10GR;
return 0xff;
}