Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
347950ff72 | ||
|
|
0bccfbd11f | ||
|
|
360bc1e86d | ||
|
|
5b385385de | ||
|
|
ea23dfedc5 | ||
|
|
34a32fa7e8 | ||
|
|
06930df7c6 | ||
|
|
df058dfe33 | ||
|
|
45213b4eac |
@@ -17,7 +17,5 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
apt update
|
apt update
|
||||||
apt install make gcc sdcc xxd python-is-python3 libjson-c-dev -y
|
apt install make gcc sdcc xxd python-is-python3 libjson-c-dev -y
|
||||||
- name: Check if machine.c can be compiled for all machines
|
|
||||||
run: make machine_check
|
|
||||||
- name: Make project
|
- name: Make project
|
||||||
run: make MACHINE="KP_9000_6XHML_X2"
|
run: make
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
|
BOOTLOADER_ADDRESS=0x100
|
||||||
|
|
||||||
VERSION=0.1.0
|
VERSION=0.1.0
|
||||||
IMAGESIZE = 524288
|
IMAGESIZE = 524288
|
||||||
DEFAULT_CONFIG_LOCATION = 454656
|
|
||||||
CONFIG_LOCATION = 458752
|
CONFIG_LOCATION = 458752
|
||||||
HTML_LOCATION = 262144
|
HTML_LOCATION = 262144
|
||||||
|
|
||||||
@@ -9,50 +10,28 @@ CC_FLAGS = -mmcs51 -I. -Ihttpd -Iuip
|
|||||||
ASM = sdas8051
|
ASM = sdas8051
|
||||||
AFLAGS= -plosgff
|
AFLAGS= -plosgff
|
||||||
|
|
||||||
SUBDIRS := tools
|
SUBDIRS := tools uip httpd
|
||||||
SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS))
|
SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS))
|
||||||
|
|
||||||
ifeq ($(MACHINE),)
|
BUILDDIR = output/
|
||||||
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
|
VERSION_HEADER := version.h
|
||||||
|
|
||||||
GIT_VERSION := $(shell git rev-parse --short HEAD)
|
all: create_build_dir $(VERSION_HEADER) $(SUBDIRS) $(BUILDDIR)rtlplayground.bin
|
||||||
ifeq ($(shell git status --porcelain --untracked-files=no),)
|
|
||||||
else
|
|
||||||
GIT_VERSION := $(GIT_VERSION)-dirty
|
|
||||||
endif
|
|
||||||
|
|
||||||
VERSION_EXTENSION = v$(VERSION)-$(GIT_VERSION)
|
|
||||||
FILENAME_EXTENSION = $(VERSION_EXTENSION)-$(MACHINE)
|
|
||||||
|
|
||||||
all: create_build_dir $(VERSION_HEADER) $(SUBDIRS) $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin
|
|
||||||
|
|
||||||
create_build_dir:
|
create_build_dir:
|
||||||
mkdir -p $(BUILDDIR)
|
mkdir -p $(BUILDDIR)
|
||||||
mkdir -p $(BUILDDIR)/uip
|
|
||||||
mkdir -p $(BUILDDIR)/httpd
|
|
||||||
|
|
||||||
SRCS = rtlplayground.c rtl837x_flash.c rtl837x_leds.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c
|
SRCS = rtlplayground.c rtl837x_flash.c rtl837x_leds.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c
|
||||||
SRCS += rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c cmd_editor.c rtl837x_bandwidth.c rtl837x_init.c syslog.c
|
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel}
|
||||||
SRCS += uip/timer.c uip/uip.c uip/uip_arp.c uip/uiplib.c uip/uip-fw.c uip/uip-neighbor.c uip/uip-split.c udp_apps.c
|
OBJS += uip/$(BUILDDIR)/timer.rel uip/$(BUILDDIR)/uip-fw.rel uip/$(BUILDDIR)/uip-neighbor.rel uip/$(BUILDDIR)/uip-split.rel uip/$(BUILDDIR)/uip.rel uip/$(BUILDDIR)/uip_arp.rel uip/$(BUILDDIR)/uiplib.rel httpd/$(BUILDDIR)/httpd.rel httpd/$(BUILDDIR)/page_impl.rel
|
||||||
SRCS += httpd/httpd.c httpd/page_impl.c
|
|
||||||
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/output/fileadder
|
html_data.c html_data.h: html tools
|
||||||
tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -d html -p html_data
|
tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -d html -p html_data
|
||||||
|
|
||||||
$(VERSION_HEADER):
|
$(VERSION_HEADER):
|
||||||
@echo "#ifndef VERSION_H" > $(VERSION_HEADER)
|
@echo "#ifndef VERSION_H" > $(VERSION_HEADER)
|
||||||
@echo "#define VERSION_H" >> $(VERSION_HEADER)
|
@echo "#define VERSION_H" >> $(VERSION_HEADER)
|
||||||
@echo "#define VERSION_SW \"$(VERSION_EXTENSION)\"" >> $(VERSION_HEADER)
|
@echo "#define VERSION_SW \"v$(VERSION)-g$(shell git rev-parse --short HEAD)\"" >> $(VERSION_HEADER)
|
||||||
@echo "#define BUILD_DATE \"$(shell date +"%Y-%m-%d %H:%M:%S")\"" >> $(VERSION_HEADER)
|
|
||||||
@echo "#endif" >> $(VERSION_HEADER)
|
@echo "#endif" >> $(VERSION_HEADER)
|
||||||
|
|
||||||
httpd: html_data.h
|
httpd: html_data.h
|
||||||
@@ -61,46 +40,36 @@ $(SUBDIRS):
|
|||||||
$(MAKE) -C $@
|
$(MAKE) -C $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -f html_data.c html_data.h $(VERSION_HEADER)
|
-make -C uip clean
|
||||||
-if [ -d $(BUILDDIR) ]; then find $(BUILDDIR) -type f ! -name "*.bin" -delete; fi
|
-make -C httpd clean
|
||||||
|
-rm html_data.c html_data.h $(VERSION_HEADER)
|
||||||
|
-rm -r $(BUILDDIR)
|
||||||
|
|
||||||
distclean:
|
$(BUILDDIR)crtstart.rel: crtstart.asm
|
||||||
-rm -f html_data.c html_data.h $(VERSION_HEADER)
|
$(ASM) $(AFLAGS) -o $@ $<
|
||||||
-rm -rf $(BUILDDIR)
|
|
||||||
|
|
||||||
$(BUILDDIR)/%.rel: %.c
|
$(BUILDDIR)crc16.rel: crc16.asm
|
||||||
$(CC) -MMD $(CC_FLAGS) -o $@ -c $<
|
$(ASM) $(AFLAGS) -o $@ $<
|
||||||
|
|
||||||
$(BUILDDIR)/%.rel: %.asm
|
$(BUILDDIR)%.rel: %.c
|
||||||
|
$(CC) $(CC_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
$(BUILDDIR)%.rel: $(BUILDDIR)%.asm
|
||||||
${ASM} ${AFLAGS} -o $@ $<
|
${ASM} ${AFLAGS} -o $@ $<
|
||||||
# mv -f $(addprefix $(basename $^), .lst .rel .sym) .
|
# mv -f $(addprefix $(basename $^), .lst .rel .sym) .
|
||||||
|
|
||||||
$(BUILDDIR)/rtlplayground.ihx: $(OBJS) $(BUILDDIR)/crtstart.rel $(BUILDDIR)/crc16.rel
|
$(BUILDDIR)rtlplayground.ihx: $(BUILDDIR)crtstart.rel $(OBJS) $(BUILDDIR)crc16.rel
|
||||||
$(CC) $(CC_FLAGS) -Wl-bHOME=0x00000 -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-r -o $@ $^
|
$(CC) $(CC_FLAGS) -Wl-bHOME=${BOOTLOADER_ADDRESS} -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-r -o $@ $^
|
||||||
|
|
||||||
$(BUILDDIR)/rtlplayground.img: $(BUILDDIR)/rtlplayground.ihx
|
$(BUILDDIR)rtlplayground.img: $(BUILDDIR)rtlplayground.ihx
|
||||||
objcopy --input-target=ihex -O binary $< $@
|
objcopy --input-target=ihex -O binary $< $@
|
||||||
|
|
||||||
$(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.img
|
$(BUILDDIR)rtlplayground.bin: $(BUILDDIR)rtlplayground.img
|
||||||
if [ -e $@ ]; then rm $@; fi
|
if [ -e $@ ]; then rm $@; fi
|
||||||
tools/output/imagebuilder -i $^ $@
|
tools/$(BUILDDIR)imagebuilder -i $^ $@
|
||||||
tools/output/fileadder -a $(DEFAULT_CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
tools/$(BUILDDIR)fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
||||||
tools/output/fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data $@
|
||||||
tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data -b BANK1 $@
|
tools/$(BUILDDIR)crc_calculator -u $@
|
||||||
tools/output/crc_calculator -u $@
|
|
||||||
ln -sf $(MACHINE)/rtlplayground-$(FILENAME_EXTENSION).bin output/rtlplayground.bin
|
|
||||||
|
|
||||||
.PHONY: clean all $(SUBDIRS) $(VERSION_HEADER)
|
|
||||||
|
|
||||||
.PHONY:
|
.PHONY: clean all $(SUBDIRS)
|
||||||
machine_check:
|
|
||||||
@mkdir -p $(BUILDDIR)/tmp
|
|
||||||
@set -eo pipefail; \
|
|
||||||
for MACHINE in `grep -e ' MACHINE_' machine.c | sed -e 's%^.* MACHINE_%%' -e 's%[ ]*//.*$$%%' | sort -u`; \
|
|
||||||
do \
|
|
||||||
echo "Checking $${MACHINE}"; \
|
|
||||||
$(CC) $(CC_FLAGS) -DMACHINE_$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine.c; \
|
|
||||||
done
|
|
||||||
@rm -rf $(BUILDDIR)/tmp
|
|
||||||
|
|
||||||
-include $(DEPS)
|
|
||||||
|
|||||||
@@ -52,145 +52,96 @@ devices by looking at the image using e.g. Ghidra. If you want to contribute to
|
|||||||
design of the web-interface or get a feeling for the interface first, a standalone
|
design of the web-interface or get a feeling for the interface first, a standalone
|
||||||
device simulator is provided, which runs entirely under Linux as a local webserver.
|
device simulator is provided, which runs entirely under Linux as a local webserver.
|
||||||
|
|
||||||
## (0) Compiling Requirements
|
## Compiling
|
||||||
|
|
||||||
Install the following particular build requisites (Debian 12/13), note that Ubuntu 24.04
|
Install the following particular build requisites (Debian 12/13), note that Ubuntu 24.04
|
||||||
still has an older version of sdcc, but you will need sdcc version 4.5 for the code to compile:
|
still has an older version of sdcc, but you will need sdcc version 4.5 for the code to compile:
|
||||||
```
|
```
|
||||||
sudo apt install make gcc sdcc xxd python-is-python3 libjson-c-dev
|
sudo apt install sdcc xxd python-is-python3 libjson-c-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
## (1) Compiling for direct chip flashing AND upgrading an existing RTLPlayground running device
|
|
||||||
|
|
||||||
Edit machine.h with an editor like vi or nano. Select the correct machine the firmware should build for.
|
|
||||||
|
|
||||||
> [!TIP]
|
|
||||||
> You can write configuration parameters in config.txt (see below) in order your switch to get
|
|
||||||
> straight at the first boot, a correct IP configuration.
|
|
||||||
|
|
||||||
Now, building the firmware image should work:
|
Now, building the firmware image should work:
|
||||||
```
|
```
|
||||||
make
|
$ make
|
||||||
|
sdas8051 -plosgff crtstart.asm
|
||||||
|
sdcc -mmcs51 -c rtlplayground.c
|
||||||
|
sdcc -mmcs51 -c rtl837x_flash.c
|
||||||
|
sdcc -mmcs51 -Wl-bHOME=0x100 -o rtlplayground.ihx crtstart.rel rtlplayground.rel rtl837x_flash.rel
|
||||||
|
objcopy --input-target=ihex -O binary rtlplayground.ihx rtlplayground.img
|
||||||
|
if [ -e rtlplayground.bin ]; then rm rtlplayground.bin; fi
|
||||||
|
echo "0000000: 00 40" | xxd -r - rtlplayground.bin
|
||||||
|
cat rtlplayground.img >> rtlplayground.bin
|
||||||
```
|
```
|
||||||
Note, that the image generated ends in .bin, not .img, in order to make IMSProg happy.
|
Note, that the image generated ends in .bin, not .img, in order to make
|
||||||
|
IMSProg happy.
|
||||||
image location is stored in `RTLPlayground/output/rtlplayground_version_machine.bin`
|
|
||||||
for example
|
|
||||||
```
|
|
||||||
rtlplayground-v0.1.0-12c98ba-dirty-LIANGUO_ZX_SWTGW215AS.bin
|
|
||||||
```
|
|
||||||
|
|
||||||
> [!CAUTION]
|
|
||||||
> This image can be flashed directly to the chip OR through the firmware update/upgrade
|
|
||||||
> interface of RTLPlaygound interface
|
|
||||||
|
|
||||||
## (2) Compiling for OEM running device with management options (web upgrade)
|
|
||||||
|
|
||||||
Managed switches can be updated from the existing original firmware using a SPECIFIC upgrade image.
|
|
||||||
You first need to build the firmware for direct chip flashing : See below (1)
|
|
||||||
|
|
||||||
Then
|
|
||||||
|
|
||||||
```
|
|
||||||
cd installer
|
|
||||||
make
|
|
||||||
```
|
|
||||||
image location is stored in `RTLPlayground/installer/output/rtlplayground_oem_upgrade.bin`
|
|
||||||
|
|
||||||
> [!CAUTION]
|
|
||||||
> This image must ONLY be used for original OEM firmware web interface firmware upgrade.
|
|
||||||
> You do not need this image if you are already on RTLplayground firmware.
|
|
||||||
> Unless you go back to the original OEM firmware, you would only flash this specific firmware
|
|
||||||
> only once. Future upgrades of RTLPlayground will only need to follow (1)
|
|
||||||
|
|
||||||
example of compilation console output
|
|
||||||
|
|
||||||
|
Managed switches can be updated from the existing original firmware using an upgrade image.
|
||||||
|
In the `installer`folder of the source code you will need to run `make` which will build
|
||||||
|
an image out of `rtlplayground.bin` built in the previous step:
|
||||||
```
|
```
|
||||||
RTLPlayground/installer$ make
|
RTLPlayground/installer$ make
|
||||||
mkdir -p output
|
mkdir -p output/
|
||||||
gcc updatebuilder.c -o output/updatebuilder
|
gcc updatebuilder.c -o output/updatebuilder
|
||||||
sdas8051 -plosgff -o output/crtstart.rel crtstart.asm
|
sdas8051 -plosgff -o output/crtstart.rel crtstart.asm
|
||||||
sdcc -mmcs51 --code-loc 0x1000 -o output/installer.rel -c installer.c
|
sdcc -mmcs51 --code-loc 0x1000 -o output/installer.rel -c installer.c
|
||||||
sdcc -mmcs51 -Wl-bHOME=0x1100 -Wl-r -o output/rtlinstaller.ihx output/crtstart.rel output/installer.rel
|
sdcc -mmcs51 -Wl-bHOME=0x1100 -Wl-r -o output/rtlinstaller.ihx output/crtstart.rel output/installer.rel
|
||||||
./output/updatebuilder -i output/rtlinstaller.ihx -o output/rtlplayground_oem_upgrade.bin ../output/rtlplayground.bin
|
cp ../output//rtlplayground.bin output/
|
||||||
|
./output//updatebuilder -i output/rtlinstaller.ihx output/rtlplayground.bin
|
||||||
Input file size: 524288
|
Input file size: 524288
|
||||||
Bytes read: 524288
|
Bytes read: 524288
|
||||||
EOF
|
EOF
|
||||||
Payload sum 1 is: 0x25100
|
Payload sum 1 is: 0x29d10
|
||||||
Payload sum 2 is: 0x25100
|
Payload sum 2 is: 0x29d10
|
||||||
Payload sum with header is: 0x264ec
|
Payload sum with header is: 0x2b0fc
|
||||||
Payload sum is: 0xf8fe94
|
Payload sum is: 0xad8a75
|
||||||
Header checksum is: 0x5a1
|
Header checksum is: 0x4c3
|
||||||
```
|
```
|
||||||
|
The resulting image can be found in `RTLPlayground/installer/output/rtlplayground.bin`
|
||||||
|
> [!CAUTION]
|
||||||
|
> DO NOT UPLOAD THE UPGADE IMAGE UNLESS YOU CAN MAKE A BACKUP USING A SOIC CLAMP OF THE
|
||||||
|
> ORIGINAL FIRMWARE!
|
||||||
|
|
||||||
## (3) Sandbox Usage with Ghidra (optional)
|
## Installation
|
||||||
|
|
||||||
You can play with the image using ghidra or flash real Switch Hardware. For
|
You can play with the image using ghidra or flash real Switch Hardware. For
|
||||||
ghidra see this information about [Ghidra images](ghidra.md).
|
ghidra see this information about [Ghidra images](ghidra.md).
|
||||||
|
|
||||||
## (4) Installation through the Web interface (software way)
|
|
||||||
|
|
||||||
Managed switches (OEM firmware of RTLplaygroud firmware) can be upgraded via the web interface.
|
|
||||||
Unmanaged switch cannot be flashed this way (see 5).
|
|
||||||
|
|
||||||
Go to "Firmware update" tab, select the correct file.
|
|
||||||
|
|
||||||
> [!IMPORTANT]
|
|
||||||
> If your device already runs RTLPlayground, you must upload the binary file /RTLPlayground/output/rtlplayground_Version_Machine.bin
|
|
||||||
> If your device is OEM, you must upload the binary file /RTLPlayground/installer/outputrtlplayground_oem_upgrade.bin
|
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> Check one more time that your device matches the machine type before flashing.
|
> NOTE THAT WHILE THIS PROCEDURE HAS BEEN SUCCESSFULLY TESTED ON ALL DEVICES ABOVE,
|
||||||
> Be shure you have a backup of the original firmware before diving in RTLPlaygroung.
|
> ABSOLUTELY NO GUARANTY CAN BE GIVEN THAT YOU WILL NOT DESTROY YOUR SWITCH,
|
||||||
|
> ANY OTHER EQUIPMENT INVOLVED OR HARM YOURSELF BY OPENING THE ELECTRONIC
|
||||||
|
> DEVICE. OPENING THE SWITCH WILL VOID ITS WARRANTY.
|
||||||
|
|
||||||
Finally, push the Upload File Button and you're done !
|
You can upload the upgrade image of managed switches via the web interface of the
|
||||||
|
original firmware just as if you were installing a firmware upgrade. However,
|
||||||
|
this is strongly discouraged, as you may brick your device, unless you can make
|
||||||
|
firmware backups via a SOIC clamp or soldered flash socket, first!
|
||||||
|
|
||||||
|
For unmanaged devices, the only way to install RTLPlayground is by flashing the
|
||||||
|
Flash memory directly.
|
||||||
|
|
||||||
## (5) Flashing the ROM directly (hardware way, but also only way to rescue)
|
You will need to open your switch to flash the image directly onto the flash chip,
|
||||||
|
which is done easiest using a SOIC-8 clip (alternatively you de-solder the
|
||||||
|
flash chip and install a SOIC adapter):
|
||||||
|
- Disconnect power from switch
|
||||||
|
- Attach the clip onto the flash chip
|
||||||
|
- Connect USB of flash programmer, the power LED on the switch will light
|
||||||
|
up, check cabling if not. Don't panic, mixing up GND and 3.3V does not
|
||||||
|
seem to destroy the switch (at leasts the on I did this to).
|
||||||
|
- Use IMSProg (flashrom should work, too) to detect the clip
|
||||||
|
- MAKE A BACKUP OF THE EXISTING FIRMWARE!
|
||||||
|
- then load the firmware into IMSProg
|
||||||
|
- and program flash
|
||||||
|
|
||||||
This procedure is the only way to flash unmanaged switches, if the ROM chip is large enough.
|
Now you can connect a serial cable to the UART port found on all the
|
||||||
This is also the only way to unbrick your device if something went wroong.
|
devices, set 8N1 @ 115200 baud and power up the switch.
|
||||||
|
|
||||||
> [!IMPORTANT]
|
The device will perform some examples and provide a minimal console, the
|
||||||
> You need a SOIC-8 clip to flash the ROM chip directly onboard.
|
documentation of which can be found in the source code rtlplayground.c`.
|
||||||
> Alternatively you can de-solder the flash chip and install a SOIC adapter).
|
|
||||||
> For flashing the chip directly, you must use the binary file /RTLPlayground/output/rtlplayground_Version_Machine.bin
|
|
||||||
|
|
||||||
> [!CAUTION]
|
## The web-interface
|
||||||
> As you need to open your switch case, consider that the warranty is gone.
|
The web-interface can be reached under the [default 192.168.10.247](http://192.168.10.247).
|
||||||
|
The default password is `1234`.
|
||||||
- Disconnect power from switch.
|
|
||||||
- Open the switch.
|
|
||||||
- Attach the clip onto the flash chip (Red line on Pin 1, Pin 1 has a point marker).
|
|
||||||
- Connect USB of flash programmer, the power LED on the switch will light up, check cabling if not.
|
|
||||||
- Don't panic, mixing up GND and 3.3V usually does not destroy the switch.
|
|
||||||
- Use IMSProg, Flashrom, or whatever Programmer to detect the chip.
|
|
||||||
- MAKE A BACKUP (DUMP) OF THE EXISTING FIRMWARE !
|
|
||||||
- ERASE THE ROM (BLANK) !
|
|
||||||
- Load the firmware into IMSProg.
|
|
||||||
- Flash is to the ROM chip.
|
|
||||||
- Disconect the clip from the ROM chip.
|
|
||||||
- You're done, ready for the first boot.
|
|
||||||
|
|
||||||
## (6) Connecting a serial interface (optional)
|
|
||||||
|
|
||||||
You can connect a serial cable to the UART port found on all the devices, set 8N1 @ 115200 baud.
|
|
||||||
|
|
||||||
## (7) Power Up
|
|
||||||
|
|
||||||
When you power up the switch, the device will perform some examples and provide a minimal console
|
|
||||||
(if wired to a serial interface), the documentation of which can be found in the source code rtlplayground.c`.
|
|
||||||
|
|
||||||
## (8) The web-interface
|
|
||||||
|
|
||||||
The web-interface can be reached under the [default 192.168.10.247](http://192.168.10.247) unless you
|
|
||||||
specified an IP adress in the config.txt before compilation.
|
|
||||||
|
|
||||||
> [!TIP]
|
|
||||||
> The default password is `1234`.
|
|
||||||
|
|
||||||
## (9) The command line
|
|
||||||
|
|
||||||
|
## The command line
|
||||||
The command line is very rudimentary and mostly for testing purposes.
|
The command line is very rudimentary and mostly for testing purposes.
|
||||||
The following is a boot-log with some examples:
|
The following is a boot-log with some examples:
|
||||||
```
|
```
|
||||||
@@ -255,6 +206,7 @@ PORT 04 1G
|
|||||||
<MODULE INSERTED> Rate: 67 Encoding: 01
|
<MODULE INSERTED> Rate: 67 Encoding: 01
|
||||||
Lightron Inc. WSPXG-ES3LC-IHA 0000
|
Lightron Inc. WSPXG-ES3LC-IHA 0000
|
||||||
|
|
||||||
|
|
||||||
> stat
|
> stat
|
||||||
CMD: stat
|
CMD: stat
|
||||||
Port State Link TxGood TxBad RxGood RxBad
|
Port State Link TxGood TxBad RxGood RxBad
|
||||||
@@ -272,40 +224,17 @@ Lightron Inc. WSPXG-ES3LC-IHA 0000
|
|||||||
CMD: sfp
|
CMD: sfp
|
||||||
Rate: 67 Encoding: 01
|
Rate: 67 Encoding: 01
|
||||||
Lightron Inc. WSPXG-ES3LC-IHA 0000
|
Lightron Inc. WSPXG-ES3LC-IHA 0000
|
||||||
```
|
|
||||||
|
|
||||||
## (10) Advanced configuration
|
|
||||||
|
|
||||||
You can configure more deeply the switch without the need of the console mode.
|
|
||||||
|
|
||||||
While in compilation part, you might write directly to config.txt file before making the binary firmware
|
|
||||||
|
|
||||||
```
|
```
|
||||||
nano config.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want to modify settings after the flash is done, go to the Advanced Settings tab in System Settings
|
|
||||||
|
|
||||||
<img width="1085" height="646" alt="ADVANCED SETTINGS" src="doc/images/advanced_settings.png" />
|
|
||||||
|
|
||||||
```
|
|
||||||
ip xxx.xxx.xxx.xxx = IP adress of the switch
|
|
||||||
gw yyy.yyy.yyy.yyy = IP adress of the gateway
|
|
||||||
netmask zzz.zzz.zzz.zzz = Network mask of the switch
|
|
||||||
port x name xxx = Name xxx the port number x
|
|
||||||
port z 1g = Set 1g speed for port z
|
|
||||||
igmp on/off = Turn IGMP on or off
|
|
||||||
```
|
|
||||||
[To be continue]
|
|
||||||
|
|
||||||
Enjoy playing!
|
Enjoy playing!
|
||||||
|
|
||||||
## (11) Other documents
|
## Other documents
|
||||||
|
The following documents give further documentation on specific features of
|
||||||
The following documents give further documentation on specific features of the RTL837x SoCs:
|
the RTL837x SoCs:
|
||||||
- [RTL8372/3 Feature support](doc/hardware.md)
|
- [RTL8372/3 Feature support](doc/hardware.md)
|
||||||
- [CPU Port](doc/CpuPort.md)
|
- [CPU Port](doc/CpuPort.md)
|
||||||
- [L2 learning](doc/l2.md)
|
- [L2 learning](doc/l2.md)
|
||||||
|
- [CPU Port](doc/CpuPort.md)
|
||||||
- [IGMP (IP-MC streaming)](doc/igmp.md)
|
- [IGMP (IP-MC streaming)](doc/igmp.md)
|
||||||
- [SFP+ ports](doc/sfp.md)
|
- [SFP+ ports](doc/sfp.md)
|
||||||
- [Trunking aka. port aggregation](doc/trunking.md)
|
- [Trunking aka. port aggregation](doc/trunking.md)
|
||||||
|
|||||||
@@ -1,208 +0,0 @@
|
|||||||
#include "cmd_parser.h"
|
|
||||||
#include "machine.h"
|
|
||||||
|
|
||||||
#pragma codeseg BANK2
|
|
||||||
#pragma constseg BANK2
|
|
||||||
|
|
||||||
// Position in the serial buffer
|
|
||||||
__xdata uint8_t l;
|
|
||||||
// Properties of currently edited command line in cmd_buffer[CMD_BUF_SIZE]
|
|
||||||
__xdata uint8_t cursor;
|
|
||||||
__xdata uint8_t cmd_line_len;
|
|
||||||
__xdata uint8_t current_cmdline[CMD_BUF_SIZE];
|
|
||||||
__xdata uint16_t history_editptr;
|
|
||||||
|
|
||||||
|
|
||||||
extern __xdata uint8_t cmd_history[CMD_HISTORY_SIZE];
|
|
||||||
extern __xdata uint16_t cmd_history_ptr;
|
|
||||||
|
|
||||||
void cmd_editor_init(void) __banked
|
|
||||||
{
|
|
||||||
l = sbuf_ptr; // We have printed out entered characters until l
|
|
||||||
cursor = 0;
|
|
||||||
cmd_line_len = 0;
|
|
||||||
cmd_available = 0;
|
|
||||||
history_editptr = 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allows editing the current command line held in cmd_buffer[CMD_BUF_SIZE] by
|
|
||||||
* identifying new characters typed or up to 4-byte escape sequences in the
|
|
||||||
* serial buffer ring sbuf[SBUF_SIZE].
|
|
||||||
* Upon detecting new characters or escape sequences, the cmd_buffer and the
|
|
||||||
* representation of the command line in the terminal are updated.
|
|
||||||
* To debug, the easist is to interpose a tty-interceptor between the physical
|
|
||||||
* serial device and a logical one created by interceptty:
|
|
||||||
* sudo interceptty -s 'ispeed 115200 ospeed 115200' /dev/ttyUSB0 /dev/tmpS
|
|
||||||
* picocom -b 115200 /dev/tmpS
|
|
||||||
*/
|
|
||||||
void cmd_edit(void) __banked
|
|
||||||
{
|
|
||||||
while (l != sbuf_ptr) {
|
|
||||||
if (sbuf[l] >= ' ' && sbuf[l] < 127) { // A printable character, copy to command line
|
|
||||||
if (cmd_line_len >= CMD_BUF_SIZE)
|
|
||||||
continue;
|
|
||||||
write_char(sbuf[l]);
|
|
||||||
// Shift buffer to right
|
|
||||||
for (uint8_t i = cmd_line_len; i > cursor; i--)
|
|
||||||
cmd_buffer[i] = cmd_buffer[i-1];
|
|
||||||
// Insert char in comand buffer
|
|
||||||
cmd_buffer[cursor++] = sbuf[l];
|
|
||||||
cmd_line_len++;
|
|
||||||
// Print rest of line
|
|
||||||
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
|
||||||
write_char(cmd_buffer[i]);
|
|
||||||
// Move backwards
|
|
||||||
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
|
||||||
write_char('\010'); // BS works like cursor-left
|
|
||||||
} else if (sbuf[l] == '\033') { // ESC-Sequence
|
|
||||||
// Wait until we have at least 3 characters including the ESC character in the serial buffer
|
|
||||||
if (((sbuf_ptr + SBUF_SIZE - l) & SBUF_MASK) < 3)
|
|
||||||
continue;
|
|
||||||
if (((sbuf_ptr > l ? sbuf_ptr - l : SBUF_SIZE + sbuf_ptr - l) >= 4)
|
|
||||||
&& sbuf[l] == '\033' && sbuf[(l + 1) & SBUF_MASK] == '[' && sbuf[(l + 2) & SBUF_MASK] == '3' && sbuf[(l + 3) & SBUF_MASK] == '~') { // DEL
|
|
||||||
if (cursor < cmd_line_len) {
|
|
||||||
write_char('\033'); write_char('['); write_char('1'); write_char('P'); // Delete to end of line
|
|
||||||
cmd_line_len--;
|
|
||||||
for (uint8_t i = cursor; i < cmd_line_len; i++) {
|
|
||||||
cmd_buffer[i] = cmd_buffer[i+1];
|
|
||||||
write_char(cmd_buffer[i]);
|
|
||||||
}
|
|
||||||
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
|
||||||
write_char('\010');
|
|
||||||
}
|
|
||||||
l += 4;
|
|
||||||
l &= SBUF_MASK;
|
|
||||||
continue;
|
|
||||||
} else if (sbuf[l] == '\033' && sbuf[(l + 1) & SBUF_MASK] == '[' && sbuf[(l + 2) & SBUF_MASK] == 'D') { // <CURSOR-LEFT>
|
|
||||||
if (cursor) {
|
|
||||||
write_char('\010'); // BS works like cursor-left
|
|
||||||
cursor--;
|
|
||||||
}
|
|
||||||
l += 3;
|
|
||||||
l &= SBUF_MASK;
|
|
||||||
continue;
|
|
||||||
} else if (sbuf[l] == '\033' && sbuf[(l + 1) & SBUF_MASK] == '[' && sbuf[(l + 2) & SBUF_MASK] == 'C') { // <CURSOR-RIGHT>
|
|
||||||
if (cursor < cmd_line_len) {
|
|
||||||
write_char('\033'); write_char('['); write_char('C');
|
|
||||||
cursor++;
|
|
||||||
}
|
|
||||||
l += 3;
|
|
||||||
l &= SBUF_MASK;
|
|
||||||
continue;
|
|
||||||
} else if (sbuf[l] == '\033' && sbuf[(l + 1) & SBUF_MASK] == '[' && sbuf[(l + 2) & SBUF_MASK] == 'A') { // <CURSOR-UP>
|
|
||||||
for (uint8_t i = 0; i < cmd_line_len; i++)
|
|
||||||
current_cmdline[i] = cmd_buffer[i];
|
|
||||||
current_cmdline[cmd_line_len] = 0;
|
|
||||||
__xdata uint16_t p;
|
|
||||||
if (history_editptr == 0xffff)
|
|
||||||
p = (cmd_history_ptr - 2) & CMD_HISTORY_MASK;
|
|
||||||
else
|
|
||||||
p = history_editptr;
|
|
||||||
// Move cursor to beginning of line
|
|
||||||
write_char('\033'); write_char('['); itoa(cursor + 2); write_char('D');
|
|
||||||
cursor = 0;
|
|
||||||
while (cmd_history[p] && cmd_history[p] != '\n') {
|
|
||||||
cursor++;
|
|
||||||
p--;
|
|
||||||
p &= CMD_HISTORY_MASK;
|
|
||||||
}
|
|
||||||
history_editptr = (p - 1) & CMD_HISTORY_MASK;
|
|
||||||
p = (p + 1) & CMD_HISTORY_MASK;
|
|
||||||
if (cursor) {
|
|
||||||
print_string("\033[2K> "); // Clear entire line: ^[[2K and print new prompt
|
|
||||||
for (uint8_t i = 0; i < cursor; i++) {
|
|
||||||
cmd_buffer[i] = cmd_history[p];
|
|
||||||
write_char(cmd_buffer[i]);
|
|
||||||
p = (p+1) & CMD_HISTORY_MASK;
|
|
||||||
}
|
|
||||||
cmd_line_len = cursor;
|
|
||||||
} else {
|
|
||||||
print_string("\033[2C"); // Move 2 right to start of editing space
|
|
||||||
}
|
|
||||||
l += 3;
|
|
||||||
l &= SBUF_MASK;
|
|
||||||
continue;
|
|
||||||
} else if (sbuf[l] == '\033' && sbuf[(l + 1) & SBUF_MASK] == '[' && sbuf[(l + 2) & SBUF_MASK] == 'B') { // <CURSOR-DOWN>
|
|
||||||
if (history_editptr != 0xffff) {
|
|
||||||
__xdata uint16_t p = (history_editptr + 2) & CMD_HISTORY_MASK;
|
|
||||||
// Move cursor to beginning of line
|
|
||||||
write_char('\033'); write_char('['); itoa(cursor + 2); write_char('D');
|
|
||||||
print_string("\033[2K> "); // Clear entire line: ^[[2K and print new prompt
|
|
||||||
uint8_t i = 0;
|
|
||||||
while (cmd_history[p] && cmd_history[p] != '\n') {
|
|
||||||
p = (p + 1) & CMD_HISTORY_MASK;
|
|
||||||
}
|
|
||||||
p = (p + 1) & CMD_HISTORY_MASK;
|
|
||||||
while (cmd_history[p] && cmd_history[p] != '\n') {
|
|
||||||
cmd_buffer[i] = cmd_history[p];
|
|
||||||
write_char(cmd_buffer[i++]);
|
|
||||||
p = (p + 1) & CMD_HISTORY_MASK;
|
|
||||||
}
|
|
||||||
history_editptr = (p - 1) & CMD_HISTORY_MASK;
|
|
||||||
if (!i) {
|
|
||||||
if (current_cmdline[i]) {
|
|
||||||
while (current_cmdline[i]) {
|
|
||||||
cmd_buffer[i] = current_cmdline[i];
|
|
||||||
write_char(cmd_buffer[i++]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
write_char('\033'); write_char('['); write_char('C');
|
|
||||||
}
|
|
||||||
history_editptr = 0xffff;
|
|
||||||
// Move cursor right
|
|
||||||
}
|
|
||||||
cmd_line_len = i;
|
|
||||||
cursor = 0;
|
|
||||||
// Move cursor again to beginning of line
|
|
||||||
write_char('\033'); write_char('['); itoa(i); write_char('D');
|
|
||||||
} else {
|
|
||||||
// If we are at the last entry of the history, just move the cursor to the end of the line
|
|
||||||
if (cursor < cmd_line_len) {
|
|
||||||
write_char('\033'); write_char('['); itoa(cmd_line_len - cursor); write_char('C');
|
|
||||||
}
|
|
||||||
cursor = cmd_line_len;
|
|
||||||
}
|
|
||||||
l += 3;
|
|
||||||
l &= SBUF_MASK;
|
|
||||||
continue;
|
|
||||||
} else { // An unknown or not yet complete Escape sequence: wait
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else if (sbuf[l] == 127 || sbuf[l] == 8) { // Backspace DEL or BS/^H
|
|
||||||
if (cursor > 0) {
|
|
||||||
write_char('\010');
|
|
||||||
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
|
||||||
write_char(cmd_buffer[i]);
|
|
||||||
write_char(' '); // Overwrite end of line
|
|
||||||
// Move backwards n steps:
|
|
||||||
for (uint8_t i = cursor; i <= cmd_line_len; i++)
|
|
||||||
write_char('\010');
|
|
||||||
cursor--;
|
|
||||||
for (uint8_t i = cursor; i <= cmd_line_len; i++)
|
|
||||||
cmd_buffer[i] = cmd_buffer[i+1];
|
|
||||||
cmd_line_len--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If the command buffer is currently in use, we cannot copy to it
|
|
||||||
if (cmd_available)
|
|
||||||
break;
|
|
||||||
// Check whether return was pressed:
|
|
||||||
if (sbuf[l] == '\n' || sbuf[l] == '\r') {
|
|
||||||
write_char('\n');
|
|
||||||
cmd_buffer[cmd_line_len] = '\0';
|
|
||||||
// write_char('>'); print_string_x(cmd_buffer); write_char('<');
|
|
||||||
// If there is a command we print the prompt after execution
|
|
||||||
// otherwise immediately because there is nothing to execute
|
|
||||||
if (cmd_line_len)
|
|
||||||
cmd_available = 1;
|
|
||||||
else
|
|
||||||
print_cmd_prompt();
|
|
||||||
cursor = 0;
|
|
||||||
cmd_line_len = 0;
|
|
||||||
history_editptr = 0xffff;
|
|
||||||
}
|
|
||||||
l++;
|
|
||||||
l &= SBUF_MASK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#ifndef _CMD_EDITOR_H_
|
|
||||||
#define _CMD_EDITOR_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void cmd_editor_init(void) __banked;
|
|
||||||
void cmd_edit(void) __banked;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -5,15 +5,11 @@
|
|||||||
|
|
||||||
#include "rtl837x_common.h"
|
#include "rtl837x_common.h"
|
||||||
|
|
||||||
extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
extern __xdata uint8_t cmd_buffer[SBUF_SIZE];
|
||||||
extern __xdata uint8_t cmd_available;
|
extern __xdata uint8_t cmd_available;
|
||||||
extern __xdata uint8_t err_status;
|
|
||||||
|
|
||||||
void cmd_tokenize(void) __banked;
|
uint8_t cmd_tokenize(void) __banked;
|
||||||
void cmd_parser(void) __banked;
|
void cmd_parser(void) __banked;
|
||||||
void execute_config(void) __banked;
|
void execute_config(void) __banked;
|
||||||
void execute_commands(__xdata uint8_t *p) __banked;
|
|
||||||
void print_sw_version(void) __banked;
|
void print_sw_version(void) __banked;
|
||||||
void clear_command_history(void) __banked;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,44 @@
|
|||||||
|
.globl __start__stack
|
||||||
|
;--------------------------------------------------------
|
||||||
|
; Stack segment in internal ram
|
||||||
|
;--------------------------------------------------------
|
||||||
|
.area SSEG (DATA)
|
||||||
|
__start__stack:
|
||||||
|
.ds 1
|
||||||
|
|
||||||
|
.area VECTOR (CODE)
|
||||||
|
.globl __interrupt_vect
|
||||||
|
__interrupt_vect:
|
||||||
|
ljmp __sdcc_gsinit_startup
|
||||||
|
ljmp _isr_ext0 ; 0x03
|
||||||
|
.ds 5
|
||||||
|
ljmp _isr_timer0 ; 0x0b
|
||||||
|
.ds 5
|
||||||
|
ljmp _isr_ext1 ; 0x13
|
||||||
|
.ds 5
|
||||||
|
reti ; 0x1b TIMER 1 IRQ
|
||||||
|
.ds 7
|
||||||
|
ljmp _isr_serial ; 0x23
|
||||||
|
.ds 5
|
||||||
|
ljmp _isr_timer2 ; 0x2b TIMER 2 IRQ
|
||||||
|
.ds 5
|
||||||
|
reti ; 0x33 NOT used by DW8051
|
||||||
|
.ds 7
|
||||||
|
reti ; 0x3b Serial port 1 RX/TX IRQ
|
||||||
|
.ds 7
|
||||||
|
ljmp _isr_ext2 ; 0x43
|
||||||
|
.ds 5
|
||||||
|
ljmp _isr_ext3 ; 0x4b
|
||||||
|
|
||||||
|
.globl __start__stack
|
||||||
|
|
||||||
|
.area GSINIT0 (CODE)
|
||||||
|
|
||||||
|
__sdcc_gsinit_startup::
|
||||||
|
mov sp,#__start__stack - 1
|
||||||
|
|
||||||
.area GSFINAL (CODE)
|
.area GSFINAL (CODE)
|
||||||
|
ljmp _bootloader
|
||||||
|
|
||||||
__sdcc_banked_call::
|
__sdcc_banked_call::
|
||||||
push _PSBANK
|
push _PSBANK
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "uip.h"
|
#include "uip.h"
|
||||||
#include "uip/uip.h"
|
#include "uip/uip.h"
|
||||||
|
|
||||||
|
extern __code struct uip_eth_addr uip_ethaddr;
|
||||||
__xdata struct dhcp_state dhcp_state;
|
__xdata struct dhcp_state dhcp_state;
|
||||||
__xdata uip_ipaddr_t server;
|
__xdata uip_ipaddr_t server;
|
||||||
|
|
||||||
@@ -71,13 +72,18 @@ struct dhcp_pkt {
|
|||||||
uint8_t cookie[4];
|
uint8_t cookie[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define DHCP_P ((__xdata struct dhcp_pkt *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE])
|
||||||
|
#define DHCP_OPT ((__xdata uint8_t *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE + sizeof (struct dhcp_pkt)])
|
||||||
|
*/
|
||||||
|
|
||||||
#define DHCP_P ((__xdata struct dhcp_pkt *)uip_appdata)
|
#define DHCP_P ((__xdata struct dhcp_pkt *)uip_appdata)
|
||||||
#define DHCP_OPT ((__xdata uint8_t *)(uip_appdata) + sizeof (struct dhcp_pkt))
|
#define DHCP_OPT ((__xdata uint8_t *)(uip_appdata) + sizeof (struct dhcp_pkt))
|
||||||
|
|
||||||
__xdata uint32_t long_value;
|
__xdata uint32_t long_value;
|
||||||
|
|
||||||
|
|
||||||
void dhcp_print_ip(__xdata uint8_t *a)
|
void dhcp_print_ip(uint8_t *a)
|
||||||
{
|
{
|
||||||
itoa(a[0]); write_char('.');
|
itoa(a[0]); write_char('.');
|
||||||
itoa(a[1]); write_char('.');
|
itoa(a[1]); write_char('.');
|
||||||
@@ -98,7 +104,7 @@ void dhcp_prepare_request(void)
|
|||||||
DHCP_P->flags = 0;
|
DHCP_P->flags = 0;
|
||||||
// Clear fields client_ip to bootp_file
|
// Clear fields client_ip to bootp_file
|
||||||
memset(DHCP_P->client_ip, 0, 224);
|
memset(DHCP_P->client_ip, 0, 224);
|
||||||
memcpy(DHCP_P->client_addr, uip_ethaddr.addr, 6);
|
memcpyc(DHCP_P->client_addr, uip_ethaddr.addr, 6);
|
||||||
DHCP_P->cookie[0] = 0x63;
|
DHCP_P->cookie[0] = 0x63;
|
||||||
DHCP_P->cookie[1] = 0x82;
|
DHCP_P->cookie[1] = 0x82;
|
||||||
DHCP_P->cookie[2] = 0x53;
|
DHCP_P->cookie[2] = 0x53;
|
||||||
@@ -111,7 +117,7 @@ void dhcp_addopt_client_id(void)
|
|||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_CLIENT_ID;
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_CLIENT_ID;
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_CLIENT_ID_LEN;
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_CLIENT_ID_LEN;
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_HW_TYPE_ETH;
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_HW_TYPE_ETH;
|
||||||
memcpy(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 6);
|
memcpyc(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 6);
|
||||||
dhcp_state.opt_ptr += 6;
|
dhcp_state.opt_ptr += 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +130,7 @@ void dhcp_addopt_request_ip(void)
|
|||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[1];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[1];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[2];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[2];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[3];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[3];
|
||||||
memcpy(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
|
memcpyc(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -136,7 +142,7 @@ void dhcp_addopt_server_id(void)
|
|||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[1];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[1];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[2];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[2];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[3];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[3];
|
||||||
memcpy(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
|
memcpyc(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -211,7 +217,7 @@ void dhcp_send_request(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ip_opt(__xdata uint8_t * ip)
|
void ip_opt(uint8_t * __xdata ip)
|
||||||
{
|
{
|
||||||
dhcp_state.opt_ptr++;
|
dhcp_state.opt_ptr++;
|
||||||
uint8_t len = DHCP_OPT[dhcp_state.opt_ptr++];
|
uint8_t len = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
@@ -348,10 +354,8 @@ void dhcp_stop(void) __banked
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dhcp_callback(uint16_t lport) __banked
|
void dhcp_callback(void) __banked
|
||||||
{
|
{
|
||||||
if (lport != HTONS(DHCPC_CLIENT_PORT)) // Is this call for us? If not, ignore it
|
|
||||||
return;
|
|
||||||
if (!dhcp_state.state)
|
if (!dhcp_state.state)
|
||||||
return;
|
return;
|
||||||
if (uip_closed()) {
|
if (uip_closed()) {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
void dhcp_start(void) __banked;
|
void dhcp_start(void) __banked;
|
||||||
void dhcp_stop(void) __banked;
|
void dhcp_stop(void) __banked;
|
||||||
// void dhcp_periodic(void) __banked;
|
// void dhcp_periodic(void) __banked;
|
||||||
void dhcp_callback(uint16_t lport) __banked;
|
void dhcp_callback(void) __banked;
|
||||||
|
|
||||||
|
|
||||||
struct dhcp_state {
|
struct dhcp_state {
|
||||||
@@ -35,9 +35,14 @@ struct dhcp_state {
|
|||||||
uint32_t rebind;
|
uint32_t rebind;
|
||||||
uint32_t renewal;
|
uint32_t renewal;
|
||||||
|
|
||||||
__xdata struct uip_udp_conn *conn;
|
struct uip_udp_conn *conn;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct dhcp_state uip_udp_appstate_t;
|
typedef struct dhcp_state uip_udp_appstate_t;
|
||||||
|
|
||||||
|
/* Finally we define the application function to be called by uIP. */
|
||||||
|
#ifndef UIP_UDP_APPCALL
|
||||||
|
#define UIP_UDP_APPCALL dhcp_callback
|
||||||
|
#endif /* UIP_APPCALL */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
# Automation
|
|
||||||
|
|
||||||
## Upload
|
|
||||||
|
|
||||||
You can automate upload of the firmware via WEB with curl:
|
|
||||||
|
|
||||||
1. Authorize with /login endpoint and save cookie:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -c cookies.txt http://${SWITCH_IP}/login -d pwd=${PASSWORD} -i
|
|
||||||
```
|
|
||||||
|
|
||||||
This will save session cookie in cookies.txt
|
|
||||||
2. Send the firmware via form:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -b cookies.txt http://${SWITCH_IP}/upload -F "uploadedfile=@${FIRMWARE_FILE_PATH}" -i
|
|
||||||
```
|
|
||||||
|
|
||||||
You can expect that server will close connection, without responding to request.
|
|
||||||
Wait for SWITCH_IP to be responding again.
|
|
||||||
|
|
||||||
## Port status
|
|
||||||
|
|
||||||
In similar way to upload, you can fetch the json status of the ports.
|
|
||||||
|
|
||||||
1. Get the session cookie as for upload.
|
|
||||||
2. Hit the `/status.json` with cookie:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -b cookies.txt http://${SWITCH_IP}/status.json
|
|
||||||
```
|
|
||||||
@@ -1,238 +0,0 @@
|
|||||||
# Egress and Ingress Bandwidth Control
|
|
||||||
The RTL8372/3 allows to control the bandwidth of data transmitted (egress) and/or
|
|
||||||
admitted (ingress) at any given port. Once admitted, packets are internally switched
|
|
||||||
at wire-speed, since the backplane of the devices has a bandwidth of 60GBit/s.
|
|
||||||
|
|
||||||
The devices schedules transmission of packets by assigning packets to 8 queues
|
|
||||||
implemented in hardware per port, which share a total of 8Mbit of memory internal
|
|
||||||
to the switching part of the SoCs. Packets are assigned to the respective queues
|
|
||||||
based on the priority assigned to a packet, which can be based on various
|
|
||||||
properties of a packet such as IEEE 802.1P priority, DSCP value, physical port
|
|
||||||
number, destination or source MAC, Ether-Type-based, CVID, SVID, IPv4 source or
|
|
||||||
destination IP, IPv4/IPv6 TOS field, IPv6 Flow Label and even TCP/UDP
|
|
||||||
source/destination port. Once in a queue, packets are scheduled for egress
|
|
||||||
based on differnent configurable algorithms.
|
|
||||||
|
|
||||||
RTLPlayground currently allows only to control the bandwidth at ingress at a port
|
|
||||||
or just before packets leave a port. There is no control of the priority assignment
|
|
||||||
or queue scheduling mechanisms. The bandwidth can be controlled in steps of 16Kbit/s
|
|
||||||
from 16Kbit/s to 10Gbp/s.
|
|
||||||
|
|
||||||
The bandwidth control as currently implemented allows e.g. to assign a certain
|
|
||||||
share of bandwidth to an attached device (e.g. to share an uplink), or simulate
|
|
||||||
connections with low bandwidth and even bad connectivity with packet drops when
|
|
||||||
ingress is not controlled by Flow Control but by simply droping packets.
|
|
||||||
|
|
||||||
## Ingress/Egress control
|
|
||||||
The relevant registers for controlling Ingress and Egress at a port are:
|
|
||||||
```
|
|
||||||
#define RTL837X_IGBW_CTRL 0x4c10
|
|
||||||
#define IGBW_INC_BYPASS_PKT 0x100
|
|
||||||
#define IGBW_INC_IFG 0x80
|
|
||||||
#define IGBW_ADM_DHCP 0x20
|
|
||||||
#define IGBW_ADM_ARPREQ 0x10
|
|
||||||
#define IGBW_ADM_RMA 0x08
|
|
||||||
#define IGBW_ADM_BPDU 0x04
|
|
||||||
#define IGBW_ADM_RTKPKT 0x02
|
|
||||||
#define IGBW_ADM_IGMP 0x01
|
|
||||||
#define RTL837X_IGBW_PORT_CTRL 0x4C18
|
|
||||||
#define RTL837X_IGBW_PORT_FC_CTRL 0x4C8C
|
|
||||||
#define RTL837X_EGBW_PORT_CTRL 0x1c34
|
|
||||||
#define RTL837X_EGBW_CTRL 0x447c
|
|
||||||
#define EGBW_INC_IFG 0x02
|
|
||||||
#define EGBW_CPUMODE 0x01
|
|
||||||
```
|
|
||||||
`RTL837X_IGBW_CTRL/RTL837X_EGBW_CTRL` control the behaviour of the bandwidth control
|
|
||||||
at ingress and egress. The flags such as `IGBW_ADM_DHCP`control whether certain types
|
|
||||||
of packets such as DHCP are exempt from being ingress controlled. The
|
|
||||||
`IGBW_INC_IFG/EGBW_INC_IFG` flags control whether the Inter Frame Gaps are part of
|
|
||||||
the bandwidth being controlled. `EGBW_CPUMODE` controls whether packets generated
|
|
||||||
by the internal CPU are subject to egress control.
|
|
||||||
|
|
||||||
`RTL837X_IGBW_PORT_CTRL/RTL837X_EGBW_PORT_CTRL` configure the bandwidth for ingress
|
|
||||||
and egress at a port.
|
|
||||||
|
|
||||||
`RTL837X_IGBW_PORT_FC_CTRL` configures whether packets are bandwidth-controlled using
|
|
||||||
Flow Control (port-bit set), or simply dropped (port-bit clear).
|
|
||||||
|
|
||||||
## Ingress/Egress bandwidth API
|
|
||||||
The code currently provides the following functions:
|
|
||||||
```
|
|
||||||
void bandwidth_setup(void) __banked;
|
|
||||||
void bandwidth_ingress_set(uint8_t port, __xdata uint32_t bw) __banked;
|
|
||||||
void bandwidth_ingress_disable(uint8_t port) __banked;
|
|
||||||
void bandwidth_ingress_drop(uint8_t port) __banked;
|
|
||||||
void bandwidth_egress_set(uint8_t port, __xdata uint32_t bw) __banked;
|
|
||||||
void bandwidth_egress_disable(uint8_t port) __banked;
|
|
||||||
void bandwidth_status(uint8_t port) __banked;
|
|
||||||
```c
|
|
||||||
|
|
||||||
`bandwidth_setup()` is called at boot-time and configures excluding all special packets
|
|
||||||
that may be for the CPU and packets outgoing from the CPU to be excluded from bandwidth
|
|
||||||
control. IFG is not part of the bandwidth calculation.
|
|
||||||
|
|
||||||
`bandwidth_ingress_set()` enables ingress bandwidth control for a particular port given
|
|
||||||
the specified bandwidth. This also enabled Flow Control at a port.
|
|
||||||
|
|
||||||
`bandwidth_ingress_set()` enables egress bandwidth control for a particular port given
|
|
||||||
the specified bandwidth
|
|
||||||
|
|
||||||
`bandwidth_ingress_disable() / bandwidth_egress_disable()` disable ingress and egress
|
|
||||||
bandwidth control at a given port
|
|
||||||
|
|
||||||
`bandwidth_ingress_drop(port)` configures packets exceeding bandwidth limitations to
|
|
||||||
simply be dropped
|
|
||||||
|
|
||||||
`bandwidth_status(port)` shows the current bandwidth control status for a given port
|
|
||||||
|
|
||||||
## Bandwidth control configuration on the Serial Console
|
|
||||||
The following commands are provided on the serial console:
|
|
||||||
```
|
|
||||||
> bw [in|out|status] <port> [<hexvalue>|off|drop]
|
|
||||||
Configures or shows the status of bandwidth control
|
|
||||||
```
|
|
||||||
The bandwidth is given as the `<hexvalue>` in Kbit/s. Note that the control is only
|
|
||||||
possible at a granularity of 16 Kbit/s and the minimum value is also 16 Kbit/s. The
|
|
||||||
hexadecimal numbers must be given in full bytes, i.e. have an even number of digits.
|
|
||||||
|
|
||||||
To enable bandwidth control of ingress for physical port 2 to be set to 256 Kbit/s
|
|
||||||
do:
|
|
||||||
```
|
|
||||||
> bw in 2 0100
|
|
||||||
```
|
|
||||||
|
|
||||||
To drop packets when the bandwidth is exceeeded at port 2 do:
|
|
||||||
```
|
|
||||||
> bw in 2 drop
|
|
||||||
```
|
|
||||||
|
|
||||||
To disable bandwidth control for incoming packets on port 2 do:
|
|
||||||
```
|
|
||||||
> bw in 2 off
|
|
||||||
```
|
|
||||||
|
|
||||||
## Bandwidth configuration via the Web Interface
|
|
||||||
Not implemented, yet!
|
|
||||||
|
|
||||||
## A Test using iperf3
|
|
||||||
The following is and example how to test bandwidth control with a signle Linux device using
|
|
||||||
network namespaces to route packets between a client and a server on the same Linux device
|
|
||||||
through an external switch.
|
|
||||||
|
|
||||||
You will need 2 network intefaces on the linux device, say, 2 USB-Ethernet controllers called
|
|
||||||
eth0 and eth1:
|
|
||||||
```
|
|
||||||
$ sudo ip netns add client
|
|
||||||
$ sudo ip netns add server
|
|
||||||
|
|
||||||
$ sudo ip link set dev eth0 netns client
|
|
||||||
$ sudo ip link set dev eth1 netns server
|
|
||||||
|
|
||||||
$ sudo ip netns exec client ip link set dev eth0 up
|
|
||||||
$ sudo ip netns exec server ip link set dev eth1 up
|
|
||||||
|
|
||||||
$ sudo ip netns exec client ip addr add dev eth0 192.168.99.1/24
|
|
||||||
$ sudo ip netns exec server ip addr add dev eth1 192.168.99.2/24
|
|
||||||
|
|
||||||
$ sudo ip netns exec server iperf3 -s
|
|
||||||
```
|
|
||||||
This will start an iper3 server in the above shell.
|
|
||||||
|
|
||||||
In a different shell you can now run the iperf3 client against your server:
|
|
||||||
```
|
|
||||||
$ sudo ip netns exec client iperf -c 192.168.99.2
|
|
||||||
```
|
|
||||||
The LEDs on your switch where your network adapters are connected should start to flicker.
|
|
||||||
On a 1GBit connection, you should see:
|
|
||||||
```
|
|
||||||
$ sudo ip netns exec client iperf3 -c 192.168.99.2
|
|
||||||
Connecting to host 192.168.99.2, port 5201
|
|
||||||
[ 5] local 192.168.99.1 port 46776 connected to 192.168.99.2 port 5201
|
|
||||||
[ ID] Interval Transfer Bitrate Retr Cwnd
|
|
||||||
[ 5] 0.00-1.00 sec 114 MBytes 952 Mbits/sec 0 339 KBytes
|
|
||||||
[ 5] 1.00-2.00 sec 113 MBytes 946 Mbits/sec 0 356 KBytes
|
|
||||||
[ 5] 2.00-3.00 sec 112 MBytes 937 Mbits/sec 0 390 KBytes
|
|
||||||
[ 5] 3.00-4.00 sec 112 MBytes 942 Mbits/sec 0 390 KBytes
|
|
||||||
[ 5] 4.00-5.00 sec 112 MBytes 943 Mbits/sec 0 390 KBytes
|
|
||||||
[ 5] 5.00-6.00 sec 112 MBytes 944 Mbits/sec 0 390 KBytes
|
|
||||||
[ 5] 6.00-7.00 sec 112 MBytes 938 Mbits/sec 0 390 KBytes
|
|
||||||
[ 5] 7.00-8.00 sec 112 MBytes 942 Mbits/sec 0 410 KBytes
|
|
||||||
[ 5] 8.00-9.00 sec 113 MBytes 947 Mbits/sec 0 410 KBytes
|
|
||||||
[ 5] 9.00-10.00 sec 112 MBytes 940 Mbits/sec 0 410 KBytes
|
|
||||||
- - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
[ ID] Interval Transfer Bitrate Retr
|
|
||||||
[ 5] 0.00-10.00 sec 1.10 GBytes 943 Mbits/sec 0 sender
|
|
||||||
[ 5] 0.00-10.00 sec 1.10 GBytes 941 Mbits/sec receiver
|
|
||||||
```
|
|
||||||
|
|
||||||
Now, we limit ingress on port 1 (connected to eth0) to 4 MBit/s:
|
|
||||||
```> bw in 1 1000
|
|
||||||
bandwidth_ingress_set called, port 04
|
|
||||||
RTL837X_IGBW_PORT_CTRL:0x00100100
|
|
||||||
RTL837X_IGBW_PORT_FC_CTRL:0x00000010
|
|
||||||
```
|
|
||||||
|
|
||||||
We now get:
|
|
||||||
```
|
|
||||||
$ sudo ip netns exec client iperf3 -c 192.168.99.2
|
|
||||||
[ 5] local 192.168.99.1 port 43324 connected to 192.168.99.2 port 5201
|
|
||||||
[ ID] Interval Transfer Bitrate Retr Cwnd
|
|
||||||
[ 5] 0.00-1.00 sec 1.12 MBytes 9.43 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 1.00-2.00 sec 640 KBytes 5.24 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 2.00-3.00 sec 384 KBytes 3.15 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 3.00-4.00 sec 384 KBytes 3.15 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 4.00-5.00 sec 640 KBytes 5.24 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 5.00-6.00 sec 256 KBytes 2.10 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 6.00-7.00 sec 640 KBytes 5.24 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 7.00-8.00 sec 384 KBytes 3.15 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 8.00-9.00 sec 640 KBytes 5.24 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 9.00-10.00 sec 256 KBytes 2.10 Mbits/sec 0 160 KBytes
|
|
||||||
- - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
[ ID] Interval Transfer Bitrate Retr
|
|
||||||
[ 5] 0.00-10.00 sec 5.25 MBytes 4.40 Mbits/sec 0 sender
|
|
||||||
[ 5] 0.00-10.16 sec 4.75 MBytes 3.92 Mbits/sec receiver
|
|
||||||
|
|
||||||
iperf Done.
|
|
||||||
```
|
|
||||||
Which is the 4Mbit/s we configured. There are no packet drops (retries) because
|
|
||||||
Flow Control is used to signal the Ethernet adapter on the incoming interface
|
|
||||||
(port 1 of the router) to slow down.
|
|
||||||
|
|
||||||
We can also configure a mere 256KBit/s and packet drop to simulate a bad connection:
|
|
||||||
```
|
|
||||||
> bw in 1 0100
|
|
||||||
bandwidth_ingress_set called, port 04
|
|
||||||
RTL837X_IGBW_PORT_CTRL:0x00100010
|
|
||||||
RTL837X_IGBW_PORT_FC_CTRL:0x00000010
|
|
||||||
|
|
||||||
> bw in 1 drop
|
|
||||||
RTL837X_IGBW_PORT_FC_CTRL:0x00000000
|
|
||||||
```
|
|
||||||
|
|
||||||
We now get:
|
|
||||||
```
|
|
||||||
$ sudo ip netns exec client iperf3 -c 192.168.99.2
|
|
||||||
Connecting to host 192.168.99.2, port 5201
|
|
||||||
[ 5] local 192.168.99.1 port 46060 connected to 192.168.99.2 port 5201
|
|
||||||
[ ID] Interval Transfer Bitrate Retr Cwnd
|
|
||||||
[ 5] 0.00-1.00 sec 384 KBytes 3.14 Mbits/sec 2 1.41 KBytes
|
|
||||||
[ 5] 1.00-2.00 sec 0.00 Bytes 0.00 bits/sec 54 1.41 KBytes
|
|
||||||
[ 5] 2.00-3.00 sec 0.00 Bytes 0.00 bits/sec 31 29.7 KBytes
|
|
||||||
[ 5] 3.00-4.00 sec 0.00 Bytes 0.00 bits/sec 2 1.41 KBytes
|
|
||||||
[ 5] 4.00-5.00 sec 0.00 Bytes 0.00 bits/sec 23 1.41 KBytes
|
|
||||||
[ 5] 5.00-6.00 sec 128 KBytes 1.05 Mbits/sec 16 14.1 KBytes
|
|
||||||
[ 5] 6.00-7.00 sec 0.00 Bytes 0.00 bits/sec 2 1.41 KBytes
|
|
||||||
[ 5] 7.00-8.00 sec 0.00 Bytes 0.00 bits/sec 11 1.41 KBytes
|
|
||||||
[ 5] 8.00-9.00 sec 128 KBytes 1.05 Mbits/sec 9 8.48 KBytes
|
|
||||||
[ 5] 9.00-10.00 sec 0.00 Bytes 0.00 bits/sec 2 1.41 KBytes
|
|
||||||
- - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
[ ID] Interval Transfer Bitrate Retr
|
|
||||||
[ 5] 0.00-10.00 sec 640 KBytes 524 Kbits/sec 152 sender
|
|
||||||
[ 5] 0.00-10.00 sec 256 KBytes 210 Kbits/sec receiver
|
|
||||||
|
|
||||||
iperf Done.
|
|
||||||
```
|
|
||||||
Which shows a large number of retries due to dropped packets and an average number
|
|
||||||
of received packets (the client sends the packets to the server, and they are sent
|
|
||||||
back to the client by the server) of 210 KBit/s, the number is higher for the transmitted
|
|
||||||
packets, because they may include dropped packets.
|
|
||||||
@@ -1,177 +0,0 @@
|
|||||||
### 2M-PCB23-V2.2
|
|
||||||
|
|
||||||
## Brands
|
|
||||||
| Brand | Type | Managed | PCB | Flash | Chip RTL |
|
|
||||||
|----------|-----------------|---------|---------------|-------|-------------|
|
|
||||||
| keepLINK | KP-9000-9XHML-X | Yes | 2M-PCB23-V2.2 | 2M | 8373 + 8224 |
|
|
||||||
|
|
||||||
## PCB
|
|
||||||
|
|
||||||
<img src="photos/2M-PCB23-V2.2-managed/2M-PCB23-V2.2-top.jpg" width="300" />
|
|
||||||
|
|
||||||
## Port overview
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ ┌──────────┐ │
|
|
||||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ SFP(J13) │ │
|
|
||||||
│ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ PORT 9 │ │
|
|
||||||
│ │ PORT 1 │ │ PORT 2 │ │ PORT 3 │ │ PORT 4 │ │ PORT 5 │ │ PORT 6 │ │ PORT 7 │ │ PORT 8 │ │ MAC 8 │ O (PWR) │
|
|
||||||
│ O │ MAC 0 │ │ MAC 1 │ │ MAC 2 │ │ MAC 3 │ │ MAC 4 │ │ MAC 5 │ │ MAC 6 │ │ MAC 7 │ │ SerDes 1 │ O (SFP) │
|
|
||||||
│ RST └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘ │
|
|
||||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
# Connectors
|
|
||||||
|
|
||||||
### J13, SFP connector
|
|
||||||
|
|
||||||
| SFP Pin | Signal | GPIO | Notes |
|
|
||||||
| ------- | ----------------- | ------ | ------------------------------ |
|
|
||||||
| 2 | TX_FAULT | ?? | |
|
|
||||||
| 3 | TX_DISABLE | ?? | |
|
|
||||||
| 4 | MODDEF2 – SDA | GPIO39 | |
|
|
||||||
| 5 | MODDEF1 – SCL | GPIO40 | |
|
|
||||||
| 6 | MODDEF0 – PRESENT | GPIO30 | "OE Exist" reported by `fiber` |
|
|
||||||
| 7 | RATE SEL | ?? | |
|
|
||||||
| 8 | LOS | GPIO37 | "OE LOS" reported by `fiber` |
|
|
||||||
| 9 | TO? | ?? | |
|
|
||||||
|
|
||||||
### T5, serial console
|
|
||||||
|
|
||||||
| pin | GPIO | Signal |
|
|
||||||
| --- | ------ | -------------- |
|
|
||||||
| 1 | GPIO32 | U0RXD (Input) |
|
|
||||||
| 2 | GND | Ground |
|
|
||||||
| 3 | GPIO31 | U0TXD (Output) |
|
|
||||||
|
|
||||||
### S1, unknown connector
|
|
||||||
|
|
||||||
| pin | GPIO | Signal |
|
|
||||||
| --- | -------- | -------------- |
|
|
||||||
| 1 | ??? | |
|
|
||||||
| x | | |
|
|
||||||
| 3 | ??? | |
|
|
||||||
| 4 | ??? | |
|
|
||||||
| 5 | ??? | |
|
|
||||||
|
|
||||||
Potentially slave interface or SMI.
|
|
||||||
|
|
||||||
### U7, flash memory
|
|
||||||
|
|
||||||
Flash chip is FM25Q16A.
|
|
||||||
|
|
||||||
### Reset button
|
|
||||||
|
|
||||||
GPIO54
|
|
||||||
|
|
||||||
## Register values
|
|
||||||
|
|
||||||
As probed with `regget` on stock firmware "V1.6".
|
|
||||||
|
|
||||||
### Model
|
|
||||||
|
|
||||||
| Name | Addr | Value |
|
|
||||||
| ------------------------- | ------ | ---------- |
|
|
||||||
| MODEL_NAME_INFO | 0x0004 | 0x83730000 |
|
|
||||||
| CHIP_MODE_INFO | 0x0008 | 0x00008000 |
|
|
||||||
| CHIP_INFO | 0x000C | 0x00300000 |
|
|
||||||
|
|
||||||
### GPIO
|
|
||||||
|
|
||||||
| Name | Addr | Value |
|
|
||||||
| ------------------------- | ------ | ---------- |
|
|
||||||
| GPIO_OUT0 | 0x003c | 0x10000000 |
|
|
||||||
| GPIO_OUT1 | 0x0040 | 0x00000010 |
|
|
||||||
| GPIO_OE0 | 0x004c | 0x10000000 |
|
|
||||||
| GPIO_OE1 | 0x0050 | 0x00000010 |
|
|
||||||
| BOND_INFO | 0x7f60 | 0x00000fff |
|
|
||||||
| STRAP_INFO | 0x7f64 | 0x0002f515 |
|
|
||||||
| IO_DRVING_0 | 0x7f68 | 0x00000000 |
|
|
||||||
| IO_DRVING_1 | 0x7f6c | 0x00000000 |
|
|
||||||
| IO_DRVING_2 | 0x7f70 | 0x00000000 |
|
|
||||||
| IO_SLEW_0 | 0x7f74 | 0x00000000 |
|
|
||||||
| IO_SLEW_1 | 0x7f78 | 0x00000000 |
|
|
||||||
| IO_SLEW_2 | 0x7f7c | 0x00000000 |
|
|
||||||
| IO_SMT_EN_0 | 0x7f80 | 0xffffffff |
|
|
||||||
| IO_SMT_EN_1 | 0x7f84 | 0xffffffff |
|
|
||||||
| IO_SMT_EN_2 | 0x7f88 | 0x0003ffff |
|
|
||||||
| IO_MUX_SEL_0 | 0x7f8c | 0x28000000 |
|
|
||||||
| IO_MUX_SEL_1 | 0x7f90 | 0x40000041 |
|
|
||||||
| IO_MUX_SEL_2 | 0x7f94 | 0x00000000 |
|
|
||||||
|
|
||||||
### LED
|
|
||||||
|
|
||||||
| Name | Addr | Value |
|
|
||||||
| ------------------------- | ------ | ---------- |
|
|
||||||
| LED_GLB_CTRL | 0x6520 | 0x0023e0f0 |
|
|
||||||
| LED3_0_SET3_2_CTRL1 | 0x6524 | 0xff001400 |
|
|
||||||
| LED3_0_SET1_0_CTRL1 | 0x6528 | 0x000f0000 |
|
|
||||||
| LED3_2_SET3_CTRL0 | 0x652c | 0x007f013f |
|
|
||||||
| LED1_0_SET3_CTRL0 | 0x6530 | 0x02000400 |
|
|
||||||
| LED3_2_SET2_CTRL0 | 0x6534 | 0x01400141 |
|
|
||||||
| LED1_0_SET2_CTRL0 | 0x6538 | 0x01440170 |
|
|
||||||
| LED3_2_SET1_CTRL0 | 0x653c | 0x18000041 |
|
|
||||||
| LED1_0_SET1_CTRL0 | 0x6540 | 0x0044017f |
|
|
||||||
| LED3_2_SET0_CTRL0 | 0x6544 | 0x00000044 |
|
|
||||||
| LED1_0_SET0_CTRL0 | 0x6548 | 0x00410175 |
|
|
||||||
| LED_PORT_SET_SEL_CTRL | 0x654c | 0x00010000 |
|
|
||||||
| SW_LED_LOAD | 0x6550 | 0x00000000 |
|
|
||||||
| LED_PORT_SW_EN_CTRL[0..7] | 0x6554 | 0x00000000 |
|
|
||||||
| LED_PORT_SW_EN_CTRL[8] | 0x6558 | 0x00000000 |
|
|
||||||
| LED_PORT_SW_CTRL[0] | 0x655c | 0x00000000 |
|
|
||||||
| LED_PORT_SW_CTRL[1] | 0x6560 | 0x00000000 |
|
|
||||||
| LED_PORT_SW_CTRL[2] | 0x6564 | 0x00000000 |
|
|
||||||
| LED_PORT_SW_CTRL[3] | 0x6568 | 0x00000000 |
|
|
||||||
| LED_PORT_SW_CTRL[4] | 0x656c | 0x00000000 |
|
|
||||||
| LED_PORT_SW_CTRL[5] | 0x6570 | 0x00000000 |
|
|
||||||
| LED_PORT_SW_CTRL[6] | 0x6574 | 0x00000000 |
|
|
||||||
| LED_PORT_SW_CTRL[7] | 0x6578 | 0x00000000 |
|
|
||||||
| LED_PORT_SW_CTRL[8] | 0x657c | 0x00000000 |
|
|
||||||
| LED_LOAD_LV1_10G | 0x6580 | 0x000fa000 |
|
|
||||||
| LED_LOAD_LV2_10G | 0x6584 | 0x00271000 |
|
|
||||||
| LED_LOAD_LV3_10G | 0x6588 | 0x004e2000 |
|
|
||||||
| LED_LOAD_LV1_5G | 0x658c | 0x000fa000 |
|
|
||||||
| LED_LOAD_LV2_5G | 0x6590 | 0x00271000 |
|
|
||||||
| LED_LOAD_LV3_5G | 0x6594 | 0x004e2000 |
|
|
||||||
| LED_LOAD_LV1_2P5G | 0x6598 | 0x000fa000 |
|
|
||||||
| LED_LOAD_LV2_2P5G | 0x659c | 0x00271000 |
|
|
||||||
| LED_LOAD_LV3_2P5G | 0x65a0 | 0x004e2000 |
|
|
||||||
| LED_LOAD_LV1_1G | 0x65a4 | 0x000fa000 |
|
|
||||||
| LED_LOAD_LV2_1G | 0x65a8 | 0x00271000 |
|
|
||||||
| LED_LOAD_LV3_1G | 0x65ac | 0x004e2000 |
|
|
||||||
| LED_LOAD_LV1_500M | 0x65b0 | 0x0007d000 |
|
|
||||||
| LED_LOAD_LV2_500M | 0x65b4 | 0x00138800 |
|
|
||||||
| LED_LOAD_LV3_500M | 0x65b8 | 0x00271000 |
|
|
||||||
| LED_LOAD_LV1_100M | 0x65bc | 0x00019000 |
|
|
||||||
| LED_LOAD_LV2_100M | 0x65c0 | 0x0003e800 |
|
|
||||||
| LED_LOAD_LV3_100M | 0x65c4 | 0x0007d000 |
|
|
||||||
| LED_LOAD_LV1_10M | 0x65c8 | 0x00002800 |
|
|
||||||
| LED_LOAD_LV2_10M | 0x65cc | 0x00006400 |
|
|
||||||
| LED_LOAD_LV3_10M | 0x65d0 | 0x0000c800 |
|
|
||||||
| LED_P_LOAD_CTRL | 0x65d4 | 0x00000000 |
|
|
||||||
| LED_GLB_ACTIVE | 0x65d8 | 0x3ffbedff |
|
|
||||||
| LED_GLB_IO_EN | 0x65dc | 0x77ffffff |
|
|
||||||
| LED_GLB_MUX_1 | 0c65e0 | 0x05102040 |
|
|
||||||
| LED_GLB_MUX_2 | 0x65e4 | 0x0c289206 |
|
|
||||||
| LED_GLB_MUX_3 | 0x65e8 | 0x1245038d |
|
|
||||||
| LED_GLB_MUX_4 | 0x65ec | 0x19616554 |
|
|
||||||
| LED_GLB_MUX_5 | 0x65f0 | 0x2079d71a |
|
|
||||||
| LED_GLB_MUX_6 | 0x65f4 | 0x000238a1 |
|
|
||||||
| LED_RLDP_CTRL_1 | 0x65f8 | 0x00000019 |
|
|
||||||
| LED_RLDP_CTRL_2 | 0x65fc | 0xffffffff |
|
|
||||||
| LED_RLDP_CTRL_3 | 0x6600 | 0x00006600 |
|
|
||||||
| LED_DUMY_0_ADDR | 0x6604 | 0x00000000 |
|
|
||||||
| LED_DUMY_1_ADDR | 0x6608 | 0x00000000 |
|
|
||||||
|
|
||||||
# LEDs
|
|
||||||
|
|
||||||
| Name | Components | Controlled by |
|
|
||||||
| ----------------------------- | --------------------------- | -------------------------- |
|
|
||||||
| RJ45 Right Green ("LINK/ACT") | | RJ45 LED0 |
|
|
||||||
| RJ45 Left Orange ("2.5G") | | RJ45 LED1 |
|
|
||||||
| RJ45 Left Green ("1G") | | RJ45 LED2 |
|
|
||||||
| "P" (PWR) | Top LED in "LED6" stack | probably pulled from Vcc |
|
|
||||||
| SFP Link ("9") | Bottom LED in "LED6" stack | SFP LED0 |
|
|
||||||
| ?? | D23 | SFP LED1 |
|
|
||||||
| ?? | D22 | SFP LED2 |
|
|
||||||
@@ -5,30 +5,13 @@
|
|||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| keepLINK | KP-9000-9XHML-X | Yes| 2M-PCB23-V3.1 | 2M| 8273N + 8224N |
|
| keepLINK | KP-9000-9XHML-X | Yes| 2M-PCB23-V3.1 | 2M| 8273N + 8224N |
|
||||||
|
|
||||||
## PCB
|
|
||||||
|
|
||||||
<img src="photos/2M-PCB23-V3.1-managed/2M-PCB23-V3.1-top.jpeg" width="300" />
|
|
||||||
|
|
||||||
## Port overview
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ ┌──────────┐ │
|
|
||||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ SFP (J4) │ │
|
|
||||||
│ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ PORT 9 │ │
|
|
||||||
│ │ PORT 1 │ │ PORT 2 │ │ PORT 3 │ │ PORT 4 │ │ PORT 5 │ │ PORT 6 │ │ PORT 7 │ │ PORT 8 │ │ MAC 8 │ O (PWR) │
|
|
||||||
│ O │ MAC 0 │ │ MAC 1 │ │ MAC 2 │ │ MAC 3 │ │ MAC 4 │ │ MAC 5 │ │ MAC 6 │ │ MAC 7 │ │ SerDes 1 │ O (SFP) │
|
|
||||||
│ RST └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘ │
|
|
||||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
# Connectors
|
# Connectors
|
||||||
|`J4` SFP PINs | Signal | Component | GPIO | Notes |
|
|`J4` SFP PINs | Signal | Component | GPIO | Notes |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
|2| TX_FAULT | | --- | |
|
|2| TX_FAULT | | --- | |
|
||||||
|3| TX_DISABLE | | --- | Pull down - 0R |
|
|3| TX_DISABLE | | --- | Pull down - 0R |
|
||||||
|4| MODDEF2 – SDA | b-r273 | GPIO39-SDA4 | |
|
|4| MODDEF2 – SDA | b-r273 | GPIO39 | |
|
||||||
|5| MODDEF1 – SCL | b-r274 | GPIO40-SCL3 | |
|
|5| MODDEF1 – SCL | b-r274 | GPIO40 | |
|
||||||
|6| MODDEF0 – PRESENT | B-R275 | GPIO38 | |
|
|6| MODDEF0 – PRESENT | B-R275 | GPIO38 | |
|
||||||
|7| RATE SEL | | --- | |
|
|7| RATE SEL | | --- | |
|
||||||
|8| LOS | B-R276 | GPIO38 | |
|
|8| LOS | B-R276 | GPIO38 | |
|
||||||
@@ -48,26 +31,15 @@ Note: component numbering `<L>-<REFDES>-<SIDE>`
|
|||||||
| 3 | GPIO32 | U0RXD (Input) |
|
| 3 | GPIO32 | U0RXD (Input) |
|
||||||
| 4 | 3V3 | PWR |
|
| 4 | 3V3 | PWR |
|
||||||
|
|
||||||
### T7, Slave Interface
|
### T7
|
||||||
|`T7` pin|what|Signal|Components|
|
|`T7` pin|what|Signal|
|
||||||
|---|---|---|---|
|
|---|---|---|
|
||||||
| 1 | Slave Interface | Slave SCK/SCL/MDC/EE_SCL | U7-6 |
|
| 1 | GPIO | |
|
||||||
| 2 | GND | | |
|
| 2 | GND | |
|
||||||
| 3 | Slave Interface | Slave SDI/SDA/MDIO/EE_SDA | U7-5 |
|
| 3 | GPIO | |
|
||||||
| 4 | 3V3 | | |
|
| 4 | 3V3 | |
|
||||||
| 5 | GPIO? | | |
|
| 5 | GPIO | |
|
||||||
| 6 | GPIO? | | |
|
| 6 | GPIO | |
|
||||||
|
|
||||||
`U7` can be a standard I2C eeprom memory, like `24LC32`.
|
|
||||||
|
|
||||||
The Slave Interface allows an extenal host to controll the SOC even if the internal MCU is used.
|
|
||||||
Depending on the `IF_SEL` bootstrap resistors, this can me `I2C`, `SPI` or `SMI`.
|
|
||||||
On this device it is `I2C` on address `0b1011100` or `0x5c` (7-bit notation).
|
|
||||||
|
|
||||||
* I2c Read: must be a write_read opperation `<Dev-ADDR><RegAddr15:8><RegAddr7:0>` `<DevAddr><Data7:0><Data15:8><Data23:16><Data31:24>`.
|
|
||||||
* I2c Write: `<Dev-ADDR><RegAddr15:8><RegAddr7:0><DevAddr><Data7:0><Data15:8><Data23:16><Data31:24>`.
|
|
||||||
|
|
||||||
Example register `0x0004` return chip id `0x00, 0x00, 0x72, 0x83` = `0x83720000`.
|
|
||||||
|
|
||||||
### T9
|
### T9
|
||||||
|`T9` SMI | Signal | Component | GPIO | Notes |
|
|`T9` SMI | Signal | Component | GPIO | Notes |
|
||||||
@@ -96,22 +68,22 @@ Reset-line found at `T-D6-L`, `T-R83`, `T-R97`, `T-R94`, `T-R93` active-low.
|
|||||||
| -------- | ------ | ---- | ---- | ---- | ---- | ---- | ---- |
|
| -------- | ------ | ---- | ---- | ---- | ---- | ---- | ---- |
|
||||||
| 00000001 | GPIO00 | T-R34-R, P1-LED-YL |? | | GPIO32 | B-r126-r | U0RXD |
|
| 00000001 | GPIO00 | T-R34-R, P1-LED-YL |? | | GPIO32 | B-r126-r | U0RXD |
|
||||||
| 00000002 | GPIO01 | T-R99-R, P1-LED-GR |? | | GPIO33 | | |
|
| 00000002 | GPIO01 | T-R99-R, P1-LED-GR |? | | GPIO33 | | |
|
||||||
| 00000004 | GPIO02 | |? | | GPIO34 | B-R172, To RTL8224 | SMI-MDC0 |
|
| 00000004 | GPIO02 | |? | | GPIO34 | B-R172, To RTL8225 | Already driver HIGH INT? |
|
||||||
| 00000008 | GPIO03 | T-R113-R, P2-LED-GR |? | | GPIO35 | B-R173, To RTL8224 | SMI-MDIO0 |
|
| 00000008 | GPIO03 | T-R113-R, P2-LED-GR |? | | GPIO35 | B-R173, To RTL8225 | Easy to pulldown Reset? |
|
||||||
| 00000010 | GPIO04 | T-R115-R, P3-LED-YL |? | | GPIO36 | | | |
|
| 00000010 | GPIO04 | T-R115-R, P3-LED-YL |? | | GPIO36 || | |
|
||||||
| 00000020 | GPIO05 | T-R117-R, P3-LED-GR |? | | GPIO37 | To RTL8224 ?? | Already driver low | |
|
| 00000020 | GPIO05 | T-R117-R, P3-LED-GR |? | | GPIO37 | To RTL8225 | Already driver low I2C-SCL? | |
|
||||||
| 00000040 | GPIO06 | |? | | GPIO38 | sfp-6 via B-R275, sfp-8 via B-R276 | SFP-PRESENT |
|
| 00000040 | GPIO06 | |? | | GPIO38 | sfp-6 via B-R275, sfp-8 via B-R276 | |
|
||||||
| 00000080 | GPIO07 | |? | | GPIO39 | sfp-4, b-r273, B-r143 | I2C4-SDA |
|
| 00000080 | GPIO07 | |? | | GPIO39 | sfp-4, b-r273, B-r143 | |
|
||||||
| 00000100 | GPIO08 | | | | GPIO40 | T9-2, sfp-5 b-r274, B-r146 | I2C3-SCL |
|
| 00000100 | GPIO08 | | | | GPIO40 | T9-2, sfp-5 b-r274, B-r146 | SMI-MDC |
|
||||||
| 00000200 | GPIO09 | |LEDx[^1] | | GPIO41 | T9-1, B-r143 | | I2C3-SDA (Unused) |
|
| 00000200 | GPIO09 | |LEDx[^1] | | GPIO41 | T9-1, | SMI-MDO , B-r143 |
|
||||||
| 00000400 | GPIO10 | | | | GPIO42 | U6?8?-P6, T-R | SPI-MEMORY, CLK |
|
| 00000400 | GPIO10 | | | | GPIO42 | U6?8?-P6, T-R | SPI-MEMORY, CLK |
|
||||||
| 00000800 | GPIO11 | |LEDx[^1] | | GPIO43 | U6?8?-P5, T-R | SPI-MEMORY, DI,IO0 |
|
| 00000800 | GPIO11 | |LEDx[^1] | | GPIO43 | U6?8?-P5, T-R | SPI-MEMORY, DI,IO0 |
|
||||||
| 00001000 | GPIO12 | |LEDx[^1] | | GPIO44 | U6?8?-P2, T-R | SPI-MEMORY, DO,IO1 |
|
| 00001000 | GPIO12 | |LEDx[^1] | | GPIO44 | U6?8?-P2, T-R | SPI-MEMORY, DO,IO1 |
|
||||||
| 00002000 | GPIO13 | |LEDx[^1] | | GPIO45 | U6?8?-P1, T-R | SPI-MEMORY, CS |
|
| 00002000 | GPIO13 | |LEDx[^1] | | GPIO45 | U6?8?-P1, T-R | SPI-MEMORY, CS |
|
||||||
| 00004000 | GPIO14 | |LEDx[^1] | | GPIO46 | T10-6 | SPI0-SCK |
|
| 00004000 | GPIO14 | |LEDx[^1] | | GPIO46 | T10-6 | |
|
||||||
| 00008000 | GPIO15 | |LEDx[^1] | | GPIO47 | T10-2 | SPI0-SDA |
|
| 00008000 | GPIO15 | |LEDx[^1] | | GPIO47 | T10-2 | |
|
||||||
| 00010000 | GPIO16 | |LEDx[^1] | | GPIO48 | T10-4, J6 (BUTTON RESET) | SPI1-SCK |
|
| 00010000 | GPIO16 | |LEDx[^1] | | GPIO48 | T10-4, J6 (BUTTON RESET) | |
|
||||||
| 00020000 | GPIO17 | |LEDx[^1] | | GPIO49 | T10-1 | SPI1-SDA |
|
| 00020000 | GPIO17 | |LEDx[^1] | | GPIO49 | T10-1 | |
|
||||||
| 00040000 | GPIO18 | |LEDx[^1] | | GPIO50 | | |
|
| 00040000 | GPIO18 | |LEDx[^1] | | GPIO50 | | |
|
||||||
| 00080000 | GPIO19 | |LEDx[^1] | | GPIO51 | | |
|
| 00080000 | GPIO19 | |LEDx[^1] | | GPIO51 | | |
|
||||||
| 00100000 | GPIO20 | |LEDx[^1] | | GPIO52 | | |
|
| 00100000 | GPIO20 | |LEDx[^1] | | GPIO52 | | |
|
||||||
@@ -124,7 +96,7 @@ Reset-line found at `T-D6-L`, `T-R83`, `T-R97`, `T-R94`, `T-R93` active-low.
|
|||||||
| 08000000 | GPIO27 | |? | | GPIO59 | | |
|
| 08000000 | GPIO27 | |? | | GPIO59 | | |
|
||||||
| 10000000 | GPIO28 | | | | GPIO60 | | |
|
| 10000000 | GPIO28 | | | | GPIO60 | | |
|
||||||
| 20000000 | GPIO29 | | | | GPIO61 | | |
|
| 20000000 | GPIO29 | | | | GPIO61 | | |
|
||||||
| 40000000 | GPIO30 | RTL8224N Reset |RTL8224 | | GPIO62 | To RTL8224 | Already driver | |
|
| 40000000 | GPIO30 | |SFP-DETE | | GPIO62 | To RTL8225 | Already driver INT? | |
|
||||||
| 80000000 | GPIO31 | B-r129-r? |U0TXD | | GPIO63 | | |
|
| 80000000 | GPIO31 | B-r129-r? |U0TXD | | GPIO63 | | |
|
||||||
|
|
||||||
## GPIO Register Input value
|
## GPIO Register Input value
|
||||||
|
|||||||
@@ -1,93 +0,0 @@
|
|||||||
# FOXNEO FNS-1200P
|
|
||||||
|
|
||||||
RTL8372-based 4×2.5G PoE+ + 2×SFP+ unmanaged switch.
|
|
||||||
|
|
||||||
Using SPI clamp in-board is the only method for initial installation.
|
|
||||||
|
|
||||||
### Label specifications
|
|
||||||
|
|
||||||
- **Manufacturer**: FOXNEO
|
|
||||||
- **Model**: FNS-1200P
|
|
||||||
- **Ports**:
|
|
||||||
- 4 × RJ45: 10/100/1000/2500 Mbps with PoE+
|
|
||||||
- 2 × SFP+: 1G / 2.5G / 10G
|
|
||||||
|
|
||||||
### What works
|
|
||||||
|
|
||||||
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps (PoE+ is not configurable via RTLPlayground)
|
|
||||||
- Both SFP+ ports supporting 1G, 2.5G and 10G modules
|
|
||||||
- LEDs: amber (2.5G) and green (1G/100M/10M) per copper port; combined link/act on SFP ports
|
|
||||||
|
|
||||||
### PCB overview
|
|
||||||
|
|
||||||
**Board markings**
|
|
||||||
- Top silkscreen: PCB-K0402W-U13-V2.0 / DIP-K0402WB-V2.0
|
|
||||||
|
|
||||||
**Key components**
|
|
||||||
- U3: SPI NOR flash, 2 MiB
|
|
||||||
- U7: unpopulated SOP8 footprint — I2C bus (RTL8372 slave at 0x5c) is accessible from its pads, useful for register dumps
|
|
||||||
- S1: unpopulated slide switch footprint (three through-holes used as serial console)
|
|
||||||
|
|
||||||
Front panel
|
|
||||||
|
|
||||||
<img src="photos/FNS-1200P/chassis-front.jpg" width="400" />
|
|
||||||
|
|
||||||
Top side (PCB)
|
|
||||||
|
|
||||||
<img src="photos/FNS-1200P/PCB-top.jpg" width="300" />
|
|
||||||
|
|
||||||
### Port layout
|
|
||||||
|
|
||||||
| Front panel position | Logical port | Physical port | Type |
|
|
||||||
|----------------------|--------------|---------------|---------|
|
|
||||||
| SFP left | 8 | 5 | SFP+ |
|
|
||||||
| RJ45 1 | 4 | 1 | Copper |
|
|
||||||
| RJ45 2 | 5 | 2 | Copper |
|
|
||||||
| RJ45 3 | 6 | 3 | Copper |
|
|
||||||
| RJ45 4 | 7 | 4 | Copper |
|
|
||||||
| SFP right | 3 | 6 | SFP+ |
|
|
||||||
|
|
||||||
### Serial console
|
|
||||||
|
|
||||||
The PCB has three unpopulated through-holes intended for a slide switch, directly connected to UART0.
|
|
||||||
Numbered from the left (SFP port side), the pinout is:
|
|
||||||
|
|
||||||
| Position (left→right) | Signal | GPIO |
|
|
||||||
|-----------------------|--------|--------------------------|
|
|
||||||
| 1 (leftmost) | RX | GPIO32\_UART0\_RX (32) |
|
|
||||||
| 2 (middle) | GND | GND |
|
|
||||||
| 3 (rightmost) | TX | GPIO31\_UART0\_TX (31) |
|
|
||||||
|
|
||||||
- **Settings**: 115200 baud / 8N1 / 3.3V TTL
|
|
||||||
- Connect a USB-TTL adapter: adapter TX → pin 1, GND → pin 2, adapter RX → pin 3
|
|
||||||
|
|
||||||
### LED configuration
|
|
||||||
|
|
||||||
Copper ports use LED SET0, SFP ports use LED SET1.
|
|
||||||
|
|
||||||
| SET | LED0 | LED2 |
|
|
||||||
|------|--------------------------------------------------|---------------------------------------------------|
|
|
||||||
| SET0 | Amber — lights on 2.5G link | Green — lights on 1G / 100M / 10M link |
|
|
||||||
| SET1 | All speeds — lights on any link with activity | — |
|
|
||||||
|
|
||||||
LED pad to physical port mapping:
|
|
||||||
|
|
||||||
| GPIO pads | Port |
|
|
||||||
|-----------|-------------------------|
|
|
||||||
| GPIO8–11 | Physical port 5 (left SFP) |
|
|
||||||
| GPIO12–14 | Physical port 1 (RJ45 1) |
|
|
||||||
| GPIO15–17 | Physical port 2 (RJ45 2) |
|
|
||||||
| GPIO18–20 | Physical port 3 (RJ45 3) |
|
|
||||||
| GPIO21–23 | Physical port 4 (RJ45 4) |
|
|
||||||
| GPIO24–27 | Physical port 6 (right SFP) |
|
|
||||||
|
|
||||||
### SFP GPIO assignments
|
|
||||||
|
|
||||||
| SFP | pin\_detect (ModAbs) | pin\_los | SerDes | I2C SDA | I2C SCL |
|
|
||||||
|------------------|-----------------------------|------------------------|--------|----------------------|--------------------------|
|
|
||||||
| Left (logical 8) | GPIO30\_ACL\_BIT3\_EN | GPIO37 | SDS1 | GPIO39\_I2C\_SDA4 | GPIO40\_I2C\_SCL3\_MDC1 |
|
|
||||||
| Right (logical 3)| GPIO50\_I2C\_SCL2\_UART1\_TX | GPIO51\_I2C\_SDA2\_UART1\_RX | SDS0 | GPIO41\_I2C\_SDA3\_MDIO1 | GPIO40\_I2C\_SCL3\_MDC1 |
|
|
||||||
|
|
||||||
GPIO assignments were verified by observing GPIO state changes during SFP module insertion/removal
|
|
||||||
and cross-checked against an original firmware register dump.
|
|
||||||
`pin_tx_disable` is GPIO\_NA on both ports (original firmware keeps all GPIOs as inputs).
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
# Hisource Hi-K0801WS
|
|
||||||
|
|
||||||
Following is documentation for unmanaged switch marked as `Hi-K0801WS`.
|
|
||||||
|
|
||||||
Using SPI clamp in-board is the only method for initial installation.
|
|
||||||
|
|
||||||
### Label specifications
|
|
||||||
|
|
||||||
- **Name**: 2.5G Ethernet Switch
|
|
||||||
- **Model**: Hi-K0801WS
|
|
||||||
- **Ports**:
|
|
||||||
- 8 × RJ45: 10/100/1000/2500 Mbps
|
|
||||||
- 1 × SFP: 1000 / 2500 / 10000 Mbps
|
|
||||||
|
|
||||||
### What works (expected from label + similar devices)
|
|
||||||
|
|
||||||
- All eight 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
|
||||||
- SFP port supporting 1G, 2.5G and 10G modules
|
|
||||||
- LEDs
|
|
||||||
|
|
||||||
### PCB overview
|
|
||||||
|
|
||||||
**Board markings**
|
|
||||||
- Top silkscreen: PCB-KO801W-V2.0 / DIP-KO801WS-V2.0
|
|
||||||
|
|
||||||
Top side
|
|
||||||
|
|
||||||
<img src="photos/K0801W-V2.0-unmanaged\PCB-top.jpg" width="300" />
|
|
||||||
|
|
||||||
Bottom
|
|
||||||
|
|
||||||
<img src="photos/K0801W-V2.0-unmanaged\PCB-bottom.jpg" width="300" />
|
|
||||||
|
|
||||||
## Power supply
|
|
||||||
|
|
||||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
# K0501W V2.0
|
|
||||||
|
|
||||||
This board appears for example in the Davuaz Da-K6501W switch.
|
|
||||||
|
|
||||||
The general design of the board is similar to Hi-K0402WS V3.0.
|
|
||||||
However, there are several differences:
|
|
||||||
- One SFP port is replaced by a RTL8221B 2.5G PHY
|
|
||||||
- Only one LED is populated for the SFP port
|
|
||||||
- No mode switch and only one flash chip
|
|
||||||
- Older design using RTL8372 instead of RTL8372N (which also means different GPIO and LED configuration)
|
|
||||||
- Like earlier versions of the K0402W(S) board, there is no UART
|
|
||||||
|
|
||||||
All ports and LEDs are supported.
|
|
||||||
Installation is possible using a flash programmer.
|
|
||||||
The BoyaMicro 25Q16BSSIG flash chip is supported by flashprog with chip name "B.25D16AS/BY25Q16BS/BY25Q16ES".
|
|
||||||
|
|
||||||
## PCB pictures
|
|
||||||
|
|
||||||
The board is marked `PCB-K0501W-V2.0 DIP-K0501WS-V2.0`.
|
|
||||||
|
|
||||||
<img src="photos/K0501W_V2_0/pcb-top.jpg" width="300" />
|
|
||||||
|
|
||||||
<img src="photos/K0501W_V2_0/pcb-bottom.jpg" width="300" />
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
# Keeplink KP-9000-6XH-X2
|
|
||||||
|
|
||||||
Following is documentation for unmanaged switch marked as `KP-9000-6XH-X2`.
|
|
||||||
|
|
||||||
Using SPI clamp in-board is the only method for initial installation.
|
|
||||||
|
|
||||||
### Label specifications
|
|
||||||
|
|
||||||
- **Name**: 4X 2.5G RJ45 Port + 2 X 10G SFP+ Port
|
|
||||||
- **Model**: KP-9000-6XH-X2
|
|
||||||
- **Ports**:
|
|
||||||
- 4 × RJ45: 10/100/1000/2500 Mbps
|
|
||||||
- 2 × SFP+: 1000 / 2500 / 10000 Mbps
|
|
||||||
|
|
||||||
### What works
|
|
||||||
|
|
||||||
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
|
||||||
- SFP port with 10G modules
|
|
||||||
- LEDs
|
|
||||||
- untested due to missing Hardware: SFP+ ports equipped with 1G or 2.5G SFPs.
|
|
||||||
|
|
||||||
### Hardware overview
|
|
||||||
|
|
||||||
Front side:
|
|
||||||
|
|
||||||
<img src="photos/2M-PCB43-V2.1-unmanaged/KP-9000-6XH-X2-front.jpg" width="600" />
|
|
||||||
|
|
||||||
Label:
|
|
||||||
|
|
||||||
<img src="photos/2M-PCB43-V2.1-unmanaged/KP-9000-6XH-X2-label.jpg" width="600" />
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### PCB overview
|
|
||||||
|
|
||||||
**Board markings**
|
|
||||||
- Top silkscreen: 2M-PCB43-V2.1
|
|
||||||
|
|
||||||
Top side
|
|
||||||
|
|
||||||
<img src="photos/2M-PCB43-V2.1-unmanaged/2M-PCB43-V2.1-top.jpg" width="600" />
|
|
||||||
|
|
||||||
Bottom
|
|
||||||
|
|
||||||
<img src="photos/2M-PCB43-V2.1-unmanaged/2M-PCB43-V2.1-bottom.jpg" width="600" />
|
|
||||||
|
|
||||||
## Reset Button
|
|
||||||
|
|
||||||
There's an unpopulated Reset button on the front left side of the PCB.
|
|
||||||
It can easily be soldered, you'll need an 4.5mmx4.5mm 90° button switch with a 3-pin footprint.
|
|
||||||
I got mine here: https://de.aliexpress.com/item/1005007295346702.html
|
|
||||||
The front case has already the hole in the metal case, you just have to punch a hole through the foil.
|
|
||||||
|
|
||||||
## Power supply
|
|
||||||
|
|
||||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
|
||||||
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
# 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.**
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
# SWTG018AS-A V2.0
|
|
||||||
|
|
||||||
The following is a documentation for the unmanaged switch marked as `SWTG018AS-A V2.0`.
|
|
||||||
It is e.g. sold under the Ampcom brand, but no branh-markings are found on the device.
|
|
||||||
|
|
||||||
The original software is running UART on 9600 baud rate.
|
|
||||||
|
|
||||||
Using a SOIC clamp in-board is the only method for initial installation.
|
|
||||||
|
|
||||||
The board has a single flash chips `BS` with 4M-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**: 9-Ports 2.5G Ethernet Switch
|
|
||||||
- **Ports**:
|
|
||||||
- 8 × RJ45: 10/100/1000/2500 Mbps
|
|
||||||
- 1 × SFP+: 1000 / 2500 / 10000 Mbps
|
|
||||||
- **Power**: 12V DC, 1A barrel connector
|
|
||||||
|
|
||||||
<img src="photos/SWTG018AS_A_V_2_0/label.jpg" width="300" />
|
|
||||||
|
|
||||||
### What works
|
|
||||||
The device is fully supported:
|
|
||||||
- All 8 2.5GBASE-T RJ45 ports work at 10/100/1000/2500 Mbps
|
|
||||||
- The SFP+ port supports 1G, 2.5G and 10G modules
|
|
||||||
- LEDs work with the same indiciations as the OEM firmware
|
|
||||||
|
|
||||||
### PCB overview
|
|
||||||
|
|
||||||
**Board markings**
|
|
||||||
- Top silkscreen: SWTG018AS-A-V2.0.1_19649
|
|
||||||
|
|
||||||
Top side
|
|
||||||
|
|
||||||
<img src="photos/SWTG018AS_A_V_2_0/pcb_top.jpg" width="300" />
|
|
||||||
|
|
||||||
Bottom
|
|
||||||
|
|
||||||
<img src="photos/SWTG018AS_A_V_2_0/pcb_bottom.jpg" width="300" />
|
|
||||||
|
|
||||||
### J1, serial console
|
|
||||||
|
|
||||||
| `J1` pin | Signal |
|
|
||||||
| -------- | ----------- |
|
|
||||||
| 1 | 3V3 |
|
|
||||||
| 2 | GND |
|
|
||||||
| 3 | RX (Input) |
|
|
||||||
| 4 | TX (Output) |
|
|
||||||
|
|
||||||
|
|
||||||
## Power supply
|
|
||||||
|
|
||||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
### ZX-SWTGW215AS
|
|
||||||
|
|
||||||
## Brands
|
|
||||||
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
|
||||||
|---|---|---|---|---|---|
|
|
||||||
| Lianguo | ZX-SWTGW215AS | Yes | PCB-SWTG115AS-V2.0 | FM25Q16A | 8272 |
|
|
||||||
|
|
||||||
## RTLPlayground target
|
|
||||||
|
|
||||||
Use machine target `MACHINE_LIANGUO_ZX_SWTGW215AS` for this device.
|
|
||||||
|
|
||||||
Physical hardware verification: 5x RJ45 ports + 1x SFP port.
|
|
||||||
Port 5 RJ45 is interfaced through a RTL8221B IC.
|
|
||||||
|
|
||||||
## PCB
|
|
||||||
|
|
||||||
<img src="photos/ZX-SWTGW215AS/pcb_top.jpg" width="300" />
|
|
||||||
|
|
||||||
# Connectors
|
|
||||||
|
|
||||||
## Port overview
|
|
||||||
|
|
||||||
```
|
|
||||||
┌──────────────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ ┌──────────┐ │
|
|
||||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ SFP (J4) │ │
|
|
||||||
│ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ PORT 6 │ │
|
|
||||||
│ │ PORT 1 │ │ PORT 2 │ │ PORT 3 │ │ PORT 4 │ │ PORT 5 │ │ LOG 8 │ │
|
|
||||||
│ O │ LOG 4 │ │ LOG 5 │ │ LOG 6 │ │ LOG 7 │ │ LOG 3 │ │ SerDes 1 │ │
|
|
||||||
│ RST └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘ │
|
|
||||||
└──────────────────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
| Type | RTLPlayground logical ports | Physical index |
|
|
||||||
|---|---|---|
|
|
||||||
| RJ45 | 3, 4, 5, 6, 7 | 1-5 |
|
|
||||||
| SFP | 8 | 6 |
|
|
||||||
|
|
||||||
## J4
|
|
||||||
|
|
||||||
* Location: SFP connector `J4`.
|
|
||||||
* Connected to: 10GMAC number 8, SerDes 1.
|
|
||||||
|
|
||||||
|`J4` SFP PINs | Signal | GPIO | Notes |
|
|
||||||
|---|---|---|---|
|
|
||||||
|3| TX_DISABLE | GPIO_NA | Not connected |
|
|
||||||
|4| MODDEF2 – SDA | GPIO39 | I2C SDA |
|
|
||||||
|5| MODDEF1 – SCL | GPIO40 | I2C SCL |
|
|
||||||
|6| MODDEF0 – PRESENT | GPIO30 | Detect |
|
|
||||||
|8| LOS | GPIO37 | RX Loss of Signal |
|
|
||||||
### Notes
|
|
||||||
* Not all signals were mapped mechanically, hence they've been left out of documentation.
|
|
||||||
|
|
||||||
## T3, Slave Interface
|
|
||||||
|
|
||||||
This connector goes to U4 `I2C EEPROM` and U10 `SPI FLASH` (mappings identical to SWTG024AS).
|
|
||||||
|
|
||||||
For detailed Slave Interface functionality and protocol information, see [T3 documentation in SWTG024AS.md](SWTG024AS.md#t3-slave-interface).
|
|
||||||
|
|
||||||
|`T3` pin|what|Signal|
|
|
||||||
|---|---|---|
|
|
||||||
|1| U4-P6, 33R U10-P6 | I2C-SCL, SPI-CLK, Slave SCK/SCL/MDC/EE_SCL |
|
|
||||||
|2| GND | --- |
|
|
||||||
|3| U4-P5, U10-P5 | I2C-SDA, SPI-DI/DO, Slave SDI/SDA/MDIO/EE_SDA |
|
|
||||||
|4| VCC |
|
|
||||||
|5| 33R -> U10-P2 | SPI-DO/D1 |
|
|
||||||
|6| U10-P1 | SPI-CS |
|
|
||||||
### Notes
|
|
||||||
* 1 pin is square shaped.
|
|
||||||
|
|
||||||
|
|
||||||
## T5, Serial Console
|
|
||||||
|
|
||||||
|`T5` pin|GPIO|Signal|
|
|
||||||
|---|---|---|
|
|
||||||
| 1 | GPIO31 | U0TXD (Output) |
|
|
||||||
| 2 | GND | |
|
|
||||||
| 3 | GPIO32 | U0RXD (Input) |
|
|
||||||
| 4 | 3V3 | |
|
|
||||||
### Notes
|
|
||||||
* 1 pin is square shaped.
|
|
||||||
|
|
||||||
## T8
|
|
||||||
|
|
||||||
|`T8` pin|GPIO|Signal|
|
|
||||||
|---|---|---|
|
|
||||||
| 1 | GPIO46 | |
|
|
||||||
| 2 | GND | |
|
|
||||||
| 3 | GPIO48 | |
|
|
||||||
| 4 | 3V3 | |
|
|
||||||
| 5 | GPIO47 | |
|
|
||||||
| 6 | GPIO49 | |
|
|
||||||
|
|
||||||
### Notes
|
|
||||||
* 1 pin is square shaped.
|
|
||||||
* Mapping unverified but assumed the same as [LIANGUO SWTG024AS](SWTG024AS.md#t8).
|
|
||||||
|
|
||||||
# Reset Circuit
|
|
||||||
| Function | GPIO |
|
|
||||||
|---|---|
|
|
||||||
| Reset button | GPIO54 |
|
|
||||||
### Notes
|
|
||||||
* Circuit is active-low
|
|
||||||
|
|
||||||
# GPIO
|
|
||||||
|
|
||||||
Note: T3/U4/U10-related signal annotations below are copied from [LIANGUO SWTG024AS T3 section](SWTG024AS.md#t3-slave-interface) as well as T8 port from [LIANGUO SWTG024AS T8 section](SWTG024AS.md#t8). They should be treated as assumed identical for ZX-SWTGW215AS as it has not been 100% confirmed true at the moment.
|
|
||||||
|
|
||||||
| HEX VAL. | GPIO | Component / Purpose | Notes | | GPIO | Component / Purpose | Notes |
|
|
||||||
| -------- | ------ | ---- | ---- | ---- | ---- | ---- | ---- |
|
|
||||||
| 00000001 | GPIO00 | | | | GPIO32 | T5-3 | U0RXD |
|
|
||||||
| 00000002 | GPIO01 | | | | GPIO33 | | |
|
|
||||||
| 00000004 | GPIO02 | | | | GPIO34 | | |
|
|
||||||
| 00000008 | GPIO03 | | | | GPIO35 | | |
|
|
||||||
| 00000010 | GPIO04 | | | | GPIO36 | | |
|
|
||||||
| 00000020 | GPIO05 | | | | GPIO37 | J4-8 | SFP LOS |
|
|
||||||
| 00000040 | GPIO06 | | | | GPIO38 | | |
|
|
||||||
| 00000080 | GPIO07 | | | | GPIO39 | J4-4 | SFP I2C SDA |
|
|
||||||
| 00000100 | GPIO08 | | | | GPIO40 | J4-5 | SFP I2C SCL |
|
|
||||||
| 00000200 | GPIO09 | | | | GPIO41 | | |
|
|
||||||
| 00000400 | GPIO10 | | | | GPIO42 | U10-P6, U4-P6, T3-1 | SPI FLASH CLK / I2C-SCL (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
|
|
||||||
| 00000800 | GPIO11 | | | | GPIO43 | U10-P5, U4-P5, T3-3 | SPI FLASH DI/IO0 / I2C-SDA (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
|
|
||||||
| 00001000 | GPIO12 | | | | GPIO44 | U10-P2, T3-5 | SPI FLASH DO/IO1 (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
|
|
||||||
| 00002000 | GPIO13 | PORT1 LED GREEN | | | GPIO45 | U10-P1, T3-6 | SPI FLASH CS (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
|
|
||||||
| 00004000 | GPIO14 | PORT1 LED ORANGE | | | GPIO46 | T8-1 | (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
|
|
||||||
| 00008000 | GPIO15 | | | | GPIO47 | T8-5 | (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
|
|
||||||
| 00010000 | GPIO16 | PORT2 LED GREEN | | | GPIO48 | T8-3 | (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
|
|
||||||
| 00020000 | GPIO17 | PORT2 LED ORANGE | | | GPIO49 | T8-6 | (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
|
|
||||||
| 00040000 | GPIO18 | PORT3 LED GREEN | | | GPIO50 | | |
|
|
||||||
| 00080000 | GPIO19 | PORT3 LED ORANGE | | | GPIO51 | | |
|
|
||||||
| 00100000 | GPIO20 | PORT4 LED GREEN | | | GPIO52 | | |
|
|
||||||
| 00200000 | GPIO21 | PORT4 LED ORANGE | | | GPIO53 | | |
|
|
||||||
| 00400000 | GPIO22 | PORT5 LED GREEN | | | GPIO54 | Reset Button | GPIO54_ACL_BIT2_EN |
|
|
||||||
| 00800000 | GPIO23 | PORT5 LED ORANGE | | | GPIO55 | | |
|
|
||||||
| 01000000 | GPIO24 | SFP LED GREEN | J4 | | GPIO56 | | |
|
|
||||||
| 02000000 | GPIO25 | | | | GPIO57 | | |
|
|
||||||
| 04000000 | GPIO26 | | | | GPIO58 | | |
|
|
||||||
| 08000000 | GPIO27 | | | | GPIO59 | | |
|
|
||||||
| 10000000 | GPIO28 | LED-SYSTEM | | | GPIO60 | | |
|
|
||||||
| 20000000 | GPIO29 | | | | GPIO61 | | |
|
|
||||||
| 40000000 | GPIO30 | J4-6 | SFP DETECT | | GPIO62 | | |
|
|
||||||
| 80000000 | GPIO31 | T5-1 | U0TXD | | GPIO63 | | |
|
|
||||||
|
|
||||||
# LEDs
|
|
||||||
|
|
||||||
| NAME | GPIO | Port(s) | Function | Notes |
|
|
||||||
| ---- | ---- | ---- | ---- | ---- |
|
|
||||||
| PORT1 LED GREEN | GPIO13 |5| Activity | LEDS_2G5, LEDS_LINK, LEDS_ACT |
|
|
||||||
| PORT1 LED ORANGE | GPIO14 | 5 | Speed | LEDS_1G, LEDS_100M, LEDS_10M, LEDS_LINK, LEDS_ACT |
|
|
||||||
| PORT2 LED GREEN | GPIO16 | 4 | Activity | LEDS_2G5, LEDS_LINK, LEDS_ACT |
|
|
||||||
| PORT2 LED ORANGE | GPIO17 | 4 | Speed | LEDS_1G, LEDS_100M, LEDS_10M, LEDS_LINK, LEDS_ACT |
|
|
||||||
| PORT3 LED GREEN | GPIO18 | 3 | Activity | LEDS_2G5, LEDS_LINK, LEDS_ACT |
|
|
||||||
| PORT3 LED ORANGE | GPIO19 | 3 | Speed | LEDS_1G, LEDS_100M, LEDS_10M, LEDS_LINK, LEDS_ACT |
|
|
||||||
| PORT4 LED GREEN | GPIO20 | 2 | Activity | LEDS_2G5, LEDS_LINK, LEDS_ACT |
|
|
||||||
| PORT4 LED ORANGE | GPIO21 | 2 | Speed | LEDS_1G, LEDS_100M, LEDS_10M, LEDS_LINK, LEDS_ACT |
|
|
||||||
| PORT5 LED GREEN | GPIO22 | 1 | Activity | LEDS_2G5, LEDS_LINK, LEDS_ACT |
|
|
||||||
| PORT5 LED ORANGE | GPIO23 | 1 | Speed | LEDS_1G, LEDS_100M, LEDS_10M, LEDS_LINK, LEDS_ACT |
|
|
||||||
| SFP LED GREEN | GPIO24 | 6 (SFP J4) | Multi-speed | LEDS_10G, LEDS_5G, LEDS_2G5, LEDS_1G, LEDS_100M, LEDS_LINK, LEDS_ACT |
|
|
||||||
| LED-SYSTEM | GPIO28 | --- | System status | --- |
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
While [SWTG024AS.md](SWTG024AS.md) can be used as a general reference for hardware concepts and interface specifications, this device should not be assumed to be identical beside the difference implicitely highlighted below. Not all information has been validated for compatibility with the SWTG215AS. Consult the SWTG024AS documentation with caution and verify any critical details against this device's.
|
|
||||||
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
### ZX-SWTGW218AS
|
|
||||||
|
|
||||||
## Brands
|
|
||||||
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
|
||||||
|---|---|---|---|---|---|
|
|
||||||
| Mokerlink | ZX-SWTGW218AS | Yes| SWTG118AS-V2.0-16029 | 2MB (FM25Q16A)| 8273N + 8224N |
|
|
||||||
| Sodola | | | | | |
|
|
||||||
| Horaco | | | | | |
|
|
||||||
|
|
||||||
|
|
||||||
## Photos
|
|
||||||
|
|
||||||
<img src="photos/SWTGW218AS-managed/front.png" width="800" />
|
|
||||||
|
|
||||||
<img src="photos/SWTGW218AS-managed/label.jpg" width="800" />
|
|
||||||
|
|
||||||
## PCB
|
|
||||||
|
|
||||||
See up'n'atom's Repo:
|
|
||||||
|
|
||||||
https://github.com/up-n-atom/SWTG118AS/blob/main/photos/SWTG118AS-v2.0/SWTG118AS-v2.0-pcb-top.JPG
|
|
||||||
|
|
||||||
https://github.com/up-n-atom/SWTG118AS/blob/main/photos/SWTG118AS-v2.0/SWTG118AS-v2.0-pcb-bottom.JPG
|
|
||||||
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
# TrendNet TEG-S562
|
|
||||||
|
|
||||||
Following is documentation for unmanaged switch marked as `TEG-S563/EU H/W: V1.0R`.
|
|
||||||
|
|
||||||
Original software is running UART on 57600 baud rate. The software does not allow to
|
|
||||||
do anything fancy via serial. There is `IP` configuration which can be printed as well.
|
|
||||||
There might be also some flash upload procedure, but using SPI clamp in-board seems to
|
|
||||||
be easier method.
|
|
||||||
|
|
||||||
The memory chip is `Winbond W25Q16JV` with 16M-bit size.
|
|
||||||
|
|
||||||
## What does work
|
|
||||||
|
|
||||||
1. 2.5G ports on all advertised speeds.
|
|
||||||
2. SFP+ communication.
|
|
||||||
3. Serial, Web UI.
|
|
||||||
4. All LEDs
|
|
||||||
|
|
||||||
## Known issues
|
|
||||||
|
|
||||||
None.
|
|
||||||
|
|
||||||
## PCB
|
|
||||||
|
|
||||||
Manufacturer information be found [on the product page](https://www.trendnet.com/support/support-detail.asp?prod=105_TEG-S562).
|
|
||||||
|
|
||||||
Top side
|
|
||||||
|
|
||||||
<img src="photos/TEG-S562/TEG-S562-v1.0R-top.jpg" width="300" />
|
|
||||||
|
|
||||||
Bottom
|
|
||||||
|
|
||||||
<img src="photos/TEG-S562/TEG-S562-v1.0R-bottom.jpg" width="300" />
|
|
||||||
|
|
||||||
## Connectors
|
|
||||||
|
|
||||||
### Port overview
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ ┌──────────┐ ┌──────────┐ │
|
|
||||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ SFP 2 │ │ SFP 1 │ │
|
|
||||||
│ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ PORT 5 │ │ PORT 6 │ │
|
|
||||||
│ │ PORT 1 │ │ PORT 2 │ │ PORT 3 │ │ PORT 4 │ │ MAC 8 │ │ MAC 3 │ │
|
|
||||||
│ │ MAC 4 │ │ MAC 5 │ │ MAC 6 │ │ MAC 7 │ │ SerDes 0 │ │ SerDes 1 │ │
|
|
||||||
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘ └──────────┘ │
|
|
||||||
└─────────────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### J2, serial console
|
|
||||||
|
|
||||||
| `J2` pin | Signal |
|
|
||||||
| -------- | ----------- |
|
|
||||||
| 1 | 3V3 |
|
|
||||||
| 2 | TX (Output) |
|
|
||||||
| 3 | RX (Input) |
|
|
||||||
| 4 | GND |
|
|
||||||
|
|
||||||
Note: 1 pin is square shaped, towards the power input.
|
|
||||||
|
|
||||||
### J5, power pass-thru
|
|
||||||
|
|
||||||
| `J5` pin | Signal |
|
|
||||||
| -------- | ------ |
|
|
||||||
| 1 | 12V |
|
|
||||||
| 2 | 12V |
|
|
||||||
| 3 | GND |
|
|
||||||
| 4 | GND |
|
|
||||||
|
|
||||||
Note: 1 pin is square shaped.
|
|
||||||
|
|
||||||
### U5, I2C eeprom placeholder
|
|
||||||
|
|
||||||
| `J5` pin | Signal |
|
|
||||||
| -------- | ------------- |
|
|
||||||
| 1 | GND |
|
|
||||||
| 2 | GND |
|
|
||||||
| 3 | GND |
|
|
||||||
| 4 | GND |
|
|
||||||
| 5 | 3V3 |
|
|
||||||
| 6 | ??? Logic Low |
|
|
||||||
| 7 | SCL |
|
|
||||||
| 8 | SDA |
|
|
||||||
|
|
||||||
SOC I2C address is 0x5c.
|
|
||||||
|
|
||||||
### SW1 GPIO switch?
|
|
||||||
|
|
||||||
Not populated but looks like a switch for selecting
|
|
||||||
GPIO level. Missing resistors in place.
|
|
||||||
|
|
||||||
GPIO mapping unknown.
|
|
||||||
|
|
||||||
### S2 Reset ciruit
|
|
||||||
|
|
||||||
Not populated but looks like a button can be added on `S2` connector,
|
|
||||||
requires additional `R571` resistor which will pull signal to ground.
|
|
||||||
|
|
||||||
GPIO mapping unknown.
|
|
||||||
|
|
||||||
### GPIO
|
|
||||||
|
|
||||||
| HEX VAL. | GPIO | When | GPIO | When |
|
|
||||||
| -------- | ------ | ----------------| ------ | -----------------------|
|
|
||||||
| 00000001 | GPIO00 | | GPIO32 | |
|
|
||||||
| 00000002 | GPIO01 | | GPIO33 | |
|
|
||||||
| 00000004 | GPIO02 | | GPIO34 | Random changes |
|
|
||||||
| 00000008 | GPIO03 | | GPIO35 | |
|
|
||||||
| 00000010 | GPIO04 | | GPIO36 | SFP2 Present |
|
|
||||||
| 00000020 | GPIO05 | | GPIO37 | SFP2 RX Los |
|
|
||||||
| 00000040 | GPIO06 | | GPIO38 | SFP1 Present |
|
|
||||||
| 00000080 | GPIO07 | | GPIO39 | |
|
|
||||||
| 00000100 | GPIO08 | | GPIO40 | |
|
|
||||||
| 00000200 | GPIO09 | | GPIO41 | |
|
|
||||||
| 00000400 | GPIO10 | | GPIO42 | Random changes |
|
|
||||||
| 00000800 | GPIO11 | | GPIO43 | |
|
|
||||||
| 00001000 | GPIO12 | PORT1 Link | GPIO44 | |
|
|
||||||
| 00002000 | GPIO13 | PORT1-LED-GREEN | GPIO45 | |
|
|
||||||
| 00004000 | GPIO14 | PORT1-LED-AMBER | GPIO46 | SFP1 I2C CLK |
|
|
||||||
| 00008000 | GPIO15 | PORT2 Link | GPIO47 | SFP1 I2C SDA |
|
|
||||||
| 00010000 | GPIO16 | PORT2-LED-GREEN | GPIO48 | SFP2 I2C CLK |
|
|
||||||
| 00020000 | GPIO17 | PORT2-LED-AMBER | GPIO49 | SFP2 I2C SDA |
|
|
||||||
| 00040000 | GPIO18 | PORT3 Link | GPIO50 | SFP1 Rx LOS |
|
|
||||||
| 00080000 | GPIO19 | PORT3-LED-GREEN | GPIO51 | SFP2 TX Disable |
|
|
||||||
| 00100000 | GPIO20 | PORT4-LED-AMBER | GPIO52 | |
|
|
||||||
| 00200000 | GPIO21 | PORT4 Link | GPIO53 | |
|
|
||||||
| 00400000 | GPIO22 | PORT4-LED-GREEN | GPIO54 | SFP1 TX Disable |
|
|
||||||
| 00800000 | GPIO23 | PORT4-LED-AMBER | GPIO55 | |
|
|
||||||
| 01000000 | GPIO24 | | GPIO56 | |
|
|
||||||
| 02000000 | GPIO25 | | GPIO57 | |
|
|
||||||
| 04000000 | GPIO26 | | GPIO58 | |
|
|
||||||
| 08000000 | GPIO27 | | GPIO59 | |
|
|
||||||
| 10000000 | GPIO28 | | GPIO60 | |
|
|
||||||
| 20000000 | GPIO29 | | GPIO61 | |
|
|
||||||
| 40000000 | GPIO30 | | GPIO62 | |
|
|
||||||
| 80000000 | GPIO31 | | GPIO63 | |
|
|
||||||
|
|
||||||
## LEDs
|
|
||||||
|
|
||||||
Ports 1-4 are amber for 100M/1G links, Green for 2.5G.
|
|
||||||
Port 5-6 are green for 10G/1G link. Both should flash on activity.
|
|
||||||
|
|
||||||
| NAME | When active |
|
|
||||||
| ---------------- | ---------------|
|
|
||||||
| PWR | 3V3 |
|
|
||||||
| SFP1 | |
|
|
||||||
| SFP2 | |
|
|
||||||
| PORT1-LED-GREEN | - |
|
|
||||||
| PORT2-LED-GREEN | PORT2 2.5G |
|
|
||||||
| PORT3-LED-GREEN | PORT3 2.5G |
|
|
||||||
| PORT4-LED-GREEN | PORT4 2.5G |
|
|
||||||
| PORT1-LED-AMBER | PORT1 1GB/100M |
|
|
||||||
| PORT2-LED-AMBER | PORT2 1GB/100M |
|
|
||||||
| PORT3-LED-AMBER | PORT3 1GB/100M |
|
|
||||||
| PORT4-LED-AMBER | PORT4 1GB/100M |
|
|
||||||
|
|
||||||
## 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 `APW8713` (U3).
|
|
||||||
|
|
||||||
### `3.3` Voltage
|
|
||||||
|
|
||||||
Voltage is crated regulated by chip marked as `GoIAT` (U2).
|
|
||||||
|
|
||||||
## SFP SPI
|
|
||||||
|
|
||||||
There is separate clock and data lines for both SFP modules. MSDA/MSCK 0 and 1 need to be enabled.
|
|
||||||
|
|
||||||
SFP1 slot is connected to SPI0. SFP2 slot is connected to SPI1.
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
# ZX310S-4T2XH/
|
|
||||||
|
|
||||||
The following is a documentation for the managed switch marked as `ZX310S-4T2XH`
|
|
||||||
and sold by Horaco.
|
|
||||||
|
|
||||||
The original software is running UART on 57600 baud rate. The solder holes
|
|
||||||
of the UART header are filled in. In order to install a UART header, they
|
|
||||||
need to be cleared first. A 1.2mm drill can be used, alternatively a
|
|
||||||
de-soldering wick.
|
|
||||||
The original firmware uses 57600 baud 8N1
|
|
||||||
|
|
||||||
CPU: RTL8372
|
|
||||||
Flash: 2MByte Winbond W25Q16DV (U3)
|
|
||||||
PHY RTL8261BE
|
|
||||||
|
|
||||||
### Label specifications
|
|
||||||
|
|
||||||
- **Name**:
|
|
||||||
- **Ports**:
|
|
||||||
- 4 × RJ45: 10/100/1000/2500 Mbps
|
|
||||||
- 1 x RJ45: 10/100/1000/2500/5000/10000 Mbps
|
|
||||||
- 1 × SFP+: 1000 / 2500 / 10000 Mbps
|
|
||||||
- **Power**: 12V DC, 2A barrel connector
|
|
||||||
|
|
||||||
<img src="photos/ZX310S-4T2XH/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
|
|
||||||
- The 10GBit port works. TODO: Fix EEE, speed selection
|
|
||||||
- The SFP+ port supports 1G, 2.5G and 10G modules
|
|
||||||
- LEDs work with the same indiciations as the OEM firmware
|
|
||||||
|
|
||||||
### PCB overview
|
|
||||||
|
|
||||||
**Board markings**
|
|
||||||
- Top silkscreen: PCB-SL310S-4T1T1X-V1.0.1-24107
|
|
||||||
|
|
||||||
Top side
|
|
||||||
|
|
||||||
<img src="photos/ZX310S-4T2XH/pcb_top.jpg" width="300" />
|
|
||||||
|
|
||||||
Bottom
|
|
||||||
|
|
||||||
<img src="photos/ZX310S-4T2XH/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.
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
# 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: 560 KiB |
|
Before Width: | Height: | Size: 536 KiB |
|
Before Width: | Height: | Size: 754 KiB |
|
Before Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 521 KiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 531 KiB |
|
Before Width: | Height: | Size: 548 KiB |
|
Before Width: | Height: | Size: 505 KiB |
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 1.6 MiB |
|
Before Width: | Height: | Size: 1.6 MiB |
|
Before Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 3.1 MiB |
|
Before Width: | Height: | Size: 2.8 MiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 876 KiB |
|
Before Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 1.8 MiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 558 KiB |
|
Before Width: | Height: | Size: 1.8 MiB |
|
Before Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 2.0 MiB |
|
Before Width: | Height: | Size: 1.9 MiB |
|
Before Width: | Height: | Size: 2.7 MiB |
|
Before Width: | Height: | Size: 3.3 MiB |
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 2.7 MiB |
@@ -1,98 +0,0 @@
|
|||||||
|
|
||||||
# GPIO Pin, Function and MUX registers.
|
|
||||||
|
|
||||||
These functions should bevalid for `RTL8372`, `RTL8372N`, `RTL8373`, and `RTL8373N`.
|
|
||||||
|
|
||||||
`N`-version doesn't seems to have all the GPIO pins available on the outside of the package.
|
|
||||||
|
|
||||||
| GPIO | Function | TYPE | MUX REG, BIT | (RTL8372) PIN# | (RTL8372N) PIN# |
|
|
||||||
| ----- | ---- | ---- | ---- | ---- | ---- |
|
|
||||||
| GPIO0 | LED0 | I/OPU | IO_MUX_SEL_0, BIT 0 | G1 | 12 |
|
|
||||||
| GPIO1 | LED1 | I/OPU | IO_MUX_SEL_0, BIT 1 | G2 | 15 |
|
|
||||||
| GPIO2 | LED2 | I/OPU | IO_MUX_SEL_0, BIT 2 | G3 | 14 |
|
|
||||||
| GPIO3 | LED3 | I/OPU | IO_MUX_SEL_0, BIT 3 | H1 | 16 |
|
|
||||||
| GPIO4 | LED4 | I/OPU | IO_MUX_SEL_0, BIT 4 | H2 | 18 |
|
|
||||||
| GPIO5 | LED5 | I/OPU | IO_MUX_SEL_0, BIT 5 | H3 | 20 |
|
|
||||||
| GPIO6 | LED6 | I/OPU | IO_MUX_SEL_0, BIT 6 | J1 | 22 |
|
|
||||||
| GPIO7 | LED7 | I/OPU | IO_MUX_SEL_0, BIT 7 | J2 | NoPin? |
|
|
||||||
| GPIO8 | LED8 | I/OPU | IO_MUX_SEL_0, BIT 8 | J3 | 24 |
|
|
||||||
| GPIO9 | LED9 | I/OPD | IO_MUX_SEL_0, BIT 9 | L1 | 23 |
|
|
||||||
| GPIO10 | LED10 | I/OPU | IO_MUX_SEL_0, BIT 10 | L2 | 26 |
|
|
||||||
| GPIO11 | LED11 | I/OPU | IO_MUX_SEL_0, BIT 11 | L3 | NoPin? |
|
|
||||||
| GPIO12 | LED12 | I/OPD | IO_MUX_SEL_0, BIT 12 | M1 | 28 |
|
|
||||||
| GPIO13 | LED13 | I/OPU | IO_MUX_SEL_0, BIT 13 | M2 | NoPin? |
|
|
||||||
| GPIO14 | LED14 | I/OPU | IO_MUX_SEL_0, BIT 14 | M3 | NoPin? |
|
|
||||||
| GPIO15 | LED15 | I/OPU | IO_MUX_SEL_0, BIT 15 | N1 | 25 |
|
|
||||||
| GPIO16 | LED16 | I/OPU | IO_MUX_SEL_0, BIT 16 | N2 | NoPin? |
|
|
||||||
| GPIO17 | LED17 | I/OPU | IO_MUX_SEL_0, BIT 17 | N3 | NoPin? |
|
|
||||||
| GPIO18 | LED18 | I/OPD | IO_MUX_SEL_0, BIT 18 | P1 | 30 |
|
|
||||||
| GPIO19 | LED19 | I/OPU | IO_MUX_SEL_0, BIT 19 | P2 | NoPin? |
|
|
||||||
| GPIO20 | LED20 | I/OPU | IO_MUX_SEL_0, BIT 20 | P3 | NoPin? |
|
|
||||||
| GPIO21 | LED21 | I/OPU | IO_MUX_SEL_0, BIT 21 | R1 | 27 |
|
|
||||||
| GPIO22 | LED22 | I/OPU | IO_MUX_SEL_0, BIT 22 | R2 | NoPin? |
|
|
||||||
| GPIO23 | LED23 | I/OPU | IO_MUX_SEL_0, BIT 23 | R3 | NoPin? |
|
|
||||||
| GPIO24 | LED24 | I/OPU | IO_MUX_SEL_0, BIT 24 | N19 | 88 |
|
|
||||||
| GPIO25 | LED25 | I/OPU | IO_MUX_SEL_0, BIT 25 | P19 | 86 |
|
|
||||||
| GPIO26 | LED26 | I/OPU | IO_MUX_SEL_0, BIT 26 | P18 | 84 |
|
|
||||||
| GPIO27 | LED27 | I/OPU | IO_MUX_SEL_0, BIT 27 | R19 | 82 |
|
|
||||||
| GPIO28 | SYS_LED | I/OPU | IO_MUX_SEL_0, BIT 28 | F1 | 13 |
|
|
||||||
| GPIO29 | GLB_RLDP_LED_EN | | IO_MUX_SEL_0, BIT 29 | | NoPin? |
|
|
||||||
| GPIO30 | ACL_BIT3_EN | | IO_MUX_SEL_2, BIT 3 | F3 | 11 |
|
|
||||||
| GPIO31 | UART TX (OUTPUT) | | IO_MUX_SEL_1, BIT 0 | L20 | 90 |
|
|
||||||
| GPIO32 | UART TX (INPUT) | | IO_MUX_SEL_1, BIT 1 | L21 | |
|
|
||||||
| GPIO33 | GPIO_INT | | IO_MUX_SEL_1, BIT 2 | | |
|
|
||||||
| GPIO34 | MDC0 | | IO_MUX_SEL_1, BIT 3 | | |
|
|
||||||
| GPIO35 | MDIO0 | | IO_MUX_SEL_1, BIT 4 | | |
|
|
||||||
| GPIO36 | PWM_OUT | | IO_MUX_SEL_1, BIT 30 | B13 | |
|
|
||||||
| GPIO37 | --- | | | L18 | |
|
|
||||||
| GPIO38 | --- | | | K19 | |
|
|
||||||
| GPIO39 | MSDA4 | | IO_MUX_SEL_1, BIT 29 | K20 | 95 |
|
|
||||||
| GPIO40 | MDC1/SCL3 | | IO_MUX_SEL_1, BIT 5 & 6 | J29 | |
|
|
||||||
| GPIO41 | MDIO1/MSDA3 | | IO_MUX_SEL_1, BIT 5 & 6 | J19 | |
|
|
||||||
| GPIO42 | SPI-MEMORY | | RTL8373_INI_MODE_ADDR, BIT 0 & 1 | D1 | |
|
|
||||||
| GPIO43 | SPI-MEMORY | | RTL8373_INI_MODE_ADDR, BIT 0 & 1 | E1 | |
|
|
||||||
| GPIO44 | SPI-MEMORY | | RTL8373_INI_MODE_ADDR, BIT 0 & 1 | D2 | |
|
|
||||||
| GPIO45 | SPI-MEMORY | | RTL8373_INI_MODE_ADDR, BIT 0 & 1 | E2 | |
|
|
||||||
| GPIO46 | MSCK0 | | IO_MUX_SEL_1, BIT 7 & 8 | A2 | |
|
|
||||||
| GPIO47 | MSDA0 | | IO_MUX_SEL_1, BIT 9 & 10 | B2 | |
|
|
||||||
| GPIO48 | MSCK1 | | IO_MUX_SEL_1, BIT 11 & 12 | A1 | |
|
|
||||||
| GPIO49 | MSDA1 | | IO_MUX_SEL_1, BIT 13 & 14 | B1 | |
|
|
||||||
| GPIO50 | MSCL2/U1TXD | | IO_MUX_SEL_1, BIT 15 & 16 | C1 | |
|
|
||||||
| GPIO51 | MSDA2/U1RXD | | IO_MUX_SEL_1, BIT 17 & 18 | C2 | |
|
|
||||||
| GPIO52 | ACL_BIT0_EN | | IO_MUX_SEL_2, BIT 0 | | |
|
|
||||||
| GPIO53 | ACL_BIT1_EN | | IO_MUX_SEL_2, BIT 1 | | |
|
|
||||||
| GPIO54 | ACL_BIT2_EN | | IO_MUX_SEL_2, BIT 2 | E5 | |
|
|
||||||
| GPIO55 | PTP_CLK125M_IN | | IO_MUX_SEL_1, BIT 19 | | |
|
|
||||||
| GPIO56 | PTP_CLK_OUT | | IO_MUX_SEL_1, BIT 20 | | |
|
|
||||||
| GPIO57 | PTP_TOD_OUT | | IO_MUX_SEL_1, BIT 21 | | |
|
|
||||||
| GPIO58 | PTP_PPS_OUT | | IO_MUX_SEL_1, BIT 22 | | |
|
|
||||||
| GPIO59 | PTP_TOD_IN | | IO_MUX_SEL_1, BIT 23 | | |
|
|
||||||
| GPIO60 | PTP_PPS_IN | | IO_MUX_SEL_1, BIT 24 | | |
|
|
||||||
| GPIO61 | SYNCELOCK0 | | IO_MUX_SEL_1, BIT 27 | | |
|
|
||||||
| GPIO62 | SYNCELOCK1 | | IO_MUX_SEL_1, BIT 28 | | |
|
|
||||||
| GPIO63 | GPIO_MDIO0 | | IO_MUX_SEL_1, BIT 4 | | |
|
|
||||||
|
|
||||||
## I2C
|
|
||||||
|
|
||||||
| I2C | Function |Type | (RTL8372) PIN# | (RTL8372N) PIN# |
|
|
||||||
| ---- | ---- | ---- | ---- | ---- |
|
|
||||||
| GPIO47 | SDA0 | I/OPU | | B1 | 142 |
|
|
||||||
| GPIO49 | SDA1 | I/OPU | | B2 | 144 |
|
|
||||||
| GPIO51 | SDA2 | I/OPU | | C2 | ??? |
|
|
||||||
| GPIO41 | SDA3 | I/OPU | | J20 | 98 |
|
|
||||||
| GPIO39 | SDA4 | I/OPU | | K20 | 95 |
|
|
||||||
| GPIO46 | SCL0 | I/OPU | | A2 | 138 |
|
|
||||||
| GPIO48 | SCL1 | I/OPU | | A1 | 140 |
|
|
||||||
| GPIO50 | SCL2 | I/OPU | | C1 | ??? |
|
|
||||||
| GPIO40? | SCL3 | OPU | | J20 | |
|
|
||||||
|
|
||||||
# Other funcitons
|
|
||||||
|
|
||||||
| Function | Type | (RTL8372) PIN# | (RTL8372N) PIN# |
|
|
||||||
| ---- | ---- | ---- | ---- |
|
|
||||||
| nRESET | | A6 | 131 |
|
|
||||||
| PTP_SYNC | | B10 | 130 |
|
|
||||||
| INT | OPU | B6 | 132 |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 64 KiB |
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## SPI-Flash Memory
|
## SPI-Flash Memory
|
||||||
|
|
||||||
SPI-Flash memory can be replaced with an other type. Because the chip is defect, like #69 & #70 or you have an unmanaged-switch with a small flash size, and want to convert it to a managed-variant to run `RTLPlayground` software on it. Currently `RTLPlayground`-firmware expects `8 MBit / 1 MiB`.
|
SPI-Flash memory can be replaced with an other type. Because the chip is defect, like #69 & #70 or you have an unmanaged-switch with a small flash size, and want to convert it to a managed-variant to run `RTLPlayground` software on it. Currently `RTLPlayground`-firmware expects `8 MBit / 2 MiB`.
|
||||||
|
|
||||||
### Size
|
### Size
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ Most use package are `SO8`-type may also called `SOIC8`-type. Which can also hav
|
|||||||
|
|
||||||
### Specification
|
### Specification
|
||||||
|
|
||||||
1. Size: At least `8 MBit / 1 MiB` (theoretic max. `128 MBit / 16 MiB`, but is not *tested*!)
|
1. Size: At least `16 MBit / 4 MiB` (theoretic max. `128 MBit / 32 MiB`, but is not *tested*!)
|
||||||
2. Speed: `62.5 MHz` or better.
|
2. Speed: `62.5 MHz` or better.
|
||||||
3. Support for `DUAL SPI operation`.
|
3. Support for `DUAL SPI operation`.
|
||||||
Device need support for command `BBh`, `Dual I/O Fast Read` or `Fast Read Dual I/O`.
|
Device need support for command `BBh`, `Dual I/O Fast Read` or `Fast Read Dual I/O`.
|
||||||
@@ -41,8 +41,6 @@ This list is incomplete.
|
|||||||
| Winbond | W25Q32FV |
|
| Winbond | W25Q32FV |
|
||||||
| Winbond | W25Q32JV |
|
| Winbond | W25Q32JV |
|
||||||
| Winbond | W25Q16JL |
|
| Winbond | W25Q16JL |
|
||||||
| Winbond | W25Q16DV |
|
|
||||||
| Winbond | W25Q80DV |
|
|
||||||
| Fundan | FM25Q16A |
|
| Fundan | FM25Q16A |
|
||||||
|
|
||||||
*NOTE*: Part numbers are incomplete. Part numbers may contain additional information such as package, temperature specifications, and even the number of devices on a reel. So always check the datasheet so that you have the right orderable partnumber.
|
*NOTE*: Part numbers are incomplete. Part numbers may contain additional information such as package, temperature specifications, and even the number of devices on a reel. So always check the datasheet so that you have the right orderable partnumber.
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ The following devices have been tested and are fully working:
|
|||||||
- Lianguo LG-SWTGW218AS (RTL8373 + RTL8224 PHY: 8x 2.5GBit + 1x 10GBit SFP+)
|
- Lianguo LG-SWTGW218AS (RTL8373 + RTL8224 PHY: 8x 2.5GBit + 1x 10GBit SFP+)
|
||||||
- No-Name ZX-SWTGW215AS, managed version of kp-9000-6hx-x, ordered on
|
- No-Name ZX-SWTGW215AS, managed version of kp-9000-6hx-x, ordered on
|
||||||
AliExpress as keepLINK 5+1 port managed
|
AliExpress as keepLINK 5+1 port managed
|
||||||
- TrendNet TEG-S562 (RTL8372: 4x 2.5GBit + 2x 10GBit SFP+)
|
|
||||||
- FNS-1200P (RTL8372: 4x 2.5GBit + 2x 10GBit SFP+)
|
|
||||||
|
|
||||||
Other device based on RTL8272/3 that may work are described here: [Up-N-Atoms 2.5 GBit RTL Switch hacking guide]
|
Other device based on RTL8272/3 that may work are described here: [Up-N-Atoms 2.5 GBit RTL Switch hacking guide]
|
||||||
(https://github.com/up-n-atom/SWTG118AS)
|
(https://github.com/up-n-atom/SWTG118AS)
|
||||||
|
|||||||
@@ -33,23 +33,15 @@ An entry is deleted by adding an invalid entry (00 instead of 0x02 in
|
|||||||
RTL837x_TBL_DATA_IN_A).
|
RTL837x_TBL_DATA_IN_A).
|
||||||
|
|
||||||
A port is assigned a PVID by setting the PVID-bits of the corresponding
|
A port is assigned a PVID by setting the PVID-bits of the corresponding
|
||||||
register of the port. 2 ports share a register. An odd port uses bits [23:12],
|
register of the port. 2 ports share a register. One port uses the higher
|
||||||
an even port uses bits [11:0]. The base register is
|
16 bits, the other (even ports) use the lower. The base register is
|
||||||
RTL837x_PVID_BASE_REG (0x4e1c) and the registers go to 0x4e2c so that also
|
RTL837x_PVID_BASE_REG (0x4e1c) and the registers go to 0x4e2c so that also
|
||||||
the CPU-Port may have a PVID.
|
the CPU-Port may have a PVID.
|
||||||
|
|
||||||
Register RTL837x_REG_INGRESS (0x4e10) allows to define the ingress rules of
|
Register RTL837x_REG_INGRESS (0x4e10) allows to define the iingress rules of
|
||||||
a port. 2 bits define a rule and bits 0-19 are being used. A value of 00
|
a port. 2 bits define a rule and bits 0-19 are being used. A value of 00
|
||||||
defines no filtering, 01 (0x01) allows only tagged packets, while 10 (0x02)
|
defines no filtering, 01 (0x01) allows only tagged packets, while 10 (0x02)
|
||||||
allows only untagged packets to enter a port.
|
allows only untagged packets to enter a port. The default PVID is 1.
|
||||||
|
|
||||||
Register RTL837X_VLAN_PORT_IGR_FLTR (0x4e18) enables or disables ingres VLAN
|
|
||||||
filtering, each bit corresponds to given port (port0 -> bit0, port9 -> bit9).
|
|
||||||
When enabled, incomming package's vlan tag is checked against VLAN membership
|
|
||||||
on given port. When package contains VLAN not in member list, package is dropped.
|
|
||||||
|
|
||||||
The default PVID on all port is 1, ingress VLAN filtering is enabled and all types of
|
|
||||||
frames are accepted on input on all ports.
|
|
||||||
|
|
||||||
By default, the ports transmit Ethernet frames with Realtek's proprietary
|
By default, the ports transmit Ethernet frames with Realtek's proprietary
|
||||||
tag format. By setting bit 6 (0x40) of the respective port configuration
|
tag format. By setting bit 6 (0x40) of the respective port configuration
|
||||||
@@ -59,9 +51,7 @@ registers 0x1238, 0x1338, ...
|
|||||||
The code currently provides the following functions:
|
The code currently provides the following functions:
|
||||||
```
|
```
|
||||||
void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked;
|
void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked;
|
||||||
uint16_t port_pvid_get(uint8_t port) __banked;
|
void vlan_create(uint16_t vlan, uint16_t members, uint16_t tagged) __banked;
|
||||||
void vlan_create(void) __banked; // reads from global vlan_settings
|
|
||||||
int8_t vlan_get(register uint16_t vlan) __banked; // returns data in sfr_data
|
|
||||||
void vlan_delete(uint16_t vlan) __banked;
|
void vlan_delete(uint16_t vlan) __banked;
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -76,26 +66,9 @@ vlan <VLAN-ID> p[t/u]...
|
|||||||
vlan <VLAN-ID> d
|
vlan <VLAN-ID> d
|
||||||
deletes the VLAN
|
deletes the VLAN
|
||||||
|
|
||||||
vlan show
|
|
||||||
Dumps the current ingress vlan settings.
|
|
||||||
|
|
||||||
vlan <VLAN-ID> mgmt
|
|
||||||
Restricts network access to the switch (web UI, syslog) to the given
|
|
||||||
VLAN. Use `vlan 0 mgmt` to disable the filter. Default is `vlan 1 mgmt`.
|
|
||||||
Warning: setting this to an unreachable VLAN locks out the web UI;
|
|
||||||
recovery requires serial console.
|
|
||||||
|
|
||||||
pvid <port> <VLAN-ID>
|
pvid <port> <VLAN-ID>
|
||||||
assigns PVID to a port. ports are numbered as on the casing
|
assigns PVID to a port. ports are numbered as on the casing
|
||||||
|
|
||||||
ingress [p]<t|u|a>...
|
ingress <port> [tagged|untagged|all]
|
||||||
Allows ingress packages on port `p` only when `t`agged, `u`ntagged or `a`ny.
|
Allows ingress only for the named packages at the given port
|
||||||
Multiple ports can be given at once as in vlan. When `p` is missing, all ports
|
|
||||||
are assigned the same mode. CPU port can not be changed.
|
|
||||||
|
|
||||||
Use `vlan show` to see current configuration.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
`ingress 1t 2a` -> Set port 1 as tagged input only, set port 2 accepting any frames.
|
|
||||||
`ingress a` -> Set all ports to accept both tagged and untagged frames (default behaviour).
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<script src="/main.js"></script>
|
|
||||||
<link rel="stylesheet" href="style.css">
|
|
||||||
<title>Ingress and Egress Bandwidth</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav id="sidebar"></nav>
|
|
||||||
<div style="margin-left:16%;padding:1px 16px;height:1000px;">
|
|
||||||
<div id="ports"></div>
|
|
||||||
<h1>Ingress and Egress Bandwidth</h1>
|
|
||||||
<table id="bwtable">
|
|
||||||
<tr> <th> </th> <th colspan="3"> Ingress </th> <th colspan="2">Egress</th> <th></th></tr>
|
|
||||||
<tr> <th>Port</th> <th>Limit</th> <th>Bandwidth [kBit/s]</th> <th>Flow Control</th> <th>Limit</th> <th>Bandwidth [kBit/s]</th> <th>Apply</th></tr>
|
|
||||||
</table>
|
|
||||||
<script src="/bandwidth.js"></script>
|
|
||||||
</div>
|
|
||||||
<script src="/navigation.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
const iLayout = '" type="number" maxlength="10" size="10" onfocus="inputFocus(';
|
|
||||||
function createBW() {
|
|
||||||
var tbl = document.getElementById('bwtable');
|
|
||||||
const limit = '<input type="checkbox" id="limit_port" onchange="exec();">'
|
|
||||||
if (tbl.rows.length <= 2 && numPorts) {
|
|
||||||
console.log("CREATING TABLE ", tbl.rows.length);
|
|
||||||
for (let i = 2; i < 2 + numPorts; i++) {
|
|
||||||
const tr = tbl.insertRow();
|
|
||||||
let td = tr.insertCell(); td.appendChild(document.createTextNode(`Port ${i-1}`));
|
|
||||||
td = tr.insertCell();
|
|
||||||
td.innerHTML = limit.replaceAll("limit_port", "ilimit_port_" + i).replace("exec()", "iClicked(" + i + ")");
|
|
||||||
td = tr.insertCell();
|
|
||||||
td.innerHTML = 'UNLIMITED';
|
|
||||||
td = tr.insertCell();
|
|
||||||
td.innerHTML = limit.replaceAll("limit_port", "fc_port_" + i).replace("exec()", "document.getElementById('bwapply_" + i + "').disabled=false;");
|
|
||||||
td = tr.insertCell();
|
|
||||||
td.innerHTML = limit.replaceAll("limit_port", "elimit_port_" + i).replace("exec()", "eClicked(" + i + ")");
|
|
||||||
td = tr.insertCell();
|
|
||||||
td.innerHTML = 'UNLIMITED';
|
|
||||||
var button = '<button type="button" id="bwapply_' + i + '" style="margin: 0 0 0 24px" onclick="applyBandwidth(' + i + ');">Apply</button>';
|
|
||||||
td = tr.insertCell();
|
|
||||||
td.innerHTML = button;
|
|
||||||
document.getElementById("bwapply_" + i).disabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function iClicked(i)
|
|
||||||
{
|
|
||||||
document.getElementById("bwapply_" + i).disabled=false;
|
|
||||||
var tbl = document.getElementById('bwtable');
|
|
||||||
var tr = tbl.rows[i];
|
|
||||||
if (!document.getElementById("ilimit_port_" + i).checked) {
|
|
||||||
tr.cells[2].innerHTML = "UNLIMITED";
|
|
||||||
document.getElementById("fc_port_" + i).disabled = true;
|
|
||||||
document.getElementById("fc_port_" + i).checked = true;
|
|
||||||
} else {
|
|
||||||
tr.cells[2].innerHTML = '<input id="ibw_' + i + iLayout + i + ')" value="0"/>';
|
|
||||||
document.getElementById("fc_port_" + i).disabled = false;
|
|
||||||
document.getElementById("fc_port_" + i).checked = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function eClicked(i)
|
|
||||||
{
|
|
||||||
document.getElementById("bwapply_" + i).disabled=false;
|
|
||||||
var tbl = document.getElementById('bwtable');
|
|
||||||
var tr = tbl.rows[i];
|
|
||||||
if (!document.getElementById("elimit_port_" + i).checked) {
|
|
||||||
tr.cells[5].innerHTML = "UNLIMITED";
|
|
||||||
} else {
|
|
||||||
tr.cells[5].innerHTML = '<input id="ebw_' + i + iLayout + i + ')" value="0"/>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function inputFocus(i)
|
|
||||||
{
|
|
||||||
document.getElementById("bwapply_" + i).disabled=false;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function doCMD(cmd)
|
|
||||||
{
|
|
||||||
console.log("Sending >" + cmd + "<");
|
|
||||||
try {
|
|
||||||
const response = await fetch('/cmd', {
|
|
||||||
method: 'POST',
|
|
||||||
body: cmd
|
|
||||||
});
|
|
||||||
console.log('Completed!', response);
|
|
||||||
} catch(err) {
|
|
||||||
console.error(`Error: ${err}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function applyBandwidth(i) {
|
|
||||||
var tbl = document.getElementById('bwtable');
|
|
||||||
var tr = tbl.rows[i];
|
|
||||||
var cmd = "bw in " + (i-1) + " off";
|
|
||||||
if (document.getElementById("ilimit_port_" + i).checked)
|
|
||||||
cmd = 'bw in ' + (i-1) + ' ' + parseInt(document.getElementById("ibw_" + i).value).toString(16).padStart(4, "0");;
|
|
||||||
doCMD(cmd);
|
|
||||||
if (document.getElementById("ilimit_port_" + i).checked) {
|
|
||||||
if (!document.getElementById("fc_port_" + i).checked)
|
|
||||||
cmd = "bw in " + (i-1) + " drop";
|
|
||||||
doCMD(cmd);
|
|
||||||
}
|
|
||||||
var cmd = "bw out " + (i-1) + " off";
|
|
||||||
if (document.getElementById("elimit_port_" + i).checked)
|
|
||||||
cmd = 'bw out ' + (i-1) + ' ' + parseInt(document.getElementById("ebw_" + i).value).toString(16).padStart(4, "0");;
|
|
||||||
doCMD(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBW() {
|
|
||||||
var xhttp = new XMLHttpRequest();
|
|
||||||
xhttp.onreadystatechange = function() {
|
|
||||||
console.log("IN getBW ");
|
|
||||||
if (this.readyState == 4 && this.status == 200) {
|
|
||||||
const s = JSON.parse(xhttp.responseText);
|
|
||||||
console.log("BW: ", JSON.stringify(s));
|
|
||||||
var tbl = document.getElementById('bwtable');
|
|
||||||
if (tbl.rows.length > 2 && numPorts) {
|
|
||||||
for (let i = 2; i < 2 + numPorts; i++) {
|
|
||||||
p = s[i-2];
|
|
||||||
let n = p.portNum;
|
|
||||||
let tr = tbl.rows[n+1];
|
|
||||||
if (!document.getElementById("bwapply_" + (n+1)).disabled)
|
|
||||||
continue;
|
|
||||||
console.log("Table Update row: " + i + " portNum is " + n + ", pState is " + pState[i-2] + ", row number is " + (n+1));
|
|
||||||
let iBW = parseInt(p.iBW,16) * 16; let eBW = parseInt(p.eBW,16) * 16;
|
|
||||||
document.getElementById("ilimit_port_" + (n+1)).checked = p.iLimited;
|
|
||||||
document.getElementById("elimit_port_" + (n+1)).checked = p.eLimited;
|
|
||||||
if (!p.iLimited) {
|
|
||||||
tr.cells[2].innerHTML = "UNLIMITED";
|
|
||||||
} else {
|
|
||||||
tr.cells[2].innerHTML = '<input id="ibw_' + (n+1) + iLayout + (n+1) + ')" value="' + iBW +'"/>';
|
|
||||||
}
|
|
||||||
if (!p.eLimited) {
|
|
||||||
tr.cells[5].innerHTML = "UNLIMITED";
|
|
||||||
} else {
|
|
||||||
tr.cells[5].innerHTML = '<input id="ebw_' + (n+1) + iLayout + (n+1) + ')" value="' + eBW +'"/>';
|
|
||||||
}
|
|
||||||
document.getElementById("fc_port_" + (n+1)).checked = p.iFC==1?true:false;
|
|
||||||
document.getElementById("fc_port_" + (n+1)).disabled = p.iLimited==1?false:true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhttp.open("GET", "/bandwidth.json", true);
|
|
||||||
xhttp.timeout = 1500; sendXHTTP(xhttp);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
|
||||||
update( () => {
|
|
||||||
createBW();
|
|
||||||
getBW();
|
|
||||||
const interval = setInterval(update, 2000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../config.txt
|
||||||
@@ -1,81 +1,32 @@
|
|||||||
var configInterval = Number();
|
var configInterval = Number();
|
||||||
var configuration = [];
|
var configuration = [];
|
||||||
const conf_cmds = [
|
const conf_cmds = [
|
||||||
/^ip\s+(\d{1,3}\.){3}\d{1,3}$/,
|
/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}/,
|
||||||
/^ip\s+dhcp$/,
|
/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)?)+/
|
||||||
/^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 = [
|
const conf_overwrite = [
|
||||||
/^ip\b/,
|
/ip/, /gw/, /netmask/, /eee\s+\w+/, /eee(\s+\w)/, /mirror/, /vlan\s+(\d{1,4})/
|
||||||
/^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){
|
function parseConf(s){
|
||||||
var a = s.split(/\r\n|\n/);
|
var a = s.split(/\r\n|\n/);
|
||||||
for (var l = 0; l < a.length; l++) {
|
for (var l = 0; l < a.length; l++) {
|
||||||
var line = a[l].trim().replace(/\s+/g, ' ');
|
if (!a[l].length || a[l] == "\n" || a[l] == "\r\n")
|
||||||
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;
|
continue;
|
||||||
}
|
console.log(l + ' --> ' + a[l]);
|
||||||
console.log(l + ' --> ' + line);
|
|
||||||
var ignore = true;
|
var ignore = true;
|
||||||
for (const x of conf_cmds)
|
for (const x of conf_cmds)
|
||||||
if (x.test(line)) { ignore = false; break; }
|
if (x.test(a[l])) ignore = false;
|
||||||
if (ignore) continue;
|
if (ignore) continue;
|
||||||
for (const x of conf_overwrite) {
|
for (const x of conf_overwrite) {
|
||||||
if (x.test(line)) {
|
if (x.test(a[l])) {
|
||||||
let m = line.match(x);
|
console.log("Match ", x, " to ", a[l]);
|
||||||
let matchStr = m[0];
|
m = a[l].match(x);
|
||||||
configuration = configuration.filter(item =>
|
console.log("Starts with ", m[0]);
|
||||||
!(item === matchStr || item.startsWith(matchStr + " ")));
|
configuration = configuration.filter(item => !(item.startsWith(m[0])));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
configuration.push(line);
|
configuration.push(a[l]);
|
||||||
}
|
}
|
||||||
console.log("Configuration now:");
|
console.log("Configuration now:");
|
||||||
for (const x of configuration) { console.log(x); }
|
for (const x of configuration) { console.log(x); }
|
||||||
@@ -98,8 +49,7 @@ async function fetchCmdLog() {
|
|||||||
console.log("CMD-Log: ", response);
|
console.log("CMD-Log: ", response);
|
||||||
const t = await response.text();
|
const t = await response.text();
|
||||||
return t;
|
return t;
|
||||||
} catch(err) {
|
} catch(error) {
|
||||||
console.error("Error: ", err);
|
console.error("Error: ", err);
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
function createEEE() {
|
function createEEE() {
|
||||||
var tbl = document.getElementById('eeetable');
|
var tbl = document.getElementById('eeetable');
|
||||||
if (tbl.rows.length <= 2 && numPorts) {
|
if (tbl.rows.length <= 2 && numPorts) {
|
||||||
|
clearInterval(createEEEInterval);
|
||||||
console.log("CREATING TABLE ", tbl.rows.length);
|
console.log("CREATING TABLE ", tbl.rows.length);
|
||||||
for (let i = 2; i < 2 + numPorts; i++) {
|
for (let i = 2; i < 2 + numPorts; i++) {
|
||||||
console.log("Table row: " + i + "pState: " + pState[i-2]);
|
console.log("Table row: " + i + "pState: " + pState[i-2]);
|
||||||
@@ -39,14 +40,11 @@ function getEEE() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhttp.open("GET", "/eee.json", true);
|
xhttp.open("GET", "/eee.json", true);
|
||||||
xhttp.timeout = 1500; sendXHTTP(xhttp);
|
xhttp.timeout = 1500; xhttp.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
window.addEventListener("load", function() {
|
||||||
update( () => {
|
|
||||||
createEEE();
|
|
||||||
getEEE();
|
getEEE();
|
||||||
const interval = setInterval(update, 2000);
|
|
||||||
const iCount = setInterval(getEEE, 2000);
|
const iCount = setInterval(getEEE, 2000);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
const createEEEInterval = setInterval(createEEE, 1000);
|
||||||
|
|||||||
@@ -2,13 +2,6 @@
|
|||||||
<html>
|
<html>
|
||||||
<script src="/main.js"></script>
|
<script src="/main.js"></script>
|
||||||
<script src="/main_info.js"></script>
|
<script src="/main_info.js"></script>
|
||||||
<script>
|
|
||||||
window.addEventListener("load", function() {
|
|
||||||
update( () => {
|
|
||||||
const interval = setInterval(update, 2000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<title>FreeSwitchOS Main Page</title>
|
<title>FreeSwitchOS Main Page</title>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -130,14 +130,10 @@ function getL2() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhttp.open("GET", "/l2.json?idx=" + l2CurrentEntry, true);
|
xhttp.open("GET", "/l2.json?idx=" + l2CurrentEntry, true);
|
||||||
xhttp.timeout = 1500; sendXHTTP(xhttp);
|
xhttp.timeout = 1500; xhttp.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
window.addEventListener("load", function() {
|
||||||
update( () => {
|
|
||||||
getL2();
|
|
||||||
const interval = setInterval(update, 2000);
|
|
||||||
l2GetInterval = setInterval(getL2, 1000);
|
l2GetInterval = setInterval(getL2, 1000);
|
||||||
});;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ var lagInterval = Number();
|
|||||||
function lagForm() {
|
function lagForm() {
|
||||||
if (!numPorts)
|
if (!numPorts)
|
||||||
return;
|
return;
|
||||||
|
clearInterval(lagInterval);
|
||||||
for (let j=0; j < 4; j++) {
|
for (let j=0; j < 4; j++) {
|
||||||
var lag = "mLAG" + j
|
var lag = "mLAG" + j
|
||||||
console.log("Adding LAG " + lag)
|
console.log("Adding LAG " + lag)
|
||||||
@@ -34,6 +35,9 @@ function setL(p, c){
|
|||||||
console.log("LAG setting: ", p, " to ", c);
|
console.log("LAG setting: ", p, " to ", c);
|
||||||
document.getElementById(p).checked=c;
|
document.getElementById(p).checked=c;
|
||||||
}
|
}
|
||||||
|
window.addEventListener("load", function() {
|
||||||
|
lagInterval = setInterval(lagForm, 200);
|
||||||
|
});
|
||||||
|
|
||||||
function fetchLag() {
|
function fetchLag() {
|
||||||
var xhttp = new XMLHttpRequest();
|
var xhttp = new XMLHttpRequest();
|
||||||
@@ -54,7 +58,7 @@ function fetchLag() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhttp.open("GET", `/lag.json`, true);
|
xhttp.open("GET", `/lag.json`, true);
|
||||||
sendXHTTP(xhttp);
|
xhttp.send();
|
||||||
}
|
}
|
||||||
async function lagSub(l) {
|
async function lagSub(l) {
|
||||||
var cmd = "lag " + l;
|
var cmd = "lag " + l;
|
||||||
@@ -72,10 +76,3 @@ async function lagSub(l) {
|
|||||||
console.error(`Error: ${err}`);
|
console.error(`Error: ${err}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
|
||||||
update( () => {
|
|
||||||
lagForm();
|
|
||||||
const interval = setInterval(update, 2000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -2,16 +2,13 @@ var txG = new BigInt64Array(10);
|
|||||||
var txB = new BigInt64Array(10);
|
var txB = new BigInt64Array(10);
|
||||||
var rxG = new BigInt64Array(10);
|
var rxG = new BigInt64Array(10);
|
||||||
var rxB = new BigInt64Array(10);
|
var rxB = new BigInt64Array(10);
|
||||||
const linkS = ["Disabled", "Down", "10M", "100M", "1000M", "500M", "10G", "2.5G", "5G"];
|
const linkS = ["Disabled", "No Link", "100M", "1000M", "500M", "10G", "2.5G", "5G"];
|
||||||
var pState = new Int8Array(10);
|
var pState = new Int8Array(10);
|
||||||
var pIsSFP = new Int8Array(10);
|
var pIsSFP = new Int8Array(10);
|
||||||
var pAdvertised = new Int8Array(10);
|
var pAdvertised = new Int8Array(10);
|
||||||
var numPorts = 0;
|
var numPorts = 0;
|
||||||
var logToPhysPort = new Int8Array(10);
|
var logToPhysPort = new Int8Array(10);
|
||||||
var physToLogPort = new Int8Array(10);
|
var physToLogPort = new Int8Array(10);
|
||||||
var portNames = new Array(10);
|
|
||||||
var currentRequests = [];
|
|
||||||
var currentCallback;
|
|
||||||
function drawPorts() {
|
function drawPorts() {
|
||||||
var f = document.getElementById('ports');
|
var f = document.getElementById('ports');
|
||||||
console.log("DRAWING PORTS: ", numPorts);
|
console.log("DRAWING PORTS: ", numPorts);
|
||||||
@@ -41,86 +38,9 @@ function drawPorts() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseUint16(val) {
|
function update() {
|
||||||
return parseInt(val, 16) & 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseInt16(val) {
|
|
||||||
let valInt = parseInt(val, 16);
|
|
||||||
let num = valInt & 0x7fff;
|
|
||||||
if (valInt & 0x8000) {
|
|
||||||
return num - 0x8000;
|
|
||||||
}
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyCalibrationSlopeOffset(val, cal) {
|
|
||||||
if (typeof cal !== 'string') {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
if (cal.startsWith("0x")) {
|
|
||||||
cal = cal.substring(2);
|
|
||||||
}
|
|
||||||
if (cal.length != 8) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
let slope = parseUint16(cal.substring(0, 4)) / 256;
|
|
||||||
let offset = parseInt16(cal.substring(4, 8));
|
|
||||||
return slope * val + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyRxPowerCalibration(val, cal) {
|
|
||||||
if (typeof cal !== 'string') {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
if (cal.startsWith("0x")) {
|
|
||||||
cal = cal.substring(2);
|
|
||||||
}
|
|
||||||
if (cal.length != 40) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
let bytes = cal.match(/.{1,2}/g).map(function (x) { return parseInt(x, 16); });
|
|
||||||
let view = new DataView(new Uint8Array(bytes).buffer);
|
|
||||||
return view.getFloat32(0) * Math.pow(val, 4)
|
|
||||||
+ view.getFloat32(4) * Math.pow(val, 3)
|
|
||||||
+ view.getFloat32(8) * Math.pow(val, 2)
|
|
||||||
+ view.getFloat32(12) * val
|
|
||||||
+ view.getFloat32(16);
|
|
||||||
}
|
|
||||||
|
|
||||||
function decodeSfpTemp(val, cal) {
|
|
||||||
let temp = parseInt16(val);
|
|
||||||
return applyCalibrationSlopeOffset(temp, cal) / 256;
|
|
||||||
}
|
|
||||||
|
|
||||||
function decodeSfpVcc(val, cal) {
|
|
||||||
let vcc = parseUint16(val);
|
|
||||||
return applyCalibrationSlopeOffset(vcc, cal) / 10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
function decodeSfpTxBias(val, cal) {
|
|
||||||
let bias = parseUint16(val);
|
|
||||||
return applyCalibrationSlopeOffset(bias, cal) / 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
function decodeSfpTxPower(val, cal) {
|
|
||||||
let txPower = parseUint16(val);
|
|
||||||
return applyCalibrationSlopeOffset(txPower, cal) / 10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
function decodeSfpRxPower(val, cal) {
|
|
||||||
let rxPower = parseUint16(val);
|
|
||||||
return applyRxPowerCalibration(rxPower, cal) / 10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
function convertPowerTodBm(val) {
|
|
||||||
return 10 * Math.log10(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
function update(callback) {
|
|
||||||
var xhttp = new XMLHttpRequest();
|
var xhttp = new XMLHttpRequest();
|
||||||
xhttp.onreadystatechange = function() {
|
xhttp.onreadystatechange = function() {
|
||||||
console.log("IN UPDATE ");
|
|
||||||
if (this.readyState == 4 && this.status == 401)
|
if (this.readyState == 4 && this.status == 401)
|
||||||
document.location = "/login.html"
|
document.location = "/login.html"
|
||||||
if (this.readyState == 4 && this.status == 200) {
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
@@ -137,7 +57,6 @@ function update(callback) {
|
|||||||
let n = p.portNum;
|
let n = p.portNum;
|
||||||
logToPhysPort[p.logPort] = n;
|
logToPhysPort[p.logPort] = n;
|
||||||
physToLogPort[n-1] = p.logPort;
|
physToLogPort[n-1] = p.logPort;
|
||||||
portNames[p.logPort] = p.name;
|
|
||||||
let pid = "port" + n;
|
let pid = "port" + n;
|
||||||
let ttid = "tt_" + n;
|
let ttid = "tt_" + n;
|
||||||
n--;
|
n--;
|
||||||
@@ -148,25 +67,16 @@ function update(callback) {
|
|||||||
continue;
|
continue;
|
||||||
var bgs = psvg.contentDocument.getElementsByClassName("bg");
|
var bgs = psvg.contentDocument.getElementsByClassName("bg");
|
||||||
var leds = psvg.contentDocument.getElementsByClassName("led");
|
var leds = psvg.contentDocument.getElementsByClassName("led");
|
||||||
if (leds[0] == null || leds[0].style == null)
|
|
||||||
continue;
|
|
||||||
const portName = p.name || portNames[p.logPort] || '';
|
|
||||||
var iHTML = "<table border=\"0\" class=\"tt_table\">";
|
|
||||||
if (portName) iHTML += "<tr><td align=\"left\">Name</td><td>:</td><td>" + portName + "</td></tr>";
|
|
||||||
if (p.enabled == 0) {
|
if (p.enabled == 0) {
|
||||||
pState[n] = -1;
|
pState[n] = -1;
|
||||||
bgs[0].style.fill = "red";
|
bgs[0].style.fill = "red";
|
||||||
leds[0].style.fill = "black"; leds[1].style.fill = "black";
|
leds[0].style.fill = "black"; leds[1].style.fill = "black";
|
||||||
psvg.style.opacity = 0.4;
|
psvg.style.opacity = 0.4;
|
||||||
iHTML += "<tr><td align=\"left\">Status</td><td>:</td><td>Not enabled.</td></tr>";
|
tt.innerHTML = "Not enabled.";
|
||||||
iHTML += "</table>";
|
|
||||||
tt.innerHTML = iHTML;
|
|
||||||
} else {
|
} else {
|
||||||
psvg.style.opacity = 1.0;
|
psvg.style.opacity = 1.0;
|
||||||
pState[n] = p.link;
|
pState[n] = p.link;
|
||||||
if (p.link == 5 || p.link == 7) {
|
if (p.link == 4 || p.link == 5 || p.link == 6) {
|
||||||
leds[0].style.fill = "green"; leds[1].style.fill = "blue";
|
|
||||||
} else if (p.link == 4 || p.link == 6) {
|
|
||||||
leds[0].style.fill = "green"; leds[1].style.fill = "orange";
|
leds[0].style.fill = "green"; leds[1].style.fill = "orange";
|
||||||
} else if (p.link == 1 || p.link == 2 || p.link == 3) {
|
} else if (p.link == 1 || p.link == 2 || p.link == 3) {
|
||||||
leds[0].style.fill = "green"; leds[1].style.fill = "green";
|
leds[0].style.fill = "green"; leds[1].style.fill = "green";
|
||||||
@@ -174,113 +84,34 @@ function update(callback) {
|
|||||||
leds[0].style.fill = "black"; leds[1].style.fill = "black";
|
leds[0].style.fill = "black"; leds[1].style.fill = "black";
|
||||||
psvg.style.opacity = 0.4
|
psvg.style.opacity = 0.4
|
||||||
}
|
}
|
||||||
|
var iHTML = "<table border=\"0\" class=\"tt_table\">";
|
||||||
iHTML += "<tr><td align=\"left\">Link speed</td><td>:</td><td>" + linkS[p.link + 1] + "</td></tr>";
|
iHTML += "<tr><td align=\"left\">Link speed</td><td>:</td><td>" + linkS[p.link + 1] + "</td></tr>";
|
||||||
if (p.isSFP) {
|
if (p.isSFP) {
|
||||||
pAdvertised[n] = 0;
|
pAdvertised[n] = 0;
|
||||||
const hasExtendedStatus = p.sfp_options & 0x40;
|
|
||||||
iHTML += "<tr><td>Vendor</td><td>:</td><td>" + p.sfp_vendor + "</td></tr>";
|
iHTML += "<tr><td>Vendor</td><td>:</td><td>" + p.sfp_vendor + "</td></tr>";
|
||||||
iHTML += "<tr><td>Model</td><td>:</td><td>" + p.sfp_model + "</td></tr>";
|
iHTML += "<tr><td>Model</td><td>:</td><td>" + p.sfp_model + "</td></tr>";
|
||||||
iHTML += "<tr><td>Serial</td><td>:</td><td>" + p.sfp_serial + "</td></tr>";
|
iHTML += "<tr><td>Serial</td><td>:</td><td>" + p.sfp_serial + "</td></tr>";
|
||||||
if (hasExtendedStatus) {
|
if (p.sfp_options & 0x40) {
|
||||||
let txPower = decodeSfpTxPower(p.sfp_txpower, p.sfp_txpower_cal);
|
iHTML += "<tr><td>Temp</td><td>:</td><td>" + (Number(p.sfp_temp) >> 8) + "." + ((Number(p.sfp_temp) & 0xff)/256.0 * 100).toFixed(0) + " ℃</td></tr>";
|
||||||
let txPowerdBm = convertPowerTodBm(txPower);
|
iHTML += "<tr><td>Vcc</td><td>:</td><td>" + (Number(p.sfp_vcc) / 10000.0).toFixed(2) + " V</td></tr>";
|
||||||
let rxPower = decodeSfpRxPower(p.sfp_rxpower, p.sfp_rxpower_cal);
|
iHTML += "<tr><td>TX-Bias</td><td>:</td><td>" + (Number(p.sfp_txbias) / 500.0).toFixed(1) + " mA</td></tr>";
|
||||||
let rxPowerdBm = convertPowerTodBm(rxPower);
|
iHTML += "<tr><td>TX-Power</td><td>:</td><td>" + (Number(p.sfp_txpower) / 10.0).toFixed(0) + " mW</td></tr>";
|
||||||
iHTML += "<tr><td>Temp</td><td>:</td><td>" + decodeSfpTemp(p.sfp_temp, p.sfp_temp_cal).toFixed(2) + " ℃</td></tr>";
|
iHTML += "<tr><td>RX-Power</td><td>:</td><td>" + (Number(p.sfp_rxpower) / 10.0).toFixed(0) + " mW</td></tr>";
|
||||||
iHTML += "<tr><td>Vcc</td><td>:</td><td>" + decodeSfpVcc(p.sfp_vcc, p.sfp_vcc_cal).toFixed(2) + " V</td></tr>";
|
|
||||||
iHTML += "<tr><td>TX-Fault</td><td>:</td><td>" + (Boolean(Number(p.sfp_state) & 0x4)) + "</td></tr>";
|
|
||||||
iHTML += "<tr><td>TX-Disabled</td><td>:</td><td>" + (Boolean(Number(p.sfp_state) & 0x80)) + "</td></tr>";
|
|
||||||
iHTML += "<tr><td>TX-Bias</td><td>:</td><td>" + decodeSfpTxBias(p.sfp_txbias, p.sfp_txbias_cal).toFixed(1) + " mA</td></tr>";
|
|
||||||
iHTML += "<tr><td>TX-Power</td><td>:</td><td>" + txPower.toFixed(3) + " mW / " + txPowerdBm.toFixed(2) + " dBm</td></tr>";
|
|
||||||
iHTML += "<tr><td>RX-Power</td><td>:</td><td>" + rxPower.toFixed(3) + " mW / " + rxPowerdBm.toFixed(2) + " dBm</td></tr>";
|
|
||||||
}
|
|
||||||
// Not all devices & modules have LOS pin...
|
|
||||||
const rx_los_pin = p.sfp_los !== null ? Boolean(Number(p.sfp_los)) : null;
|
|
||||||
const rx_los_module = hasExtendedStatus ? Boolean(Number(p.sfp_state) & 0x2) : null;
|
|
||||||
if (rx_los_module !== null || rx_los_pin !== null) {
|
|
||||||
iHTML += `<tr><td>RX-LOS</td><td>:</td><td>${rxLosHTML(rx_los_pin, rx_los_module)}</td></tr>`;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pAdvertised[n] = parseInt(p.adv, 2);
|
pAdvertised[n] = parseInt(p.adv, 2);
|
||||||
};
|
}
|
||||||
iHTML += "</table>";
|
iHTML += "</table>";
|
||||||
tt.innerHTML = iHTML;
|
tt.innerHTML = iHTML;
|
||||||
}}
|
}
|
||||||
if (callback)
|
}
|
||||||
callback();
|
}
|
||||||
}};
|
};
|
||||||
xhttp.open("GET", "/status.json", true);
|
xhttp.open("GET", "/status.json", true);
|
||||||
xhttp.timeout = 5000;
|
xhttp.timeout = 5000; xhttp.send();
|
||||||
sendXHTTP(xhttp);
|
|
||||||
}
|
|
||||||
|
|
||||||
function rxLosHTML(pinStatus, moduleStatus) {
|
|
||||||
if (moduleStatus !== null && pinStatus !== null && moduleStatus !== pinStatus) {
|
|
||||||
return `pin=${pinStatus}<br/>mod=${moduleStatus}<br/>❗❗❗❗`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns first non null value
|
|
||||||
return moduleStatus ?? pinStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
function callbackXHTTP()
|
|
||||||
{
|
|
||||||
x = currentRequests.shift();
|
|
||||||
x.onreadystatechange = currentCallback;
|
|
||||||
x.onreadystatechange();
|
|
||||||
if (currentRequests.length === 0)
|
|
||||||
return;
|
|
||||||
x = currentRequests[0];
|
|
||||||
currentCallback = x.onreadystatechange;
|
|
||||||
x.onreadystatechange = callbackXHTTP;
|
|
||||||
var retries = 10;
|
|
||||||
while (retries) {
|
|
||||||
try {
|
|
||||||
setTimeout(() => {
|
|
||||||
x.send();
|
|
||||||
console.log("B1");
|
|
||||||
}, 20);
|
|
||||||
} catch (error) {
|
|
||||||
retries--;
|
|
||||||
setTimeout(() => {
|
|
||||||
console.log(`Retry ${retries}/${maxRetries} failed: ${error.message}`);
|
|
||||||
}, 200);
|
|
||||||
if (retries < 1) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log("B2");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendXHTTP(x)
|
|
||||||
{
|
|
||||||
console.log("sendXHTTP ", x);
|
|
||||||
if (currentRequests.length === 0) {
|
|
||||||
currentRequests.push(x);
|
|
||||||
currentCallback = x.onreadystatechange;
|
|
||||||
x.onreadystatechange = callbackXHTTP;
|
|
||||||
var retries = 10;
|
|
||||||
while (retries) {
|
|
||||||
try {
|
|
||||||
x.send();
|
|
||||||
console.log("A1");
|
|
||||||
} catch (error) {
|
|
||||||
retries--;
|
|
||||||
setTimeout(() => {
|
|
||||||
console.log(`Retry ${retries}/${maxRetries} failed: ${error.message}`);
|
|
||||||
}, 200);
|
|
||||||
if (retries < 1) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log("A2");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log("A3");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
currentRequests.push(x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.addEventListener("load", function() {
|
||||||
|
update();
|
||||||
|
const interval = setInterval(update, 2000);
|
||||||
|
});
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ const mirrors = ["mPortsTX", "mPortsRX"];
|
|||||||
function mirrorForm() {
|
function mirrorForm() {
|
||||||
if (!numPorts)
|
if (!numPorts)
|
||||||
return;
|
return;
|
||||||
|
clearInterval(mirrorInterval);
|
||||||
for (let j=0; j < mirrors.length; j++) {
|
for (let j=0; j < mirrors.length; j++) {
|
||||||
console.log("Adding Mirror " + j)
|
console.log("Adding Mirror " + j)
|
||||||
var m = document.getElementById(mirrors[j]);
|
var m = document.getElementById(mirrors[j]);
|
||||||
@@ -33,6 +34,9 @@ function mirrorForm() {
|
|||||||
function setM(p, c){
|
function setM(p, c){
|
||||||
document.getElementById(p).checked=c;
|
document.getElementById(p).checked=c;
|
||||||
}
|
}
|
||||||
|
window.addEventListener("load", function() {
|
||||||
|
mirrorInterval = setInterval(mirrorForm, 200);
|
||||||
|
});
|
||||||
|
|
||||||
function fetchMirror() {
|
function fetchMirror() {
|
||||||
var xhttp = new XMLHttpRequest();
|
var xhttp = new XMLHttpRequest();
|
||||||
@@ -47,18 +51,11 @@ function fetchMirror() {
|
|||||||
for (let i = 1; i <= numPorts; i++) {
|
for (let i = 1; i <= numPorts; i++) {
|
||||||
let p = i - 1;
|
let p = i - 1;
|
||||||
if (numPorts < 9)
|
if (numPorts < 9)
|
||||||
p = physToLogPort[p];
|
p = physToLogPort[p];members & (1<<p)
|
||||||
setM("mPortsTX"+i, m_tx&(1<<p)); setM("mPortsRX"+i, m_rx&(1<<p));
|
setM("mPortsTX"+i, m_tx&(1<<p)); setM("mPortsRX"+i, m_rx&(1<<p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhttp.open("GET", `/mirror.json`, true);
|
xhttp.open("GET", `/mirror.json`, true);
|
||||||
sendXHTTP(xhttp);
|
xhttp.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
|
||||||
update( () => {
|
|
||||||
mirrorForm();
|
|
||||||
const interval = setInterval(update, 2000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -7,6 +7,5 @@ document.getElementById('sidebar').innerHTML =
|
|||||||
+ "<li><a href='mirror.html'>Mirroring</a></li>"
|
+ "<li><a href='mirror.html'>Mirroring</a></li>"
|
||||||
+ "<li><a href='lag.html'>Link Aggregation</a></li>"
|
+ "<li><a href='lag.html'>Link Aggregation</a></li>"
|
||||||
+ "<li><a href='eee.html'>EEE</a></li>"
|
+ "<li><a href='eee.html'>EEE</a></li>"
|
||||||
+ "<li><a href='bandwidth.html'>Bandwidth Limits</a></li>"
|
|
||||||
+ "<li><a href='system.html'>System Settings</a></li>"
|
+ "<li><a href='system.html'>System Settings</a></li>"
|
||||||
+ "<li><a href='update.html'>Firmware Update</a></li></ul>";
|
+ "<li><a href='update.html'>Firmware Update</a></li></ul>";
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<h1>Port Configuration</h1>
|
<h1>Port Configuration</h1>
|
||||||
<form id="vform" action="/vlan.html">
|
<form id="vform" action="/vlan.html">
|
||||||
<table id="speedtable">
|
<table id="speedtable">
|
||||||
<tr> <th>Port</th> <th>Name</th> <th>Current Link Speed</th><th>Set Speed</th><th>Disabled</th><th>Apply</th></tr>
|
<tr> <th>Port</th> <th>Current Link Speed</th><th>Set Speed</th><th>Disabled</th><th>Apply</th></tr>
|
||||||
</table>
|
</table>
|
||||||
<h2 style="margin-top:3em">Configure Maximum Frame Size (MTU) forwarded at Port</h2>
|
<h2 style="margin-top:3em">Configure Maximum Frame Size (MTU) forwarded at Port</h2>
|
||||||
<table id="mtutable" style="margin-top:1em">
|
<table id="mtutable" style="margin-top:1em">
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ var clicked = new Int8Array(10);
|
|||||||
function createPortTable() {
|
function createPortTable() {
|
||||||
var tbl = document.getElementById('speedtable');
|
var tbl = document.getElementById('speedtable');
|
||||||
if (tbl.rows.length <= 2 && numPorts) {
|
if (tbl.rows.length <= 2 && numPorts) {
|
||||||
|
clearInterval(pTableInterval);
|
||||||
const sSelect = '<select name="speed_sel" id="speed_sel">'
|
const sSelect = '<select name="speed_sel" id="speed_sel">'
|
||||||
+ '<option value="auto">Auto</option>'
|
+ '<option value="auto">Auto</option>'
|
||||||
+ '<option value="2g5">2500MBit/Full</option>'
|
+ '<option value="2g5">2500MBit/Full</option>'
|
||||||
@@ -19,8 +20,6 @@ function createPortTable() {
|
|||||||
console.log("Table row: " + i + "pState: " + pState[i-2]);
|
console.log("Table row: " + i + "pState: " + pState[i-2]);
|
||||||
const tr = tbl.insertRow();
|
const tr = tbl.insertRow();
|
||||||
let td = tr.insertCell(); td.appendChild(document.createTextNode(`Port ${i}`));
|
let td = tr.insertCell(); td.appendChild(document.createTextNode(`Port ${i}`));
|
||||||
let portName = portNames[physToLogPort[i-1]] || '';
|
|
||||||
td = tr.insertCell(); td.appendChild(document.createTextNode(portName));
|
|
||||||
td = tr.insertCell(); td.innerHTML = linkS[pState[i] + 1];
|
td = tr.insertCell(); td.innerHTML = linkS[pState[i] + 1];
|
||||||
td = tr.insertCell(); td.innerHTML = sSelect.replaceAll("speed_sel", "speed_sel_" + i);
|
td = tr.insertCell(); td.innerHTML = sSelect.replaceAll("speed_sel", "speed_sel_" + i);
|
||||||
td = tr.insertCell(); td.innerHTML = dSwitch.replaceAll("disable_port", "disable_port_" + i)
|
td = tr.insertCell(); td.innerHTML = dSwitch.replaceAll("disable_port", "disable_port_" + i)
|
||||||
@@ -68,7 +67,7 @@ function updatePortTable() {
|
|||||||
for (let i = 1; i <= numPorts ; i++) {
|
for (let i = 1; i <= numPorts ; i++) {
|
||||||
if (pIsSFP[i-1])
|
if (pIsSFP[i-1])
|
||||||
continue;
|
continue;
|
||||||
tbl.rows[i].cells[2].innerHTML = `${linkS[pState[i-1]+1]}`;
|
tbl.rows[i].cells[1].innerHTML = `${linkS[pState[i-1]+1]}`;
|
||||||
if (!clicked[i] && pState[i - 1] < 0) {
|
if (!clicked[i] && pState[i - 1] < 0) {
|
||||||
document.getElementById('speed_sel_' + i).disabled = true;
|
document.getElementById('speed_sel_' + i).disabled = true;
|
||||||
document.getElementById('disable_port_' + i).checked = true;
|
document.getElementById('disable_port_' + i).checked = true;
|
||||||
@@ -131,19 +130,17 @@ function getMTUs() {
|
|||||||
if (!mtu)
|
if (!mtu)
|
||||||
continue;
|
continue;
|
||||||
mtu.value = mtus[n];
|
mtu.value = mtus[n];
|
||||||
|
clearInterval(pMTUInterval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhttp.open("GET", "/mtu.json", true);
|
xhttp.open("GET", "/mtu.json", true);
|
||||||
xhttp.timeout = 1500; sendXHTTP(xhttp);
|
xhttp.timeout = 1500; xhttp.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
window.addEventListener("load", function() {
|
||||||
update( () => {
|
|
||||||
createPortTable();
|
|
||||||
updatePortTable();
|
|
||||||
getMTUs()
|
|
||||||
const interval = setInterval(update, 2000);
|
|
||||||
const updatePortTableInterval = setInterval(updatePortTable, 1000);
|
const updatePortTableInterval = setInterval(updatePortTable, 1000);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const pTableInterval = setInterval(createPortTable, 1000);
|
||||||
|
const pMTUInterval = setInterval(getMTUs, 1200);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<h1>Port Statistics</h1>
|
<h1>Port Statistics</h1>
|
||||||
<table id="statstable">
|
<table id="statstable">
|
||||||
<tr> <th>Port</th> <th>Name</th> <th>link</th> <th>TX Good</th> <th>TX Bad</th> <th>RX Good</th> <th>RX Bad</th> <th> All Counters </th></tr>
|
<tr> <th>Port</th> <th>link</th> <th>TX Good</th> <th>TX Bad</th> <th>RX Good</th> <th>RX Bad</th> <th> All Counters </th></tr>
|
||||||
<script src="/stat.js"></script>
|
<script src="/stat.js"></script>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ function getCounters(port) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhttp.open("GET", "/counters.json?port=" + port, true);
|
xhttp.open("GET", "/counters.json?port=" + port, true);
|
||||||
xhttp.timeout = 1500; sendXHTTP(xhttp);
|
xhttp.timeout = 1500; xhttp.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -162,19 +162,17 @@ function fillStats() {
|
|||||||
if (tbl.rows.length > 1) {
|
if (tbl.rows.length > 1) {
|
||||||
for (let i = 0; i < numPorts; i++) {
|
for (let i = 0; i < numPorts; i++) {
|
||||||
console.log("Table Update row: " + i + " state " + pState[i] + " is " + linkS[pState[i] +1]);
|
console.log("Table Update row: " + i + " state " + pState[i] + " is " + linkS[pState[i] +1]);
|
||||||
tbl.rows[i+1].cells[2].innerHTML = `${linkS[pState[i]+1]}`;
|
tbl.rows[i+1].cells[1].innerHTML = `${linkS[pState[i]+1]}`;
|
||||||
tbl.rows[i+1].cells[3].innerHTML = `${txG[i]} pkts`;
|
tbl.rows[i+1].cells[2].innerHTML = `${txG[i]} pkts`;
|
||||||
tbl.rows[i+1].cells[4].innerHTML = `${txB[i]} pkts`;
|
tbl.rows[i+1].cells[3].innerHTML = `${txB[i]} pkts`;
|
||||||
tbl.rows[i+1].cells[5].innerHTML = `${rxG[i]} pkts`;
|
tbl.rows[i+1].cells[4].innerHTML = `${rxG[i]} pkts`;
|
||||||
tbl.rows[i+1].cells[6].innerHTML = `${rxB[i]} pkts`;
|
tbl.rows[i+1].cells[5].innerHTML = `${rxB[i]} pkts`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < numPorts; i++) {
|
for (let i = 0; i < numPorts; i++) {
|
||||||
console.log("Table row: " + i);
|
console.log("Table row: " + i);
|
||||||
const tr = tbl.insertRow();
|
const tr = tbl.insertRow();
|
||||||
let td = tr.insertCell(); td.appendChild(document.createTextNode(`Port ${i+1}`));
|
let td = tr.insertCell(); td.appendChild(document.createTextNode(`Port ${i+1}`));
|
||||||
let portName = portNames[physToLogPort[i]] || '';
|
|
||||||
td = tr.insertCell(); td.appendChild(document.createTextNode(portName));
|
|
||||||
td = tr.insertCell(); td.appendChild(document.createTextNode(`${linkS[pState[i]+1]}`));
|
td = tr.insertCell(); td.appendChild(document.createTextNode(`${linkS[pState[i]+1]}`));
|
||||||
td = tr.insertCell(); td.appendChild(document.createTextNode(`${txG[i]} pkts`));
|
td = tr.insertCell(); td.appendChild(document.createTextNode(`${txG[i]} pkts`));
|
||||||
td = tr.insertCell();td.appendChild(document.createTextNode(`${txB[i]} pkts`));
|
td = tr.insertCell();td.appendChild(document.createTextNode(`${txB[i]} pkts`));
|
||||||
@@ -186,6 +184,8 @@ function fillStats() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const stat = setInterval(fillStats, 1000);
|
||||||
|
|
||||||
const popup = document.getElementById('popup');
|
const popup = document.getElementById('popup');
|
||||||
const closePopup = document.getElementById('closePopup');
|
const closePopup = document.getElementById('closePopup');
|
||||||
closePopup.addEventListener('click', () => {
|
closePopup.addEventListener('click', () => {
|
||||||
@@ -196,12 +196,3 @@ window.addEventListener('click', (event) => {
|
|||||||
popup.style.display = 'none';
|
popup.style.display = 'none';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
|
||||||
update( () => {
|
|
||||||
update();
|
|
||||||
fillStats();
|
|
||||||
const stat = setInterval(fillStats, 1000);
|
|
||||||
const interval = setInterval(update, 2000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -6,9 +6,8 @@ ul {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 12%;
|
width: 12%;
|
||||||
height: calc(100% - 50px);
|
height: 100%;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 50px;
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,4 +162,3 @@ margin: 30px 0;
|
|||||||
}
|
}
|
||||||
select { text-align-last: right; font-family: monospace}
|
select { text-align-last: right; font-family: monospace}
|
||||||
option { direction: rtl; font-family: sans-serif}
|
option { direction: rtl; font-family: sans-serif}
|
||||||
#vlanTable td { text-align: left; }
|
|
||||||
|
|||||||
@@ -3,26 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<title>System Settings</title>
|
<title>System Settings</title>
|
||||||
<style>
|
|
||||||
.tab-bar { display: flex; border-bottom: 2px solid #226; margin-bottom: 0; margin-left: 16%; padding: 1px 16px; padding-bottom: 0; }
|
|
||||||
.tab-btn { padding: 10px 20px; background-color: #ddf; border: none; cursor: pointer; font-size: 1em; border-radius: 8px 8px 0 0; margin-right: 4px; }
|
|
||||||
.tab-btn:hover { background-color: #aaf; }
|
|
||||||
.tab-btn.active { background-color: #aaf; font-weight: bold; border-bottom: 2px solid #aaf; margin-bottom: -2px; }
|
|
||||||
.tab-content { display: none; }
|
|
||||||
.tab-content.active { display: block; }
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="tab-bar">
|
|
||||||
<button class="tab-btn active" onclick="openTab(event, 'system-tab')">System</button>
|
|
||||||
<button class="tab-btn" onclick="openTab(event, 'advanced-tab')">Advanced</button>
|
|
||||||
<button class="tab-btn" onclick="openTab(event, 'console-tab')">Console</button>
|
|
||||||
</div>
|
|
||||||
<nav id="sidebar"></nav>
|
<nav id="sidebar"></nav>
|
||||||
<div style="margin-left:16%;padding:1px 16px;height:1000px;">
|
<div style="margin-left:16%;padding:1px 16px;height:1000px;">
|
||||||
<div id="ports"></div>
|
<div id="ports"></div>
|
||||||
|
|
||||||
<div id="system-tab" class="tab-content active">
|
|
||||||
<h1>System Settings</h1>
|
<h1>System Settings</h1>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="lcol"> <label for="ip">IP address:</label></div>
|
<div class="lcol"> <label for="ip">IP address:</label></div>
|
||||||
@@ -36,49 +21,16 @@
|
|||||||
<div class="lcol"> <label for="gw">Gateway:</label></div>
|
<div class="lcol"> <label for="gw">Gateway:</label></div>
|
||||||
<div class="rcol"><input id="gw" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
<div class="rcol"><input id="gw" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
<br/><br/>
|
||||||
When updating the above settings, remember to point your browser to the new IP afterwards:<br/>
|
When updating the above settings, remember to point your browser to the new IP afterwards:<br/>
|
||||||
<input style="width:40%;" class="action" id="ip_sub" onclick="ipSub();" type="button" value="Update Settings"><br/>
|
<input style="width:40%;" class="action" id="ip_sub" onclick="ipSub();" type="button" value="Update Settings"><br/>
|
||||||
<br/>
|
<br/><br/>
|
||||||
Save all current settings to Flash:<br/>
|
Save all current settings to Flash:<br/>
|
||||||
<input style="width:40%;" class="action" id="flash_sub" onclick="flashSave();" type="button" value="Save Settings to Flash">
|
<input style="width:40%;" class="action" id="flash_sub" onclick="flashSave();" type="button" value="Save Settings to Flash">
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="advanced-tab" class="tab-content">
|
|
||||||
<h1>Advanced Settings</h1>
|
|
||||||
<div class="lcol"> <label for="config_display">Startup configuration:</label></div>
|
|
||||||
<textarea id="config_display" rows="8" cols="60"></textarea>
|
|
||||||
<br/><br/>
|
|
||||||
Be careful when saving the directly edited startup configuration, you can lock yourself out:<br/>
|
|
||||||
<input style="width:40%;" class="action" id="clear_config" onclick="clearConfig();" type="button" value="Clear Startup Config">
|
|
||||||
<br/>
|
|
||||||
<input style="width:40%;" class="action" id="flash_startup_sub" onclick="flashStartupSave();" type="button" value="Save Startup Settings to Flash">
|
|
||||||
<br/>
|
|
||||||
<input style="width:40%;" class="action" id="switch_reset" onclick="resetSwitch();" type="button" value="Reset Switch">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="console-tab" class="tab-content">
|
|
||||||
<h1>Console Command</h1>
|
|
||||||
<label for="console_command">Enter command:</label>
|
|
||||||
<input type="text" id="console_cmd" name="console_cmd" style="width:40%;">
|
|
||||||
<input style="width:20%;" class="action" id="cmd_sub" onclick="cmdSub();" type="button" value="Send Command"><br/>
|
|
||||||
<br/><br/>
|
|
||||||
Be careful when entering console commands, you can lock yourself out!<br/>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<script src="/config.js"></script>
|
<script src="/config.js"></script>
|
||||||
<script src="/system.js"></script>
|
<script src="/system.js"></script>
|
||||||
<script src="/navigation.js"></script>
|
<script src="/navigation.js"></script>
|
||||||
<script>
|
|
||||||
function openTab(evt, tabId) {
|
|
||||||
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
|
|
||||||
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
|
|
||||||
document.getElementById(tabId).classList.add('active');
|
|
||||||
evt.currentTarget.classList.add('active');
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
var systemInterval = Number();
|
var systemInterval = Number();
|
||||||
var isSaving = false;
|
|
||||||
const ips = ["ip", "netmask", "gw"];
|
const ips = ["ip", "netmask", "gw"];
|
||||||
|
|
||||||
function checkIp(ip) {
|
function checkIp(ip) {
|
||||||
@@ -13,10 +12,8 @@ async function ipSub() {
|
|||||||
if (!checkIp(document.getElementById(ips[i]).value))
|
if (!checkIp(document.getElementById(ips[i]).value))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var cmd = '';
|
|
||||||
for (let i=0; i<3;i++){
|
for (let i=0; i<3;i++){
|
||||||
cmd += ips[i]+' '+document.getElementById(ips[i]).value+'\n';
|
var cmd = ips[i]+' '+document.getElementById(ips[i]).value;
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/cmd', {
|
const response = await fetch('/cmd', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -27,86 +24,35 @@ async function ipSub() {
|
|||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.error(`Error: ${err}`);
|
console.error(`Error: ${err}`);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async function cmdSub() {
|
|
||||||
var cmd = document.getElementById('console_cmd').value;
|
|
||||||
try {
|
|
||||||
const response = await fetch('/cmd', {
|
|
||||||
method: 'POST',
|
|
||||||
body: cmd
|
|
||||||
});
|
|
||||||
console.log('Completed!', response);
|
|
||||||
} catch(err) {
|
|
||||||
console.error(`Error: ${err}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function sendConfig(c) {
|
async function sendConfig(c) {
|
||||||
if (isSaving) return;
|
|
||||||
isSaving = true;
|
|
||||||
clearInterval(systemInterval);
|
|
||||||
const form = new FormData();
|
const form = new FormData();
|
||||||
form.append("MAX_FILE_SIZE", "4096");
|
form.append("MAX_FILE_SIZE", "4096");
|
||||||
form.append("configuration", new Blob([c], {type: "application/octet-stream"}), "config.txt");
|
form.append("configuration", new Blob([c], {type: "application/octet-stream"}));
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/config', {
|
const response = await fetch('/config', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: form
|
body: form
|
||||||
});
|
});
|
||||||
console.log('Completed!', response);
|
console.log('Completed!', response);
|
||||||
try {
|
|
||||||
await fetch('/cmd_log_clear', { method: 'GET' });
|
|
||||||
} catch(e) {}
|
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.error(`Error: ${err}`);
|
console.error(`Error: ${err}`);
|
||||||
} finally {
|
|
||||||
isSaving = false;
|
|
||||||
systemInterval = setInterval(fetchIP, 1000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function flashSave() {
|
async function flashSave() {
|
||||||
configuration = [];
|
fetchConfig().then((s) => {
|
||||||
const savedConfig = await fetchConfig();
|
parseConf(s);
|
||||||
const cmdLog = await fetchCmdLog();
|
fetchCmdLog().then((s) => {
|
||||||
if (savedConfig) parseConf(savedConfig);
|
parseConf(s);
|
||||||
if (cmdLog) parseConf(cmdLog);
|
var body = "";
|
||||||
const body = configuration.join('\n') + '\n';
|
for (const x of configuration) { body = body + x + "\n"; }
|
||||||
console.log("CONFIGURATION to save: ", body);
|
console.log("CONFIGURATION to save: ", body);
|
||||||
await sendConfig(body);
|
sendConfig(body);
|
||||||
}
|
});
|
||||||
|
});
|
||||||
async function flashStartupSave() {
|
|
||||||
var configContent = document.getElementById("config_display").value;
|
|
||||||
console.log("CONFIGURATION to save: ", configContent);
|
|
||||||
sendConfig(configContent);
|
|
||||||
// Clear the command log 1 second after initiating the config save
|
|
||||||
setTimeout(() => {
|
|
||||||
fetch('/cmd_log_clear', { method: 'GET' })
|
|
||||||
.then(response => console.log('Command log cleared', response))
|
|
||||||
.catch(err => console.error('Error clearing command log:', err));
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearConfig() {
|
|
||||||
document.getElementById("config_display").value = "";
|
|
||||||
|
|
||||||
// Validate and populate with current IP settings
|
|
||||||
for (let i=0; i<3; i++) {
|
|
||||||
if (!checkIp(document.getElementById(ips[i]).value))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var configLines = "";
|
|
||||||
for (let i=0; i<3; i++){
|
|
||||||
var cmd = ips[i]+' '+document.getElementById(ips[i]).value;
|
|
||||||
configLines += cmd + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("config_display").value = configLines;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchIP() {
|
function fetchIP() {
|
||||||
@@ -119,32 +65,12 @@ function fetchIP() {
|
|||||||
document.getElementById("netmask").value=s.ip_netmask;
|
document.getElementById("netmask").value=s.ip_netmask;
|
||||||
document.getElementById("gw").value=s.ip_gateway;
|
document.getElementById("gw").value=s.ip_gateway;
|
||||||
clearInterval(systemInterval);
|
clearInterval(systemInterval);
|
||||||
// Fetch and populate the config textbox
|
}
|
||||||
fetchConfig().then((configText) => {
|
|
||||||
let fullConfig = configText;
|
|
||||||
// Fetch and append cmd_log
|
|
||||||
//return fetchCmdLog().then((cmdLogText) => {
|
|
||||||
// if (cmdLogText) {
|
|
||||||
// fullConfig = fullConfig + cmdLogText;
|
|
||||||
// }
|
|
||||||
document.getElementById("config_display").value = fullConfig;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
xhttp.open("GET", `/information.json`, true);
|
xhttp.open("GET", `/information.json`, true);
|
||||||
xhttp.send();
|
xhttp.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetSwitch() {
|
|
||||||
if (!confirm('Are you sure you want to reset the switch?')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fetch('/reset', { method: 'GET' }).catch(() => {});
|
|
||||||
setTimeout(() => {
|
|
||||||
alert('Switch is resetting. Please wait and refresh the page.');
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
window.addEventListener("load", function() {
|
||||||
systemInterval = setInterval(fetchIP, 1000);
|
systemInterval = setInterval(fetchIP, 1000);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,16 +10,9 @@
|
|||||||
<div id="ports"></div>
|
<div id="ports"></div>
|
||||||
<h1>VLAN Configuration</h1>
|
<h1>VLAN Configuration</h1>
|
||||||
<form id="vform" action="/vlan.html">
|
<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>
|
<div>
|
||||||
<label for="vid">VLAN ID:</label>
|
<label for="vid">VLAN ID:</label>
|
||||||
<input type="number" min="1" max="4094" id="vid" name="vid">
|
<input type="number" min="1" max="2047" id="vid" name="vid">
|
||||||
<button type="button" style="margin: 0 0 0 24px" onclick="fetchVLAN();">Get Configuration</button>
|
<button type="button" style="margin: 0 0 0 24px" onclick="fetchVLAN();">Get Configuration</button>
|
||||||
</div>
|
</div>
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
@@ -36,22 +29,6 @@
|
|||||||
<br/> <input style="width:40%;" class="action" id="vlan_sub" onclick="vlanSub();" type="button" value="Update / Create">
|
<br/> <input style="width:40%;" class="action" id="vlan_sub" onclick="vlanSub();" type="button" value="Update / Create">
|
||||||
<script src="/vlan_sub.js"></script>
|
<script src="/vlan_sub.js"></script>
|
||||||
</form>
|
</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>
|
</div>
|
||||||
<script src="/navigation.js"></script>
|
<script src="/navigation.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ var vlanInterval = Number();
|
|||||||
function vlanForm() {
|
function vlanForm() {
|
||||||
if (!numPorts)
|
if (!numPorts)
|
||||||
return;
|
return;
|
||||||
|
clearInterval(vlanInterval);
|
||||||
var t = document.getElementById('tPorts');
|
var t = document.getElementById('tPorts');
|
||||||
var u = document.getElementById('uPorts');
|
var u = document.getElementById('uPorts');
|
||||||
var p = document.getElementById('pPorts');
|
var p = document.getElementById('pPorts');
|
||||||
@@ -38,6 +39,11 @@ function vlanForm() {
|
|||||||
|
|
||||||
function setC(t, p, c){
|
function setC(t, p, c){
|
||||||
document.getElementById(t+'port'+p).checked=c;
|
document.getElementById(t+'port'+p).checked=c;
|
||||||
|
// When a tagged port is checked, automatically select the PVID port as well
|
||||||
|
const tportElem = document.getElementById('tport'+p);
|
||||||
|
if (tportElem && tportElem.checked) {
|
||||||
|
document.getElementById('pport'+p).checked=true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function utClicked(t){
|
function utClicked(t){
|
||||||
@@ -52,6 +58,10 @@ function pvClicked(p){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.addEventListener("load", function() {
|
||||||
|
vlanInterval = setInterval(vlanForm, 100);
|
||||||
|
});
|
||||||
|
|
||||||
function fetchVLAN() {
|
function fetchVLAN() {
|
||||||
var xhttp = new XMLHttpRequest();
|
var xhttp = new XMLHttpRequest();
|
||||||
xhttp.onreadystatechange = function() {
|
xhttp.onreadystatechange = function() {
|
||||||
@@ -60,17 +70,10 @@ function fetchVLAN() {
|
|||||||
console.log("VLAN: ", JSON.stringify(s));
|
console.log("VLAN: ", JSON.stringify(s));
|
||||||
m = parseInt(s.members, 16);
|
m = parseInt(s.members, 16);
|
||||||
document.getElementById('vname').value = s.name;
|
document.getElementById('vname').value = s.name;
|
||||||
var members = m & 0x3FF;
|
for (let i = 1; i <= numPorts; i++) {
|
||||||
var untag = (m >> 10) & 0x3FF;
|
setC('t', i, (m>>(10+i-1))&1);
|
||||||
var pvid = parseInt(s.pvid, 16);
|
setC('u', i, (m>>(i-1))&1);
|
||||||
console.log("PVID: ", pvid);
|
setC('p', i, (m>>(20+i-1))&1);
|
||||||
for (let p = 1; p <= numPorts; p++) {
|
|
||||||
var bit = physToLogPort[p-1];
|
|
||||||
var isMember = (members >> bit) & 1;
|
|
||||||
var isUntag = (untag >> bit) & 1;
|
|
||||||
setC('t', p, isMember && !isUntag);
|
|
||||||
setC('u', p, isMember && isUntag);
|
|
||||||
setC('p', p, (pvid >> bit) & 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -80,132 +83,5 @@ function fetchVLAN() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xhttp.open("GET", `/vlan.json?vid=${v}`, true);
|
xhttp.open("GET", `/vlan.json?vid=${v}`, true);
|
||||||
sendXHTTP(xhttp);
|
xhttp.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ async function vlanSub() {
|
|||||||
});
|
});
|
||||||
console.log('Completed!', response);
|
console.log('Completed!', response);
|
||||||
}
|
}
|
||||||
refreshVlanViews();
|
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.error(`Error: ${err}`);
|
console.error(`Error: ${err}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
CC = sdcc
|
||||||
|
CC_FLAGS = -mmcs51 -I. -I.. -I../uip
|
||||||
|
ASM = sdas8051
|
||||||
|
AFLAGS= -plosgff
|
||||||
|
|
||||||
|
BUILDDIR = output/
|
||||||
|
|
||||||
|
SRCS = httpd.c page_impl.c
|
||||||
|
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel}
|
||||||
|
|
||||||
|
all: create_build_dir $(OBJS)
|
||||||
|
|
||||||
|
create_build_dir:
|
||||||
|
mkdir -p $(BUILDDIR)
|
||||||
|
|
||||||
|
$(BUILDDIR)%.asm: %.c
|
||||||
|
$(CC) $(CC_FLAGS) -o $@ -c -S $<
|
||||||
|
|
||||||
|
$(BUILDDIR)%.rel: $(BUILDDIR)%.asm
|
||||||
|
${ASM} ${AFLAGS} -o $@ $^
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -r $(BUILDDIR)
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
@@ -14,6 +14,12 @@
|
|||||||
#define SESSION_ID_LENGTH 12
|
#define SESSION_ID_LENGTH 12
|
||||||
#define SESSION_TIMEOUT 200
|
#define SESSION_TIMEOUT 200
|
||||||
|
|
||||||
|
// Upload Firmware to 1M
|
||||||
|
#define FIRMWARE_UPLOAD_START 0x100000
|
||||||
|
|
||||||
|
// SPI FLASH MEMORY PAGE SIZE.
|
||||||
|
#define FLASHMEM_PAGE_SIZE 0x100
|
||||||
|
|
||||||
#define CMARK_S 6
|
#define CMARK_S 6
|
||||||
|
|
||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK1
|
||||||
@@ -24,10 +30,9 @@ extern __code uint8_t * __code hex;
|
|||||||
extern __code struct f_data f_data[];
|
extern __code struct f_data f_data[];
|
||||||
extern __code char * __code mime_strings[];
|
extern __code char * __code mime_strings[];
|
||||||
extern __xdata struct flash_region_t flash_region;
|
extern __xdata struct flash_region_t flash_region;
|
||||||
extern __xdata uint32_t flash_size;
|
|
||||||
|
|
||||||
// Flash buffer to optimize flash writing speed, write_len is the current filling position
|
// Flash buffer to optimize flash writing speed, write_len is the current filling position
|
||||||
extern __xdata uint8_t flash_buf[FLASH_BUF_SIZE];
|
extern __xdata uint8_t flash_buf[512];
|
||||||
__xdata uint32_t uptr; // Current flash write position
|
__xdata uint32_t uptr; // Current flash write position
|
||||||
__xdata uint16_t write_len;
|
__xdata uint16_t write_len;
|
||||||
|
|
||||||
@@ -62,7 +67,6 @@ __xdata uint32_t last_session_use;
|
|||||||
#define TSTATE_ACKED 2
|
#define TSTATE_ACKED 2
|
||||||
#define TSTATE_CLOSED 3
|
#define TSTATE_CLOSED 3
|
||||||
#define TSTATE_POST 4
|
#define TSTATE_POST 4
|
||||||
#define TSTATE_MULTIPART 5
|
|
||||||
|
|
||||||
extern __xdata uint16_t crc_value;
|
extern __xdata uint16_t crc_value;
|
||||||
__xdata uint16_t crc_final;
|
__xdata uint16_t crc_final;
|
||||||
@@ -116,88 +120,33 @@ char strcmp(__xdata uint8_t *c, __code uint8_t * __xdata d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool is_word(__xdata uint8_t *xdata_str_p, __code uint8_t * __xdata code_str_p)
|
char is_word(__xdata uint8_t *c, __code uint8_t * __xdata d)
|
||||||
{
|
{
|
||||||
uint8_t u, c;
|
uint8_t i = 0;
|
||||||
|
|
||||||
while (1) {
|
while (d[i] && (d[i] == c[i]))
|
||||||
u = *xdata_str_p++;
|
i++;
|
||||||
c = *code_str_p++;
|
|
||||||
|
|
||||||
if (c == '\0') {
|
if (d[i])
|
||||||
if (u != '\0' && u != ' ' && u != '\t' && u != ':' && u != '?' && u != '=' && u != '\n' && u != '\r')
|
return 0;
|
||||||
return false;
|
if (c[i] != ' ' && c[i] != '\t' && c[i] != ':' && c[i] != '?' && c[i] != '=' && c[i] != '\n' && c[i] != '\r' && c[i])
|
||||||
return true;
|
return 0;
|
||||||
}
|
return 1;
|
||||||
|
|
||||||
if (c != u) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool is_url_word_x(__xdata uint8_t *uri_str_p, __xdata uint8_t *src_str_p)
|
char is_word_x(__xdata uint8_t *c, __xdata uint8_t *d)
|
||||||
{
|
{
|
||||||
uint8_t u, s;
|
register uint8_t i = 0;
|
||||||
|
|
||||||
while(1) {
|
while (d[i] && (d[i] == c[i]))
|
||||||
u = *uri_str_p++;
|
i++;
|
||||||
s = *src_str_p++;
|
|
||||||
|
|
||||||
if (s == '\0') {
|
if (d[i])
|
||||||
if (u != '\0' && u != ' ' && u != '\t' && u != ':' && u != '?' && u != '=' && u != '\n' && u != '\r')
|
return 0;
|
||||||
return false;
|
if (c[i] != ' ' && c[i] != '\t' && c[i] != ':' && c[i] != '?' && c[i] != '=' && c[i] != '\n' && c[i] != '\r' && c[i])
|
||||||
return true;
|
return 0;
|
||||||
}
|
return 1;
|
||||||
|
|
||||||
if (u == '%') {
|
|
||||||
bool again = true;
|
|
||||||
u = 0;
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
// Swap instruction is fine for rotation
|
|
||||||
u = (u << 4) | (u >> 4);
|
|
||||||
|
|
||||||
uint8_t p = *uri_str_p++;
|
|
||||||
u |= p - '0' < 10 ? (p - '0') : (p - 'A' + 10);
|
|
||||||
|
|
||||||
// force `jbc`-instruction.
|
|
||||||
if (again) {
|
|
||||||
again = false;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (u == '+') {
|
|
||||||
u = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s != u) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool is_word_x(__xdata uint8_t *lhs_str_p, __xdata uint8_t *rhs_str_p)
|
|
||||||
{
|
|
||||||
uint8_t u, c;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
u = *lhs_str_p++;
|
|
||||||
c = *rhs_str_p++;
|
|
||||||
|
|
||||||
if (c == '\0') {
|
|
||||||
if (u != '\0' && u != ' ' && u != '\t' && u != ':' && u != '?' && u != '=' && u != '\n' && u != '\r')
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c != u) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -347,14 +296,12 @@ uint8_t stream_upload(uint16_t bptr)
|
|||||||
if (verify_crc) {
|
if (verify_crc) {
|
||||||
dbg_string("CRC16: "); dbg_short(crc_final); dbg_char('\n');
|
dbg_string("CRC16: "); dbg_short(crc_final); dbg_char('\n');
|
||||||
if (crc_final == 0xb001) {
|
if (crc_final == 0xb001) {
|
||||||
print_string("Checksum OK.\nUpload to flash done, will reset!\n");
|
print_string("Checksum OK.");
|
||||||
// close connection to avoid retries by browser
|
|
||||||
uip_close();
|
|
||||||
reset_chip();
|
|
||||||
} else {
|
} else {
|
||||||
print_string("Checksum incorrect! Aborting.\n");
|
print_string("Checksum incorrect!");
|
||||||
uip_close();
|
|
||||||
}
|
}
|
||||||
|
print_string("\nUpload to flash done, will reset!\n");
|
||||||
|
reset_chip();
|
||||||
}
|
}
|
||||||
// Make sure there is a 0 at the end of the uploaded data
|
// Make sure there is a 0 at the end of the uploaded data
|
||||||
flash_buf[0] = 0;
|
flash_buf[0] = 0;
|
||||||
@@ -363,9 +310,6 @@ uint8_t stream_upload(uint16_t bptr)
|
|||||||
flash_write_bytes(flash_buf);
|
flash_write_bytes(flash_buf);
|
||||||
if (bptr >= uip_len)
|
if (bptr >= uip_len)
|
||||||
return 0;
|
return 0;
|
||||||
if(!verify_crc)
|
|
||||||
//ugly hack to signal connection finished after config upload.
|
|
||||||
uip_close();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (p[bptr] == boundary[bindex]) {
|
if (p[bptr] == boundary[bindex]) {
|
||||||
@@ -382,22 +326,18 @@ uint8_t stream_upload(uint16_t bptr)
|
|||||||
}
|
}
|
||||||
crc16(p + bptr);
|
crc16(p + bptr);
|
||||||
flash_buf[write_len++] = p[bptr++];
|
flash_buf[write_len++] = p[bptr++];
|
||||||
if (write_len >= FLASH_PAGE_SIZE) {
|
if (write_len >= FLASHMEM_PAGE_SIZE) {
|
||||||
dbg_string("len: "); dbg_short(write_len); dbg_char(' ');
|
dbg_string("len: "); dbg_short(write_len); dbg_char(' ');
|
||||||
dbg_string("CRC16: "); dbg_short(crc_value); dbg_char('\n');
|
dbg_string("CRC16: "); dbg_short(crc_value); dbg_char('\n');
|
||||||
if (uptr % FLASH_SECTOR_SIZE == 0) {
|
|
||||||
flash_region.addr = uptr;
|
flash_region.addr = uptr;
|
||||||
flash_sector_erase();
|
flash_region.len = FLASHMEM_PAGE_SIZE;
|
||||||
}
|
|
||||||
flash_region.addr = uptr;
|
|
||||||
flash_region.len = FLASH_PAGE_SIZE;
|
|
||||||
flash_write_bytes(flash_buf);
|
flash_write_bytes(flash_buf);
|
||||||
uptr += FLASH_PAGE_SIZE;
|
uptr += FLASHMEM_PAGE_SIZE;
|
||||||
write_len -= FLASH_PAGE_SIZE;
|
write_len -= FLASHMEM_PAGE_SIZE;
|
||||||
|
|
||||||
// Copy the remaining byte for the next page to the beginning of the buffer.
|
// Copy the remaining byte for the next page to the beginning of the buffer.
|
||||||
if (write_len > 0) {
|
if (write_len > 0) {
|
||||||
memcpy(flash_buf, flash_buf + FLASH_PAGE_SIZE, write_len);
|
memcpy(flash_buf, flash_buf + FLASHMEM_PAGE_SIZE, write_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bindex = 0;
|
bindex = 0;
|
||||||
@@ -412,8 +352,6 @@ void handle_post(void)
|
|||||||
__xdata uint8_t *p = uip_appdata;
|
__xdata uint8_t *p = uip_appdata;
|
||||||
__xdata uint8_t *request_path = p + 6;
|
__xdata uint8_t *request_path = p + 6;
|
||||||
|
|
||||||
// Was the multipart header sent in multiple packets?
|
|
||||||
if (s->tstate != TSTATE_MULTIPART) {
|
|
||||||
dbg_string("Is POST\n");
|
dbg_string("Is POST\n");
|
||||||
p += 5; // Skip post
|
p += 5; // Skip post
|
||||||
// Find end of request path
|
// Find end of request path
|
||||||
@@ -430,56 +368,23 @@ void handle_post(void)
|
|||||||
send_not_found();
|
send_not_found();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (is_word(request_path, "upload")) {
|
|
||||||
if (flash_size < FIRMWARE_UPLOAD_START*2)
|
|
||||||
{
|
|
||||||
print_string("Flash too small for firmware upload!\n");
|
|
||||||
send_bad_request();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
print_string("Firmware upload started.");
|
|
||||||
uptr = FIRMWARE_UPLOAD_START;
|
|
||||||
verify_crc = 1;
|
|
||||||
max_upload = 1024576;
|
|
||||||
} else if (is_word(request_path, "config")) {
|
|
||||||
if (!authenticated) {
|
|
||||||
send_unauthorized();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dbg_string("Configuration upload, erasing config mem!\n");
|
|
||||||
uptr = CONFIG_START;
|
|
||||||
verify_crc = 0;
|
|
||||||
max_upload = 2048;
|
|
||||||
flash_region.addr = CONFIG_START;
|
|
||||||
flash_sector_erase();
|
|
||||||
}
|
|
||||||
// Check for other POST requests, which are not multipart, below
|
|
||||||
} else {
|
|
||||||
dbg_string("Multipart request\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_word(request_path, "cmd")) {
|
if (is_word(request_path, "cmd")) {
|
||||||
|
register uint8_t i = 0;
|
||||||
p += 4;
|
p += 4;
|
||||||
if (!authenticated) {
|
if (!authenticated) {
|
||||||
send_unauthorized();
|
send_unauthorized();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
execute_commands(p);
|
while (*p && *p != '\n' && *p != '\r')
|
||||||
if (err_status != ERR_OK) {
|
cmd_buffer[i++] = *p++;
|
||||||
send_bad_request();
|
cmd_buffer[i] = '\0';
|
||||||
return;
|
if (i)
|
||||||
}
|
cmd_available = 1;
|
||||||
} else if (is_word(request_path, "login")) {
|
} else if (is_word(request_path, "login")) {
|
||||||
dbg_string("POST login\n");
|
dbg_string("POST login\n");
|
||||||
|
|
||||||
if (!content_type || !is_word(content_type, "application/x-www-form-urlencoded")) {
|
|
||||||
dbg_string("Bad request!\n");
|
|
||||||
send_bad_request();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
p += 8; // Read also over "pwd="
|
p += 8; // Read also over "pwd="
|
||||||
if (is_url_word_x(p, passwd)) {
|
if (is_word_x(p, passwd)) {
|
||||||
dbg_string("Password accepted!\n");
|
dbg_string("Password accepted!\n");
|
||||||
read_reg_timer(&last_session_use);
|
read_reg_timer(&last_session_use);
|
||||||
gen_random_bytes(session_id, SESSION_ID_LENGTH);
|
gen_random_bytes(session_id, SESSION_ID_LENGTH);
|
||||||
@@ -490,11 +395,10 @@ void handle_post(void)
|
|||||||
outbuf[slen++] = session_id[i];
|
outbuf[slen++] = session_id[i];
|
||||||
slen += strtox(outbuf + slen, "; SameSite=Strict\r\n\r\n");
|
slen += strtox(outbuf + slen, "; SameSite=Strict\r\n\r\n");
|
||||||
} else {
|
} else {
|
||||||
dbg_string("Password invalid!\n");
|
|
||||||
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\nLocation: login.html\r\n\r\n");
|
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\nLocation: login.html\r\n\r\n");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (s->tstate == TSTATE_MULTIPART || is_word(request_path, "upload") || is_word(request_path, "config")) {
|
} else if (is_word(request_path, "upload") || is_word(request_path, "config")) {
|
||||||
dbg_string("POST upload/config request\n");
|
dbg_string("POST upload/config request\n");
|
||||||
if (!authenticated) {
|
if (!authenticated) {
|
||||||
send_unauthorized();
|
send_unauthorized();
|
||||||
@@ -508,10 +412,8 @@ void handle_post(void)
|
|||||||
// We skip the intial parts as part of the header
|
// We skip the intial parts as part of the header
|
||||||
do {
|
do {
|
||||||
p = skip_boundary(p);
|
p = skip_boundary(p);
|
||||||
if (!*p) {
|
if (!*p)
|
||||||
s->tstate = TSTATE_MULTIPART;
|
goto bad_request;
|
||||||
return;
|
|
||||||
}
|
|
||||||
p = scan_header(p);
|
p = scan_header(p);
|
||||||
if (!*p)
|
if (!*p)
|
||||||
goto bad_request;
|
goto bad_request;
|
||||||
@@ -521,6 +423,19 @@ void handle_post(void)
|
|||||||
dbg_string("Have content octets\n");
|
dbg_string("Have content octets\n");
|
||||||
p += 4; // Skip \r\n\r\n sequence at end of preamble of part
|
p += 4; // Skip \r\n\r\n sequence at end of preamble of part
|
||||||
|
|
||||||
|
if (is_word(request_path, "upload")) {
|
||||||
|
print_string("Firmware upload started.");
|
||||||
|
uptr = FIRMWARE_UPLOAD_START;
|
||||||
|
verify_crc = 1;
|
||||||
|
max_upload = 1024576;
|
||||||
|
} else {
|
||||||
|
dbg_string("Configuration upload, erasing config mem!\n");
|
||||||
|
uptr = CONFIG_START;
|
||||||
|
verify_crc = 0;
|
||||||
|
max_upload = 2048;
|
||||||
|
flash_region.addr = CONFIG_START;
|
||||||
|
flash_sector_erase();
|
||||||
|
}
|
||||||
flash_init(0); // Re-initialize flash for non-DIO operation, otherwise flashing fails
|
flash_init(0); // Re-initialize flash for non-DIO operation, otherwise flashing fails
|
||||||
set_sys_led_state(SYS_LED_FAST);
|
set_sys_led_state(SYS_LED_FAST);
|
||||||
|
|
||||||
@@ -549,12 +464,6 @@ void httpd_appcall(void)
|
|||||||
__xdata struct httpd_state * __xdata s = &(uip_conn->appstate);
|
__xdata struct httpd_state * __xdata s = &(uip_conn->appstate);
|
||||||
|
|
||||||
dbg_char('P');
|
dbg_char('P');
|
||||||
#ifdef DEBUG
|
|
||||||
if (uip_newdata())
|
|
||||||
write_char('N');
|
|
||||||
print_byte(s->tstate);
|
|
||||||
write_char(' ');
|
|
||||||
#endif
|
|
||||||
if(uip_connected() && s->tstate == TSTATE_CLOSED) {
|
if(uip_connected() && s->tstate == TSTATE_CLOSED) {
|
||||||
dbg_string("Connected...\n");
|
dbg_string("Connected...\n");
|
||||||
s->tstate = TSTATE_NONE;
|
s->tstate = TSTATE_NONE;
|
||||||
@@ -626,10 +535,10 @@ void httpd_appcall(void)
|
|||||||
dbg_char('\n');
|
dbg_char('\n');
|
||||||
#endif
|
#endif
|
||||||
p = uip_appdata;
|
p = uip_appdata;
|
||||||
if (is_word(p, "POST") || s->tstate == TSTATE_MULTIPART) {
|
if (is_word(p, "POST")) {
|
||||||
handle_post();
|
handle_post();
|
||||||
// If this is an ongoing post stream, then wait for the next packet
|
// If this is an ongoing post stream, then wait for the next packet
|
||||||
if (s->tstate == TSTATE_POST || s->tstate == TSTATE_MULTIPART) {
|
if (s->tstate == TSTATE_POST) {
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -668,8 +577,6 @@ void httpd_appcall(void)
|
|||||||
send_counters(q[20]-'0');
|
send_counters(q[20]-'0');
|
||||||
} else if (is_word(q, "/eee.json")) {
|
} else if (is_word(q, "/eee.json")) {
|
||||||
send_eee();
|
send_eee();
|
||||||
} else if (is_word(q, "/bandwidth.json")) {
|
|
||||||
send_bandwidth();
|
|
||||||
} else if (is_word(q, "/l2.json")) {
|
} else if (is_word(q, "/l2.json")) {
|
||||||
parse_short(q + 13); // e.g.: /l2.json?idx=10
|
parse_short(q + 13); // e.g.: /l2.json?idx=10
|
||||||
send_l2(short_parsed);
|
send_l2(short_parsed);
|
||||||
@@ -682,19 +589,10 @@ void httpd_appcall(void)
|
|||||||
send_mtu();
|
send_mtu();
|
||||||
} else if (is_word(q, "/lag.json")) {
|
} else if (is_word(q, "/lag.json")) {
|
||||||
send_lag();
|
send_lag();
|
||||||
} else if (is_word(q, "/vlanlist")) {
|
|
||||||
send_vlanlist();
|
|
||||||
} else if (is_word(q, "/config")) {
|
} else if (is_word(q, "/config")) {
|
||||||
send_config();
|
send_config();
|
||||||
} else if (is_word(q, "/cmd_log")) {
|
} else if (is_word(q, "/cmd_log")) {
|
||||||
send_cmd_log();
|
send_cmd_log();
|
||||||
} else if (is_word(q, "/cmd_log_clear")) {
|
|
||||||
clear_command_history();
|
|
||||||
send_mtu(); // dummy response
|
|
||||||
} else if (is_word(q, "/reset")) {
|
|
||||||
uip_close();
|
|
||||||
delay(1000); //wait for the close packet to be sent, otherwise the browser will retry
|
|
||||||
reset_chip();
|
|
||||||
} else {
|
} else {
|
||||||
send_not_found();
|
send_not_found();
|
||||||
}
|
}
|
||||||
@@ -714,7 +612,7 @@ void httpd_appcall(void)
|
|||||||
|
|
||||||
slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nContent-Type: ");
|
slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nContent-Type: ");
|
||||||
slen += strtox(outbuf + slen, mime_strings[f_data[entry].mime]);
|
slen += strtox(outbuf + slen, mime_strings[f_data[entry].mime]);
|
||||||
slen += strtox(outbuf + slen, "; charset=UTF-8\r\nCache-Control: max-age=60, must-revalidate\r\nAccess-Control-Allow-Origin: *\r\nContent-Security-Policy: style-src 'self' 'unsafe-inline'\r\n\r\n");
|
slen += strtox(outbuf + slen, "; charset=UTF-8\r\nCache-Control: max-age=60, must-revalidate\r\nAccess-Control-Allow-Origin: *\r\n\r\n");
|
||||||
|
|
||||||
len_left = f_data[entry].len;
|
len_left = f_data[entry].len;
|
||||||
if (len_left > (TCP_OUTBUF_SIZE - slen)) {
|
if (len_left > (TCP_OUTBUF_SIZE - slen)) {
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "page_impl.h"
|
#include "page_impl.h"
|
||||||
#include "syslog.h"
|
|
||||||
|
|
||||||
// #define DEBUG
|
// #define DEBUG
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
@@ -30,6 +29,7 @@ extern __xdata uint16_t cont_len;
|
|||||||
extern __xdata uint32_t cont_addr;
|
extern __xdata uint32_t cont_addr;
|
||||||
extern __code uint8_t * __code hex;
|
extern __code uint8_t * __code hex;
|
||||||
extern __xdata uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
|
extern __xdata uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
|
||||||
|
extern __code struct uip_eth_addr uip_ethaddr;
|
||||||
|
|
||||||
extern __xdata uint8_t sfr_data[4];
|
extern __xdata uint8_t sfr_data[4];
|
||||||
extern __xdata uint8_t sfp_pins_last;
|
extern __xdata uint8_t sfp_pins_last;
|
||||||
@@ -97,23 +97,6 @@ void itoa_html(uint8_t v)
|
|||||||
char_to_html('0' + (v % 10));
|
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++);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t stat_content(void)
|
uint16_t stat_content(void)
|
||||||
{
|
{
|
||||||
@@ -188,15 +171,11 @@ void send_sfp_info(uint8_t sfp)
|
|||||||
|
|
||||||
void sfp_send_data(uint8_t slot, uint8_t reg, uint8_t len)
|
void sfp_send_data(uint8_t slot, uint8_t reg, uint8_t len)
|
||||||
{
|
{
|
||||||
// maximum supported transfer size is 16 bytes
|
|
||||||
if (len > 16)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (reg & 0x80) { // Configure SFP readings address (0x51) as I2C device address
|
if (reg & 0x80) { // Configure SFP readings address (0x51) as I2C device address
|
||||||
reg &= 0x7f;
|
reg &= 0x7f;
|
||||||
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | (len - 1) & 0xf, 0x51 >> 5, (0x51 << 3) & 0xff);
|
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | len & 0xf, 0x51 >> 5, (0x51 << 3) & 0xff);
|
||||||
} else {
|
} else {
|
||||||
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | (len - 1) & 0xf, 0x50 >> 5, (0x50 << 3) & 0xff);
|
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | len & 0xf, 0x50 >> 5, (0x50 << 3) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_read_m(RTL837X_REG_I2C_CTRL);
|
reg_read_m(RTL837X_REG_I2C_CTRL);
|
||||||
@@ -213,9 +192,12 @@ void sfp_send_data(uint8_t slot, uint8_t reg, uint8_t len)
|
|||||||
reg_read_m(RTL837X_REG_I2C_CTRL);
|
reg_read_m(RTL837X_REG_I2C_CTRL);
|
||||||
} while (sfr_data[3] & 0x1);
|
} while (sfr_data[3] & 0x1);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len & 0xf; i++) {
|
||||||
if (!(i & 0x3))
|
if (!(i & 0x3))
|
||||||
reg_read_m(RTL837X_REG_I2C_OUT + i);
|
reg_read_m(RTL837X_REG_I2C_OUT + (i >> 2));
|
||||||
|
if (len & 0x80)
|
||||||
|
char_to_html(sfr_data[3 - (i & 0x3)]);
|
||||||
|
else
|
||||||
byte_to_html(sfr_data[3 - (i & 0x3)]);
|
byte_to_html(sfr_data[3 - (i & 0x3)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,11 +222,6 @@ void send_basic_info(void)
|
|||||||
itoa_html(uip_netmask[0] >> 8); char_to_html('.');
|
itoa_html(uip_netmask[0] >> 8); char_to_html('.');
|
||||||
itoa_html(uip_netmask[1]); char_to_html('.');
|
itoa_html(uip_netmask[1]); char_to_html('.');
|
||||||
itoa_html(uip_netmask[1] >> 8);
|
itoa_html(uip_netmask[1] >> 8);
|
||||||
slen += strtox(outbuf + slen, "\",\"syslog_server_ip\":\"");
|
|
||||||
itoa_html(syslog_state.server_ip[0]); char_to_html('.');
|
|
||||||
itoa_html(syslog_state.server_ip[1]); char_to_html('.');
|
|
||||||
itoa_html(syslog_state.server_ip[2]); char_to_html('.');
|
|
||||||
itoa_html(syslog_state.server_ip[3]);
|
|
||||||
slen += strtox(outbuf + slen, "\",\"mac_address\":\"");
|
slen += strtox(outbuf + slen, "\",\"mac_address\":\"");
|
||||||
byte_to_html(uip_ethaddr.addr[0]); char_to_html(':');
|
byte_to_html(uip_ethaddr.addr[0]); char_to_html(':');
|
||||||
byte_to_html(uip_ethaddr.addr[1]); char_to_html(':');
|
byte_to_html(uip_ethaddr.addr[1]); char_to_html(':');
|
||||||
@@ -254,23 +231,16 @@ void send_basic_info(void)
|
|||||||
byte_to_html(uip_ethaddr.addr[5]);
|
byte_to_html(uip_ethaddr.addr[5]);
|
||||||
slen += strtox(outbuf + slen, "\",\"sw_ver\":\"");
|
slen += strtox(outbuf + slen, "\",\"sw_ver\":\"");
|
||||||
slen += strtox(outbuf + slen, VERSION_SW);
|
slen += strtox(outbuf + slen, VERSION_SW);
|
||||||
slen += strtox(outbuf + slen, "\",\"build_date\":\"");
|
|
||||||
slen += strtox(outbuf + slen, BUILD_DATE);
|
|
||||||
slen += strtox(outbuf + slen, "\",\"hw_ver\":\"");
|
slen += strtox(outbuf + slen, "\",\"hw_ver\":\"");
|
||||||
slen += strtox(outbuf + slen, machine.machine_name);
|
slen += strtox(outbuf + slen, machine.machine_name);
|
||||||
slen += strtox(outbuf + slen, "\",\"flash_size\":\"");
|
|
||||||
string_to_html(get_flash_size_str());
|
|
||||||
|
|
||||||
if (machine.n_sfp) {
|
|
||||||
slen += strtox(outbuf + slen, "\",\"sfp_slot_0\":\"");
|
slen += strtox(outbuf + slen, "\",\"sfp_slot_0\":\"");
|
||||||
send_sfp_info(0);
|
send_sfp_info(0);
|
||||||
if (machine.n_sfp == 2) {
|
|
||||||
slen += strtox(outbuf + slen, "\",\"sfp_slot_1\":\"");
|
|
||||||
send_sfp_info(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
char_to_html('"');
|
char_to_html('"');
|
||||||
|
if (machine.n_sfp == 2) {
|
||||||
|
slen += strtox(outbuf + slen, ",\"sfp_slot_1\":\"");
|
||||||
|
send_sfp_info(1);
|
||||||
|
char_to_html('"');
|
||||||
|
}
|
||||||
char_to_html('}');
|
char_to_html('}');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,14 +261,6 @@ void send_vlan(uint16_t vlan)
|
|||||||
while(vlan_names[n] && vlan_names[n] != ' ')
|
while(vlan_names[n] && vlan_names[n] != ' ')
|
||||||
char_to_html(vlan_names[n++]);
|
char_to_html(vlan_names[n++]);
|
||||||
}
|
}
|
||||||
slen += strtox(outbuf + slen, "\",\"pvid\":\"0x");
|
|
||||||
uint16_t pvid_mask = 0;
|
|
||||||
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
|
||||||
if (port_pvid_get(i) == vlan)
|
|
||||||
pvid_mask |= (1 << i);
|
|
||||||
}
|
|
||||||
byte_to_html(pvid_mask >> 8);
|
|
||||||
byte_to_html(pvid_mask);
|
|
||||||
slen += strtox(outbuf + slen, "\"}");
|
slen += strtox(outbuf + slen, "\"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,50 +537,6 @@ void send_eee(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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++) {
|
|
||||||
slen += strtox(outbuf + slen, "{\"portNum\":");
|
|
||||||
itoa_html(machine.log_to_phys_port[i]);
|
|
||||||
slen += strtox(outbuf + slen, ",\"iLimited\":");
|
|
||||||
reg_read_m(RTL837X_IGBW_PORT_CTRL + i * 4);
|
|
||||||
if (sfr_data[1] & 0x10)
|
|
||||||
char_to_html('1');
|
|
||||||
else
|
|
||||||
char_to_html('0');
|
|
||||||
slen += strtox(outbuf + slen, ",\"iBW\":\"");
|
|
||||||
byte_to_html(sfr_data[1] & 0x0f);
|
|
||||||
byte_to_html(sfr_data[2]);
|
|
||||||
byte_to_html(sfr_data[3]);
|
|
||||||
slen += strtox(outbuf + slen, "\",\"iFC\":");
|
|
||||||
if (reg_bit_test(RTL837X_IGBW_PORT_FC_CTRL, i))
|
|
||||||
char_to_html('1');
|
|
||||||
else
|
|
||||||
char_to_html('0');
|
|
||||||
reg_read_m(RTL837X_EGBW_PORT_CTRL + i * 1024);
|
|
||||||
slen += strtox(outbuf + slen, ",\"eLimited\":");
|
|
||||||
if (sfr_data[1] & 0x10)
|
|
||||||
char_to_html('1');
|
|
||||||
else
|
|
||||||
char_to_html('0');
|
|
||||||
slen += strtox(outbuf + slen, ",\"eBW\":\"");
|
|
||||||
byte_to_html(sfr_data[1] & 0x0f);
|
|
||||||
byte_to_html(sfr_data[2]);
|
|
||||||
byte_to_html(sfr_data[3]);
|
|
||||||
char_to_html('"');
|
|
||||||
char_to_html('}');
|
|
||||||
if (i < machine.max_port)
|
|
||||||
char_to_html(',');
|
|
||||||
else
|
|
||||||
char_to_html(']');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void send_mtu(void)
|
void send_mtu(void)
|
||||||
{
|
{
|
||||||
dbg_string("send_mtu called\n");
|
dbg_string("send_mtu called\n");
|
||||||
@@ -653,11 +571,6 @@ void send_status(void)
|
|||||||
itoa_html(machine.log_to_phys_port[i]);
|
itoa_html(machine.log_to_phys_port[i]);
|
||||||
slen += strtox(outbuf + slen, ",\"logPort\":");
|
slen += strtox(outbuf + slen, ",\"logPort\":");
|
||||||
itoa_html(i);
|
itoa_html(i);
|
||||||
slen += strtox(outbuf + slen, ",\"name\":\"");
|
|
||||||
for (uint8_t j = 0; j < PORT_NAME_SIZE && port_names[i][j]; j++) {
|
|
||||||
char_to_html(port_names[i][j]);
|
|
||||||
}
|
|
||||||
slen += strtox(outbuf + slen, "\"");
|
|
||||||
|
|
||||||
if (machine.is_sfp[i]) {
|
if (machine.is_sfp[i]) {
|
||||||
slen += strtox(outbuf + slen, ",\"isSFP\":1,\"enabled\":");
|
slen += strtox(outbuf + slen, ",\"isSFP\":1,\"enabled\":");
|
||||||
@@ -666,6 +579,7 @@ void send_status(void)
|
|||||||
slen += strtox(outbuf + slen,",\"sfp_options\":\"0x");
|
slen += strtox(outbuf + slen,",\"sfp_options\":\"0x");
|
||||||
byte_to_html(sfp_options[machine.is_sfp[i]-1]);
|
byte_to_html(sfp_options[machine.is_sfp[i]-1]);
|
||||||
if (sfp_options[machine.is_sfp[i]-1] & 0x40) {
|
if (sfp_options[machine.is_sfp[i]-1] & 0x40) {
|
||||||
|
sfp_send_data(machine.is_sfp[i] - 1, 92, 1);
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_temp\":\"0x");
|
slen += strtox(outbuf + slen,"\",\"sfp_temp\":\"0x");
|
||||||
sfp_send_data(machine.is_sfp[i] - 1, 224, 2);
|
sfp_send_data(machine.is_sfp[i] - 1, 224, 2);
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_vcc\":\"0x");
|
slen += strtox(outbuf + slen,"\",\"sfp_vcc\":\"0x");
|
||||||
@@ -676,19 +590,6 @@ void send_status(void)
|
|||||||
sfp_send_data(machine.is_sfp[i] - 1, 230, 2);
|
sfp_send_data(machine.is_sfp[i] - 1, 230, 2);
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_rxpower\":\"0x");
|
slen += strtox(outbuf + slen,"\",\"sfp_rxpower\":\"0x");
|
||||||
sfp_send_data(machine.is_sfp[i] - 1, 232, 2);
|
sfp_send_data(machine.is_sfp[i] - 1, 232, 2);
|
||||||
if (sfp_options[machine.is_sfp[i]-1] & 0x10) {
|
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_temp_cal\":\"0x");
|
|
||||||
sfp_send_data(machine.is_sfp[i] - 1, 212, 4);
|
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_vcc_cal\":\"0x");
|
|
||||||
sfp_send_data(machine.is_sfp[i] - 1, 216, 4);
|
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_txbias_cal\":\"0x");
|
|
||||||
sfp_send_data(machine.is_sfp[i] - 1, 204, 4);
|
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_txpower_cal\":\"0x");
|
|
||||||
sfp_send_data(machine.is_sfp[i] - 1, 208, 4);
|
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_rxpower_cal\":\"0x");
|
|
||||||
sfp_send_data(machine.is_sfp[i] - 1, 184, 16);
|
|
||||||
sfp_send_data(machine.is_sfp[i] - 1, 200, 4);
|
|
||||||
}
|
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_state\":\"0x");
|
slen += strtox(outbuf + slen,"\",\"sfp_state\":\"0x");
|
||||||
sfp_send_data(machine.is_sfp[i] - 1, 238, 1);
|
sfp_send_data(machine.is_sfp[i] - 1, 238, 1);
|
||||||
}
|
}
|
||||||
@@ -701,12 +602,7 @@ void send_status(void)
|
|||||||
slen += strtox(outbuf + slen,"\",\"sfp_serial\":\"");
|
slen += strtox(outbuf + slen,"\",\"sfp_serial\":\"");
|
||||||
for (register uint8_t s = 0; s < 16; s++)
|
for (register uint8_t s = 0; s < 16; s++)
|
||||||
outbuf[slen++] = sfp_module_serial[machine.is_sfp[i]-1][s];
|
outbuf[slen++] = sfp_module_serial[machine.is_sfp[i]-1][s];
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_los\":");
|
char_to_html('"');
|
||||||
if (machine.sfp_port[machine.is_sfp[i]-1].pin_los == GPIO_NA) {
|
|
||||||
slen += strtox(outbuf + slen,"null");
|
|
||||||
} else {
|
|
||||||
bool_to_html(sfp_pins_last & (0x2 << (((machine.is_sfp[i]-1) << 2))));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
bool_to_html(0);
|
bool_to_html(0);
|
||||||
}
|
}
|
||||||
@@ -732,24 +628,12 @@ void send_status(void)
|
|||||||
|
|
||||||
slen += strtox(outbuf + slen, ",\"link\":");
|
slen += strtox(outbuf + slen, ",\"link\":");
|
||||||
|
|
||||||
uint8_t b = 0;
|
|
||||||
// Determine link state
|
|
||||||
reg_read_m(RTL837X_REG_LINKS_STS);
|
|
||||||
if(!((sfr_data[(i / 8) + 1] >> (i % 8 ) & 1)))
|
|
||||||
{
|
|
||||||
b = 0; //link down
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Determine link speed
|
|
||||||
if (i < 8)
|
if (i < 8)
|
||||||
reg_read_m(RTL837X_REG_LINKS);
|
reg_read_m(RTL837X_REG_LINKS);
|
||||||
else
|
else
|
||||||
reg_read_m(RTL837X_REG_LINKS_89);
|
reg_read_m(RTL837X_REG_LINKS_89);
|
||||||
|
uint8_t b = sfr_data[3 - ((i & 7) >> 1)];
|
||||||
b = sfr_data[3 - ((i & 7) >> 1)];
|
b = (i & 1) ? b >> 4 : b & 0xf;
|
||||||
b = ((i & 1) ? b >> 4 : b & 0xf) + 1;
|
|
||||||
}
|
|
||||||
char_to_html('0' + b);
|
char_to_html('0' + b);
|
||||||
|
|
||||||
STAT_GET(STAT_COUNTER_TX_PKTS, i);
|
STAT_GET(STAT_COUNTER_TX_PKTS, i);
|
||||||
@@ -781,45 +665,26 @@ void send_status(void)
|
|||||||
void send_config(void)
|
void send_config(void)
|
||||||
{
|
{
|
||||||
dbg_string("send_config called\n");
|
dbg_string("send_config called\n");
|
||||||
__xdata uint32_t pos = CONFIG_START;
|
__xdata uint32_t pos = CONFIG_START; // 70000 , 6c000 / 0xc000 = 9
|
||||||
__xdata uint16_t valid_len = 0;
|
|
||||||
__xdata uint16_t len_left = CONFIG_LEN;
|
|
||||||
__xdata uint8_t flash_buf[256];
|
|
||||||
|
|
||||||
|
extern __xdata uint16_t len_left = CONFIG_LEN;
|
||||||
slen = strtox(outbuf, HTTP_RESPONCE_TXT);
|
slen = strtox(outbuf, HTTP_RESPONCE_TXT);
|
||||||
|
while (read_flash((CONFIG_START-CODE0_SIZE) / CODE_BANK_SIZE + 1,
|
||||||
// Scan through config to find the end of valid data (null terminator)
|
(__code uint8_t *) (((CONFIG_START + len_left - CODE0_SIZE) % CODE_BANK_SIZE) + CODE0_SIZE + len_left)) == 0xff) {
|
||||||
do {
|
dbg_short(len_left);
|
||||||
flash_region.addr = pos;
|
len_left--;
|
||||||
flash_region.len = (len_left > 256) ? 256 : len_left;
|
|
||||||
flash_read_bulk(flash_buf);
|
|
||||||
|
|
||||||
// Look for null terminator in this chunk
|
|
||||||
for (uint16_t i = 0; i < flash_region.len; i++) {
|
|
||||||
if (flash_buf[i] == 0) {
|
|
||||||
// Found end of valid data
|
|
||||||
valid_len += i;
|
|
||||||
goto found_end;
|
|
||||||
}
|
}
|
||||||
|
len_left++;
|
||||||
|
|
||||||
|
if (len_left > (TCP_OUTBUF_SIZE - slen)) {
|
||||||
|
cont_len = len_left - (TCP_OUTBUF_SIZE - slen);
|
||||||
|
len_left = TCP_OUTBUF_SIZE - slen;
|
||||||
|
cont_addr = len_left;
|
||||||
}
|
}
|
||||||
|
|
||||||
valid_len += flash_region.len;
|
|
||||||
len_left -= flash_region.len;
|
|
||||||
pos += flash_region.len;
|
|
||||||
} while (len_left > 0);
|
|
||||||
|
|
||||||
found_end:
|
|
||||||
// Now send the valid data
|
|
||||||
if (valid_len > (TCP_OUTBUF_SIZE - slen)) {
|
|
||||||
cont_len = valid_len - (TCP_OUTBUF_SIZE - slen);
|
|
||||||
valid_len = TCP_OUTBUF_SIZE - slen;
|
|
||||||
cont_addr = valid_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
flash_region.addr = CONFIG_START;
|
flash_region.addr = CONFIG_START;
|
||||||
flash_region.len = valid_len;
|
flash_region.len = len_left;
|
||||||
flash_read_bulk(outbuf + slen);
|
flash_read_bulk(outbuf + slen);
|
||||||
slen += valid_len;
|
slen += len_left;
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_cmd_log(void)
|
void send_cmd_log(void)
|
||||||
@@ -838,46 +703,3 @@ void send_cmd_log(void)
|
|||||||
p = (p + 1) & CMD_HISTORY_MASK;
|
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(']');
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ void send_counters(char port);
|
|||||||
void send_status(void);
|
void send_status(void);
|
||||||
void send_vlan(uint16_t vlan);
|
void send_vlan(uint16_t vlan);
|
||||||
void send_basic_info(void);
|
void send_basic_info(void);
|
||||||
void send_bandwidth(void);
|
|
||||||
void send_eee(void);
|
void send_eee(void);
|
||||||
void send_l2(uint16_t idx);
|
void send_l2(uint16_t idx);
|
||||||
void l2_delete(uint16_t idx);
|
void l2_delete(uint16_t idx);
|
||||||
@@ -14,7 +13,6 @@ void send_mtu(void);
|
|||||||
void send_config(void);
|
void send_config(void);
|
||||||
void send_cmd_log(void);
|
void send_cmd_log(void);
|
||||||
void send_lag(void);
|
void send_lag(void);
|
||||||
void send_vlanlist(void);
|
|
||||||
|
|
||||||
/* Convert only the lower nibble to ascii HEX char.
|
/* Convert only the lower nibble to ascii HEX char.
|
||||||
For convenience the upper nibble is masked out.
|
For convenience the upper nibble is masked out.
|
||||||
|
|||||||
@@ -6,36 +6,37 @@ CC_FLAGS = -mmcs51
|
|||||||
ASM = sdas8051
|
ASM = sdas8051
|
||||||
AFLAGS= -plosgff
|
AFLAGS= -plosgff
|
||||||
|
|
||||||
BUILDDIR = output
|
BUILDDIR = output/
|
||||||
|
|
||||||
SRCS = installer.c
|
SRCS = installer.c
|
||||||
OBJS = ${SRCS:%.c=$(BUILDDIR)/%.rel}
|
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel}
|
||||||
|
|
||||||
all: create_build_dir $(BUILDDIR)/updatebuilder $(BUILDDIR)/rtlplayground_oem_upgrade.bin
|
all: create_build_dir $(BUILDDIR)updatebuilder $(BUILDDIR)rtlplayground.bin
|
||||||
|
|
||||||
create_build_dir:
|
create_build_dir:
|
||||||
mkdir -p $(BUILDDIR)
|
mkdir -p $(BUILDDIR)
|
||||||
|
|
||||||
$(BUILDDIR)/updatebuilder: updatebuilder.c
|
$(BUILDDIR)updatebuilder: updatebuilder.c
|
||||||
gcc $^ -o $@
|
gcc $^ -o $@
|
||||||
|
|
||||||
$(BUILDDIR)/installer.rel: installer.c
|
$(BUILDDIR)installer.rel: installer.c
|
||||||
$(CC) $(CC_FLAGS) --code-loc ${CODE_LOCATION} -o $@ -c $<
|
$(CC) $(CC_FLAGS) --code-loc ${CODE_LOCATION} -o $@ -c $<
|
||||||
|
|
||||||
$(BUILDDIR)/crtstart.rel: crtstart.asm
|
$(BUILDDIR)crtstart.rel: crtstart.asm
|
||||||
$(ASM) $(AFLAGS) -o $@ $<
|
$(ASM) $(AFLAGS) -o $@ $<
|
||||||
|
|
||||||
$(BUILDDIR)/%.rel: $(BUILDDIR)/%.asm
|
$(BUILDDIR)%.rel: $(BUILDDIR)%.asm
|
||||||
${ASM} ${AFLAGS} -o $@ $^
|
${ASM} ${AFLAGS} -o $@ $^
|
||||||
|
|
||||||
$(BUILDDIR)/%.rel: %.c
|
$(BUILDDIR)%.rel: %.c
|
||||||
$(CC) $(CC_FLAGS) -o $@ -c $<
|
$(CC) $(CC_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
$(BUILDDIR)/rtlinstaller.ihx: $(BUILDDIR)/crtstart.rel $(OBJS)
|
$(BUILDDIR)rtlinstaller.ihx: $(BUILDDIR)crtstart.rel $(OBJS)
|
||||||
$(CC) $(CC_FLAGS) -Wl-bHOME=${INSTALLER_ADDRESS} -Wl-r -o $@ $^
|
$(CC) $(CC_FLAGS) -Wl-bHOME=${INSTALLER_ADDRESS} -Wl-r -o $@ $^
|
||||||
|
|
||||||
$(BUILDDIR)/rtlplayground_oem_upgrade.bin: $(BUILDDIR)/rtlinstaller.ihx ../$(BUILDDIR)/rtlplayground.bin
|
$(BUILDDIR)rtlplayground.bin: $(BUILDDIR)rtlinstaller.ihx ../$(BUILDDIR)/rtlplayground.bin
|
||||||
./$(BUILDDIR)/updatebuilder -i $< -o $(BUILDDIR)/rtlplayground_oem_upgrade.bin ../$(BUILDDIR)/rtlplayground.bin
|
cp ../$(BUILDDIR)/rtlplayground.bin $(BUILDDIR)
|
||||||
|
./$(BUILDDIR)/updatebuilder -i $< $(BUILDDIR)rtlplayground.bin
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -r $(BUILDDIR)
|
rm -r $(BUILDDIR)
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "rtl837x_pins.h"
|
#include "rtl837x_pins.h"
|
||||||
#include "rtl837x_leds.h"
|
#include "rtl837x_leds.h"
|
||||||
#include "rtl837x_sfr.h"
|
|
||||||
#include "rtl837x_regs.h"
|
|
||||||
#include "rtl837x_common.h"
|
|
||||||
|
|
||||||
#ifdef MACHINE_KP_9000_6XHML_X2
|
#ifdef MACHINE_KP_9000_6XHML_X2
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
@@ -14,21 +11,19 @@ __code const struct machine machine = {
|
|||||||
.n_sfp = 2,
|
.n_sfp = 2,
|
||||||
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
.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},
|
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||||
.is_sfp = {0, 0, 0, 1, 0, 0, 0, 0, 2},
|
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
// Left SFP port (5)
|
|
||||||
.sfp_port[0].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
.sfp_port[0].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
||||||
.sfp_port[0].pin_los = GPIO10_LED10,
|
.sfp_port[0].pin_los = GPIO10_LED10,
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
.sfp_port[0].sds = 0,
|
.sfp_port[0].sds = 0,
|
||||||
.sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
// Right SFP port (6)
|
|
||||||
.sfp_port[1].pin_detect = GPIO30_ACL_BIT3_EN,
|
.sfp_port[1].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
.sfp_port[1].pin_los = GPIO37,
|
.sfp_port[1].pin_los = GPIO37,
|
||||||
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
.sfp_port[1].sds = 1,
|
.sfp_port[1].sds = 1,
|
||||||
.sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
.reset_pin = GPIO54_ACL_BIT2_EN,
|
.reset_pin = GPIO46_I2C_SCL0,
|
||||||
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 },
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
/* Conditions for LED on:
|
/* Conditions for LED on:
|
||||||
* dual led orange: ledset_0 & ledset_2
|
* dual led orange: ledset_0 & ledset_2
|
||||||
@@ -40,10 +35,14 @@ __code const struct machine machine = {
|
|||||||
LEDS_1G | LEDS_LINK,
|
LEDS_1G | LEDS_LINK,
|
||||||
0 },
|
0 },
|
||||||
},
|
},
|
||||||
|
.led_mux_custom = 0,
|
||||||
|
// LED0 LED1 LED2 LED3 LED4 LED5 LED6 LED7 LED8 LED9 LED10 LED11 LED12 LED13 LED14 LED15
|
||||||
|
// L-SFP R-SFP | PORT 1
|
||||||
|
// LED16 LED17 LED18 LED19 LED20 LED21 LED22 LED23 LED24 LED25 LED26 LED27
|
||||||
|
// | PORT 2 | PORT 3 | PORT 4
|
||||||
|
// .led_mux = { 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x0f, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14,
|
||||||
|
// 0x15, 0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x23 },
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_KP_9000_6XH_X
|
#elif defined MACHINE_KP_9000_6XH_X
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "keepLink KP-9000-6XH-X",
|
.machine_name = "keepLink KP-9000-6XH-X",
|
||||||
@@ -58,6 +57,7 @@ __code const struct machine machine = {
|
|||||||
.sfp_port[0].pin_los = GPIO37,
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
.sfp_port[0].sds = 1,
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c_bus = { .sda = 4, .scl = 3 },
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
.reset_pin = GPIO_NA,
|
.reset_pin = GPIO_NA,
|
||||||
/* Conditions for LED on:
|
/* Conditions for LED on:
|
||||||
@@ -71,64 +71,9 @@ __code const struct machine machine = {
|
|||||||
0 },
|
0 },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_KP_9000_6XH_X2
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "keepLink KP-9000-6XH-X2",
|
|
||||||
.isRTL8373 = 0,
|
|
||||||
.min_port = 3,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 2,
|
|
||||||
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
|
||||||
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
|
||||||
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
|
||||||
|
|
||||||
// Left SFP port
|
|
||||||
.sfp_port[0].pin_detect = GPIO38,
|
|
||||||
.sfp_port[0].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
|
|
||||||
// Right SFP port
|
|
||||||
.sfp_port[1].pin_detect = GPIO37,
|
|
||||||
.sfp_port[1].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[1].sds = 0,
|
|
||||||
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
|
|
||||||
.reset_pin = GPIO48_I2C_SCL1, // Button-Switch is unpopulated on PCB, but can be added manually (hole in case is already there)
|
|
||||||
.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, // Left LED (Amber)
|
|
||||||
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // Right LED (Green)
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined MACHINE_KP_9000_9XH_X_EU
|
#elif defined MACHINE_KP_9000_9XH_X_EU
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "keepLink KP-9000-9XH-X-EU",
|
.machine_name = "keepLink KP-9000-6XH-X-EU",
|
||||||
.isRTL8373 = 1,
|
.isRTL8373 = 1,
|
||||||
.min_port = 0,
|
.min_port = 0,
|
||||||
.max_port = 8,
|
.max_port = 8,
|
||||||
@@ -142,7 +87,7 @@ __code const struct machine machine = {
|
|||||||
.sfp_port[0].sds = 1,
|
.sfp_port[0].sds = 1,
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
.reset_pin = GPIO_NA,
|
.reset_pin = GPIO_NA,
|
||||||
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 },
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
.led_sets = { { LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
.led_sets = { { LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
||||||
LEDS_2G5 | LEDS_LINK,
|
LEDS_2G5 | LEDS_LINK,
|
||||||
@@ -151,144 +96,9 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
#elif defined MACHINE_SWGT024_V2_0
|
||||||
|
|
||||||
#elif defined MACHINE_KP_9000_9XHML_X_V2_2
|
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "keepLink KP-9000-9XHML-X V2.2",
|
.machine_name = "SWGT024 V2.0",
|
||||||
.isRTL8373 = 1,
|
|
||||||
.min_port = 0,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 1,
|
|
||||||
.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 },
|
|
||||||
.is_sfp = { 0, 0, 0, 0, 0, 0, 0, 0, 1 },
|
|
||||||
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
|
||||||
.sfp_port[0].pin_los = GPIO37,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
.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, 1 },
|
|
||||||
.led_sets = {
|
|
||||||
{ /* Set 0 for RJ45 connectors */
|
|
||||||
/* LED0: Right Green */
|
|
||||||
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
/* LED1: Left Orange */
|
|
||||||
LEDS_2G5 | LEDS_LINK,
|
|
||||||
/* LED2: Left Green */
|
|
||||||
LEDS_1G | LEDS_LINK,
|
|
||||||
/* LED3: None */
|
|
||||||
0,
|
|
||||||
}, { /* Set 1 for SFP port */
|
|
||||||
/* LED0: Single Green "9" LED */
|
|
||||||
LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
|
||||||
/* LED1: D23 LED on PCB */
|
|
||||||
LEDS_1G | LEDS_LINK,
|
|
||||||
/* LED2: D22 LED on PCB */
|
|
||||||
LEDS_2G5 | LEDS_LINK,
|
|
||||||
/* LED3: Unused */
|
|
||||||
LEDS_COL | LEDS_DUPLEX,
|
|
||||||
}, { /* Set 2: Unused, but set to same things as stock firmware for consistency */
|
|
||||||
LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
LEDS_1G | LEDS_LINK | LEDS_ACT,
|
|
||||||
LEDS_2G5 | LEDS_LINK | LEDS_ACT | LEDS_5G,
|
|
||||||
LEDS_10G | LEDS_ACT | LEDS_LINK,
|
|
||||||
}, { /* Set 3: Unused, but set to same things as stock firmware for consistency */
|
|
||||||
LEDS_TX,
|
|
||||||
LEDS_RX,
|
|
||||||
LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
|
||||||
LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_KP_9000_9XHML_X_V3_1
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "keepLink KP-9000-9XHML-X V3.1",
|
|
||||||
.isRTL8373 = 1,
|
|
||||||
.min_port = 0,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 1,
|
|
||||||
.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},
|
|
||||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
.sfp_port[0].pin_detect = GPIO38,
|
|
||||||
.sfp_port[0].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
.reset_pin = GPIO48_I2C_SCL1,
|
|
||||||
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
.led_sets = {
|
|
||||||
{ /* RJ45: First LED, yellow, second LED: green */
|
|
||||||
LEDS_2G5 | LEDS_LINK,
|
|
||||||
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
}, { /* SFP PORT, SINGLE GREEN LED */
|
|
||||||
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
}},
|
|
||||||
.led_mux_custom = 1,
|
|
||||||
.led_mux = {0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0c, 0x09, 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) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_SWGT024_V2_0_MANAGED
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "SWGT024 V2.0 Managed",
|
|
||||||
.isRTL8373 = 0,
|
|
||||||
.min_port = 3,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 2,
|
|
||||||
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
|
||||||
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
|
||||||
.is_sfp= {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
|
||||||
// Left SFP port (J4)
|
|
||||||
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
|
||||||
.sfp_port[0].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 39 */
|
|
||||||
// Right SFP port (J2)
|
|
||||||
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
|
||||||
.sfp_port[1].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[1].sds = 0,
|
|
||||||
.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, 1, 0, 0, 0, 0, 1},
|
|
||||||
.led_sets = {
|
|
||||||
{ /* 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,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_SWGT024_V2_0_UNMANAGED
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "SWGT024 V2.0 Unmanaged",
|
|
||||||
.isRTL8373 = 0,
|
.isRTL8373 = 0,
|
||||||
.min_port = 3,
|
.min_port = 3,
|
||||||
.max_port = 8,
|
.max_port = 8,
|
||||||
@@ -308,68 +118,21 @@ __code const struct machine machine = {
|
|||||||
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
.sfp_port[1].sds = 0,
|
.sfp_port[1].sds = 0,
|
||||||
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 40 */
|
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 40 */
|
||||||
.reset_pin = GPIO_NA,
|
.reset_pin = GPIO36_PWM_OUT,
|
||||||
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 },
|
||||||
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
.led_sets = {
|
/* Conditions for LED on:
|
||||||
{ /* RJ45: Green LED */
|
* dual led orange: ledset_0 & ledset_2
|
||||||
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
* dual led green: ledset_2 & !ledset_0
|
||||||
0,
|
* single right led green: ledset_0 & !ledset_1
|
||||||
/* Amber LED */
|
*/
|
||||||
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
.led_sets = { { LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
0
|
LEDS_2G5 | LEDS_LINK | LEDS_10G,
|
||||||
}, { /* SFP PORT: SINGLE GREEN LED */
|
LEDS_1G | LEDS_LINK,
|
||||||
LEDS_10M | LEDS_100M | LEDS_1G | LEDS_2G5 | LEDS_10G | LEDS_LINK | LEDS_ACT,
|
0 },
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_SWTG018AS_A_V_2_0
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "SWTG018AS-A V2.0",
|
|
||||||
.isRTL8373 = 1,
|
|
||||||
.min_port = 0,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 1,
|
|
||||||
.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},
|
|
||||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
.sfp_port[0].pin_detect = GPIO38,
|
|
||||||
.sfp_port[0].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
.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, 1},
|
|
||||||
.led_sets = {
|
|
||||||
{ /* RJ45: First LED, yellow, second LED: green */
|
|
||||||
LEDS_2G5 | LEDS_LINK,
|
|
||||||
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
}, { /* SFP PORT, SINGLE GREEN LED */
|
|
||||||
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
}},
|
|
||||||
.led_mux_custom = 1,
|
|
||||||
.led_mux = { 0x00, 0x01, 0x04, 0x05, 0x08, // 65e0
|
|
||||||
0x09, 0x0c, 0x09, 0x0d, 0x10, // 65e4
|
|
||||||
0x11, 0x0e, 0x14, 0x11, 0x12, // 65e8
|
|
||||||
0x15, 0x15, 0x16, 0x18, 0x19, // 65ec
|
|
||||||
0x1a, 0x19, 0x1d, 0x1e, 0x1c, // 65f0
|
|
||||||
0x1d, 0x20, 0x21 },
|
|
||||||
};
|
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_HG0402XG_V1_1
|
#elif defined MACHINE_HG0402XG_V1_1
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "HG0402XG V1.1",
|
.machine_name = "HG0402XG V1.1",
|
||||||
@@ -384,12 +147,12 @@ __code const struct machine machine = {
|
|||||||
.sfp_port[0].pin_los = 10,
|
.sfp_port[0].pin_los = 10,
|
||||||
.sfp_port[0].pin_tx_disable = 0xFF,
|
.sfp_port[0].pin_tx_disable = 0xFF,
|
||||||
.sfp_port[0].sds = 1,
|
.sfp_port[0].sds = 1,
|
||||||
.sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[0].i2c_bus ={ .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
.sfp_port[1].pin_detect = 30,
|
.sfp_port[1].pin_detect = 30,
|
||||||
.sfp_port[1].pin_los = 51,
|
.sfp_port[1].pin_los = 51,
|
||||||
.sfp_port[1].pin_tx_disable = 0xFF,
|
.sfp_port[1].pin_tx_disable = 0xFF,
|
||||||
.sfp_port[1].sds = 0,
|
.sfp_port[1].sds = 0,
|
||||||
.sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[1].i2c_bus = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
.reset_pin = GPIO_NA,
|
.reset_pin = GPIO_NA,
|
||||||
.high_leds = { .mux = LED_27 , .enable = LED_27 | LED_29 },
|
.high_leds = { .mux = LED_27 , .enable = LED_27 | LED_29 },
|
||||||
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
@@ -407,45 +170,9 @@ __code const struct machine machine = {
|
|||||||
0 },
|
0 },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
#elif defined MACHINE_ZX_SWTGW215AS_HASIVO
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_SWTGW218AS
|
|
||||||
|
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "SWTGW218AS 8+1 Managed Switch",
|
.machine_name = "ZX-SWTGW215AS HASIVO",
|
||||||
.isRTL8373 = 1,
|
|
||||||
.min_port = 0,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 1,
|
|
||||||
.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},
|
|
||||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
|
||||||
.sfp_port[0].pin_los = GPIO37,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
.reset_pin = GPIO54_ACL_BIT2_EN,
|
|
||||||
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
|
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
.led_sets = { { LEDS_2G5 | LEDS_LINK | LEDS_ACT, // Green LED (right)
|
|
||||||
0, // unused
|
|
||||||
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // Amber LED (left)
|
|
||||||
0
|
|
||||||
}, // unused
|
|
||||||
{ LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT, // SFP LED
|
|
||||||
0, // unused
|
|
||||||
0, // unused
|
|
||||||
0
|
|
||||||
}, // unused },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
#elif defined MACHINE_LIANGUO_ZX_SWTGW215AS // Has PCB branded PCB-SWTG115AS-V2.0 but is labeled and reports as a ZX-SWTGW215AS, seems to be identical to the "real" ZX-SWTGW215AS except for the LEDs
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "Lianguo ZX-SWTGW215AS",
|
|
||||||
.isRTL8373 = 0,
|
.isRTL8373 = 0,
|
||||||
.min_port = 3,
|
.min_port = 3,
|
||||||
.max_port = 8,
|
.max_port = 8,
|
||||||
@@ -458,26 +185,33 @@ __code const struct machine machine = {
|
|||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
.sfp_port[0].sds = 1,
|
.sfp_port[0].sds = 1,
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
|
.sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
.reset_pin = GPIO54_ACL_BIT2_EN,
|
.reset_pin = GPIO54_ACL_BIT2_EN,
|
||||||
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 },
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
.led_sets = { { LEDS_2G5 | LEDS_LINK | LEDS_ACT, // Green LED (right)
|
.led_sets = {
|
||||||
0, // unused
|
/* The Ethernet ports have 1 amber LED (bi-color left) and 2 green LED (left/right)
|
||||||
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // Amber LED (left)
|
* The SFP port has 1 green LED
|
||||||
0
|
* Ethernet ports use LED-set 0, SFP port uses LED-set 1
|
||||||
}, // unused
|
* Amber-LED: ledid0 & ledid1 & !ledid2
|
||||||
{ LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT, // SFP LED
|
* Left-Green: ledid-2
|
||||||
0, // unused
|
* Right-Green: ledid-0
|
||||||
0, // unused
|
* ledid3 is not used
|
||||||
0
|
*/
|
||||||
}, // unused },
|
{ LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_10G,
|
||||||
|
LEDS_1G | LEDS_LINK,
|
||||||
|
0 },
|
||||||
|
{
|
||||||
|
LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
||||||
|
LEDS_1G | LEDS_LINK,
|
||||||
|
LEDS_2G5 | LEDS_LINK,
|
||||||
|
LEDS_COL | LEDS_DUPLEX,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
.led_mux_custom = 0,
|
.led_mux_custom = 0,
|
||||||
};
|
};
|
||||||
|
#elif defined DEFAULT_8C_1SFP
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_DEFAULT_8C_1SFP
|
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "8+1 SFP Port Switch",
|
.machine_name = "8+1 SFP Port Switch",
|
||||||
.isRTL8373 = 1,
|
.isRTL8373 = 1,
|
||||||
@@ -493,7 +227,7 @@ __code const struct machine machine = {
|
|||||||
.sfp_port[0].sds = 1,
|
.sfp_port[0].sds = 1,
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
.reset_pin = GPIO_NA,
|
.reset_pin = GPIO_NA,
|
||||||
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 },
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
.led_sets = { { LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
.led_sets = { { LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
||||||
LEDS_2G5 | LEDS_LINK,
|
LEDS_2G5 | LEDS_LINK,
|
||||||
@@ -501,392 +235,4 @@ __code const struct machine machine = {
|
|||||||
LEDS_2G5 | LEDS_LINK | LEDS_ACT },
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_TRENDNET_TEG_S562
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "Trendnet TEG-S562",
|
|
||||||
.isRTL8373 = 0,
|
|
||||||
.min_port = 3,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 2,
|
|
||||||
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
|
||||||
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
|
||||||
.is_sfp = {0, 0, 0, 1, 0, 0, 0, 0, 2},
|
|
||||||
.sfp_port[0].pin_detect = GPIO38,
|
|
||||||
.sfp_port[0].pin_los = GPIO50_I2C_SCL2_UART1_TX,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO54_ACL_BIT2_EN,
|
|
||||||
.sfp_port[0].sds = 0,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO47_I2C_SDA0, .scl = GPIO46_I2C_SCL0 },
|
|
||||||
.sfp_port[1].pin_detect = GPIO36_PWM_OUT,
|
|
||||||
.sfp_port[1].pin_los = GPIO37,
|
|
||||||
.sfp_port[1].pin_tx_disable = GPIO51_I2C_SDA2_UART1_RX,
|
|
||||||
.sfp_port[1].sds = 1,
|
|
||||||
.sfp_port[1].i2c = { .sda = GPIO49_I2C_SDA1, .scl = GPIO48_I2C_SCL1 },
|
|
||||||
.reset_pin = GPIO_NA,
|
|
||||||
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
|
||||||
.led_sets = {
|
|
||||||
{
|
|
||||||
0, // Unused
|
|
||||||
LEDS_2G5 | LEDS_LINK | LEDS_ACT, // Green
|
|
||||||
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // Amber
|
|
||||||
0 // Unused
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0, // Unused
|
|
||||||
0, // Unused
|
|
||||||
LEDS_10G | LEDS_1G | LEDS_LINK | LEDS_ACT, // Green
|
|
||||||
0, // Unused
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#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 = "PCB-K0402WS-V3.0",
|
|
||||||
.isRTL8373 = 0,
|
|
||||||
.min_port = 3,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 2,
|
|
||||||
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
|
||||||
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
|
||||||
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
|
||||||
|
|
||||||
// Left SFP port
|
|
||||||
.sfp_port[0].pin_detect = GPIO38,
|
|
||||||
.sfp_port[0].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
|
|
||||||
// Right SFP port
|
|
||||||
.sfp_port[1].pin_detect = GPIO37,
|
|
||||||
.sfp_port[1].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[1].sds = 0,
|
|
||||||
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .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_10M | LEDS_ACT,
|
|
||||||
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
|
||||||
LEDS_1G | LEDS_LINK,
|
|
||||||
0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK,
|
|
||||||
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined MACHINE_K0501W_V2_0
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "K0501W V2.0",
|
|
||||||
.isRTL8373 = 0,
|
|
||||||
.min_port = 3,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 1,
|
|
||||||
.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, 1},
|
|
||||||
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
|
||||||
.sfp_port[0].pin_los = GPIO37,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
|
|
||||||
.reset_pin = GPIO_NA,
|
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
.led_sets = {
|
|
||||||
{
|
|
||||||
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_ZX310S_4T2XH
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "ZX310S-4T2XH",
|
|
||||||
.isRTL8373 = 0,
|
|
||||||
.min_port = 3,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 1,
|
|
||||||
.n_10g = 1,
|
|
||||||
.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, 1},
|
|
||||||
.sfp_port[0].pin_detect = GPIO38,
|
|
||||||
.sfp_port[0].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
.reset_pin = GPIO48_I2C_SCL1,
|
|
||||||
.high_leds = { .mux = LED_28_SYS, .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: Orange: 2.5GBit, Green: 10/100/1000MBit
|
|
||||||
* Port 5: Blue: 10GBit, Green: 10Mbit-5GBit
|
|
||||||
* SFP-port: Blue: 10GBit, Green 100MBit-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_5G,
|
|
||||||
LEDS_LINK | LEDS_ACT | LEDS_10G,
|
|
||||||
LEDS_2G5 | LEDS_LINK,
|
|
||||||
LEDS_COL | LEDS_DUPLEX
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_HI_K0801WS
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "Hi-Source HI-k0801WS",
|
|
||||||
.isRTL8373 = 1,
|
|
||||||
.min_port = 0,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 1,
|
|
||||||
.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},
|
|
||||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
|
|
||||||
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
|
||||||
.sfp_port[0].pin_los = GPIO37,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = {
|
|
||||||
.sda = GPIO39_I2C_SDA4,
|
|
||||||
.scl = GPIO40_I2C_SCL3_MDC1
|
|
||||||
},
|
|
||||||
|
|
||||||
.reset_pin = GPIO_NA,
|
|
||||||
|
|
||||||
.high_leds = {
|
|
||||||
.mux = LED_27 | LED_29,
|
|
||||||
.enable = LED_28_SYS | LED_29
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Ports 1-8 use set 0, port 9 SFP uses set 1 */
|
|
||||||
.port_led_set = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
|
|
||||||
.led_sets = {
|
|
||||||
{ /* Set 0: RJ45 copper ports
|
|
||||||
* Amber = 2.5G
|
|
||||||
* Green = 1G/100M/10M with activity
|
|
||||||
*/
|
|
||||||
LEDS_2G5 | LEDS_LINK | LEDS_ACT, /* Amber */
|
|
||||||
0,
|
|
||||||
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, /* Green */
|
|
||||||
0
|
|
||||||
},
|
|
||||||
{ /* Set 1: SFP port, single green LED for all valid speeds */
|
|
||||||
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_FNS1200P
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "FNS-1200P",
|
|
||||||
.isRTL8373 = 0,
|
|
||||||
.min_port = 3,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 2,
|
|
||||||
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
|
||||||
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
|
||||||
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
|
||||||
|
|
||||||
/* Left SFP (logical 8, SDS1): GPIO30=ModAbs, GPIO37=RX_LOS */
|
|
||||||
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
|
||||||
.sfp_port[0].pin_los = GPIO37,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
|
|
||||||
/* Right SFP (logical 3, SDS0): GPIO50=ModAbs, GPIO51=RX_LOS */
|
|
||||||
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
|
||||||
.sfp_port[1].pin_los = GPIO51_I2C_SDA2_UART1_RX,
|
|
||||||
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[1].sds = 0,
|
|
||||||
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
|
|
||||||
.reset_pin = GPIO_NA,
|
|
||||||
|
|
||||||
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
|
|
||||||
|
|
||||||
/* Copper ports use SET0; SFP ports use SET1 */
|
|
||||||
.port_led_set = {0, 0, 0, 1, 0, 0, 0, 0, 1},
|
|
||||||
|
|
||||||
.led_sets = {
|
|
||||||
{ /* SET0: copper — LED0=amber (2.5G), LED2=green (1G/100M/10M) */
|
|
||||||
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
0
|
|
||||||
},
|
|
||||||
{ /* SET1: SFP — all speeds link/act */
|
|
||||||
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
0, 0
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
.led_mux_custom = 1,
|
|
||||||
.led_mux = {
|
|
||||||
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, /* GPIO0-7: unused */
|
|
||||||
0x0f, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12, /* GPIO8-14 */
|
|
||||||
0x14, 0x15, 0x16, 0x18, 0x19, 0x1a, /* GPIO15-20 */
|
|
||||||
0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x23 /* GPIO21-27 */
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
#endif
|
||||||
|
|||||||
@@ -8,25 +8,14 @@
|
|||||||
*/
|
*/
|
||||||
// #define MACHINE_KP_9000_6XHML_X2
|
// #define MACHINE_KP_9000_6XHML_X2
|
||||||
// #define MACHINE_KP_9000_6XH_X
|
// #define MACHINE_KP_9000_6XH_X
|
||||||
// #define MACHINE_KP_9000_6XH_X2
|
|
||||||
// #define MACHINE_KP_9000_9XH_X_EU
|
// #define MACHINE_KP_9000_9XH_X_EU
|
||||||
// #define MACHINE_KP_9000_9XHML_X_V2_2
|
// #define MACHINE_SWGT024_V2_0
|
||||||
// #define MACHINE_KP_9000_9XHML_X_V3_1
|
// #define MACHINE_HORACO_ZX_SG4T2
|
||||||
// #define MACHINE_SWGT024_V2_0_MANAGED
|
|
||||||
// #define MACHINE_SWGT024_V2_0_UNMANAGED
|
|
||||||
// #define MACHINE_TRENDNET_TEG_S562
|
|
||||||
// #define MACHINE_HG0402XG_V1_1
|
// #define MACHINE_HG0402XG_V1_1
|
||||||
// #define MACHINE_SWTG018AS_A_V_2_0
|
#define MACHINE_ZX_SWTGW215AS_HASIVO
|
||||||
// #define MACHINE_SWTGW218AS
|
// #define DEFAULT_8C_1SFP
|
||||||
// #define MACHINE_PCB_K0402WS_V3
|
|
||||||
// #define MACHINE_K0501W_V2_0
|
// #define DEFAULT_5C_1SFP
|
||||||
// #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 {
|
typedef struct {
|
||||||
// GPIO pins for SDA/SCL
|
// GPIO pins for SDA/SCL
|
||||||
@@ -36,8 +25,7 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
#define LED_27 1
|
#define LED_27 1
|
||||||
// SYSTEM LED
|
#define LED_28 2
|
||||||
#define LED_28_SYS 2
|
|
||||||
#define LED_29 4
|
#define LED_29 4
|
||||||
|
|
||||||
struct high_leds {
|
struct high_leds {
|
||||||
@@ -59,25 +47,17 @@ struct sfp_port
|
|||||||
typedef struct machine {
|
typedef struct machine {
|
||||||
char machine_name[30];
|
char machine_name[30];
|
||||||
uint8_t isRTL8373;
|
uint8_t isRTL8373;
|
||||||
// Lowest logical port number
|
|
||||||
uint8_t min_port;
|
uint8_t min_port;
|
||||||
// Highest logical port number
|
|
||||||
uint8_t max_port;
|
uint8_t max_port;
|
||||||
uint8_t n_sfp;
|
uint8_t n_sfp;
|
||||||
uint8_t n_10g;
|
|
||||||
uint8_t log_to_phys_port[9];
|
uint8_t log_to_phys_port[9];
|
||||||
uint8_t phys_to_log_port[9]; // Starts at 0 for port 1
|
uint8_t phys_to_log_port[9]; // Starts at 0 for port 1
|
||||||
uint8_t is_sfp[9]; // 0 for non-SFP ports 1 or 2 for the I2C port number
|
uint8_t is_sfp[9]; // 0 for non-SFP ports 1 or 2 for the I2C port number
|
||||||
// sfp_port[0] is the first SFP-port from the left on the device, sfp_port[1] the next if present
|
// sfp_port[0] is the first SFP-port from the left on the device, sfp_port[1] the next if present
|
||||||
struct sfp_port sfp_port[2];
|
struct sfp_port sfp_port[2];
|
||||||
uint8_t reset_pin;
|
int8_t reset_pin;
|
||||||
struct high_leds high_leds;
|
struct high_leds high_leds;
|
||||||
// Defines which led-set (0-3) will be used for given logical port
|
|
||||||
// led-set is physical group of LEDs that can be configured to show different port status combinations (see port_led_set below)
|
|
||||||
uint8_t port_led_set[9];
|
uint8_t port_led_set[9];
|
||||||
// Defines led-set configuration, applied to all ports using particular led-set
|
|
||||||
// Each led-set can have 4 different hardware LED configurations. Which one should be used, depends how LED is wired on the board
|
|
||||||
// See stock RTL837X_REG_LED3_2_SETx and RTL837X_REG_LED1_0_SETx registers for reference configuration
|
|
||||||
uint32_t led_sets[4][4];
|
uint32_t led_sets[4][4];
|
||||||
uint8_t led_mux_custom;
|
uint8_t led_mux_custom;
|
||||||
uint8_t led_mux[28];
|
uint8_t led_mux[28];
|
||||||
@@ -89,6 +69,4 @@ typedef struct machine_runtime
|
|||||||
uint8_t isN : 1;
|
uint8_t isN : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -28,15 +28,10 @@
|
|||||||
#define PHY_EEE_LP_ABILITY 0x3d
|
#define PHY_EEE_LP_ABILITY 0x3d
|
||||||
#define PHY_EEE_ADV2 0x3e
|
#define PHY_EEE_ADV2 0x3e
|
||||||
#define PHY_EEE_LP_ABILITY2 0x3f
|
#define PHY_EEE_LP_ABILITY2 0x3f
|
||||||
|
|
||||||
// Register bits for EEE capabilities at a given speed
|
// Register bits for EEE capabilities at a given speed
|
||||||
// PHY_EEE_ADV2
|
|
||||||
#define PHY_EEE_BIT_2G5 0x01
|
#define PHY_EEE_BIT_2G5 0x01
|
||||||
#define PHY_EEE_BIT_5G 0x02
|
|
||||||
// PHY_EEE_ADV
|
|
||||||
#define PHY_EEE_BIT_1G 0x04
|
#define PHY_EEE_BIT_1G 0x04
|
||||||
#define PHY_EEE_BIT_100M 0x02
|
#define PHY_EEE_BIT_100M 0x02
|
||||||
#define PHY_EEE_BIT_10G 0x08
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MMD 31 Registers
|
* MMD 31 Registers
|
||||||
|
|||||||
@@ -1,122 +0,0 @@
|
|||||||
// #define REGDBG
|
|
||||||
// #define DEBUG
|
|
||||||
|
|
||||||
#include "rtl837x_common.h"
|
|
||||||
#include "rtl837x_sfr.h"
|
|
||||||
#include "rtl837x_regs.h"
|
|
||||||
#include "rtl837x_bandwidth.h"
|
|
||||||
#include "machine.h"
|
|
||||||
|
|
||||||
#pragma codeseg BANK2
|
|
||||||
#pragma constseg BANK2
|
|
||||||
|
|
||||||
extern __xdata uint8_t sfr_data[4];
|
|
||||||
|
|
||||||
void bandwidth_setup(void) __banked
|
|
||||||
{
|
|
||||||
print_string("bandwidth_setup called\n");
|
|
||||||
// Exclude all packets possibly for the CPU port, but do not include bypassed packets or Inter-Frame-Gap into bandwidth
|
|
||||||
REG_SET(RTL837X_IGBW_CTRL, IGBW_ADM_DHCP | IGBW_ADM_ARPREQ | IGBW_ADM_RMA | IGBW_ADM_BPDU | IGBW_ADM_RTKPKT | IGBW_ADM_IGMP);
|
|
||||||
|
|
||||||
// We do not count IFG for Egress and allways allow CPU-traffic
|
|
||||||
REG_SET(RTL837X_EGBW_CTRL, EGBW_CPUMODE);
|
|
||||||
|
|
||||||
print_string("RTL837X_IGBW_CTRL: "); print_reg(RTL837X_IGBW_CTRL); write_char('\n');
|
|
||||||
print_string("RTL837X_EGBW_CTRL: "); print_reg(RTL837X_EGBW_CTRL); write_char('\n');
|
|
||||||
print_string("bandwidth_setup done\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the ingress bandwidth
|
|
||||||
* bw: Bandwidth in kb
|
|
||||||
*/
|
|
||||||
void bandwidth_ingress_set(uint8_t port, __xdata uint32_t bw) __banked
|
|
||||||
{
|
|
||||||
__xdata uint8_t * __xdata bwptr = &bw;
|
|
||||||
|
|
||||||
print_string("bandwidth_ingress_set called, port "); print_byte(port); write_char('\n');
|
|
||||||
sfr_data[0] = 0;
|
|
||||||
sfr_data[1] = 0x10 | (*(bwptr + 2) >> 4); // Set bit 20 to enable ingress bandwidth control
|
|
||||||
sfr_data[2] = (*(bwptr + 2) << 4) | (*(bwptr + 1) >> 4);
|
|
||||||
sfr_data[3] = (*(bwptr) >> 4) | (*(bwptr + 1) << 4);
|
|
||||||
reg_write_m(RTL837X_IGBW_PORT_CTRL + port * 4);
|
|
||||||
|
|
||||||
// We enable Flow Control instead of just dropping packets
|
|
||||||
reg_bit_set(RTL837X_IGBW_PORT_FC_CTRL, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void bandwidth_ingress_drop(uint8_t port) __banked
|
|
||||||
{
|
|
||||||
reg_bit_clear(RTL837X_IGBW_PORT_FC_CTRL, port);
|
|
||||||
print_string("RTL837X_IGBW_PORT_FC_CTRL:"); print_reg(RTL837X_IGBW_PORT_FC_CTRL); write_char('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void bandwidth_ingress_fc(uint8_t port) __banked
|
|
||||||
{
|
|
||||||
reg_bit_set(RTL837X_IGBW_PORT_FC_CTRL, port);
|
|
||||||
print_string("RTL837X_IGBW_PORT_FC_CTRL:"); print_reg(RTL837X_IGBW_PORT_FC_CTRL); write_char('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void bandwidth_ingress_disable(uint8_t port) __banked
|
|
||||||
{
|
|
||||||
print_string("Ingress bandwidth limit disabled, port "); print_byte(port); write_char('\n');
|
|
||||||
REG_SET(RTL837X_IGBW_PORT_CTRL + port * 4, 0x0fffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void bandwidth_egress_set(uint8_t port, __xdata uint32_t bw) __banked
|
|
||||||
{
|
|
||||||
__xdata uint8_t * __xdata bwptr = &bw;
|
|
||||||
|
|
||||||
print_string("bandwidth_egress_set called, port "); print_byte(port); write_char('\n');
|
|
||||||
sfr_data[0] = 0;
|
|
||||||
sfr_data[1] = 0x10 | (*(bwptr + 2) >> 4); // Set bit 20 to enable egress bandwidth control
|
|
||||||
sfr_data[2] = (*(bwptr + 2) << 4) | (*(bwptr + 1) >> 4);
|
|
||||||
sfr_data[3] = (*(bwptr) >> 4) | (*(bwptr + 1) << 4);
|
|
||||||
reg_write_m(RTL837X_EGBW_PORT_CTRL + port * 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void bandwidth_egress_disable(uint8_t port) __banked
|
|
||||||
{
|
|
||||||
print_string("Egress bandwidth limit disabled, port "); print_byte(port); write_char('\n');
|
|
||||||
REG_SET(RTL837X_EGBW_PORT_CTRL + port * 1024, 0x0fffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void bandwidth_status(uint8_t port) __banked
|
|
||||||
{
|
|
||||||
print_string("ingress: ");
|
|
||||||
reg_read_m(RTL837X_IGBW_PORT_CTRL + port * 4);
|
|
||||||
if (sfr_data[1] & 0x10) {
|
|
||||||
print_string("enabled: ");
|
|
||||||
sfr_data[1] &= 0xef;
|
|
||||||
print_string("0x");
|
|
||||||
print_byte(sfr_data[1]);
|
|
||||||
print_byte(sfr_data[2]);
|
|
||||||
print_byte(sfr_data[3]);
|
|
||||||
write_char('0');
|
|
||||||
write_char('\n');
|
|
||||||
} else {
|
|
||||||
print_string("disabled\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
print_string("egress: ");
|
|
||||||
reg_read_m(RTL837X_EGBW_PORT_CTRL + port * 1024);
|
|
||||||
if (sfr_data[1] & 0x10) {
|
|
||||||
print_string("enabled: ");
|
|
||||||
sfr_data[1] &= 0xef;
|
|
||||||
print_string("0x");
|
|
||||||
print_byte(sfr_data[1]);
|
|
||||||
print_byte(sfr_data[2]);
|
|
||||||
print_byte(sfr_data[3]);
|
|
||||||
write_char('0');
|
|
||||||
write_char('\n');
|
|
||||||
} else {
|
|
||||||
print_string("disabled\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#ifndef _RTL837X_BANDWIDTH_H_
|
|
||||||
#define _RTL837X_BANDWIDTH_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void bandwidth_setup(void) __banked;
|
|
||||||
void bandwidth_ingress_set(uint8_t port, __xdata uint32_t bw) __banked;
|
|
||||||
void bandwidth_ingress_disable(uint8_t port) __banked;
|
|
||||||
void bandwidth_ingress_drop(uint8_t port) __banked;
|
|
||||||
void bandwidth_ingress_fc(uint8_t port) __banked;
|
|
||||||
void bandwidth_egress_set(uint8_t port, __xdata uint32_t bw) __banked;
|
|
||||||
void bandwidth_egress_disable(uint8_t port) __banked;
|
|
||||||
void bandwidth_status(uint8_t port) __banked;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -19,37 +19,16 @@
|
|||||||
#define LOOKUP_MISS_DROP_9 0x00015555
|
#define LOOKUP_MISS_DROP_9 0x00015555
|
||||||
#define LOOKUP_MISS_FLOOD 0x00000000
|
#define LOOKUP_MISS_FLOOD 0x00000000
|
||||||
|
|
||||||
/* Buffer for serial input, SBUF_SIZE must be power of 2 < 256
|
// The serial buffer. Defines the command line size
|
||||||
* Writing to this buffer is under the sole control of the serial ISR
|
// Must be 2^x and <= 128
|
||||||
* Note that key-presses such as <cursor-left> can create multiple
|
#define SBUF_SIZE 128
|
||||||
* keys (3 to 4) being sent via the serial line, so this must be
|
|
||||||
* sufficiently large */
|
|
||||||
#define SBUF_SIZE 16
|
|
||||||
#define SBUF_MASK (SBUF_SIZE - 1)
|
|
||||||
|
|
||||||
extern __xdata volatile uint8_t sbuf_ptr;
|
|
||||||
extern __xdata uint8_t sbuf[SBUF_SIZE];
|
|
||||||
|
|
||||||
// Define the command buffer size, Must be 2^x and <= 128
|
|
||||||
#define CMD_BUF_SIZE 128
|
|
||||||
|
|
||||||
// Size of the TCP Output buffer
|
// Size of the TCP Output buffer
|
||||||
#define TCP_OUTBUF_SIZE 2500
|
#define TCP_OUTBUF_SIZE 2500
|
||||||
|
|
||||||
// Size of the port name, including the terminating null byte
|
|
||||||
#define PORT_NAME_SIZE 32
|
|
||||||
|
|
||||||
// Size of the memory area dedicated to VLAN-names
|
// Size of the memory area dedicated to VLAN-names
|
||||||
#define VLAN_NAMES_SIZE 1024
|
#define VLAN_NAMES_SIZE 1024
|
||||||
|
|
||||||
// Size of the flash buffer used for writing to flash, must be a multiple of the flash page size (0x100)
|
|
||||||
#define FLASH_BUF_SIZE 512
|
|
||||||
|
|
||||||
// Errors for commands
|
|
||||||
#define ERR_OK 0
|
|
||||||
#define ERR_TOO_MANY_ARGUMENTS 1
|
|
||||||
#define ERR_CMD_TOO_LONG 2
|
|
||||||
|
|
||||||
// For RX data, a propriatary RTL FRAME is inserted. Instead of 0x0800 for IPv4,
|
// For RX data, a propriatary RTL FRAME is inserted. Instead of 0x0800 for IPv4,
|
||||||
// the RTL_FRAME_TAG_ID is used as part of an 8-byte tag. When VLAN is activated,
|
// the RTL_FRAME_TAG_ID is used as part of an 8-byte tag. When VLAN is activated,
|
||||||
// the VLAN tag is inserted after the RTL tag
|
// the VLAN tag is inserted after the RTL tag
|
||||||
@@ -70,37 +49,23 @@ struct vlan_tag {
|
|||||||
#define RTL_TAG_SIZE (sizeof (struct rtl_tag))
|
#define RTL_TAG_SIZE (sizeof (struct rtl_tag))
|
||||||
#define VLAN_TAG_SIZE (sizeof (struct vlan_tag))
|
#define VLAN_TAG_SIZE (sizeof (struct vlan_tag))
|
||||||
#define RTL_FRAME_TAG_ID 0x8899
|
#define RTL_FRAME_TAG_ID 0x8899
|
||||||
#define RTL_FRAME_TAG_VERSION 0x04
|
|
||||||
|
|
||||||
// For TX, an 8 byte (plus 4 byte padding when when VLAN is enabled)
|
// For RX and TX, an 8 byte header describing the frame to be moved to the Asic
|
||||||
// header describing the frame to be moved to the Asic is used
|
// and received from the Asic is used
|
||||||
#define RTL_FRAME_DESC_SIZE 12
|
#define RTL_FRAME_HEADER_SIZE 8
|
||||||
|
|
||||||
// This is the standard size of an Ethernet frame header
|
// This is the standard size of an Ethernet frame header
|
||||||
#define ETHER_HEADER_SIZE 14
|
#define ETHER_HEADER_SIZE 14
|
||||||
|
|
||||||
#define DEFAULT_CONFIG_START 0x6f000
|
|
||||||
#define CONFIG_START 0x70000
|
#define CONFIG_START 0x70000
|
||||||
#define CONFIG_LEN 0x1000
|
#define CONFIG_LEN 0x1000
|
||||||
#define CODE0_SIZE 0x4000
|
#define CODE0_SIZE 0x4000
|
||||||
#define CODE_BANK_SIZE 0xc000
|
#define CODE_BANK_SIZE 0xc000
|
||||||
|
|
||||||
// Store update image after running image
|
|
||||||
#define FIRMWARE_UPLOAD_START 0x80000
|
|
||||||
|
|
||||||
// Constants for the circular command buffer, the size must be 2^n
|
// Constants for the circular command buffer, the size must be 2^n
|
||||||
#define CMD_HISTORY_SIZE 0x400
|
#define CMD_HISTORY_SIZE 0x400
|
||||||
#define CMD_HISTORY_MASK (CMD_HISTORY_SIZE - 1)
|
#define CMD_HISTORY_MASK (CMD_HISTORY_SIZE - 1)
|
||||||
|
|
||||||
enum sfp_speeds {
|
|
||||||
SFP_SPEED_AUTO = 0,
|
|
||||||
SFP_SPEED_100M,
|
|
||||||
SFP_SPEED_1G,
|
|
||||||
SFP_SPEED_2G5,
|
|
||||||
SFP_SPEED_5G,
|
|
||||||
SFP_SPEED_10G
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Representation of a 48-bit Ethernet address.
|
* Representation of a 48-bit Ethernet address.
|
||||||
*/
|
*/
|
||||||
@@ -113,22 +78,16 @@ struct flash_region_t {
|
|||||||
uint16_t len;
|
uint16_t len;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern __xdata char port_names[9][PORT_NAME_SIZE];
|
|
||||||
|
|
||||||
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
|
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
|
||||||
extern __xdata struct uip_eth_addr uip_ethaddr;
|
|
||||||
|
|
||||||
// Headers for calls in the common code area (HOME/BANK0)
|
// Headers for calls in the common code area (HOME/BANK0)
|
||||||
void print_string_no_syslog(__code char *p);
|
|
||||||
void print_string(__code char *p);
|
void print_string(__code char *p);
|
||||||
void print_string_x(__xdata char *p);
|
void print_long(__xdata uint32_t a);
|
||||||
void print_long(uint32_t a);
|
|
||||||
void print_short(uint16_t a);
|
void print_short(uint16_t a);
|
||||||
void print_byte(uint8_t a);
|
void print_byte(uint8_t a);
|
||||||
void itoa(uint8_t v);
|
void itoa(uint8_t v);
|
||||||
void print_sfr_data(void);
|
void print_sfr_data(void);
|
||||||
void print_phy_data(void);
|
void print_phy_data(void);
|
||||||
void print_cmd_prompt(void);
|
|
||||||
void phy_write_mask(uint16_t phy_mask, uint8_t dev_id, uint16_t reg, uint16_t v);
|
void phy_write_mask(uint16_t phy_mask, uint8_t dev_id, uint16_t reg, uint16_t v);
|
||||||
void phy_write(uint8_t phy_id, uint8_t dev_id, uint16_t reg, uint16_t v);
|
void phy_write(uint8_t phy_id, uint8_t dev_id, uint16_t reg, uint16_t v);
|
||||||
void phy_read(uint8_t phy_id, uint8_t dev_id, uint16_t reg);
|
void phy_read(uint8_t phy_id, uint8_t dev_id, uint16_t reg);
|
||||||
@@ -137,17 +96,13 @@ void reg_read(uint16_t reg_addr);
|
|||||||
void reg_read_m(uint16_t reg_addr);
|
void reg_read_m(uint16_t reg_addr);
|
||||||
void reg_write(uint16_t reg_addr);
|
void reg_write(uint16_t reg_addr);
|
||||||
void reg_write_m(uint16_t reg_addr);
|
void reg_write_m(uint16_t reg_addr);
|
||||||
void sds_read(uint8_t sds_id, uint8_t page, uint8_t reg);
|
|
||||||
void sds_write_v(uint8_t sds_id, uint8_t page, uint8_t reg, uint16_t v);
|
|
||||||
void delay(uint16_t t);
|
void delay(uint16_t t);
|
||||||
void sleep(uint16_t t);
|
void sleep(uint16_t t);
|
||||||
void write_char_no_syslog(char c);
|
|
||||||
void write_char(char c);
|
void write_char(char c);
|
||||||
void print_reg(uint16_t reg);
|
void print_reg(uint16_t reg);
|
||||||
uint8_t sfp_read_reg(uint8_t slot, uint8_t reg);
|
uint8_t sfp_read_reg(uint8_t slot, uint8_t reg);
|
||||||
void reg_bit_set(uint16_t reg_addr, char bit);
|
void reg_bit_set(uint16_t reg_addr, char bit);
|
||||||
void reg_bit_clear(uint16_t reg_addr, char bit);
|
void reg_bit_clear(uint16_t reg_addr, char bit);
|
||||||
uint8_t reg_bit_test(uint16_t reg_addr, char bit);
|
|
||||||
void sfr_mask_data(uint8_t n, uint8_t mask, uint8_t set);
|
void sfr_mask_data(uint8_t n, uint8_t mask, uint8_t set);
|
||||||
void sfr_set_zero(void);
|
void sfr_set_zero(void);
|
||||||
void reset_chip(void);
|
void reset_chip(void);
|
||||||
@@ -157,17 +112,13 @@ void memset(register __xdata uint8_t *dst, register __xdata uint8_t v, register
|
|||||||
uint16_t strlen(register __code const char *s);
|
uint16_t strlen(register __code const char *s);
|
||||||
uint16_t strlen_x(register __xdata const char *s);
|
uint16_t strlen_x(register __xdata const char *s);
|
||||||
uint16_t strtox(register __xdata uint8_t *dst, register __code const char *s);
|
uint16_t strtox(register __xdata uint8_t *dst, register __code const char *s);
|
||||||
uint16_t strcpy(register __xdata uint8_t *dst, register const char *s);
|
|
||||||
void tcpip_output(void);
|
void tcpip_output(void);
|
||||||
|
void print_string_x(__xdata char *p);
|
||||||
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
|
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
|
||||||
void get_random_32(void);
|
void get_random_32(void);
|
||||||
void read_reg_timer(__xdata uint32_t * tmr);
|
void read_reg_timer(uint32_t * tmr);
|
||||||
void sfp_print_info(uint8_t sfp);
|
void sfp_print_info(uint8_t sfp);
|
||||||
bool gpio_pin_test(uint8_t pin);
|
bool gpio_pin_test(uint8_t pin);
|
||||||
void set_sys_led_state(uint8_t state);
|
void set_sys_led_state(uint8_t state);
|
||||||
void sds_read(uint8_t sds_id, uint8_t page, uint8_t reg);
|
|
||||||
void sds_write_v(uint8_t sds_id, uint8_t page, uint8_t reg, uint16_t v);
|
|
||||||
void sds_config_mac(uint8_t sds, uint8_t mode);
|
|
||||||
void sds_config(uint8_t sds, uint8_t mode);
|
|
||||||
void handle_sfp(void);
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
__xdata uint8_t dio_enabled;
|
__xdata uint8_t dio_enabled;
|
||||||
__xdata struct flash_region_t flash_region;
|
__xdata struct flash_region_t flash_region;
|
||||||
|
|
||||||
__xdata uint32_t flash_size;
|
|
||||||
__xdata uint8_t flash_capacity_code;
|
|
||||||
|
|
||||||
// For the flash commands, see e.g. Windbond W25Q32JV datasheet
|
// For the flash commands, see e.g. Windbond W25Q32JV datasheet
|
||||||
#define CMD_WRITE_STATUS 0x01
|
#define CMD_WRITE_STATUS 0x01
|
||||||
@@ -19,7 +17,6 @@ __xdata uint8_t flash_capacity_code;
|
|||||||
// Don't use command `READ 0x03`, because on many device this command can't run at maximum SPI-clock speed.
|
// Don't use command `READ 0x03`, because on many device this command can't run at maximum SPI-clock speed.
|
||||||
// Use `Fast READ 0x0b` instead!
|
// Use `Fast READ 0x0b` instead!
|
||||||
//#define CMD_READ 0x03
|
//#define CMD_READ 0x03
|
||||||
#define CMD_READ_STATUS 0x05
|
|
||||||
#define CMD_WRITE_ENABLE 0x06
|
#define CMD_WRITE_ENABLE 0x06
|
||||||
#define CMD_FREAD 0x0b
|
#define CMD_FREAD 0x0b
|
||||||
#define CMD_SECTOR_ERASE 0x20
|
#define CMD_SECTOR_ERASE 0x20
|
||||||
@@ -90,7 +87,7 @@ uint8_t flash_read_status(void)
|
|||||||
|
|
||||||
// setup status read command
|
// setup status read command
|
||||||
SFR_FLASH_TCONF = 0x11;
|
SFR_FLASH_TCONF = 0x11;
|
||||||
SFR_FLASH_CMD_R = CMD_READ_STATUS;
|
SFR_FLASH_CMD_R = 5;
|
||||||
|
|
||||||
// execute and wait for controller done
|
// execute and wait for controller done
|
||||||
SFR_FLASH_EXEC_GO = 1;
|
SFR_FLASH_EXEC_GO = 1;
|
||||||
@@ -122,10 +119,9 @@ void flash_read_uid(void)
|
|||||||
print_byte(SFR_FLASH_DATA8);
|
print_byte(SFR_FLASH_DATA8);
|
||||||
print_byte(SFR_FLASH_DATA16);
|
print_byte(SFR_FLASH_DATA16);
|
||||||
print_byte(SFR_FLASH_DATA24);
|
print_byte(SFR_FLASH_DATA24);
|
||||||
write_char(' ');
|
|
||||||
|
|
||||||
SFR_FLASH_DUMMYCYCLES = 24; // Doesn't seem to work; we get the same data as for the first transfer
|
|
||||||
SFR_FLASH_EXEC_GO = 1;
|
SFR_FLASH_EXEC_GO = 1;
|
||||||
|
SFR_FLASH_DUMMYCYCLES = 24;
|
||||||
while(SFR_FLASH_EXEC_BUSY);
|
while(SFR_FLASH_EXEC_BUSY);
|
||||||
|
|
||||||
print_byte(SFR_FLASH_DATA0);
|
print_byte(SFR_FLASH_DATA0);
|
||||||
@@ -136,19 +132,6 @@ void flash_read_uid(void)
|
|||||||
flash_configure_mmio();
|
flash_configure_mmio();
|
||||||
}
|
}
|
||||||
|
|
||||||
__code char* get_flash_size_str(void)
|
|
||||||
{
|
|
||||||
switch (flash_capacity_code) {
|
|
||||||
case 0x12: return "256 KB";
|
|
||||||
case 0x13: return "512 KB";
|
|
||||||
case 0x14: return "1 MB";
|
|
||||||
case 0x15: return "2 MB";
|
|
||||||
case 0x16: return "4 MB";
|
|
||||||
case 0x17: return "8 MB";
|
|
||||||
case 0x18: return "16 MB";
|
|
||||||
default: return "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void flash_read_jedecid(void)
|
void flash_read_jedecid(void)
|
||||||
{
|
{
|
||||||
@@ -165,16 +148,15 @@ void flash_read_jedecid(void)
|
|||||||
SFR_FLASH_EXEC_GO = 1;
|
SFR_FLASH_EXEC_GO = 1;
|
||||||
while(SFR_FLASH_EXEC_BUSY);
|
while(SFR_FLASH_EXEC_BUSY);
|
||||||
|
|
||||||
print_string("Flash information:\n");
|
|
||||||
print_string(" Manufacturer ID: 0x");
|
|
||||||
print_byte(SFR_FLASH_DATA0);
|
print_byte(SFR_FLASH_DATA0);
|
||||||
print_string("\n Memory Type: 0x");
|
|
||||||
print_byte(SFR_FLASH_DATA8);
|
print_byte(SFR_FLASH_DATA8);
|
||||||
print_string("\n Capacity: 0x");
|
print_byte(SFR_FLASH_DATA16);
|
||||||
flash_capacity_code = SFR_FLASH_DATA16;
|
print_byte(SFR_FLASH_DATA24);
|
||||||
flash_size = 1UL << flash_capacity_code;
|
|
||||||
print_byte(flash_capacity_code);
|
// Reset slow read mode
|
||||||
print_string(" = "); print_string(get_flash_size_str()); write_char('\n');
|
SFR_FLASH_MODEB = 0x0;
|
||||||
|
SFR_FLASH_CMD_R = CMD_FREAD;
|
||||||
|
SFR_FLASH_DUMMYCYCLES = 8;
|
||||||
|
|
||||||
flash_configure_mmio();
|
flash_configure_mmio();
|
||||||
}
|
}
|
||||||
@@ -206,6 +188,51 @@ void flash_write_enable(void)
|
|||||||
} while (!(status & 0x2));
|
} while (!(status & 0x2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void flash_dump(uint8_t len)
|
||||||
|
{
|
||||||
|
short status;
|
||||||
|
do {
|
||||||
|
status = flash_read_status();
|
||||||
|
print_short(status);
|
||||||
|
} while (status & 0x1);
|
||||||
|
|
||||||
|
// Set fast read mode
|
||||||
|
if (dio_enabled) {
|
||||||
|
SFR_FLASH_MODEB = 0x18;
|
||||||
|
SFR_FLASH_CMD_R = CMD_FREAD_DIO;
|
||||||
|
SFR_FLASH_DUMMYCYCLES = 4;
|
||||||
|
} else {
|
||||||
|
SFR_FLASH_MODEB = 0x0;
|
||||||
|
SFR_FLASH_CMD_R = CMD_FREAD; // Fast read
|
||||||
|
SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks after read?
|
||||||
|
}
|
||||||
|
// Read 4 bytes
|
||||||
|
SFR_FLASH_TCONF = 4;
|
||||||
|
while (len) {
|
||||||
|
SFR_FLASH_ADDR16 = flash_region.addr >> 16;
|
||||||
|
SFR_FLASH_ADDR8 = flash_region.addr >> 8;
|
||||||
|
SFR_FLASH_ADDR0 = flash_region.addr;
|
||||||
|
flash_region.addr += 4;
|
||||||
|
|
||||||
|
SFR_FLASH_EXEC_GO = 1;
|
||||||
|
while(SFR_FLASH_EXEC_BUSY);
|
||||||
|
|
||||||
|
print_short(SFR_FLASH_DATA0);
|
||||||
|
if (len == 1)
|
||||||
|
return;
|
||||||
|
print_short(SFR_FLASH_DATA8);
|
||||||
|
if (len == 2)
|
||||||
|
return;
|
||||||
|
print_short(SFR_FLASH_DATA16);
|
||||||
|
if (len == 3)
|
||||||
|
return;
|
||||||
|
print_short(SFR_FLASH_DATA24);
|
||||||
|
|
||||||
|
len -= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reads bulk data of length len from the flash memory starging at address src
|
* Reads bulk data of length len from the flash memory starging at address src
|
||||||
* and writes the data into a buffer pointed to by dst in XMEM
|
* and writes the data into a buffer pointed to by dst in XMEM
|
||||||
@@ -288,7 +315,7 @@ void flash_read_security(void)
|
|||||||
if (flash_region.len == 3)
|
if (flash_region.len == 3)
|
||||||
break;
|
break;
|
||||||
print_byte(SFR_FLASH_DATA24);
|
print_byte(SFR_FLASH_DATA24);
|
||||||
write_char(' ');
|
|
||||||
flash_region.len -= 4;
|
flash_region.len -= 4;
|
||||||
} while(flash_region.len);
|
} while(flash_region.len);
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,6 @@
|
|||||||
#ifndef _RTL837X_FLASH_H_
|
#ifndef _RTL837X_FLASH_H_
|
||||||
#define _RTL837X_FLASH_H_
|
#define _RTL837X_FLASH_H_
|
||||||
|
|
||||||
// SPI FLASH MEMORY PAGE SIZE.
|
|
||||||
#define FLASH_PAGE_SIZE 0x100
|
|
||||||
// SPI FLASH MEMORY SECTOR SIZE = ERASE SIZE.
|
|
||||||
#define FLASH_SECTOR_SIZE 0x1000
|
|
||||||
|
|
||||||
#if (FLASH_SECTOR_SIZE % FLASH_PAGE_SIZE) != 0
|
|
||||||
#error "FLASH_SECTOR_SIZE must be a multiple of FLASH_PAGE_SIZE"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void flash_init(uint8_t enable_dio);
|
void flash_init(uint8_t enable_dio);
|
||||||
void flash_read_uid(void);
|
void flash_read_uid(void);
|
||||||
void flash_write_enable(void);
|
void flash_write_enable(void);
|
||||||
@@ -20,7 +10,4 @@ void flash_read_security(void);
|
|||||||
void flash_sector_erase(void);
|
void flash_sector_erase(void);
|
||||||
void flash_read_bulk(__xdata uint8_t *dst);
|
void flash_read_bulk(__xdata uint8_t *dst);
|
||||||
void flash_write_bytes(__xdata uint8_t *ptr);
|
void flash_write_bytes(__xdata uint8_t *ptr);
|
||||||
__code char* get_flash_size_str(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||