Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a457c29ac | ||
|
|
8c61010a84 | ||
|
|
201289990b | ||
|
|
3a93ce1786 | ||
|
|
4b42be8cae | ||
|
|
32f9b91def | ||
|
|
d253c9feee | ||
|
|
2552f586d8 | ||
|
|
f113b2c0e5 | ||
|
|
2d912d80c9 | ||
|
|
0682df3027 | ||
|
|
4b40efafbb | ||
|
|
02992771ad | ||
|
|
f81c497728 | ||
|
|
b46cc2087f | ||
|
|
3904daced7 | ||
|
|
623247da4f | ||
|
|
aa5368cf34 | ||
|
|
2b39d723c7 | ||
|
|
f6cb1152f9 | ||
|
|
bf9fa35338 | ||
|
|
8ab2a6a9da | ||
|
|
2316ffd493 | ||
|
|
a71eb57702 | ||
|
|
a2b2dbcfbf | ||
|
|
8cee16e96b | ||
|
|
a1135863bb | ||
|
|
ede4137101 | ||
|
|
0106f99ee0 | ||
|
|
733348059d | ||
|
|
950b763d69 | ||
|
|
22aaa9fbfe | ||
|
|
89e22f0893 | ||
|
|
809efaa8d8 | ||
|
|
271878a62f | ||
|
|
299b54f2a3 | ||
|
|
f47fec7098 | ||
|
|
04ce2cb8a1 | ||
|
|
96eddf5a0c | ||
|
|
2cd6f5d782 | ||
|
|
c6dc5cc21c | ||
|
|
502033590e | ||
|
|
f81529bd07 | ||
|
|
9714818b1f | ||
|
|
9c668969d4 | ||
|
|
241bcb273f | ||
|
|
10367d0cdb | ||
|
|
09d90d6d97 | ||
|
|
12c98ba6bd | ||
|
|
3f66a18104 | ||
|
|
8abbececd1 | ||
|
|
d6dbf4e4dd | ||
|
|
e2b3201c9f | ||
|
|
a7f4543698 | ||
|
|
2e0e55967c | ||
|
|
7877ce60f3 | ||
|
|
a3dd25e0fe | ||
|
|
441340a4d4 | ||
|
|
9a3f8c359d | ||
|
|
63ab6500c0 | ||
|
|
ec5f74bbed | ||
|
|
a597d2d08b | ||
|
|
abc9cb7afd | ||
|
|
6d579c4f00 | ||
|
|
c342964327 | ||
|
|
fd3a272255 | ||
|
|
4f4f69ecc1 | ||
|
|
c8e21b394b | ||
|
|
c34249b90a | ||
|
|
042f4324a4 | ||
|
|
e280ccd2f9 | ||
|
|
baa4e5e142 | ||
|
|
b53e7e1a06 | ||
|
|
14b45735e2 | ||
|
|
946e80cebe | ||
|
|
e2df95ba90 | ||
|
|
570ee6c995 | ||
|
|
e849af4a70 | ||
|
|
812bf3bb67 | ||
|
|
da8ec8fe88 | ||
|
|
01fa43510e | ||
|
|
d2e79d4d80 | ||
|
|
016061d8db | ||
|
|
f7989cc737 | ||
|
|
5035366551 | ||
|
|
2a8f183e6a | ||
|
|
18225f5d22 | ||
|
|
224471d676 | ||
|
|
50d06c61bc | ||
|
|
d5709bcaf3 | ||
|
|
52d943d5e4 | ||
|
|
e79e90dd35 | ||
|
|
da768171a5 | ||
|
|
94bf4425ba | ||
|
|
3e599f0e06 | ||
|
|
6c6d11ab33 | ||
|
|
791f68582d | ||
|
|
facc4afe40 | ||
|
|
8134ca7ec7 | ||
|
|
642030c7b2 | ||
|
|
8324edc5f7 | ||
|
|
f2ff7d7737 | ||
|
|
a24b63a81f | ||
|
|
abe3513bc6 | ||
|
|
49c43082a3 | ||
|
|
f71e869b97 | ||
|
|
1fe236246a | ||
|
|
2acf2499d1 | ||
|
|
56e0d0a5d1 | ||
|
|
7380aeb10d | ||
|
|
0d698dc572 | ||
|
|
c7fb354f08 | ||
|
|
2cdab5f9d9 | ||
|
|
301577efc8 | ||
|
|
1156f00f95 | ||
|
|
8cbafaa347 | ||
|
|
80ff1b25c9 | ||
|
|
1a5208110c | ||
|
|
e2717ef7ca | ||
|
|
1769528420 | ||
|
|
9d4c06d752 | ||
|
|
2565aeadf4 | ||
|
|
c3530aaafc | ||
|
|
6af19e1e6b | ||
|
|
1683eef94b | ||
|
|
036d9ca229 | ||
|
|
b31179acbe | ||
|
|
b7ad67d336 | ||
|
|
e130777b24 | ||
|
|
41f0dad49d | ||
|
|
2e48415c95 | ||
|
|
22f8b9a287 | ||
|
|
c91177d992 | ||
|
|
c1a414833d | ||
|
|
2a9c7d2828 | ||
|
|
d776118815 | ||
|
|
f7b8aed2f7 | ||
|
|
7eb3676aaf | ||
|
|
eaa21d5975 | ||
|
|
193eacf51b | ||
|
|
b60811b984 | ||
|
|
b85861347b | ||
|
|
b21bfac917 | ||
|
|
d4d12fe3b4 | ||
|
|
4440bcc43a | ||
|
|
f6a5163f33 | ||
|
|
e210f31f0e | ||
|
|
9eecdd071a | ||
|
|
c4368c68be | ||
|
|
1b02f303b2 | ||
|
|
fd9a7717ce | ||
|
|
29ce05b70e | ||
|
|
97ae6bf1d3 | ||
|
|
4ccb988d70 | ||
|
|
075d7e43f7 | ||
|
|
97e73d95aa | ||
|
|
2eb6bac4a5 | ||
|
|
7d4ccf8f23 | ||
|
|
c0f6b8a1a6 | ||
|
|
f3b6c16161 | ||
|
|
73f92f2e12 | ||
|
|
bfab8cbba3 | ||
|
|
eedb0dec01 | ||
|
|
08ad843c56 | ||
|
|
05693f5171 | ||
|
|
6eaa1985aa | ||
|
|
45ba32f65d | ||
|
|
0b4f59483b | ||
|
|
385c850d2f | ||
|
|
cdbc48f2c2 | ||
|
|
efe0c282ba | ||
|
|
54fced05b0 | ||
|
|
b64dfd8c25 | ||
|
|
5f1cd4cce0 | ||
|
|
7ffd0c25c2 | ||
|
|
8b4e09ad69 | ||
|
|
34d53dddf2 | ||
|
|
ec5f655bba | ||
|
|
7291f38e46 | ||
|
|
c3b99fdcdf | ||
|
|
9f800bae01 | ||
|
|
df498b0879 | ||
|
|
03422463e4 | ||
|
|
2bfbe5358b | ||
|
|
3bb89bfb80 | ||
|
|
dba3679e2f | ||
|
|
f331a6129a | ||
|
|
877e5a68fb | ||
|
|
ed6c95e522 | ||
|
|
cb8d0e45bb | ||
|
|
877b16e837 | ||
|
|
fce64ac368 | ||
|
|
dd9e5c8ff8 | ||
|
|
f7fcf0eda7 | ||
|
|
905cf38f1f | ||
|
|
b0370f7bb3 | ||
|
|
d21d269d49 | ||
|
|
cb81f82cf6 | ||
|
|
59e7a21955 | ||
|
|
c530ec4ae3 | ||
|
|
8e2b48ef25 | ||
|
|
65f094c1d1 | ||
|
|
090283d538 | ||
|
|
7e3a0f5d8f | ||
|
|
4706f6232a | ||
|
|
b47a868db3 | ||
|
|
454eb28bce | ||
|
|
dc283bc724 | ||
|
|
a001cd3da7 | ||
|
|
e92b4a2358 | ||
|
|
47c5443f0e | ||
|
|
baa3e7edb7 | ||
|
|
34d46aa29a | ||
|
|
6b64534f40 | ||
|
|
b18ed62042 | ||
|
|
16edc6b421 | ||
|
|
f1e5b7e31a | ||
|
|
1f6e07a1af | ||
|
|
0952676504 | ||
|
|
95cbc1a2e0 | ||
|
|
d5fdaf28e8 | ||
|
|
511d35f63d | ||
|
|
96484bc62a | ||
|
|
765000ce4f | ||
|
|
dc9b211924 | ||
|
|
b559c3b868 | ||
|
|
13fe354da7 | ||
|
|
fc4b12725c | ||
|
|
0a52386e60 | ||
|
|
4b167151a5 | ||
|
|
f474b5822b | ||
|
|
fa37940075 | ||
|
|
893dcd8fcf | ||
|
|
16f4e2a1c6 | ||
|
|
364d538abd | ||
|
|
4cef63200f | ||
|
|
a0313eab87 |
@@ -17,5 +17,7 @@ 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 MACHINE="KP_9000_6XHML_X2"
|
||||||
|
|||||||
@@ -9,34 +9,49 @@ CC_FLAGS = -mmcs51 -I. -Ihttpd -Iuip
|
|||||||
ASM = sdas8051
|
ASM = sdas8051
|
||||||
AFLAGS= -plosgff
|
AFLAGS= -plosgff
|
||||||
|
|
||||||
SUBDIRS := tools uip httpd
|
SUBDIRS := tools
|
||||||
SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS))
|
SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS))
|
||||||
|
|
||||||
BUILDDIR = output/
|
BUILDDIR = output
|
||||||
VERSION_HEADER := version.h
|
VERSION_HEADER := version.h
|
||||||
|
|
||||||
ifeq ($(MACHINE),)
|
ifeq ($(MACHINE),)
|
||||||
|
MACHINE:= $(shell grep "^\s*#define MACHINE_" machine.h | sed "s/^\s*#define MACHINE_//")
|
||||||
else
|
else
|
||||||
CC_FLAGS += -DMACHINE_$(MACHINE)
|
CC_FLAGS += -DMACHINE_$(MACHINE)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all: create_build_dir $(VERSION_HEADER) $(SUBDIRS) $(BUILDDIR)rtlplayground.bin
|
GIT_VERSION := $(shell git rev-parse --short HEAD)
|
||||||
|
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 cmd_editor.c rtl837x_bandwidth.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
|
html_data.c html_data.h: $(HTML) tools/$(BUILDDIR)/fileadder
|
||||||
tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -d html -p html_data
|
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 \"v$(VERSION)-g$(shell git rev-parse --short HEAD)\"" >> $(VERSION_HEADER)
|
@echo "#define VERSION_SW \"$(VERSION_EXTENSION)\"" >> $(VERSION_HEADER)
|
||||||
@echo "#define BUILD_DATE \"$(shell date +"%Y-%m-%d %H:%M:%S")\"" >> $(VERSION_HEADER)
|
@echo "#define BUILD_DATE \"$(shell date +"%Y-%m-%d %H:%M:%S")\"" >> $(VERSION_HEADER)
|
||||||
@echo "#endif" >> $(VERSION_HEADER)
|
@echo "#endif" >> $(VERSION_HEADER)
|
||||||
|
|
||||||
@@ -46,37 +61,46 @@ $(SUBDIRS):
|
|||||||
$(MAKE) -C $@
|
$(MAKE) -C $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-make -C uip clean
|
-rm -f html_data.c html_data.h $(VERSION_HEADER)
|
||||||
-make -C httpd clean
|
-if [ -d $(BUILDDIR) ]; then find $(BUILDDIR) -type f ! -name "*.bin" -delete; fi
|
||||||
-rm html_data.c html_data.h $(VERSION_HEADER)
|
|
||||||
-rm -r $(BUILDDIR)
|
|
||||||
|
|
||||||
$(BUILDDIR)crtstart.rel: crtstart.asm
|
distclean:
|
||||||
$(ASM) $(AFLAGS) -o $@ $<
|
-rm -f html_data.c html_data.h $(VERSION_HEADER)
|
||||||
|
-rm -rf $(BUILDDIR)
|
||||||
|
|
||||||
$(BUILDDIR)crc16.rel: crc16.asm
|
$(BUILDDIR)/%.rel: %.c
|
||||||
$(ASM) $(AFLAGS) -o $@ $<
|
$(CC) -MMD $(CC_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
$(BUILDDIR)%.rel: %.c
|
$(BUILDDIR)/%.rel: %.asm
|
||||||
$(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: $(OBJS) $(BUILDDIR)/crtstart.rel $(BUILDDIR)/crc16.rel
|
||||||
$(CC) $(CC_FLAGS) -Wl-bHOME=0x00000 -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-r -o $@ $^
|
$(CC) $(CC_FLAGS) -Wl-bHOME=0x00000 -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.bin: $(BUILDDIR)rtlplayground.img
|
$(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.img
|
||||||
if [ -e $@ ]; then rm $@; fi
|
if [ -e $@ ]; then rm $@; fi
|
||||||
tools/$(BUILDDIR)imagebuilder -i $^ $@
|
tools/$(BUILDDIR)/imagebuilder -i $^ $@
|
||||||
tools/$(BUILDDIR)fileadder -a $(DEFAULT_CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
tools/$(BUILDDIR)/fileadder -a $(DEFAULT_CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
||||||
tools/$(BUILDDIR)fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
tools/$(BUILDDIR)/fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
||||||
tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data $@
|
tools/$(BUILDDIR)/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data -b BANK1 $@
|
||||||
tools/$(BUILDDIR)crc_calculator -u $@
|
tools/$(BUILDDIR)/crc_calculator -u $@
|
||||||
|
ln -sf rtlplayground-$(FILENAME_EXTENSION).bin $(BUILDDIR)/rtlplayground.bin
|
||||||
|
|
||||||
|
.PHONY: clean all $(SUBDIRS) $(VERSION_HEADER)
|
||||||
|
|
||||||
.PHONY: clean all $(SUBDIRS)
|
.PHONY:
|
||||||
|
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,88 +52,145 @@ 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.
|
||||||
|
|
||||||
## Compiling
|
## (0) Compiling Requirements
|
||||||
|
|
||||||
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 make gcc 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.
|
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
|
||||||
```
|
```
|
||||||
Note, that the image generated ends in .bin, not .img, in order to make
|
Note, that the image generated ends in .bin, not .img, in order to make IMSProg happy.
|
||||||
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
|
||||||
cp ../output//rtlplayground.bin output/
|
./output/updatebuilder -i output/rtlinstaller.ihx -o output/rtlplayground_oem_upgrade.bin ../output/rtlplayground.bin
|
||||||
./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: 0x29d10
|
Payload sum 1 is: 0x25100
|
||||||
Payload sum 2 is: 0x29d10
|
Payload sum 2 is: 0x25100
|
||||||
Payload sum with header is: 0x2b0fc
|
Payload sum with header is: 0x264ec
|
||||||
Payload sum is: 0xad8a75
|
Payload sum is: 0xf8fe94
|
||||||
Header checksum is: 0x4c3
|
Header checksum is: 0x5a1
|
||||||
```
|
```
|
||||||
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!
|
|
||||||
|
|
||||||
## Installation
|
## (3) Sandbox Usage with Ghidra (optional)
|
||||||
|
|
||||||
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]
|
||||||
> NOTE THAT WHILE THIS PROCEDURE HAS BEEN SUCCESSFULLY TESTED ON ALL DEVICES ABOVE,
|
> Check one more time that your device matches the machine type before flashing.
|
||||||
> ABSOLUTELY NO GUARANTY CAN BE GIVEN THAT YOU WILL NOT DESTROY YOUR SWITCH,
|
> Be shure you have a backup of the original firmware before diving in RTLPlaygroung.
|
||||||
> ANY OTHER EQUIPMENT INVOLVED OR HARM YOURSELF BY OPENING THE ELECTRONIC
|
|
||||||
> DEVICE. OPENING THE SWITCH WILL VOID ITS WARRANTY.
|
|
||||||
|
|
||||||
You can upload the upgrade image of managed switches via the web interface of the
|
Finally, push the Upload File Button and you're done !
|
||||||
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.
|
|
||||||
|
|
||||||
You will need to open your switch to flash the image directly onto the flash chip,
|
## (5) Flashing the ROM directly (hardware way, but also only way to rescue)
|
||||||
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
|
|
||||||
|
|
||||||
Now you can connect a serial cable to the UART port found on all the
|
This procedure is the only way to flash unmanaged switches, if the ROM chip is large enough.
|
||||||
devices, set 8N1 @ 115200 baud and power up the switch.
|
This is also the only way to unbrick your device if something went wroong.
|
||||||
|
|
||||||
The device will perform some examples and provide a minimal console, the
|
> [!IMPORTANT]
|
||||||
documentation of which can be found in the source code rtlplayground.c`.
|
> You need a SOIC-8 clip to flash the ROM chip directly onboard.
|
||||||
|
> 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
|
||||||
|
|
||||||
## The web-interface
|
> [!CAUTION]
|
||||||
The web-interface can be reached under the [default 192.168.10.247](http://192.168.10.247).
|
> As you need to open your switch case, consider that the warranty is gone.
|
||||||
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:
|
||||||
```
|
```
|
||||||
@@ -198,7 +255,6 @@ 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
|
||||||
@@ -216,17 +272,40 @@ 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!
|
||||||
|
|
||||||
## Other documents
|
## (11) Other documents
|
||||||
The following documents give further documentation on specific features of
|
|
||||||
the RTL837x SoCs:
|
The following documents give further documentation on specific features of 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)
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ void cmd_edit(void) __banked
|
|||||||
} else { // An unknown or not yet complete Escape sequence: wait
|
} else { // An unknown or not yet complete Escape sequence: wait
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (sbuf[l] == 127) { // Backspace
|
} else if (sbuf[l] == 127 || sbuf[l] == 8) { // Backspace DEL or BS/^H
|
||||||
if (cursor > 0) {
|
if (cursor > 0) {
|
||||||
write_char('\010');
|
write_char('\010');
|
||||||
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
||||||
@@ -197,7 +197,7 @@ void cmd_edit(void) __banked
|
|||||||
if (cmd_line_len)
|
if (cmd_line_len)
|
||||||
cmd_available = 1;
|
cmd_available = 1;
|
||||||
else
|
else
|
||||||
print_string("\n> ");
|
print_cmd_prompt();
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
cmd_line_len = 0;
|
cmd_line_len = 0;
|
||||||
history_editptr = 0xffff;
|
history_editptr = 0xffff;
|
||||||
|
|||||||
@@ -7,10 +7,13 @@
|
|||||||
|
|
||||||
extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
||||||
extern __xdata uint8_t cmd_available;
|
extern __xdata uint8_t cmd_available;
|
||||||
|
extern __xdata uint8_t err_status;
|
||||||
|
|
||||||
uint8_t cmd_tokenize(void) __banked;
|
void 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;
|
void clear_command_history(void) __banked;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -71,18 +71,13 @@ 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(uint8_t *a)
|
void dhcp_print_ip(__xdata uint8_t *a)
|
||||||
{
|
{
|
||||||
itoa(a[0]); write_char('.');
|
itoa(a[0]); write_char('.');
|
||||||
itoa(a[1]); write_char('.');
|
itoa(a[1]); write_char('.');
|
||||||
@@ -216,7 +211,7 @@ void dhcp_send_request(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ip_opt(uint8_t * __xdata ip)
|
void ip_opt(__xdata uint8_t * 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++];
|
||||||
@@ -353,8 +348,10 @@ void dhcp_stop(void) __banked
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dhcp_callback(void) __banked
|
void dhcp_callback(uint16_t lport) __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(void) __banked;
|
void dhcp_callback(uint16_t lport) __banked;
|
||||||
|
|
||||||
|
|
||||||
struct dhcp_state {
|
struct dhcp_state {
|
||||||
@@ -35,14 +35,9 @@ struct dhcp_state {
|
|||||||
uint32_t rebind;
|
uint32_t rebind;
|
||||||
uint32_t renewal;
|
uint32_t renewal;
|
||||||
|
|
||||||
struct uip_udp_conn *conn;
|
__xdata 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
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# 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
|
||||||
|
```
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
### 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 |
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
# 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).
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# 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.
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# 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" />
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
### 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.
|
||||||
|
|
||||||
@@ -14,10 +14,11 @@ The memory chip is `Winbond W25Q16JV` with 16M-bit size.
|
|||||||
1. 2.5G ports on all advertised speeds.
|
1. 2.5G ports on all advertised speeds.
|
||||||
2. SFP+ communication.
|
2. SFP+ communication.
|
||||||
3. Serial, Web UI.
|
3. Serial, Web UI.
|
||||||
|
4. All LEDs
|
||||||
|
|
||||||
## Known issues
|
## Known issues
|
||||||
|
|
||||||
1. LEDs are not initialized properly.
|
None.
|
||||||
|
|
||||||
## PCB
|
## PCB
|
||||||
|
|
||||||
@@ -38,10 +39,10 @@ Bottom
|
|||||||
```
|
```
|
||||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||||
│ ┌──────────┐ ┌──────────┐ │
|
│ ┌──────────┐ ┌──────────┐ │
|
||||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ SFP │ │ SFP │ │
|
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ SFP 2 │ │ SFP 1 │ │
|
||||||
│ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ PORT 5 │ │ PORT 6 │ │
|
│ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ PORT 5 │ │ PORT 6 │ │
|
||||||
│ │ PORT 1 │ │ PORT 2 │ │ PORT 3 │ │ PORT 4 │ │ MAC ? │ │ MAC ? │ │
|
│ │ PORT 1 │ │ PORT 2 │ │ PORT 3 │ │ PORT 4 │ │ MAC 8 │ │ MAC 3 │ │
|
||||||
│ │ MAC 4 │ │ MAC 5 │ │ MAC 6 │ │ MAC 7 │ │ SerDes ? │ │ SerDes ? │ │
|
│ │ MAC 4 │ │ MAC 5 │ │ MAC 6 │ │ MAC 7 │ │ SerDes 0 │ │ SerDes 1 │ │
|
||||||
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘ └──────────┘ │
|
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘ └──────────┘ │
|
||||||
└─────────────────────────────────────────────────────────────────────────────┘
|
└─────────────────────────────────────────────────────────────────────────────┘
|
||||||
```
|
```
|
||||||
@@ -105,9 +106,9 @@ GPIO mapping unknown.
|
|||||||
| 00000002 | GPIO01 | | GPIO33 | |
|
| 00000002 | GPIO01 | | GPIO33 | |
|
||||||
| 00000004 | GPIO02 | | GPIO34 | Random changes |
|
| 00000004 | GPIO02 | | GPIO34 | Random changes |
|
||||||
| 00000008 | GPIO03 | | GPIO35 | |
|
| 00000008 | GPIO03 | | GPIO35 | |
|
||||||
| 00000010 | GPIO04 | | GPIO36 | SFP1 Present |
|
| 00000010 | GPIO04 | | GPIO36 | SFP2 Present |
|
||||||
| 00000020 | GPIO05 | | GPIO37 | SFP1 RX Los |
|
| 00000020 | GPIO05 | | GPIO37 | SFP2 RX Los |
|
||||||
| 00000040 | GPIO06 | | GPIO38 | SFP2 Present |
|
| 00000040 | GPIO06 | | GPIO38 | SFP1 Present |
|
||||||
| 00000080 | GPIO07 | | GPIO39 | |
|
| 00000080 | GPIO07 | | GPIO39 | |
|
||||||
| 00000100 | GPIO08 | | GPIO40 | |
|
| 00000100 | GPIO08 | | GPIO40 | |
|
||||||
| 00000200 | GPIO09 | | GPIO41 | |
|
| 00000200 | GPIO09 | | GPIO41 | |
|
||||||
@@ -119,11 +120,11 @@ GPIO mapping unknown.
|
|||||||
| 00008000 | GPIO15 | PORT2 Link | GPIO47 | SFP1 I2C SDA |
|
| 00008000 | GPIO15 | PORT2 Link | GPIO47 | SFP1 I2C SDA |
|
||||||
| 00010000 | GPIO16 | PORT2-LED-GREEN | GPIO48 | SFP2 I2C CLK |
|
| 00010000 | GPIO16 | PORT2-LED-GREEN | GPIO48 | SFP2 I2C CLK |
|
||||||
| 00020000 | GPIO17 | PORT2-LED-AMBER | GPIO49 | SFP2 I2C SDA |
|
| 00020000 | GPIO17 | PORT2-LED-AMBER | GPIO49 | SFP2 I2C SDA |
|
||||||
| 00040000 | GPIO18 | PORT3 Link | GPIO50 | SFP2 Rx LOS |
|
| 00040000 | GPIO18 | PORT3 Link | GPIO50 | SFP1 Rx LOS |
|
||||||
| 00080000 | GPIO19 | PORT3-LED-GREEN | GPIO51 | SFP1 TX Disable |
|
| 00080000 | GPIO19 | PORT3-LED-GREEN | GPIO51 | SFP2 TX Disable |
|
||||||
| 00100000 | GPIO20 | PORT4-LED-AMBER | GPIO52 | |
|
| 00100000 | GPIO20 | PORT4-LED-AMBER | GPIO52 | |
|
||||||
| 00200000 | GPIO21 | PORT4 Link | GPIO53 | |
|
| 00200000 | GPIO21 | PORT4 Link | GPIO53 | |
|
||||||
| 00400000 | GPIO22 | PORT4-LED-GREEN | GPIO54 | SFP2 TX Disable |
|
| 00400000 | GPIO22 | PORT4-LED-GREEN | GPIO54 | SFP1 TX Disable |
|
||||||
| 00800000 | GPIO23 | PORT4-LED-AMBER | GPIO55 | |
|
| 00800000 | GPIO23 | PORT4-LED-AMBER | GPIO55 | |
|
||||||
| 01000000 | GPIO24 | | GPIO56 | |
|
| 01000000 | GPIO24 | | GPIO56 | |
|
||||||
| 02000000 | GPIO25 | | GPIO57 | |
|
| 02000000 | GPIO25 | | GPIO57 | |
|
||||||
@@ -136,8 +137,6 @@ GPIO mapping unknown.
|
|||||||
|
|
||||||
## LEDs
|
## LEDs
|
||||||
|
|
||||||
Leds are not yet working as in stock firmware. This will be handled later.
|
|
||||||
|
|
||||||
Ports 1-4 are amber for 100M/1G links, Green for 2.5G.
|
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.
|
Port 5-6 are green for 10G/1G link. Both should flash on activity.
|
||||||
|
|
||||||
@@ -166,7 +165,7 @@ Voltage is made by a `APW8713` (U3).
|
|||||||
|
|
||||||
### `3.3` Voltage
|
### `3.3` Voltage
|
||||||
|
|
||||||
Voltage is crated regulated by chip marke as `GoIAT` (U2).
|
Voltage is crated regulated by chip marked as `GoIAT` (U2).
|
||||||
|
|
||||||
## SFP SPI
|
## SFP SPI
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# 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.
|
||||||
|
After Width: | Height: | Size: 560 KiB |
|
After Width: | Height: | Size: 536 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 521 KiB After Width: | Height: | Size: 521 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 531 KiB |
|
After Width: | Height: | Size: 548 KiB |
|
After Width: | Height: | Size: 505 KiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 2.4 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 3.3 MiB |
@@ -0,0 +1,98 @@
|
|||||||
|
|
||||||
|
# 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 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 64 KiB |
@@ -41,6 +41,8 @@ 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.
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ The following devices have been tested and are fully working:
|
|||||||
- 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+)
|
- 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,15 +33,23 @@ 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. One port uses the higher
|
register of the port. 2 ports share a register. An odd port uses bits [23:12],
|
||||||
16 bits, the other (even ports) use the lower. The base register is
|
an even port uses bits [11:0]. 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 iingress rules of
|
Register RTL837x_REG_INGRESS (0x4e10) allows to define the ingress 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. The default PVID is 1.
|
allows only untagged packets to enter a port.
|
||||||
|
|
||||||
|
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
|
||||||
@@ -51,7 +59,9 @@ 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;
|
||||||
void vlan_create(uint16_t vlan, uint16_t members, uint16_t tagged) __banked;
|
uint16_t port_pvid_get(uint8_t port) __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;
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -66,9 +76,26 @@ 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 <port> [tagged|untagged|all]
|
ingress [p]<t|u|a>...
|
||||||
Allows ingress only for the named packages at the given port
|
Allows ingress packages on port `p` only when `t`agged, `u`ntagged or `a`ny.
|
||||||
|
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).
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ function createBW() {
|
|||||||
var tbl = document.getElementById('bwtable');
|
var tbl = document.getElementById('bwtable');
|
||||||
const limit = '<input type="checkbox" id="limit_port" onchange="exec();">'
|
const limit = '<input type="checkbox" id="limit_port" onchange="exec();">'
|
||||||
if (tbl.rows.length <= 2 && numPorts) {
|
if (tbl.rows.length <= 2 && numPorts) {
|
||||||
clearInterval(createBWInterval);
|
|
||||||
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++) {
|
||||||
const tr = tbl.insertRow();
|
const tr = tbl.insertRow();
|
||||||
@@ -94,6 +93,7 @@ async function applyBandwidth(i) {
|
|||||||
function getBW() {
|
function getBW() {
|
||||||
var xhttp = new XMLHttpRequest();
|
var xhttp = new XMLHttpRequest();
|
||||||
xhttp.onreadystatechange = function() {
|
xhttp.onreadystatechange = function() {
|
||||||
|
console.log("IN getBW ");
|
||||||
if (this.readyState == 4 && this.status == 200) {
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
const s = JSON.parse(xhttp.responseText);
|
const s = JSON.parse(xhttp.responseText);
|
||||||
console.log("BW: ", JSON.stringify(s));
|
console.log("BW: ", JSON.stringify(s));
|
||||||
@@ -126,11 +126,13 @@ function getBW() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhttp.open("GET", "/bandwidth.json", true);
|
xhttp.open("GET", "/bandwidth.json", true);
|
||||||
xhttp.timeout = 1500; xhttp.send();
|
xhttp.timeout = 1500; sendXHTTP(xhttp);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
window.addEventListener("load", function() {
|
||||||
getBW();
|
update( () => {
|
||||||
const iCount = setInterval(getBW, 2000);
|
createBW();
|
||||||
|
getBW();
|
||||||
|
const interval = setInterval(update, 2000);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
const createBWInterval = setInterval(createBW, 1010);
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
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]);
|
||||||
@@ -40,11 +39,14 @@ function getEEE() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhttp.open("GET", "/eee.json", true);
|
xhttp.open("GET", "/eee.json", true);
|
||||||
xhttp.timeout = 1500; xhttp.send();
|
xhttp.timeout = 1500; sendXHTTP(xhttp);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
window.addEventListener("load", function() {
|
||||||
getEEE();
|
update( () => {
|
||||||
const iCount = setInterval(getEEE, 2000);
|
createEEE();
|
||||||
|
getEEE();
|
||||||
|
const interval = setInterval(update, 2000);
|
||||||
|
const iCount = setInterval(getEEE, 2000);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
const createEEEInterval = setInterval(createEEE, 1000);
|
|
||||||
|
|||||||
@@ -2,6 +2,13 @@
|
|||||||
<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,10 +130,14 @@ function getL2() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhttp.open("GET", "/l2.json?idx=" + l2CurrentEntry, true);
|
xhttp.open("GET", "/l2.json?idx=" + l2CurrentEntry, true);
|
||||||
xhttp.timeout = 1500; xhttp.send();
|
xhttp.timeout = 1500; sendXHTTP(xhttp);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
window.addEventListener("load", function() {
|
||||||
l2GetInterval = setInterval(getL2, 1000);
|
update( () => {
|
||||||
|
getL2();
|
||||||
|
const interval = setInterval(update, 2000);
|
||||||
|
l2GetInterval = setInterval(getL2, 1000);
|
||||||
|
});;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ 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)
|
||||||
@@ -35,9 +34,6 @@ 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();
|
||||||
@@ -58,7 +54,7 @@ function fetchLag() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhttp.open("GET", `/lag.json`, true);
|
xhttp.open("GET", `/lag.json`, true);
|
||||||
xhttp.send();
|
sendXHTTP(xhttp);
|
||||||
}
|
}
|
||||||
async function lagSub(l) {
|
async function lagSub(l) {
|
||||||
var cmd = "lag " + l;
|
var cmd = "lag " + l;
|
||||||
@@ -76,3 +72,10 @@ async function lagSub(l) {
|
|||||||
console.error(`Error: ${err}`);
|
console.error(`Error: ${err}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.addEventListener("load", function() {
|
||||||
|
update( () => {
|
||||||
|
lagForm();
|
||||||
|
const interval = setInterval(update, 2000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ 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);
|
||||||
@@ -38,9 +41,86 @@ function drawPorts() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function update() {
|
function parseUint16(val) {
|
||||||
|
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) {
|
||||||
@@ -57,6 +137,7 @@ function update() {
|
|||||||
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--;
|
||||||
@@ -67,16 +148,25 @@ function update() {
|
|||||||
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;
|
||||||
tt.innerHTML = "Not enabled.";
|
iHTML += "<tr><td align=\"left\">Status</td><td>:</td><td>Not enabled.</td></tr>";
|
||||||
|
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 == 4 || p.link == 5 || p.link == 6) {
|
if (p.link == 5 || p.link == 7) {
|
||||||
|
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";
|
||||||
@@ -84,34 +174,113 @@ function update() {
|
|||||||
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 (p.sfp_options & 0x40) {
|
if (hasExtendedStatus) {
|
||||||
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 txPower = decodeSfpTxPower(p.sfp_txpower, p.sfp_txpower_cal);
|
||||||
iHTML += "<tr><td>Vcc</td><td>:</td><td>" + (Number(p.sfp_vcc) / 10000.0).toFixed(2) + " V</td></tr>";
|
let txPowerdBm = convertPowerTodBm(txPower);
|
||||||
iHTML += "<tr><td>TX-Bias</td><td>:</td><td>" + (Number(p.sfp_txbias) / 500.0).toFixed(1) + " mA</td></tr>";
|
let rxPower = decodeSfpRxPower(p.sfp_rxpower, p.sfp_rxpower_cal);
|
||||||
iHTML += "<tr><td>TX-Power</td><td>:</td><td>" + (Number(p.sfp_txpower) / 10.0).toFixed(0) + " mW</td></tr>";
|
let rxPowerdBm = convertPowerTodBm(rxPower);
|
||||||
iHTML += "<tr><td>RX-Power</td><td>:</td><td>" + (Number(p.sfp_rxpower) / 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>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.timeout = 5000;
|
||||||
|
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");
|
||||||
xhttp.open("GET", "/status.json", true);
|
return;
|
||||||
xhttp.timeout = 5000; xhttp.send();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,7 +4,6 @@ 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]);
|
||||||
@@ -34,9 +33,6 @@ 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();
|
||||||
@@ -51,11 +47,18 @@ 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];members & (1<<p)
|
p = physToLogPort[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);
|
||||||
xhttp.send();
|
sendXHTTP(xhttp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.addEventListener("load", function() {
|
||||||
|
update( () => {
|
||||||
|
mirrorForm();
|
||||||
|
const interval = setInterval(update, 2000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -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>Current Link Speed</th><th>Set Speed</th><th>Disabled</th><th>Apply</th></tr>
|
<tr> <th>Port</th> <th>Name</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,7 +3,6 @@ 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>'
|
||||||
@@ -20,6 +19,8 @@ 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)
|
||||||
@@ -67,7 +68,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[1].innerHTML = `${linkS[pState[i-1]+1]}`;
|
tbl.rows[i].cells[2].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;
|
||||||
@@ -130,17 +131,19 @@ 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; xhttp.send();
|
xhttp.timeout = 1500; sendXHTTP(xhttp);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
window.addEventListener("load", function() {
|
||||||
const updatePortTableInterval = setInterval(updatePortTable, 1000);
|
update( () => {
|
||||||
|
createPortTable();
|
||||||
|
updatePortTable();
|
||||||
|
getMTUs()
|
||||||
|
const interval = setInterval(update, 2000);
|
||||||
|
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>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>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>
|
||||||
<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; xhttp.send();
|
xhttp.timeout = 1500; sendXHTTP(xhttp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -162,17 +162,19 @@ 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[1].innerHTML = `${linkS[pState[i]+1]}`;
|
tbl.rows[i+1].cells[2].innerHTML = `${linkS[pState[i]+1]}`;
|
||||||
tbl.rows[i+1].cells[2].innerHTML = `${txG[i]} pkts`;
|
tbl.rows[i+1].cells[3].innerHTML = `${txG[i]} pkts`;
|
||||||
tbl.rows[i+1].cells[3].innerHTML = `${txB[i]} pkts`;
|
tbl.rows[i+1].cells[4].innerHTML = `${txB[i]} pkts`;
|
||||||
tbl.rows[i+1].cells[4].innerHTML = `${rxG[i]} pkts`;
|
tbl.rows[i+1].cells[5].innerHTML = `${rxG[i]} pkts`;
|
||||||
tbl.rows[i+1].cells[5].innerHTML = `${rxB[i]} pkts`;
|
tbl.rows[i+1].cells[6].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`));
|
||||||
@@ -184,8 +186,6 @@ 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,3 +196,12 @@ 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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
<div class="tab-bar">
|
<div class="tab-bar">
|
||||||
<button class="tab-btn active" onclick="openTab(event, 'system-tab')">System</button>
|
<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, 'advanced-tab')">Advanced</button>
|
||||||
|
<button class="tab-btn" onclick="openTab(event, 'console-tab')">Console</button>
|
||||||
</div>
|
</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;">
|
||||||
@@ -56,6 +57,17 @@
|
|||||||
<input style="width:40%;" class="action" id="switch_reset" onclick="resetSwitch();" type="button" value="Reset Switch">
|
<input style="width:40%;" class="action" id="switch_reset" onclick="resetSwitch();" type="button" value="Reset Switch">
|
||||||
</div>
|
</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>
|
||||||
|
|||||||
@@ -12,21 +12,36 @@ 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++){
|
||||||
var cmd = ips[i]+' '+document.getElementById(ips[i]).value;
|
cmd += ips[i]+' '+document.getElementById(ips[i]).value+'\n';
|
||||||
try {
|
}
|
||||||
const response = await fetch('/cmd', {
|
try {
|
||||||
method: 'POST',
|
const response = await fetch('/cmd', {
|
||||||
body: cmd
|
method: 'POST',
|
||||||
});
|
body: cmd
|
||||||
console.log('Completed!', response);
|
});
|
||||||
fetchIP();
|
console.log('Completed!', response);
|
||||||
} catch(err) {
|
fetchIP();
|
||||||
console.error(`Error: ${err}`);
|
} catch(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) {
|
||||||
const form = new FormData();
|
const form = new FormData();
|
||||||
form.append("MAX_FILE_SIZE", "4096");
|
form.append("MAX_FILE_SIZE", "4096");
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<form id="vform" action="/vlan.html">
|
<form id="vform" action="/vlan.html">
|
||||||
<div>
|
<div>
|
||||||
<label for="vid">VLAN ID:</label>
|
<label for="vid">VLAN ID:</label>
|
||||||
<input type="number" min="1" max="2047" id="vid" name="vid">
|
<input type="number" min="1" max="4094" 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/>
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ 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');
|
||||||
@@ -39,11 +38,6 @@ 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){
|
||||||
@@ -58,10 +52,6 @@ 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() {
|
||||||
@@ -70,10 +60,17 @@ 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;
|
||||||
for (let i = 1; i <= numPorts; i++) {
|
var members = m & 0x3FF;
|
||||||
setC('t', i, (m>>(10+i-1))&1);
|
var untag = (m >> 10) & 0x3FF;
|
||||||
setC('u', i, (m>>(i-1))&1);
|
var pvid = parseInt(s.pvid, 16);
|
||||||
setC('p', i, (m>>(20+i-1))&1);
|
console.log("PVID: ", pvid);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -83,5 +80,12 @@ function fetchVLAN() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xhttp.open("GET", `/vlan.json?vid=${v}`, true);
|
xhttp.open("GET", `/vlan.json?vid=${v}`, true);
|
||||||
xhttp.send();
|
sendXHTTP(xhttp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.addEventListener("load", function() {
|
||||||
|
update( () => {
|
||||||
|
vlanForm();
|
||||||
|
const interval = setInterval(update, 2000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
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,9 +14,6 @@
|
|||||||
#define SESSION_ID_LENGTH 12
|
#define SESSION_ID_LENGTH 12
|
||||||
#define SESSION_TIMEOUT 200
|
#define SESSION_TIMEOUT 200
|
||||||
|
|
||||||
// SPI FLASH MEMORY PAGE SIZE.
|
|
||||||
#define FLASHMEM_PAGE_SIZE 0x100
|
|
||||||
|
|
||||||
#define CMARK_S 6
|
#define CMARK_S 6
|
||||||
|
|
||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK1
|
||||||
@@ -60,11 +57,12 @@ __xdata uint32_t now;
|
|||||||
__xdata uint8_t *timeptr;
|
__xdata uint8_t *timeptr;
|
||||||
__xdata uint32_t last_session_use;
|
__xdata uint32_t last_session_use;
|
||||||
|
|
||||||
#define TSTATE_NONE 0
|
#define TSTATE_NONE 0
|
||||||
#define TSTATE_TX 1
|
#define TSTATE_TX 1
|
||||||
#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;
|
||||||
@@ -118,33 +116,88 @@ char strcmp(__xdata uint8_t *c, __code uint8_t * __xdata d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char is_word(__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)
|
||||||
{
|
{
|
||||||
uint8_t i = 0;
|
uint8_t u, c;
|
||||||
|
|
||||||
while (d[i] && (d[i] == c[i]))
|
while (1) {
|
||||||
i++;
|
u = *xdata_str_p++;
|
||||||
|
c = *code_str_p++;
|
||||||
|
|
||||||
if (d[i])
|
if (c == '\0') {
|
||||||
return 0;
|
if (u != '\0' && u != ' ' && u != '\t' && u != ':' && u != '?' && u != '=' && u != '\n' && u != '\r')
|
||||||
if (c[i] != ' ' && c[i] != '\t' && c[i] != ':' && c[i] != '?' && c[i] != '=' && c[i] != '\n' && c[i] != '\r' && c[i])
|
return false;
|
||||||
return 0;
|
return true;
|
||||||
return 1;
|
}
|
||||||
|
|
||||||
|
if (c != u) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char is_word_x(__xdata uint8_t *c, __xdata uint8_t *d)
|
bool is_url_word_x(__xdata uint8_t *uri_str_p, __xdata uint8_t *src_str_p)
|
||||||
{
|
{
|
||||||
register uint8_t i = 0;
|
uint8_t u, s;
|
||||||
|
|
||||||
while (d[i] && (d[i] == c[i]))
|
while(1) {
|
||||||
i++;
|
u = *uri_str_p++;
|
||||||
|
s = *src_str_p++;
|
||||||
|
|
||||||
if (d[i])
|
if (s == '\0') {
|
||||||
return 0;
|
if (u != '\0' && u != ' ' && u != '\t' && u != ':' && u != '?' && u != '=' && u != '\n' && u != '\r')
|
||||||
if (c[i] != ' ' && c[i] != '\t' && c[i] != ':' && c[i] != '?' && c[i] != '=' && c[i] != '\n' && c[i] != '\r' && c[i])
|
return false;
|
||||||
return 0;
|
return true;
|
||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -294,14 +347,14 @@ 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.");
|
print_string("Checksum OK.\nUpload to flash done, will reset!\n");
|
||||||
|
// close connection to avoid retries by browser
|
||||||
|
uip_close();
|
||||||
|
reset_chip();
|
||||||
} else {
|
} else {
|
||||||
print_string("Checksum incorrect!");
|
print_string("Checksum incorrect! Aborting.\n");
|
||||||
|
uip_close();
|
||||||
}
|
}
|
||||||
print_string("\nUpload to flash done, will reset!\n");
|
|
||||||
// close connection to avoid retries by browser
|
|
||||||
uip_close();
|
|
||||||
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;
|
||||||
@@ -329,18 +382,22 @@ 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 >= FLASHMEM_PAGE_SIZE) {
|
if (write_len >= FLASH_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_sector_erase();
|
||||||
|
}
|
||||||
flash_region.addr = uptr;
|
flash_region.addr = uptr;
|
||||||
flash_region.len = FLASHMEM_PAGE_SIZE;
|
flash_region.len = FLASH_PAGE_SIZE;
|
||||||
flash_write_bytes(flash_buf);
|
flash_write_bytes(flash_buf);
|
||||||
uptr += FLASHMEM_PAGE_SIZE;
|
uptr += FLASH_PAGE_SIZE;
|
||||||
write_len -= FLASHMEM_PAGE_SIZE;
|
write_len -= FLASH_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 + FLASHMEM_PAGE_SIZE, write_len);
|
memcpy(flash_buf, flash_buf + FLASH_PAGE_SIZE, write_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bindex = 0;
|
bindex = 0;
|
||||||
@@ -355,39 +412,74 @@ 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;
|
||||||
|
|
||||||
dbg_string("Is POST\n");
|
// Was the multipart header sent in multiple packets?
|
||||||
p += 5; // Skip post
|
if (s->tstate != TSTATE_MULTIPART) {
|
||||||
// Find end of request path
|
dbg_string("Is POST\n");
|
||||||
while (*p && !is_separator(*p))
|
p += 5; // Skip post
|
||||||
p++;
|
// Find end of request path
|
||||||
*p++ = '\0';
|
while (*p && !is_separator(*p))
|
||||||
|
p++;
|
||||||
|
*p++ = '\0';
|
||||||
|
|
||||||
// Find end of request header
|
// Find end of request header
|
||||||
boundary[0] ='\0';
|
boundary[0] ='\0';
|
||||||
p = scan_header(p);
|
p = scan_header(p);
|
||||||
dbg_string("Boundary: >"); dbg_string_x(boundary); dbg_string("<\n");
|
dbg_string("Boundary: >"); dbg_string_x(boundary); dbg_string("<\n");
|
||||||
if (!*p || !content_type) {
|
if (!*p || !content_type) {
|
||||||
dbg_string("Bad Request!\n");
|
dbg_string("Bad Request!\n");
|
||||||
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;
|
||||||
}
|
}
|
||||||
while (*p && *p != '\n' && *p != '\r')
|
execute_commands(p);
|
||||||
cmd_buffer[i++] = *p++;
|
if (err_status != ERR_OK) {
|
||||||
cmd_buffer[i] = '\0';
|
send_bad_request();
|
||||||
if (i)
|
return;
|
||||||
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_word_x(p, passwd)) {
|
if (is_url_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);
|
||||||
@@ -398,10 +490,11 @@ 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 (is_word(request_path, "upload") || is_word(request_path, "config")) {
|
} else if (s->tstate == TSTATE_MULTIPART || 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();
|
||||||
@@ -415,8 +508,10 @@ 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) {
|
||||||
goto bad_request;
|
s->tstate = TSTATE_MULTIPART;
|
||||||
|
return;
|
||||||
|
}
|
||||||
p = scan_header(p);
|
p = scan_header(p);
|
||||||
if (!*p)
|
if (!*p)
|
||||||
goto bad_request;
|
goto bad_request;
|
||||||
@@ -426,25 +521,6 @@ 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")) {
|
|
||||||
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 {
|
|
||||||
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);
|
||||||
|
|
||||||
@@ -473,6 +549,12 @@ 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;
|
||||||
@@ -544,10 +626,10 @@ void httpd_appcall(void)
|
|||||||
dbg_char('\n');
|
dbg_char('\n');
|
||||||
#endif
|
#endif
|
||||||
p = uip_appdata;
|
p = uip_appdata;
|
||||||
if (is_word(p, "POST")) {
|
if (is_word(p, "POST") || s->tstate == TSTATE_MULTIPART) {
|
||||||
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) {
|
if (s->tstate == TSTATE_POST || s->tstate == TSTATE_MULTIPART) {
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -630,7 +712,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\n\r\n");
|
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");
|
||||||
|
|
||||||
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,11 +13,11 @@
|
|||||||
#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"
|
||||||
|
|
||||||
|
|
||||||
#define L2_MAX_TRANSFER 30
|
#define L2_MAX_TRANSFER 30
|
||||||
|
|
||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK1
|
||||||
@@ -97,7 +97,7 @@ void itoa_html(uint8_t v)
|
|||||||
char_to_html('0' + (v % 10));
|
char_to_html('0' + (v % 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
void string_to_html(register char *s)
|
void string_to_html(__code char *s)
|
||||||
{
|
{
|
||||||
while (*s) char_to_html(*s++);
|
while (*s) char_to_html(*s++);
|
||||||
}
|
}
|
||||||
@@ -175,11 +175,15 @@ 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 & 0xf, 0x51 >> 5, (0x51 << 3) & 0xff);
|
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | (len - 1) & 0xf, 0x51 >> 5, (0x51 << 3) & 0xff);
|
||||||
} else {
|
} else {
|
||||||
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | len & 0xf, 0x50 >> 5, (0x50 << 3) & 0xff);
|
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | (len - 1) & 0xf, 0x50 >> 5, (0x50 << 3) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_read_m(RTL837X_REG_I2C_CTRL);
|
reg_read_m(RTL837X_REG_I2C_CTRL);
|
||||||
@@ -196,13 +200,10 @@ 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 & 0xf; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
if (!(i & 0x3))
|
if (!(i & 0x3))
|
||||||
reg_read_m(RTL837X_REG_I2C_OUT + (i >> 2));
|
reg_read_m(RTL837X_REG_I2C_OUT + i);
|
||||||
if (len & 0x80)
|
byte_to_html(sfr_data[3 - (i & 0x3)]);
|
||||||
char_to_html(sfr_data[3 - (i & 0x3)]);
|
|
||||||
else
|
|
||||||
byte_to_html(sfr_data[3 - (i & 0x3)]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,6 +227,11 @@ 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(':');
|
||||||
@@ -242,14 +248,16 @@ void send_basic_info(void)
|
|||||||
slen += strtox(outbuf + slen, "\",\"flash_size\":\"");
|
slen += strtox(outbuf + slen, "\",\"flash_size\":\"");
|
||||||
string_to_html(get_flash_size_str());
|
string_to_html(get_flash_size_str());
|
||||||
|
|
||||||
slen += strtox(outbuf + slen, "\",\"sfp_slot_0\":\"");
|
if (machine.n_sfp) {
|
||||||
send_sfp_info(0);
|
slen += strtox(outbuf + slen, "\",\"sfp_slot_0\":\"");
|
||||||
char_to_html('"');
|
send_sfp_info(0);
|
||||||
if (machine.n_sfp == 2) {
|
if (machine.n_sfp == 2) {
|
||||||
slen += strtox(outbuf + slen, ",\"sfp_slot_1\":\"");
|
slen += strtox(outbuf + slen, "\",\"sfp_slot_1\":\"");
|
||||||
send_sfp_info(1);
|
send_sfp_info(1);
|
||||||
char_to_html('"');
|
}
|
||||||
}
|
}
|
||||||
|
char_to_html('"');
|
||||||
|
|
||||||
char_to_html('}');
|
char_to_html('}');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,6 +278,14 @@ 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, "\"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,6 +640,11 @@ 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\":");
|
||||||
@@ -632,7 +653,6 @@ 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");
|
||||||
@@ -643,6 +663,19 @@ 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);
|
||||||
}
|
}
|
||||||
@@ -655,7 +688,12 @@ 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];
|
||||||
char_to_html('"');
|
slen += strtox(outbuf + slen,"\",\"sfp_los\":");
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,37 +6,36 @@ 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.bin
|
all: create_build_dir $(BUILDDIR)/updatebuilder $(BUILDDIR)/rtlplayground_oem_upgrade.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.bin: $(BUILDDIR)rtlinstaller.ihx ../$(BUILDDIR)/rtlplayground.bin
|
$(BUILDDIR)/rtlplayground_oem_upgrade.bin: $(BUILDDIR)/rtlinstaller.ihx ../$(BUILDDIR)/rtlplayground.bin
|
||||||
cp ../$(BUILDDIR)/rtlplayground.bin $(BUILDDIR)
|
./$(BUILDDIR)/updatebuilder -i $< -o $(BUILDDIR)/rtlplayground_oem_upgrade.bin ../$(BUILDDIR)/rtlplayground.bin
|
||||||
./$(BUILDDIR)/updatebuilder -i $< $(BUILDDIR)rtlplayground.bin
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -r $(BUILDDIR)
|
rm -r $(BUILDDIR)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ __code const struct machine machine = {
|
|||||||
.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 = GPIO54_ACL_BIT2_EN,
|
||||||
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 },
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
.port_led_set = { 0, 0, 0, 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
|
||||||
@@ -73,6 +73,58 @@ __code const struct machine machine = {
|
|||||||
|
|
||||||
void machine_custom_init(void) { }
|
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-9XH-X-EU",
|
||||||
@@ -89,7 +141,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 | LED_29 },
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
.port_led_set = { 0, 0, 0, 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,
|
||||||
@@ -100,9 +152,62 @@ __code const struct machine machine = {
|
|||||||
|
|
||||||
void machine_custom_init(void) { }
|
void machine_custom_init(void) { }
|
||||||
|
|
||||||
#elif defined MACHINE_KP_9000_9XHML_X
|
#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",
|
.machine_name = "keepLink KP-9000-9XHML-X V2.2",
|
||||||
|
.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,
|
.isRTL8373 = 1,
|
||||||
.min_port = 0,
|
.min_port = 0,
|
||||||
.max_port = 8,
|
.max_port = 8,
|
||||||
@@ -115,7 +220,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 = GPIO48_I2C_SCL1,
|
.reset_pin = GPIO48_I2C_SCL1,
|
||||||
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 },
|
.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},
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
.led_sets = {
|
.led_sets = {
|
||||||
{ /* RJ45: First LED, yellow, second LED: green */
|
{ /* RJ45: First LED, yellow, second LED: green */
|
||||||
@@ -137,9 +242,48 @@ __code const struct machine machine = {
|
|||||||
|
|
||||||
void machine_custom_init(void) { }
|
void machine_custom_init(void) { }
|
||||||
|
|
||||||
#elif defined MACHINE_SWGT024_V2_0
|
#elif defined MACHINE_SWGT024_V2_0_MANAGED
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "SWGT024 V2.0",
|
.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, 0, 0, 0, 0, 0, 0},
|
||||||
|
.led_sets = {
|
||||||
|
{
|
||||||
|
/* Green LED */
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
0,
|
||||||
|
/* Amber LED */
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
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,
|
||||||
@@ -159,19 +303,19 @@ __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 = GPIO36_PWM_OUT,
|
.reset_pin = GPIO_NA,
|
||||||
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 },
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
/* Conditions for LED on:
|
.led_sets = {
|
||||||
* dual led orange: ledset_0 & ledset_2
|
{
|
||||||
* dual led green: ledset_2 & !ledset_0
|
/* Green LED */
|
||||||
* single right led green: ledset_0 & !ledset_1
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
*/
|
0,
|
||||||
.led_sets = { { LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
/* Amber LED */
|
||||||
LEDS_2G5 | LEDS_LINK | LEDS_10G,
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
LEDS_1G | LEDS_LINK,
|
0
|
||||||
0 },
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
void machine_custom_init(void) { }
|
||||||
@@ -192,7 +336,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 | LED_29 },
|
.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},
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
.led_sets = {
|
.led_sets = {
|
||||||
{ /* RJ45: First LED, yellow, second LED: green */
|
{ /* RJ45: First LED, yellow, second LED: green */
|
||||||
@@ -231,12 +375,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_bus ={ .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[0].i2c = { .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_bus = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[1].i2c = { .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},
|
||||||
@@ -274,7 +418,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 = GPIO54_ACL_BIT2_EN,
|
.reset_pin = GPIO54_ACL_BIT2_EN,
|
||||||
.high_leds = { .mux = LED_27 | LED_28 | LED_29, .enable = LED_28 | LED_29 },
|
.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},
|
.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 = { { LEDS_2G5 | LEDS_LINK | LEDS_ACT, // Green LED (right)
|
||||||
0, // unused
|
0, // unused
|
||||||
@@ -289,6 +433,39 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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,
|
||||||
|
.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 = 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 },
|
||||||
|
},
|
||||||
|
.led_mux_custom = 0,
|
||||||
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
void machine_custom_init(void) { }
|
||||||
|
|
||||||
#elif defined MACHINE_DEFAULT_8C_1SFP
|
#elif defined MACHINE_DEFAULT_8C_1SFP
|
||||||
@@ -307,7 +484,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 | LED_29 },
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
.port_led_set = { 0, 0, 0, 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,
|
||||||
@@ -326,19 +503,35 @@ __code const struct machine machine = {
|
|||||||
.max_port = 8,
|
.max_port = 8,
|
||||||
.n_sfp = 2,
|
.n_sfp = 2,
|
||||||
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
||||||
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
||||||
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
.is_sfp = {0, 0, 0, 1, 0, 0, 0, 0, 2},
|
||||||
.sfp_port[0].pin_detect = GPIO36_PWM_OUT,
|
.sfp_port[0].pin_detect = GPIO38,
|
||||||
.sfp_port[0].pin_los = GPIO37,
|
.sfp_port[0].pin_los = GPIO50_I2C_SCL2_UART1_TX,
|
||||||
.sfp_port[0].pin_tx_disable = GPIO51_I2C_SDA2_UART1_RX,
|
.sfp_port[0].pin_tx_disable = GPIO54_ACL_BIT2_EN,
|
||||||
.sfp_port[0].sds = 0,
|
.sfp_port[0].sds = 0,
|
||||||
.sfp_port[0].i2c = { .sda = GPIO47_I2C_SDA0, .scl = GPIO46_I2C_SCL0 },
|
.sfp_port[0].i2c = { .sda = GPIO47_I2C_SDA0, .scl = GPIO46_I2C_SCL0 },
|
||||||
.sfp_port[1].pin_detect = GPIO38,
|
.sfp_port[1].pin_detect = GPIO36_PWM_OUT,
|
||||||
.sfp_port[1].pin_los = GPIO50_I2C_SCL2_UART1_TX,
|
.sfp_port[1].pin_los = GPIO37,
|
||||||
.sfp_port[1].pin_tx_disable = GPIO54_ACL_BIT2_EN,
|
.sfp_port[1].pin_tx_disable = GPIO51_I2C_SDA2_UART1_RX,
|
||||||
.sfp_port[1].sds = 1,
|
.sfp_port[1].sds = 1,
|
||||||
.sfp_port[1].i2c = { .sda = GPIO49_I2C_SDA1, .scl = GPIO48_I2C_SCL1 },
|
.sfp_port[1].i2c = { .sda = GPIO49_I2C_SDA1, .scl = GPIO48_I2C_SCL1 },
|
||||||
.reset_pin = GPIO_NA,
|
.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) { }
|
void machine_custom_init(void) { }
|
||||||
@@ -367,7 +560,7 @@ __code const struct machine machine = {
|
|||||||
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
|
|
||||||
.reset_pin = GPIO_NA,
|
.reset_pin = GPIO_NA,
|
||||||
.high_leds = { .mux = LED_28 | LED_29, .enable = LED_27 | LED_28 | LED_29 },
|
.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},
|
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
.led_sets = {
|
.led_sets = {
|
||||||
{
|
{
|
||||||
@@ -392,6 +585,199 @@ __code const struct machine machine = {
|
|||||||
void machine_custom_init(void) {
|
void machine_custom_init(void) {
|
||||||
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "Please select a machine type in machine.h"
|
#error "Please select a machine type in machine.h"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,16 +8,23 @@
|
|||||||
*/
|
*/
|
||||||
// #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
|
// #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_TRENDNET_TEG_S562
|
||||||
// #define MACHINE_HG0402XG_V1_1
|
// #define MACHINE_HG0402XG_V1_1
|
||||||
// #define MACHINE_SWTG018AS_A_V_2_0
|
// #define MACHINE_SWTG018AS_A_V_2_0
|
||||||
// #define MACHINE_SWTGW218AS
|
// #define MACHINE_SWTGW218AS
|
||||||
// #define MACHINE_HI_K0402WS
|
// #define MACHINE_HI_K0402WS
|
||||||
|
// #define MACHINE_K0501W_V2_0
|
||||||
|
// #define MACHINE_LIANGUO_ZX_SWTGW215AS
|
||||||
|
// #define MACHINE_ZX310S_4T2XH
|
||||||
// #define MACHINE_DEFAULT_8C_1SFP
|
// #define MACHINE_DEFAULT_8C_1SFP
|
||||||
|
// #define MACHINE_HI_K0801WS
|
||||||
|
// #define MACHINE_FNS1200P
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// GPIO pins for SDA/SCL
|
// GPIO pins for SDA/SCL
|
||||||
@@ -27,7 +34,8 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
#define LED_27 1
|
#define LED_27 1
|
||||||
#define LED_28 2
|
// SYSTEM LED
|
||||||
|
#define LED_28_SYS 2
|
||||||
#define LED_29 4
|
#define LED_29 4
|
||||||
|
|
||||||
struct high_leds {
|
struct high_leds {
|
||||||
@@ -49,9 +57,12 @@ 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
|
||||||
@@ -59,7 +70,12 @@ typedef struct machine {
|
|||||||
struct sfp_port sfp_port[2];
|
struct sfp_port sfp_port[2];
|
||||||
uint8_t reset_pin;
|
uint8_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];
|
||||||
|
|||||||
@@ -22,16 +22,21 @@
|
|||||||
#define PHY_ANEG_CTRL 0x00
|
#define PHY_ANEG_CTRL 0x00
|
||||||
#define PHY_ANEG_ADV 0x10
|
#define PHY_ANEG_ADV 0x10
|
||||||
#define PHY_ANEG_LP_ABILITY 0x13
|
#define PHY_ANEG_LP_ABILITY 0x13
|
||||||
#define PHY_ANEG_MGBASE_CTRL 0x20
|
#define PHY_ANEG_MGBASE_CTRL 0x20
|
||||||
#define PHY_ANEG_MGBASE_ADV 0x21
|
#define PHY_ANEG_MGBASE_ADV 0x21
|
||||||
#define PHY_EEE_ADV 0x3c
|
#define PHY_EEE_ADV 0x3c
|
||||||
#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
|
||||||
|
|||||||
@@ -36,12 +36,20 @@ extern __xdata uint8_t sbuf[SBUF_SIZE];
|
|||||||
// 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)
|
// 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
|
#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
|
||||||
@@ -62,10 +70,11 @@ 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 RX and TX, an 8 byte header describing the frame to be moved to the Asic
|
// For TX, an 8 byte (plus 4 byte padding when when VLAN is enabled)
|
||||||
// and received from the Asic is used
|
// header describing the frame to be moved to the Asic is used
|
||||||
#define RTL_FRAME_HEADER_SIZE 8
|
#define RTL_FRAME_DESC_SIZE 12
|
||||||
|
|
||||||
// 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
|
||||||
@@ -83,6 +92,15 @@ struct vlan_tag {
|
|||||||
#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.
|
||||||
*/
|
*/
|
||||||
@@ -95,10 +113,13 @@ 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;
|
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_string_x(__xdata char *p);
|
||||||
void print_long(uint32_t a);
|
void print_long(uint32_t a);
|
||||||
@@ -107,6 +128,7 @@ 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);
|
||||||
@@ -115,8 +137,11 @@ 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);
|
||||||
@@ -136,9 +161,13 @@ uint16_t strcpy(register __xdata uint8_t *dst, register const char *s);
|
|||||||
void tcpip_output(void);
|
void tcpip_output(void);
|
||||||
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(uint32_t * tmr);
|
void read_reg_timer(__xdata 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
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
#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);
|
||||||
@@ -13,3 +23,4 @@ void flash_write_bytes(__xdata uint8_t *ptr);
|
|||||||
__code char* get_flash_size_str(void);
|
__code char* get_flash_size_str(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,264 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include "rtl837x_common.h"
|
||||||
|
#include "rtl837x_sfr.h"
|
||||||
|
#include "rtl837x_regs.h"
|
||||||
|
#include "rtl837x_port.h"
|
||||||
|
#include "rtl837x_phy.h"
|
||||||
|
#include "phy.h"
|
||||||
|
#include "machine.h"
|
||||||
|
|
||||||
|
extern __xdata uint8_t sfr_data[4];
|
||||||
|
extern __code struct machine machine;
|
||||||
|
extern __xdata struct machine_runtime machine_detected;
|
||||||
|
|
||||||
|
#pragma codeseg BANK2
|
||||||
|
#pragma constseg BANK2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure the PHY-Side of the SDS-SDS link between SoC and PHY
|
||||||
|
*/
|
||||||
|
void static sds_init(void)
|
||||||
|
{
|
||||||
|
phy_read(0, PHY_MMD30, 0xd);
|
||||||
|
uint16_t pval = SFR_DATA_U16;
|
||||||
|
|
||||||
|
// PHY Initialization:
|
||||||
|
REG_WRITE(0x2f8, 0, 0, pval >> 8, pval);
|
||||||
|
delay(20);
|
||||||
|
|
||||||
|
pval &= 0xfff0;
|
||||||
|
pval |= 0x0a;
|
||||||
|
REG_WRITE(0x2f4, 0, 0, pval >> 8, pval);
|
||||||
|
delay(10);
|
||||||
|
|
||||||
|
phy_write_mask(0x1, PHY_MMD30, 0xd, pval);
|
||||||
|
|
||||||
|
phy_read(0, PHY_MMD30, 0xd);
|
||||||
|
pval = SFR_DATA_U16;
|
||||||
|
|
||||||
|
REG_WRITE(0x2f8, 0, 0, pval >> 8, pval);
|
||||||
|
|
||||||
|
pval &= 0xfff0;
|
||||||
|
REG_WRITE(0x2f4, 0, 0, pval >> 8, pval);
|
||||||
|
|
||||||
|
phy_write_mask(0x1, PHY_MMD30, 0xd, pval);
|
||||||
|
|
||||||
|
if (machine_detected.isN) {
|
||||||
|
uint16_t pval;
|
||||||
|
|
||||||
|
print_string(" N-settings");
|
||||||
|
if (machine.n_10g)
|
||||||
|
print_string(" - 10g");
|
||||||
|
// Serdes 0 RX PN swap for 64B/66B
|
||||||
|
sds_read(1, 6, 2);
|
||||||
|
pval = SFR_DATA_U16;
|
||||||
|
sds_write_v(1, 6, 2, pval | 0x2000);
|
||||||
|
|
||||||
|
// Serdes 1 RX PN swap for 8B/10B
|
||||||
|
sds_read(1, 0, 0);
|
||||||
|
pval = SFR_DATA_U16;
|
||||||
|
sds_write_v(1, 0, 0, pval | 0x200);
|
||||||
|
|
||||||
|
// Serdes 0 RX PN swap for 64B/66B
|
||||||
|
sds_read(0, 6, 2);
|
||||||
|
pval = SFR_DATA_U16;
|
||||||
|
sds_write_v(0, 6, 2, pval | 0x2000);
|
||||||
|
|
||||||
|
if (!machine.n_10g) {
|
||||||
|
if (machine_detected.isRTL8373) {
|
||||||
|
// RTL8224: Serdes 0 RX PN swap for 64B/66B
|
||||||
|
// We assume that RTL8373N always paired with RTL8224N.
|
||||||
|
// This sds register value is 0x0000 at reset.
|
||||||
|
// So only write to it.
|
||||||
|
RTL8224_SDS_WRITE(0, 6, 2, 0x2000);
|
||||||
|
} else {
|
||||||
|
// Serdes 0 RX PN swap for 8B/10B
|
||||||
|
sds_read(0, 0, 0);
|
||||||
|
pval = SFR_DATA_U16;
|
||||||
|
sds_write_v(0, 0, 0, pval | 0x200);
|
||||||
|
}
|
||||||
|
} else if (machine.n_10g == 1) {
|
||||||
|
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
||||||
|
sfr_mask_data(0, 0x0f,0x0c);
|
||||||
|
reg_write_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
||||||
|
REG_SET(RTL837X_CFG_PHY_TX_POLARITY_SWAP, 0x0000596a);
|
||||||
|
} else if (machine.n_10g == 2) {
|
||||||
|
REG_SET(RTL837X_CFG_PHY_MDI_REVERSE, 0xc);
|
||||||
|
REG_SET(RTL837X_CFG_PHY_TX_POLARITY_SWAP, 0x0000596a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print_string("\nsds_init done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void rtl8373_init(void) __banked
|
||||||
|
{
|
||||||
|
print_string("\nrtl8373_init called\n");
|
||||||
|
|
||||||
|
// r65d8:3ffbedff R65d8-3ffbedff
|
||||||
|
reg_bit_set(0x65d8, 0x1d);
|
||||||
|
|
||||||
|
sds_init();
|
||||||
|
// Disable all SERDES for configuration
|
||||||
|
REG_SET(RTL837X_REG_SDS_MODES, 0x000037ff);
|
||||||
|
|
||||||
|
// q000601:c800 Q000601:c804 q000601:c804 Q000601:c800
|
||||||
|
sds_read(0, 0x06, 0x01);
|
||||||
|
uint16_t pval = SFR_DATA_U16;
|
||||||
|
sds_write_v(0, 0x06, 0x01, pval | 0x04);
|
||||||
|
delay(50);
|
||||||
|
sds_read(0, 0x06, 0x01);
|
||||||
|
pval = SFR_DATA_U16;
|
||||||
|
sds_write_v(0, 0x06, 0x01, pval & 0xfffb);
|
||||||
|
|
||||||
|
phy_config_8224();
|
||||||
|
sds_config_mac(1, SDS_OFF); // Off for now until SFP+ port used
|
||||||
|
sds_config_mac(2, SDS_SGMII); // For RTL8224
|
||||||
|
sds_config(0, SDS_QXGMII); // For RTL8224
|
||||||
|
|
||||||
|
// SDS 1 setup
|
||||||
|
// q012100:4902 Q012100:4906 q013605:0000 Q013605:4000 Q011f02:001f q011f15:0086
|
||||||
|
sds_write_v(1, 0x21, 0x00, 0x4906);
|
||||||
|
sds_write_v(1, 0x36, 0x05, 0x4000);
|
||||||
|
sds_write_v(1, 0x1f, 0x02, 0x001f);
|
||||||
|
sds_read(1, 0x1f, 0x15);
|
||||||
|
pval = SFR_DATA_U16;
|
||||||
|
|
||||||
|
// r0a90:000000f3 R0a90-000000fc
|
||||||
|
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
||||||
|
sfr_mask_data(0, 0x0f,0x0c);
|
||||||
|
reg_write_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
||||||
|
|
||||||
|
if (machine_detected.isN) {
|
||||||
|
print_string(" TX_POLARITY_SWAP\n");
|
||||||
|
// FOR N-Version: #TX_POLARITY_SWAP
|
||||||
|
reg_read_m(RTL837X_CFG_PHY_TX_POLARITY_SWAP);
|
||||||
|
sfr_data[2] = 0x59;
|
||||||
|
sfr_data[3] = 0x6a;
|
||||||
|
reg_write_m(RTL837X_CFG_PHY_TX_POLARITY_SWAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
rtl8224_phy_enable();
|
||||||
|
|
||||||
|
// Disable PHYs for configuration
|
||||||
|
phy_write_mask(0xff,PHY_MMD31,0xa610,0x2858);
|
||||||
|
|
||||||
|
// Set bits 0x13 and 0x14 of 0x5fd4
|
||||||
|
// r5fd4:0002914a R5fd4-001a914a
|
||||||
|
reg_bit_set(0x5fd4, 0x13);
|
||||||
|
reg_bit_set(0x5fd4, 0x14);
|
||||||
|
|
||||||
|
// Configure ports
|
||||||
|
uint16_t reg = 0x1238; // Port base register for the bits we set
|
||||||
|
for (char i = 0; i < 9; i++) {
|
||||||
|
// Bit 7 (0x40) enables replacement of the RTL-VLAN tag with an 802.1Q VLAN tag
|
||||||
|
REG_SET(reg, 0xe77);
|
||||||
|
reg += 0x100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// r0b7c:000000d8 R0b7c-000000f8 r6040:00000030 R6040-00000031
|
||||||
|
reg_bit_set(0xb7c, 5);
|
||||||
|
|
||||||
|
// R7124-00001050 R7128-00001050 R712c-00001050 R7130-00001050 R7134-00001050 R7138-00001050
|
||||||
|
// R713c-00001050 R7140-00001050 R7144-00001050 R7148-00001050
|
||||||
|
REG_SET(0x7124, 0x1050); REG_SET(0x7128, 0x1050); REG_SET(0x712c, 0x1050);
|
||||||
|
REG_SET(0x7130, 0x1050); REG_SET(0x7134, 0x1050); REG_SET(0x7138, 0x1050);
|
||||||
|
REG_SET(0x713c, 0x1050); REG_SET(0x7140, 0x1050); REG_SET(0x7144, 0x1050);
|
||||||
|
REG_SET(0x7148, 0x1050);
|
||||||
|
|
||||||
|
reg_bit_set(RTL837X_REG_HW_CONF, 0);
|
||||||
|
|
||||||
|
// enable EEE for all ports at 2.5G, but don't reset the PHYs
|
||||||
|
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
|
||||||
|
|
||||||
|
// TODO: patch the PHYs
|
||||||
|
|
||||||
|
// Re-enable PHY after configuration
|
||||||
|
phy_write_mask(0xff,PHY_MMD31,0xa610,0x2058);
|
||||||
|
|
||||||
|
// Enables MAC access
|
||||||
|
// Set bits 0xc-0x14 of 0x632c to 0x1f8, see rtl8372_init
|
||||||
|
// r632c:00000540 R632c-001f8540 // RTL8373: 001ff540
|
||||||
|
reg_read_m(0x632c);
|
||||||
|
sfr_mask_data(1, 0x70, 0xf0); // The ports of the RTL8824
|
||||||
|
sfr_mask_data(2, 0x10, 0x1f);
|
||||||
|
reg_write_m(0x632c);
|
||||||
|
|
||||||
|
print_string("\nrtl8373_init done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void rtl8372_init(void) __banked
|
||||||
|
{
|
||||||
|
print_string("\nrtl8372_init called\n");
|
||||||
|
|
||||||
|
sds_init();
|
||||||
|
if (machine.n_10g != 2)
|
||||||
|
phy_config(8); // PHY configuration: External 8221B?
|
||||||
|
if (machine.n_10g)
|
||||||
|
phy_config_8261(3, 0);
|
||||||
|
if (machine.n_10g == 2)
|
||||||
|
phy_config_8261(8, 1);
|
||||||
|
else
|
||||||
|
phy_config(3); // PHY configuration: all internal PHYs?
|
||||||
|
// Set the MAC SerDes Modes Bits 0-4: SDS 0 = 0x2 (0x2), Bits 5-9: SDS 1: 1f (off)
|
||||||
|
// r7b20:00000bff R7b20-00000bff r7b20:00000bff R7b20-00000bff r7b20:00000bff R7b20-000003ff r7b20:000003ff R7b20-000003e2 r7b20:000003e2 R7b20-000003e2
|
||||||
|
if (machine.n_10g == 1) {
|
||||||
|
REG_SET(RTL837X_REG_SDS_MODES, 0x3ed); // Disable SFP for now, set RTL8261BE SDS 0 to 0xd
|
||||||
|
} else if(machine.n_10g == 2) {
|
||||||
|
REG_SET(RTL837X_REG_SDS_MODES, 0x1ad); // Both 10g ports use SDS_QXGMII
|
||||||
|
} else {
|
||||||
|
reg_read_m(RTL837X_REG_SDS_MODES);
|
||||||
|
sfr_mask_data(1, 0, 0x03);
|
||||||
|
sfr_mask_data(0, 0, 0xe2);
|
||||||
|
reg_write_m(RTL837X_REG_SDS_MODES);
|
||||||
|
}
|
||||||
|
|
||||||
|
// r0a90:000000f3 R0a90-000000fc
|
||||||
|
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
||||||
|
sfr_mask_data(0, 0x0f, 0x0c);
|
||||||
|
reg_write_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
||||||
|
|
||||||
|
// Disable PHYs for configuration
|
||||||
|
phy_write_mask(0xf0,PHY_MMD31,0xa610,0x2858);
|
||||||
|
|
||||||
|
// Set bits 0x13 and 0x14 of 0x5fd4
|
||||||
|
// r5fd4:0002914a R5fd4-001a914a
|
||||||
|
reg_bit_set(0x5fd4, 0x13);
|
||||||
|
reg_bit_set(0x5fd4, 0x14);
|
||||||
|
|
||||||
|
// Configure ports 3-8:
|
||||||
|
//
|
||||||
|
// r1538:00000e33 R1538-00000e37 r1538:00000e37 R1538-00000e37 r1538:00000e37 R1538-00000f37
|
||||||
|
// [...]
|
||||||
|
///
|
||||||
|
uint16_t reg = 0x1238 + 0x300; // Port base register for the bits we set
|
||||||
|
for (char i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
|
// Bit 7 (0x40) enables replacement of the RTL-VLAN tag with an 802.1Q VLAN tag
|
||||||
|
REG_SET(reg, 0xe77);
|
||||||
|
reg += 0x100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// r0b7c:000000d8 R0b7c-000000f8 r6040:00000030 R6040-00000031
|
||||||
|
reg_bit_set(0xb7c, 5);
|
||||||
|
|
||||||
|
reg_bit_set(RTL837X_REG_HW_CONF, 0);
|
||||||
|
|
||||||
|
|
||||||
|
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
|
||||||
|
port_eee_enable_all(EEE_10G | EEE_NORESET);
|
||||||
|
|
||||||
|
// TODO: patch the PHYs
|
||||||
|
|
||||||
|
// Re-enable PHY after configuration
|
||||||
|
phy_write_mask(0xf0,PHY_MMD31,0xa610,0x2058);
|
||||||
|
|
||||||
|
// Enables MAC access
|
||||||
|
// Set bits 0xc-0x14 of 0x632c to 0x1f8, see rtl8372_init
|
||||||
|
// r632c:00000540 R632c-001f8540 // RTL8373: 001ff540
|
||||||
|
reg_read_m(0x632c);
|
||||||
|
sfr_mask_data(1, 0x70, 0x80);
|
||||||
|
sfr_mask_data(2, 0x10, 0x1f);
|
||||||
|
reg_write_m(0x632c);
|
||||||
|
print_string("\nrtl8372_init done\n");
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef _RTL837X_INIT_H_
|
||||||
|
#define _RTL837X_INIT_H_
|
||||||
|
|
||||||
|
void rtl8372_init(void) __banked;
|
||||||
|
void rtl8373_init(void) __banked;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -35,6 +35,7 @@ void leds_dump(void) __banked
|
|||||||
print_string("RTL837X_REG_LED1_0_SET2: "); print_reg(RTL837X_REG_LED1_0_SET2); write_char('\n');
|
print_string("RTL837X_REG_LED1_0_SET2: "); print_reg(RTL837X_REG_LED1_0_SET2); write_char('\n');
|
||||||
print_string("RTL837X_REG_LED3_2_SET2: "); print_reg(RTL837X_REG_LED3_2_SET2); write_char('\n');
|
print_string("RTL837X_REG_LED3_2_SET2: "); print_reg(RTL837X_REG_LED3_2_SET2); write_char('\n');
|
||||||
print_string("RTL837X_REG_LED1_0_SET3: "); print_reg(RTL837X_REG_LED1_0_SET3); write_char('\n');
|
print_string("RTL837X_REG_LED1_0_SET3: "); print_reg(RTL837X_REG_LED1_0_SET3); write_char('\n');
|
||||||
|
print_string("RTL837X_REG_LED3_2_SET3: "); print_reg(RTL837X_REG_LED3_2_SET3); write_char('\n');
|
||||||
print_string("RTL837X_REG_LED3_0_SET1: "); print_reg(RTL837X_REG_LED3_0_SET1); write_char('\n');
|
print_string("RTL837X_REG_LED3_0_SET1: "); print_reg(RTL837X_REG_LED3_0_SET1); write_char('\n');
|
||||||
print_string("RTL837X_REG_LED3_0_SET3: "); print_reg(RTL837X_REG_LED3_0_SET3); write_char('\n');
|
print_string("RTL837X_REG_LED3_0_SET3: "); print_reg(RTL837X_REG_LED3_0_SET3); write_char('\n');
|
||||||
print_string("RTL837X_LED_PORT_SET_SEL: "); print_reg(RTL837X_LED_PORT_SET_SEL); write_char('\n');
|
print_string("RTL837X_LED_PORT_SET_SEL: "); print_reg(RTL837X_LED_PORT_SET_SEL); write_char('\n');
|
||||||
@@ -190,7 +191,8 @@ void leds_setup(void) __banked
|
|||||||
else
|
else
|
||||||
reg_bit_clear(RTL837X_PIN_MUX_0, 27);
|
reg_bit_clear(RTL837X_PIN_MUX_0, 27);
|
||||||
|
|
||||||
if (machine.high_leds.mux & LED_28)
|
// SYSTEM LED
|
||||||
|
if (machine.high_leds.mux & LED_28_SYS)
|
||||||
reg_bit_set(RTL837X_PIN_MUX_0, 28);
|
reg_bit_set(RTL837X_PIN_MUX_0, 28);
|
||||||
else
|
else
|
||||||
reg_bit_clear(RTL837X_PIN_MUX_0, 28);
|
reg_bit_clear(RTL837X_PIN_MUX_0, 28);
|
||||||
@@ -205,7 +207,8 @@ void leds_setup(void) __banked
|
|||||||
else
|
else
|
||||||
reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 27);
|
reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 27);
|
||||||
|
|
||||||
if (machine.high_leds.enable & LED_28)
|
// SYSTEM LED
|
||||||
|
if (machine.high_leds.enable & LED_28_SYS)
|
||||||
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 28);
|
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 28);
|
||||||
else
|
else
|
||||||
reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 28);
|
reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 28);
|
||||||
|
|||||||
@@ -86,6 +86,76 @@ void rtl8224_phy_enable(void) __banked
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void phy_config_8261(uint8_t phy, uint8_t sds) __banked
|
||||||
|
{
|
||||||
|
print_string("phy_config_8261: phy "); print_byte(phy);
|
||||||
|
print_string(" sds "); print_byte(sds); write_char('\n');
|
||||||
|
phy_write(phy, PHY_MMD30, 0x141, 0x80aa); // P000008.1e000141:80aa P000008.1e000143:8c07 p031e.0143:0c07
|
||||||
|
phy_write(phy, PHY_MMD30, 0x143, 0x8c07);
|
||||||
|
phy_read(phy, PHY_MMD30, 0x143);
|
||||||
|
print_phy_data();
|
||||||
|
phy_write(phy, PHY_MMD30, 0x141, 0x5078); // P000008.1e000141:5078 P000008.1e000143:8c86 p031e.0143:0c86
|
||||||
|
phy_write(phy, PHY_MMD30, 0x143, 0x8c86);
|
||||||
|
phy_read(phy, PHY_MMD30, 0x143);
|
||||||
|
print_phy_data();
|
||||||
|
phy_read(phy, PHY_MMD30, 0x105);
|
||||||
|
print_phy_data(); // p031e.0105:0000
|
||||||
|
|
||||||
|
phy_write(phy, PHY_MMD30, 0xe1, 0x00); // P000008.1e0000e1:0000
|
||||||
|
phy_write(phy, PHY_MMD30, 0xe3, 0x00); // P000008.1e0000e3:0000
|
||||||
|
phy_write(phy, PHY_MMD30, 0xe4, 0x01); // P000008.1e0000e4:0001
|
||||||
|
phy_write(phy, PHY_MMD30, 0xe0, 0x2f); // P000008.1e0000e0:002f
|
||||||
|
|
||||||
|
// The following are actually bit-ops:
|
||||||
|
phy_write(phy, PHY_MMD31, 0xa442, 0x8418); // p031f.a442:0418 P000008.1f00a442:8418
|
||||||
|
phy_write(phy, PHY_MMD31, 0xa448, 0x07a0); // p031f.a448:07a0 P000008.1f00a448:07a0
|
||||||
|
phy_write(phy, PHY_MMD31, 0xa43a, 0x003f); // p031f.a43a:0030 P000008.1e0000e2:003f
|
||||||
|
|
||||||
|
phy_write(phy, PHY_MMD31, 0xc800, 0x5a02); // P000008.1f00c800:5a02
|
||||||
|
|
||||||
|
phy_write(phy, PHY_MMD30, 0x01ee, 0x5a02); // p031e.01ee:5a00 P000008.1e0001ee:5a02
|
||||||
|
phy_write(phy, PHY_MMD30, 0x0230, 0x0002); // p031e.0230:0000 P000008.1e000230:0002
|
||||||
|
phy_write(phy, PHY_MMD31, 0xc802, 0x0073); // p031f.c802:0000 P000008.1f00c802:0073
|
||||||
|
phy_write(phy, PHY_MMD30, 0x01ef, 0xe004); // p031e.01ef:0004 P000008.1e0001ef:e004
|
||||||
|
delay(20);
|
||||||
|
phy_write(phy, PHY_MMD30, 0x01ef, 0x0004); // p031e.01ef:e004 P000008.1e0001ef:0004
|
||||||
|
delay(20);
|
||||||
|
phy_write(phy, PHY_MMD30, 0x0230, 0x01c2); // p031e.0230:01c2 P000008.1e000230:0002
|
||||||
|
|
||||||
|
phy_read(phy, PHY_MMD30, 0x103);
|
||||||
|
print_phy_data(); // p031e.0103:8261
|
||||||
|
|
||||||
|
phy_write(phy, PHY_MMD30, 0x01c8, 0x0104); // p031e.01c8:0104 P000008.1e0001c8:0104
|
||||||
|
phy_write(phy, PHY_MMD30, 0x01c9, 0x8080); // p031e.01c9:8080 P000008.1e0001c9:8080
|
||||||
|
phy_write(phy, PHY_MMD30, 0x01ca, 0x2020); // p031e.01ca:2020 P000008.1e0001ca:2020
|
||||||
|
phy_write(phy, PHY_MMD30, 0x0105, 0x0000); // p031e.0105:0000 P000008.1e000105:0000
|
||||||
|
phy_write(phy, PHY_MMD30, 0x00c2, 0x880d); // p031e.00c2:880d P000008.1e0000c2:880d
|
||||||
|
phy_write(phy, PHY_MMD30, 0x03f1, 0x0072); // p031e.03f1:0072 P000008.1e0003f1:0072
|
||||||
|
phy_write(phy, PHY_MMD30, 0x02a2, 0x0010); // p031e.02a2:0010 P000008.1e0002a2:0010
|
||||||
|
phy_write(phy, PHY_MMD30, 0x00c1, 0x0127); // p031e.00c1:0127 P000008.1e0000c1:0127
|
||||||
|
phy_write(phy, PHY_MMD30, 0x00c1, 0x0167); // p031e.00c1:0127 P000008.1e0000c1:0167
|
||||||
|
|
||||||
|
sds_write_v(sds, 0x21, 0x00, 0x4096); // Q002100:4906
|
||||||
|
sds_write_v(sds, 0x36, 0x05, 0x4000); // Q003605:4000
|
||||||
|
sds_write_v(sds, 0x1f, 0x02, 0x001f); // Q001f02:001f
|
||||||
|
|
||||||
|
phy_read(phy, 0x01, 0x0000);
|
||||||
|
print_phy_data(); // p0301.0000:2040
|
||||||
|
|
||||||
|
phy_write(phy, 0x01, 0x0000, 0x2040); // P000008.01000000:2040
|
||||||
|
delay(20);
|
||||||
|
|
||||||
|
sds_write_v(sds, 0, 0, 0x1603); // Q000000:1603
|
||||||
|
delay(20);
|
||||||
|
sds_write_v(sds, 0, 0, 0x1601); // Q000000:1601
|
||||||
|
delay(20);
|
||||||
|
sds_write_v(sds, 0, 0, 0x1603); //Q000000:1603
|
||||||
|
delay(20);
|
||||||
|
// r6330:00005555 R6330-00005555 r7b20:000003ed R7b20-000003ed
|
||||||
|
print_string("\r\nphy_config_8261 done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void phy_config(uint8_t phy) __banked
|
void phy_config(uint8_t phy) __banked
|
||||||
{
|
{
|
||||||
print_string("\r\nphy_config: ");
|
print_string("\r\nphy_config: ");
|
||||||
@@ -193,6 +263,10 @@ void phy_set_speed(void) __banked
|
|||||||
uint16_t v;
|
uint16_t v;
|
||||||
|
|
||||||
print_string("Setting port "); write_char(machine.log_to_phys_port[phy_settings.port] + '0');
|
print_string("Setting port "); write_char(machine.log_to_phys_port[phy_settings.port] + '0');
|
||||||
|
if (machine.n_10g && phy_settings.port == 3)
|
||||||
|
phy_settings.is10g_port = 1;
|
||||||
|
if (machine.n_10g == 2 && phy_settings.port == 8)
|
||||||
|
phy_settings.is10g_port = 1;
|
||||||
if (phy_settings.speed == PHY_OFF) {
|
if (phy_settings.speed == PHY_OFF) {
|
||||||
print_string(" to disabled");
|
print_string(" to disabled");
|
||||||
} else {
|
} else {
|
||||||
@@ -200,6 +274,8 @@ void phy_set_speed(void) __banked
|
|||||||
switch(phy_settings.speed) {
|
switch(phy_settings.speed) {
|
||||||
case PHY_SPEED_AUTO:
|
case PHY_SPEED_AUTO:
|
||||||
print_string("auto");
|
print_string("auto");
|
||||||
|
if (phy_settings.is10g_port)
|
||||||
|
print_string (" (10g)");
|
||||||
break;
|
break;
|
||||||
case PHY_SPEED_10M:
|
case PHY_SPEED_10M:
|
||||||
print_string("10M");
|
print_string("10M");
|
||||||
@@ -246,7 +322,10 @@ void phy_set_speed(void) __banked
|
|||||||
// bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD
|
// bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
||||||
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
||||||
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200); // Loop timing enabled
|
if (phy_settings.is10g_port)
|
||||||
|
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0e00);
|
||||||
|
else
|
||||||
|
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200);
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3200); // Restart AN
|
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3200); // Restart AN
|
||||||
} else {
|
} else {
|
||||||
// AN Control Register (MMD 7.0x0000)
|
// AN Control Register (MMD 7.0x0000)
|
||||||
@@ -285,6 +364,12 @@ void phy_set_speed(void) __banked
|
|||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
||||||
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
||||||
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
||||||
|
} else if (phy_settings.speed == PHY_SPEED_5G) {
|
||||||
|
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
||||||
|
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0400, 0x0000);
|
||||||
|
} else if (phy_settings.speed == PHY_SPEED_10G) {
|
||||||
|
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
||||||
|
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0800, 0x0000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3000); // Enable AN
|
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3000); // Enable AN
|
||||||
@@ -367,12 +452,15 @@ void phy_show(uint8_t port) __banked
|
|||||||
print_string("5G");
|
print_string("5G");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
print_string("10M");
|
print_string("Down");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (((v & 0x0600) >> 7) | ((v & 0x0030) >> 4)) <= 6) { // Link is up
|
||||||
|
if (v & 0x8)
|
||||||
|
print_string(" full duplex");
|
||||||
|
else
|
||||||
|
print_string(" half duplex");
|
||||||
}
|
}
|
||||||
if (v & 0x8)
|
|
||||||
print_string(" full duplex");
|
|
||||||
else
|
|
||||||
print_string(" half duplex");
|
|
||||||
|
|
||||||
phy_read(port, PHY_MMD_AN, PHY_ANEG_CTRL);
|
phy_read(port, PHY_MMD_AN, PHY_ANEG_CTRL);
|
||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
@@ -439,6 +527,10 @@ void phy_show(uint8_t port) __banked
|
|||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
if (v & 0x0080)
|
if (v & 0x0080)
|
||||||
print_string(" 2500BaseN-Full");
|
print_string(" 2500BaseN-Full");
|
||||||
|
if (v & 0x0100)
|
||||||
|
print_string(" 5000BaseN-Full");
|
||||||
|
if (v & 0x1000)
|
||||||
|
print_string(" 10GBaseN-Full");
|
||||||
}
|
}
|
||||||
phy_read(port, PHY_MMD_AN, PHY_ANEG_LP_ABILITY);
|
phy_read(port, PHY_MMD_AN, PHY_ANEG_LP_ABILITY);
|
||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ struct phy_settings {
|
|||||||
uint8_t duplex;
|
uint8_t duplex;
|
||||||
uint8_t port;
|
uint8_t port;
|
||||||
uint8_t speed;
|
uint8_t speed;
|
||||||
|
uint8_t is10g_port;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern __xdata struct phy_settings phy_settings;
|
extern __xdata struct phy_settings phy_settings;
|
||||||
@@ -28,6 +29,7 @@ void phy_reset(uint8_t port) __banked;
|
|||||||
void rtl8224_read_reg_u16(uint16_t reg) __banked;
|
void rtl8224_read_reg_u16(uint16_t reg) __banked;
|
||||||
void rtl8224_write_reg_u16(uint16_t reg, uint16_t val) __banked;
|
void rtl8224_write_reg_u16(uint16_t reg, uint16_t val) __banked;
|
||||||
void rtl8224_sds_write(uint16_t sds_cmd, uint16_t val) __banked;
|
void rtl8224_sds_write(uint16_t sds_cmd, uint16_t val) __banked;
|
||||||
|
void phy_config_8261(uint8_t phy, uint8_t sds) __banked;
|
||||||
|
|
||||||
#define RTL8224_SDS_WRITE(sds_id, page, reg, v) uint16_t _sdscmd = (uint16_t)(sds_id & 0x01) | (1 << 14) | (1 << 15); \
|
#define RTL8224_SDS_WRITE(sds_id, page, reg, v) uint16_t _sdscmd = (uint16_t)(sds_id & 0x01) | (1 << 14) | (1 << 15); \
|
||||||
_sdscmd |= (page & 0x3F) << 1; \
|
_sdscmd |= (page & 0x3F) << 1; \
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
#include "rtl837x_common.h"
|
#include "rtl837x_common.h"
|
||||||
#include "rtl837x_regs.h"
|
#include "rtl837x_regs.h"
|
||||||
|
|
||||||
uint8_t i2c_bus_from_sda_pin(uint8_t sda_pin) {
|
#pragma codeseg BANK2
|
||||||
|
#pragma constseg BANK2
|
||||||
|
|
||||||
|
uint8_t i2c_bus_from_sda_pin(uint8_t sda_pin) __banked {
|
||||||
switch (sda_pin) {
|
switch (sda_pin) {
|
||||||
case GPIO47_I2C_SDA0:
|
case GPIO47_I2C_SDA0:
|
||||||
return 0;
|
return 0;
|
||||||
@@ -19,7 +22,7 @@ uint8_t i2c_bus_from_sda_pin(uint8_t sda_pin) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t i2c_bus_from_scl_pin(uint8_t scl_pin) {
|
uint8_t i2c_bus_from_scl_pin(uint8_t scl_pin) __banked{
|
||||||
switch (scl_pin) {
|
switch (scl_pin) {
|
||||||
case GPIO46_I2C_SCL0:
|
case GPIO46_I2C_SCL0:
|
||||||
return 0;
|
return 0;
|
||||||
@@ -35,18 +38,18 @@ uint8_t i2c_bus_from_scl_pin(uint8_t scl_pin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns RTL837X_REG_GPIO_XX_OUTPUT register address */
|
/* Returns RTL837X_REG_GPIO_XX_OUTPUT register address */
|
||||||
static uint16_t gpio_output_reg(uint8_t pin) {
|
static uint16_t gpio_output_reg(uint8_t pin) __banked{
|
||||||
return pin < 32 ? RTL837X_REG_GPIO_00_31_OUTPUT : RTL837X_REG_GPIO_32_63_OUTPUT;
|
return pin < 32 ? RTL837X_REG_GPIO_00_31_OUTPUT : RTL837X_REG_GPIO_32_63_OUTPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns RTL837X_REG_GPIO_XX_DIRECTION register address */
|
/* Returns RTL837X_REG_GPIO_XX_DIRECTION register address */
|
||||||
static uint16_t gpio_direction_reg(uint8_t pin) {
|
static uint16_t gpio_direction_reg(uint8_t pin) __banked {
|
||||||
return pin < 32 ? RTL837X_REG_GPIO_00_31_DIRECTION : RTL837X_REG_GPIO_32_63_DIRECTION;
|
return pin < 32 ? RTL837X_REG_GPIO_00_31_DIRECTION : RTL837X_REG_GPIO_32_63_DIRECTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Enable GPIO functions for pin */
|
/* Enable GPIO functions for pin */
|
||||||
static void gpio_mux_setup(uint8_t pin)
|
static void gpio_mux_setup(uint8_t pin) __banked
|
||||||
{
|
{
|
||||||
// Some GPIOs require setting MUX registers to enable GPIO
|
// Some GPIOs require setting MUX registers to enable GPIO
|
||||||
switch (pin) {
|
switch (pin) {
|
||||||
@@ -94,7 +97,7 @@ static void gpio_mux_setup(uint8_t pin)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_input_setup(uint8_t pin) {
|
void gpio_input_setup(uint8_t pin) __banked {
|
||||||
if (pin == GPIO_NA) {
|
if (pin == GPIO_NA) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -103,7 +106,7 @@ void gpio_input_setup(uint8_t pin) {
|
|||||||
reg_bit_clear(gpio_direction_reg(pin), (pin % 32));
|
reg_bit_clear(gpio_direction_reg(pin), (pin % 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_output_setup(uint8_t pin, __xdata uint8_t initial_val) {
|
void gpio_output_setup(uint8_t pin, __xdata uint8_t initial_val) __banked{
|
||||||
if (pin == GPIO_NA) {
|
if (pin == GPIO_NA) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,22 +72,22 @@
|
|||||||
#define GPIO_NA 0xFF
|
#define GPIO_NA 0xFF
|
||||||
|
|
||||||
/* Convert SDA PIN GPIO to I2C bus number */
|
/* Convert SDA PIN GPIO to I2C bus number */
|
||||||
uint8_t i2c_bus_from_sda_pin(uint8_t sda_pin);
|
uint8_t i2c_bus_from_sda_pin(uint8_t sda_pin) __banked;
|
||||||
|
|
||||||
/* Convert SCL PIN GPIO to I2C bus number */
|
/* Convert SCL PIN GPIO to I2C bus number */
|
||||||
uint8_t i2c_bus_from_scl_pin(uint8_t scl_pin);
|
uint8_t i2c_bus_from_scl_pin(uint8_t scl_pin) __banked;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup a GPIO pin as input
|
* Setup a GPIO pin as input
|
||||||
* pin: GPIO pin number 0-63
|
* pin: GPIO pin number 0-63
|
||||||
*/
|
*/
|
||||||
void gpio_input_setup(uint8_t pin);
|
void gpio_input_setup(uint8_t pin) __banked;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup a GPIO pin as output
|
* Setup a GPIO pin as output
|
||||||
* pin: GPIO pin number 0-63
|
* pin: GPIO pin number 0-63
|
||||||
* initial_val: 1 for bit set in RTL837X_REG_GPIO_xx_OUTPUT, 0 for bit not set
|
* initial_val: 1 for bit set in RTL837X_REG_GPIO_xx_OUTPUT, 0 for bit not set
|
||||||
*/
|
*/
|
||||||
void gpio_output_setup(uint8_t pin, __xdata uint8_t initial_val);
|
void gpio_output_setup(uint8_t pin, __xdata uint8_t initial_val) __banked;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata u
|
|||||||
print_string("\nport_mirror_set called \n");
|
print_string("\nport_mirror_set called \n");
|
||||||
print_string("Mirroring port: "); print_byte(port); print_string(" with rx-mask: ");
|
print_string("Mirroring port: "); print_byte(port); print_string(" with rx-mask: ");
|
||||||
print_short(rx_pmask); print_string(", tx mask: "); print_short(tx_pmask);
|
print_short(rx_pmask); print_string(", tx mask: "); print_short(tx_pmask);
|
||||||
|
write_char('\n');
|
||||||
|
|
||||||
REG_WRITE(RTL837x_MIRROR_CONF, rx_pmask >> 8, rx_pmask, tx_pmask >> 8, tx_pmask);
|
REG_WRITE(RTL837x_MIRROR_CONF, rx_pmask >> 8, rx_pmask, tx_pmask >> 8, tx_pmask);
|
||||||
REG_WRITE(RTL837x_MIRROR_CTRL, 0, 0, 0, (port << 1) | 0x1);
|
REG_WRITE(RTL837x_MIRROR_CTRL, 0, 0, 0, (port << 1) | 0x1);
|
||||||
@@ -48,16 +49,38 @@ void port_mirror_del(void) __banked
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void port_ingress_filter(__xdata uint8_t port, __xdata uint8_t type) __banked
|
bool port_ingress_filter(__xdata uint8_t port, __xdata vlan_ingress_mode_t type) __banked
|
||||||
{
|
{
|
||||||
if (type & 0x1)
|
if (port > 9 || type >= VLAN_INVALID) {
|
||||||
|
print_string("Invalid port or ingress filter type\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & 0x1) {
|
||||||
reg_bit_set(RTL837x_REG_INGRESS, port << 1);
|
reg_bit_set(RTL837x_REG_INGRESS, port << 1);
|
||||||
else
|
} else {
|
||||||
reg_bit_clear(RTL837x_REG_INGRESS, port << 1);
|
reg_bit_clear(RTL837x_REG_INGRESS, port << 1);
|
||||||
if (type & 0x2)
|
}
|
||||||
|
if (type & 0x2) {
|
||||||
reg_bit_set(RTL837x_REG_INGRESS, (port << 1) + 1);
|
reg_bit_set(RTL837x_REG_INGRESS, (port << 1) + 1);
|
||||||
else
|
} else {
|
||||||
reg_bit_clear(RTL837x_REG_INGRESS, (port << 1) + 1);
|
reg_bit_clear(RTL837x_REG_INGRESS, (port << 1) + 1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
vlan_ingress_mode_t port_ingress_filter_get(__xdata uint8_t port) __banked
|
||||||
|
{
|
||||||
|
reg_read_m(RTL837x_REG_INGRESS);
|
||||||
|
if (port > 9) {
|
||||||
|
return VLAN_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each port is represented by 2 bits in the ingress register, starting from bit 0 for port 0
|
||||||
|
const uint8_t sfr_index = 3 - (port / 4);
|
||||||
|
const uint8_t shift = (port % 4) << 1;
|
||||||
|
|
||||||
|
return (vlan_ingress_mode_t)((sfr_data[sfr_index] >> shift) & 0x03);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -78,6 +101,17 @@ void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t port_pvid_get(uint8_t port) __banked
|
||||||
|
{
|
||||||
|
uint16_t reg = RTL837x_PVID_BASE_REG + ((port >> 1) << 2);
|
||||||
|
reg_read_m(reg);
|
||||||
|
if (port & 0x1) {
|
||||||
|
return (sfr_data[1] << 4) | (sfr_data[2] >> 4);
|
||||||
|
} else {
|
||||||
|
return ((sfr_data[2] & 0x0f) << 8) | sfr_data[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void vlan_delete(uint16_t vlan) __banked
|
void vlan_delete(uint16_t vlan) __banked
|
||||||
{
|
{
|
||||||
@@ -93,7 +127,7 @@ void vlan_delete(uint16_t vlan) __banked
|
|||||||
*/
|
*/
|
||||||
int8_t vlan_get(register uint16_t vlan) __banked
|
int8_t vlan_get(register uint16_t vlan) __banked
|
||||||
{
|
{
|
||||||
if (vlan >= 0x3ff) // VLAN 4095 is special
|
if (vlan >= 0xfff) // VLAN 4095 is special
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
REG_WRITE(RTL837X_TBL_CTRL, vlan >> 8, vlan, TBL_VLAN, TBL_EXECUTE);
|
REG_WRITE(RTL837X_TBL_CTRL, vlan >> 8, vlan, TBL_VLAN, TBL_EXECUTE);
|
||||||
@@ -199,7 +233,8 @@ void vlan_setup(void) __banked
|
|||||||
// EGRESS filtering for port: removal of additional VLAN tag (mode 0x3 for each port)
|
// EGRESS filtering for port: removal of additional VLAN tag (mode 0x3 for each port)
|
||||||
reg_bit_clear(RTL837X_VLAN_PORT_EGR_TAG, i << 1);
|
reg_bit_clear(RTL837X_VLAN_PORT_EGR_TAG, i << 1);
|
||||||
reg_bit_clear(RTL837X_VLAN_PORT_EGR_TAG, (i << 1) + 1);
|
reg_bit_clear(RTL837X_VLAN_PORT_EGR_TAG, (i << 1) + 1);
|
||||||
reg_bit_set(RTL837X_VLAN_PORT_IGR_FLTR, i);
|
// Enable INGRESS filtering for port: discard packets not belonging to member VLAN on that port
|
||||||
|
port_ingress_vlan_filter_set(i, true);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print_string("\n");
|
print_string("\n");
|
||||||
@@ -224,6 +259,7 @@ void vlan_setup(void) __banked
|
|||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print_string("\nvlan_setup, REG 0x6738: "); print_reg(0x6738);
|
print_string("\nvlan_setup, REG 0x6738: "); print_reg(0x6738);
|
||||||
|
print_string("\nvlan_setup, REG 0x4e10: "); print_reg(0x4e10);
|
||||||
print_string("\nvlan_setup, REG 0x4e18: "); print_reg(0x4e18);
|
print_string("\nvlan_setup, REG 0x4e18: "); print_reg(0x4e18);
|
||||||
print_string("\nvlan_setup, REG 0x4e14: "); print_reg(0x4e14);
|
print_string("\nvlan_setup, REG 0x4e14: "); print_reg(0x4e14);
|
||||||
print_string("\nvlan_setup, REG 0x4e30: "); print_reg(0x4e30);
|
print_string("\nvlan_setup, REG 0x4e30: "); print_reg(0x4e30);
|
||||||
@@ -351,7 +387,7 @@ void port_l2_setup(void) __banked
|
|||||||
|
|
||||||
void port_stats_print(void) __banked
|
void port_stats_print(void) __banked
|
||||||
{
|
{
|
||||||
print_string("\n Port\tState\tLink\tTxGood\t\tTxBad\t\tRxGood\t\tRxBad\n");
|
print_string("\nPort\tState\tLink\tTxGood\t\tTxBad\t\tRxGood\t\tRxBad\n");
|
||||||
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
write_char('0' + machine.log_to_phys_port[i]); write_char('\t');
|
write_char('0' + machine.log_to_phys_port[i]); write_char('\t');
|
||||||
|
|
||||||
@@ -404,6 +440,9 @@ void port_stats_print(void) __banked
|
|||||||
case 5:
|
case 5:
|
||||||
print_string("2.5G\t");
|
print_string("2.5G\t");
|
||||||
break;
|
break;
|
||||||
|
case 6:
|
||||||
|
print_string("5G\t");
|
||||||
|
break;
|
||||||
case 99:
|
case 99:
|
||||||
print_string("Down\t");
|
print_string("Down\t");
|
||||||
break;
|
break;
|
||||||
@@ -427,14 +466,14 @@ void port_stats_print(void) __banked
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void port_isolate(register uint8_t port, __xdata uint16_t pmask)
|
void port_isolate(register uint8_t port, __xdata uint16_t pmask) __banked
|
||||||
{
|
{
|
||||||
if (port <= machine.max_port)
|
if (port <= machine.max_port)
|
||||||
REG_SET(RTL837X_PORT_ISOLATION_BASE + (port << 2), pmask);
|
REG_SET(RTL837X_PORT_ISOLATION_BASE + (port << 2), pmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t port_isolation_get(register uint8_t port)
|
uint16_t port_isolation_get(register uint8_t port) __banked
|
||||||
{
|
{
|
||||||
if (port > machine.max_port)
|
if (port > machine.max_port)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -453,20 +492,19 @@ void port_eee_enable(__xdata uint8_t port,__xdata uint8_t speed) __banked
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
REG_SET(RTL837X_EEE_CTRL_BASE + (port << 8), EEE_RX_ENABLE | EEE_TX_ENABLE);
|
||||||
print_string("EEE on for "); print_byte(port); print_string(" speed ");
|
print_string("EEE on for "); print_byte(port); print_string(" speed ");
|
||||||
// Enable all speeds up to the specified speed
|
// Enable all speeds up to the specified speed
|
||||||
if ((speed & (EEE_100 | EEE_1000 | EEE_2G5)) == EEE_100) {
|
if (speed & EEE_100) {
|
||||||
print_string("100m\n");
|
print_string("100m\n");
|
||||||
REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100);
|
|
||||||
// Enable EEE advertisement for 100BASE-T via EEE Advertisement Reg
|
// Enable EEE advertisement for 100BASE-T via EEE Advertisement Reg
|
||||||
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_100M);
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_100M);
|
||||||
if (!(speed & EEE_NORESET))
|
if (!(speed & EEE_NORESET))
|
||||||
phy_reset(port);
|
phy_reset(port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((speed & (EEE_100 | EEE_1000 | EEE_2G5)) == EEE_1000) {
|
if (speed & EEE_1000) {
|
||||||
print_string("1g\n");
|
print_string("1g\n");
|
||||||
REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100 | EEE_1000);
|
|
||||||
// Disable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
// Disable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
||||||
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV2, 0);
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV2, 0);
|
||||||
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
||||||
@@ -475,9 +513,8 @@ void port_eee_enable(__xdata uint8_t port,__xdata uint8_t speed) __banked
|
|||||||
phy_reset(port);
|
phy_reset(port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((speed & (EEE_100 | EEE_1000 | EEE_2G5)) == EEE_2G5) {
|
if (speed & EEE_2G5) {
|
||||||
print_string("2g5\n");
|
print_string("2g5\n");
|
||||||
REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100 | EEE_1000 | EEE_2G5);
|
|
||||||
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
||||||
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_1G | PHY_EEE_BIT_100M);
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_1G | PHY_EEE_BIT_100M);
|
||||||
// Enable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
// Enable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
||||||
@@ -486,6 +523,26 @@ void port_eee_enable(__xdata uint8_t port,__xdata uint8_t speed) __banked
|
|||||||
phy_reset(port);
|
phy_reset(port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (speed & EEE_5G) {
|
||||||
|
print_string("5g\n");
|
||||||
|
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
||||||
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_1G | PHY_EEE_BIT_100M);
|
||||||
|
// Enable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
||||||
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV2, PHY_EEE_BIT_2G5 | PHY_EEE_BIT_5G);
|
||||||
|
if (!(speed & EEE_NORESET))
|
||||||
|
phy_reset(port);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (speed & EEE_10G) {
|
||||||
|
print_string("10g\n");
|
||||||
|
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
||||||
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_10G | PHY_EEE_BIT_1G | PHY_EEE_BIT_100M);
|
||||||
|
// Enable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
||||||
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV2, PHY_EEE_BIT_2G5 | PHY_EEE_BIT_5G);
|
||||||
|
if (!(speed & EEE_NORESET))
|
||||||
|
phy_reset(port);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,7 +553,7 @@ void port_eee_disable(uint8_t port) __banked
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
print_string("EEE off for "); print_byte(port); write_char('\n');
|
print_string("EEE off for "); print_byte(port); write_char('\n');
|
||||||
REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), 0);
|
REG_SET(RTL837X_EEE_CTRL_BASE + (port << 8), 0);
|
||||||
// Disable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
// Disable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
||||||
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, 0);
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, 0);
|
||||||
// Disable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
// Disable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
||||||
@@ -516,8 +573,24 @@ void port_eee_status(uint8_t port) __banked
|
|||||||
|
|
||||||
uint16_t v;
|
uint16_t v;
|
||||||
print_string("Advertising: ");
|
print_string("Advertising: ");
|
||||||
|
|
||||||
|
if (machine.n_10g) {
|
||||||
|
phy_read(port, PHY_MMD_AN, PHY_EEE_ADV);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (v & PHY_EEE_BIT_10G)
|
||||||
|
print_string(" 10G");
|
||||||
|
else
|
||||||
|
print_string(" ");
|
||||||
|
}
|
||||||
phy_read(port, PHY_MMD_AN, PHY_EEE_ADV2);
|
phy_read(port, PHY_MMD_AN, PHY_EEE_ADV2);
|
||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
|
if (machine.n_10g) {
|
||||||
|
if (v & PHY_EEE_BIT_5G)
|
||||||
|
print_string(" 5G");
|
||||||
|
else
|
||||||
|
print_string(" ");
|
||||||
|
}
|
||||||
|
v = SFR_DATA_U16;
|
||||||
if (v & PHY_EEE_BIT_2G5)
|
if (v & PHY_EEE_BIT_2G5)
|
||||||
print_string(" 2.5G");
|
print_string(" 2.5G");
|
||||||
else
|
else
|
||||||
@@ -534,8 +607,22 @@ void port_eee_status(uint8_t port) __banked
|
|||||||
print_string(" ");
|
print_string(" ");
|
||||||
|
|
||||||
print_string(" Link Partner: ");
|
print_string(" Link Partner: ");
|
||||||
|
if (machine.n_10g) {
|
||||||
|
phy_read(port, PHY_MMD_AN, PHY_EEE_LP_ABILITY);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (v & PHY_EEE_BIT_10G)
|
||||||
|
print_string(" 10G");
|
||||||
|
else
|
||||||
|
print_string(" ");
|
||||||
|
}
|
||||||
phy_read(port, PHY_MMD_AN, PHY_EEE_LP_ABILITY2);
|
phy_read(port, PHY_MMD_AN, PHY_EEE_LP_ABILITY2);
|
||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
|
if (machine.n_10g) {
|
||||||
|
if (v & PHY_EEE_BIT_5G)
|
||||||
|
print_string(" 5G");
|
||||||
|
else
|
||||||
|
print_string(" ");
|
||||||
|
}
|
||||||
if (v & PHY_EEE_BIT_2G5)
|
if (v & PHY_EEE_BIT_2G5)
|
||||||
print_string(" 2.5G");
|
print_string(" 2.5G");
|
||||||
else
|
else
|
||||||
@@ -563,7 +650,16 @@ void port_eee_status(uint8_t port) __banked
|
|||||||
void port_eee_enable_all(__xdata uint8_t speed) __banked
|
void port_eee_enable_all(__xdata uint8_t speed) __banked
|
||||||
{
|
{
|
||||||
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
port_eee_enable(i, speed);
|
if (i == 3 && machine.n_10g) {
|
||||||
|
port_eee_enable(i, speed);
|
||||||
|
} else if (i == 8 && machine.n_10g == 2) {
|
||||||
|
port_eee_enable(i, speed);
|
||||||
|
} else {
|
||||||
|
if (speed & EEE_10G)
|
||||||
|
port_eee_enable(i, speed & EEE_NORESET | EEE_2G5);
|
||||||
|
else
|
||||||
|
port_eee_enable(i, speed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,8 +701,9 @@ void port_rldp_on(__xdata uint16_t p_ms)
|
|||||||
void port_lag_members_set(__xdata uint8_t lag, __xdata uint16_t members) __banked
|
void port_lag_members_set(__xdata uint8_t lag, __xdata uint16_t members) __banked
|
||||||
{
|
{
|
||||||
print_string("port_lag_members_set, lag: "); print_byte(lag); print_string(", members: "); print_short(members);
|
print_string("port_lag_members_set, lag: "); print_byte(lag); print_string(", members: "); print_short(members);
|
||||||
|
write_char('\n');
|
||||||
if (lag > 3)
|
if (lag > 3)
|
||||||
print_string("Link aggregation group must be 0-3!");
|
print_string("Link aggregation group must be 0-3!\n");
|
||||||
reg_read_m(RTL837X_TRK_HASH_CTRL_BASE + (lag << 2));
|
reg_read_m(RTL837X_TRK_HASH_CTRL_BASE + (lag << 2));
|
||||||
if (!(sfr_data[0] | sfr_data [1] | sfr_data [2] | sfr_data [3]))
|
if (!(sfr_data[0] | sfr_data [1] | sfr_data [2] | sfr_data [3]))
|
||||||
REG_SET(RTL837X_TRK_HASH_CTRL_BASE, LAG_HASH_DEFAULT);
|
REG_SET(RTL837X_TRK_HASH_CTRL_BASE, LAG_HASH_DEFAULT);
|
||||||
@@ -621,7 +718,82 @@ void port_lag_members_set(__xdata uint8_t lag, __xdata uint16_t members) __banke
|
|||||||
void port_lag_hash_set(__xdata uint8_t lag, __xdata uint8_t hash_bits) __banked
|
void port_lag_hash_set(__xdata uint8_t lag, __xdata uint8_t hash_bits) __banked
|
||||||
{
|
{
|
||||||
print_string("port_lag_hash_set, lag: "); print_byte(lag); print_string(", hash: "); print_byte(hash_bits);
|
print_string("port_lag_hash_set, lag: "); print_byte(lag); print_string(", hash: "); print_byte(hash_bits);
|
||||||
|
write_char('\n');
|
||||||
if (lag > 3)
|
if (lag > 3)
|
||||||
print_string("Link aggregation group must be 0-3!");
|
print_string("Link aggregation group must be 0-3!\n");
|
||||||
REG_WRITE(RTL837X_TRK_HASH_CTRL_BASE + (lag << 2), 0, 0, 0, hash_bits);
|
REG_WRITE(RTL837X_TRK_HASH_CTRL_BASE + (lag << 2), 0, 0, 0, hash_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_port_ingress_filter_mode(vlan_ingress_mode_t mode) __banked
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case VLAN_UNTAGGED:
|
||||||
|
print_string("Untag.");
|
||||||
|
break;
|
||||||
|
case VLAN_TAGGED:
|
||||||
|
print_string("Tagged");
|
||||||
|
break;
|
||||||
|
case VLAN_ALL:
|
||||||
|
print_string("Any");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_string("!!err!!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_phys_port(uint8_t port) __banked
|
||||||
|
{
|
||||||
|
if (port >= machine.min_port && port <= machine.max_port)
|
||||||
|
write_char(machine.log_to_phys_port[port] + '0');
|
||||||
|
else if (port == 9)
|
||||||
|
write_char('9');
|
||||||
|
else
|
||||||
|
write_char('?');
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_vlan_ingress_port(uint8_t log_port) __banked
|
||||||
|
{
|
||||||
|
print_phys_port(log_port);write_char('\t');
|
||||||
|
print_short(port_pvid_get(log_port));write_char('\t');
|
||||||
|
print_port_ingress_filter_mode(port_ingress_filter_get(log_port));write_char('\t');
|
||||||
|
port_ingress_vlan_filter_get(log_port) ? print_string("Enabled") : print_string("Disabled");
|
||||||
|
write_char('\n');
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Dumps the VLAN ingress configuration
|
||||||
|
*/
|
||||||
|
void vlan_dump(void) __banked
|
||||||
|
{
|
||||||
|
print_string("Ingress VLAN configuration:\n");
|
||||||
|
print_string("Port\tPVID\tType\tFiltering\n");
|
||||||
|
for (uint8_t port = machine.min_port; port <= machine.max_port; port++) {
|
||||||
|
print_vlan_ingress_port(port);
|
||||||
|
}
|
||||||
|
print_vlan_ingress_port(9);
|
||||||
|
|
||||||
|
write_char('\n');
|
||||||
|
print_string("Type - Which frame types are allowed: untagged, tagged or any\n");
|
||||||
|
print_string("Filtering - Whether packets not belonging to member VLANs on that port are dropped\n");
|
||||||
|
print_string("PVID - Assumed VLAN for untagged packets\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Set the ingress VLAN filtering */
|
||||||
|
bool port_ingress_vlan_filter_set(__xdata uint8_t port, __xdata bool enabled) __banked
|
||||||
|
{
|
||||||
|
if (port < machine.min_port || port > machine.max_port && port != 9) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
reg_bit_set(RTL837X_VLAN_PORT_IGR_FLTR, port);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the ingress VLAN filtering status */
|
||||||
|
bool port_ingress_vlan_filter_get(__xdata uint8_t port) __banked
|
||||||
|
{
|
||||||
|
if (port < machine.min_port || port > machine.max_port && port != 9) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return reg_bit_test(RTL837X_VLAN_PORT_IGR_FLTR, port);
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define _RTL837X_PORT_H_
|
#define _RTL837X_PORT_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "rtl837x_regs.h"
|
||||||
|
|
||||||
#define STAT_COUNTER_TX_PKTS 46
|
#define STAT_COUNTER_TX_PKTS 46
|
||||||
#define STAT_COUNTER_RX_PKTS 47
|
#define STAT_COUNTER_RX_PKTS 47
|
||||||
@@ -13,12 +14,35 @@
|
|||||||
reg_read_m(RTL837X_STAT_GET); \
|
reg_read_m(RTL837X_STAT_GET); \
|
||||||
} while (sfr_data[3] & 0x1);
|
} while (sfr_data[3] & 0x1);
|
||||||
|
|
||||||
|
// Possible values for ingress filter type
|
||||||
|
typedef enum {
|
||||||
|
VLAN_ALL = INGR_ALLOW_ALL,
|
||||||
|
VLAN_TAGGED = INGR_ALLOW_TAGGED,
|
||||||
|
VLAN_UNTAGGED = INGR_ALLOW_UNTAGGED,
|
||||||
|
VLAN_INVALID = 3
|
||||||
|
} vlan_ingress_mode_e;
|
||||||
|
|
||||||
|
// Since we lack a way to force enum to be 1 byte,
|
||||||
|
// This is a typedef for the VLAN ingress filter type
|
||||||
|
// which holds vlan_ingress_mode_e values
|
||||||
|
typedef uint8_t vlan_ingress_mode_t;
|
||||||
|
|
||||||
struct vlan_settings {
|
struct vlan_settings {
|
||||||
uint16_t vlan;
|
uint16_t vlan;
|
||||||
uint16_t members;
|
uint16_t members;
|
||||||
uint16_t tagged;
|
uint16_t tagged;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Port EEE settings
|
||||||
|
*/
|
||||||
|
#define EEE_100 0x01
|
||||||
|
#define EEE_1000 0x04
|
||||||
|
#define EEE_2G5 0x10
|
||||||
|
#define EEE_5G 0x20
|
||||||
|
#define EEE_10G 0x40
|
||||||
|
#define EEE_NORESET 0x80
|
||||||
|
|
||||||
extern __xdata struct vlan_settings vlan_settings;
|
extern __xdata struct vlan_settings vlan_settings;
|
||||||
|
|
||||||
uint8_t port_l2_forget(void) __banked;
|
uint8_t port_l2_forget(void) __banked;
|
||||||
@@ -28,11 +52,13 @@ int8_t vlan_get(register uint16_t vlan) __banked;
|
|||||||
__xdata uint16_t vlan_name(register uint16_t vlan) __banked;
|
__xdata uint16_t vlan_name(register uint16_t vlan) __banked;
|
||||||
void vlan_setup(void) __banked;
|
void vlan_setup(void) __banked;
|
||||||
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(void) __banked;
|
void vlan_create(void) __banked;
|
||||||
void vlan_delete(uint16_t vlan) __banked;
|
void vlan_delete(uint16_t vlan) __banked;
|
||||||
|
void vlan_dump(void) __banked;
|
||||||
void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked;
|
void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked;
|
||||||
void port_mirror_del(void) __banked;
|
void port_mirror_del(void) __banked;
|
||||||
void port_ingress_filter(__xdata uint8_t port, __xdata uint8_t type) __banked;
|
bool port_ingress_filter(__xdata uint8_t port, __xdata vlan_ingress_mode_t type) __banked;
|
||||||
void port_l2_setup(void) __banked;
|
void port_l2_setup(void) __banked;
|
||||||
void port_lag_members_set(__xdata uint8_t lag, __xdata uint16_t members) __banked;
|
void port_lag_members_set(__xdata uint8_t lag, __xdata uint16_t members) __banked;
|
||||||
void port_lag_hash_set(__xdata uint8_t lag, __xdata uint8_t hash) __banked;
|
void port_lag_hash_set(__xdata uint8_t lag, __xdata uint8_t hash) __banked;
|
||||||
@@ -42,4 +68,10 @@ void port_eee_status_all(void) __banked;
|
|||||||
void port_eee_enable(__xdata uint8_t port, __xdata uint8_t speed) __banked;
|
void port_eee_enable(__xdata uint8_t port, __xdata uint8_t speed) __banked;
|
||||||
void port_eee_disable(uint8_t port) __banked;
|
void port_eee_disable(uint8_t port) __banked;
|
||||||
void port_eee_status(uint8_t port) __banked;
|
void port_eee_status(uint8_t port) __banked;
|
||||||
|
void print_port_ingress_filter_mode(vlan_ingress_mode_t mode) __banked;
|
||||||
|
bool port_ingress_vlan_filter_set(__xdata uint8_t port, __xdata bool enabled) __banked;
|
||||||
|
bool port_ingress_vlan_filter_get(__xdata uint8_t port) __banked;
|
||||||
|
void port_isolate(register uint8_t port, __xdata uint16_t pmask) __banked;
|
||||||
|
uint16_t port_isolation_get(register uint8_t port) __banked;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#define RTL837X_REG_LED_GLB_IO_EN 0x65DC
|
#define RTL837X_REG_LED_GLB_IO_EN 0x65DC
|
||||||
#define RTL837X_REG_LED3_0_SET3 0x6524
|
#define RTL837X_REG_LED3_0_SET3 0x6524
|
||||||
#define RTL837X_REG_LED3_0_SET1 0x6528
|
#define RTL837X_REG_LED3_0_SET1 0x6528
|
||||||
|
#define RTL837X_REG_LED3_2_SET3 0x652C
|
||||||
#define RTL837X_REG_LED1_0_SET3 0x6530
|
#define RTL837X_REG_LED1_0_SET3 0x6530
|
||||||
#define RTL837X_REG_LED3_2_SET2 0x6534
|
#define RTL837X_REG_LED3_2_SET2 0x6534
|
||||||
#define RTL837X_REG_LED1_0_SET2 0x6538
|
#define RTL837X_REG_LED1_0_SET2 0x6538
|
||||||
@@ -72,6 +73,7 @@
|
|||||||
*/
|
*/
|
||||||
#define SDS_SGMII 0x02
|
#define SDS_SGMII 0x02
|
||||||
#define SDS_1000BX_FIBER 0x04
|
#define SDS_1000BX_FIBER 0x04
|
||||||
|
#define SDS_100FX 0x05
|
||||||
#define SDS_QXGMII 0x0d
|
#define SDS_QXGMII 0x0d
|
||||||
#define SDS_HISGMII 0x12
|
#define SDS_HISGMII 0x12
|
||||||
#define SDS_HSG 0x16
|
#define SDS_HSG 0x16
|
||||||
@@ -268,14 +270,11 @@
|
|||||||
/*
|
/*
|
||||||
* EEE
|
* EEE
|
||||||
*/
|
*/
|
||||||
#define RTL837X_EEE_STATUS 0x125C
|
#define RTL837X_EEE_CTRL_BASE 0x125C
|
||||||
|
#define EEE_RX_ENABLE 0x01
|
||||||
|
#define EEE_TX_ENABLE 0x02
|
||||||
#define RTL837X_MAC_EEE_ABLTY 0x6404
|
#define RTL837X_MAC_EEE_ABLTY 0x6404
|
||||||
#define RTL8373_PHY_EEE_ABLTY 0x642C
|
#define RTL8373_PHY_EEE_ABLTY 0x642C
|
||||||
#define RTL8373_EEE_CTRL_BASE 0x606c
|
|
||||||
#define EEE_100 0x01
|
|
||||||
#define EEE_1000 0x04
|
|
||||||
#define EEE_2G5 0x10
|
|
||||||
#define EEE_NORESET 0x80
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RANDOM
|
* RANDOM
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ struct stp_pkt_in {
|
|||||||
uint8_t stp_addr[6];
|
uint8_t stp_addr[6];
|
||||||
uint8_t src_addr[6];
|
uint8_t src_addr[6];
|
||||||
struct rtl_tag rtl_tag;
|
struct rtl_tag rtl_tag;
|
||||||
uint8_t vtag[4];
|
struct vlan_tag vlan_tag;
|
||||||
uint16_t msg_len;
|
uint16_t msg_len;
|
||||||
uint8_t dsap;
|
uint8_t dsap;
|
||||||
uint8_t ssap;
|
uint8_t ssap;
|
||||||
@@ -82,7 +82,7 @@ struct stp_pkt_in {
|
|||||||
uint16_t fwd_delay;
|
uint16_t fwd_delay;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define STP_O ((__xdata struct stp_pkt *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE])
|
#define STP_O ((__xdata struct stp_pkt *)&uip_buf[RTL_FRAME_DESC_SIZE])
|
||||||
#define STP_I ((__xdata struct stp_pkt_in *)&uip_buf[0])
|
#define STP_I ((__xdata struct stp_pkt_in *)&uip_buf[0])
|
||||||
|
|
||||||
#define FLAG_PROPOSAL 0x02
|
#define FLAG_PROPOSAL 0x02
|
||||||
@@ -136,7 +136,7 @@ void stp_in(void) __banked
|
|||||||
// print_string("Flags: "); print_byte(STP_I->flags); write_char('\n');
|
// print_string("Flags: "); print_byte(STP_I->flags); write_char('\n');
|
||||||
print_string("Check new Root\n");
|
print_string("Check new Root\n");
|
||||||
if (STP_I->root.prio < root_bridge.prio
|
if (STP_I->root.prio < root_bridge.prio
|
||||||
|| ((STP_I->root.prio == root_bridge.prio) && cmpMAC(STP_I->root.mac, STP_I->root.mac) < 0)) {
|
|| ((STP_I->root.prio == root_bridge.prio) && cmpMAC(STP_I->root.mac, root_bridge.mac) < 0)) {
|
||||||
print_string("Updating Root bridge\n");
|
print_string("Updating Root bridge\n");
|
||||||
root_bridge.prio = STP_I->root.prio;
|
root_bridge.prio = STP_I->root.prio;
|
||||||
memcpy(root_bridge.mac, STP_I->root.mac, 6);
|
memcpy(root_bridge.mac, STP_I->root.mac, 6);
|
||||||
@@ -149,8 +149,8 @@ void stp_cnf_send(uint8_t port)
|
|||||||
STP_O->stp_addr[0] = 0x01; STP_O->stp_addr[1] = 0x80; STP_O->stp_addr[2] = 0xc2;
|
STP_O->stp_addr[0] = 0x01; STP_O->stp_addr[1] = 0x80; STP_O->stp_addr[2] = 0xc2;
|
||||||
STP_O->stp_addr[3] = STP_O->stp_addr[4] = STP_O->stp_addr[5] = 0x00;
|
STP_O->stp_addr[3] = STP_O->stp_addr[4] = STP_O->stp_addr[5] = 0x00;
|
||||||
|
|
||||||
STP_O->rtl_tag.tag = HTONS(0x8899);
|
STP_O->rtl_tag.tag = HTONS(RTL_FRAME_TAG_ID);
|
||||||
STP_O->rtl_tag.version = 0x04;
|
STP_O->rtl_tag.version = RTL_FRAME_TAG_VERSION;
|
||||||
STP_O->rtl_tag.reason = 0x00;
|
STP_O->rtl_tag.reason = 0x00;
|
||||||
STP_O->rtl_tag.flags = 0x0020; // Disable L2 learning
|
STP_O->rtl_tag.flags = 0x0020; // Disable L2 learning
|
||||||
STP_O->rtl_tag.pmask = HTONS(((uint16_t)1) << port);
|
STP_O->rtl_tag.pmask = HTONS(((uint16_t)1) << port);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "rtl837x_igmp.h"
|
#include "rtl837x_igmp.h"
|
||||||
#include "rtl837x_leds.h"
|
#include "rtl837x_leds.h"
|
||||||
#include "rtl837x_bandwidth.h"
|
#include "rtl837x_bandwidth.h"
|
||||||
|
#include "rtl837x_init.h"
|
||||||
#include "dhcp.h"
|
#include "dhcp.h"
|
||||||
#include "cmd_parser.h"
|
#include "cmd_parser.h"
|
||||||
#include "cmd_editor.h"
|
#include "cmd_editor.h"
|
||||||
@@ -23,6 +24,7 @@
|
|||||||
#include "uip/uip_arp.h"
|
#include "uip/uip_arp.h"
|
||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "phy.h"
|
#include "phy.h"
|
||||||
|
#include "syslog.h"
|
||||||
|
|
||||||
extern __code const struct machine machine;
|
extern __code const struct machine machine;
|
||||||
extern __xdata uint32_t flash_size;
|
extern __xdata uint32_t flash_size;
|
||||||
@@ -30,6 +32,8 @@ extern __xdata uint32_t flash_size;
|
|||||||
extern __xdata uint16_t crc_value;
|
extern __xdata uint16_t crc_value;
|
||||||
__xdata struct machine_runtime machine_detected;
|
__xdata struct machine_runtime machine_detected;
|
||||||
void crc16(__xdata uint8_t *v) __naked;
|
void crc16(__xdata uint8_t *v) __naked;
|
||||||
|
void flash_default_config(void);
|
||||||
|
void early_boot_handle_button(void);
|
||||||
|
|
||||||
// See setup_serial_timer1() for valid baudrate settings!
|
// See setup_serial_timer1() for valid baudrate settings!
|
||||||
#define SERIAL_BAUD_RATE 115200
|
#define SERIAL_BAUD_RATE 115200
|
||||||
@@ -95,6 +99,7 @@ extern __xdata struct dhcp_state dhcp_state;
|
|||||||
__xdata volatile uint8_t sbuf_ptr;
|
__xdata volatile uint8_t sbuf_ptr;
|
||||||
__xdata uint8_t sbuf[SBUF_SIZE];
|
__xdata uint8_t sbuf[SBUF_SIZE];
|
||||||
|
|
||||||
|
// Registry data in sfr is in *big endian* order, so sfr_data[0] is the MSB and sfr_data[3] the LSB
|
||||||
__xdata uint8_t sfr_data[4];
|
__xdata uint8_t sfr_data[4];
|
||||||
|
|
||||||
extern __xdata uint8_t gpio_last_value[8];
|
extern __xdata uint8_t gpio_last_value[8];
|
||||||
@@ -124,17 +129,62 @@ __code uint16_t bit_mask[16] = {
|
|||||||
|
|
||||||
__xdata uint8_t linkbits_last[4];
|
__xdata uint8_t linkbits_last[4];
|
||||||
__xdata uint8_t linkbits_last_p89;
|
__xdata uint8_t linkbits_last_p89;
|
||||||
|
// Last known state of the SFP detection/Loss of Signal pins
|
||||||
|
// SFP1 b0 = 1 => module missing, b1 = 1 => LOS;
|
||||||
|
// SFP2 b4 = 1 => module missing, b5 = 1 => LOS;
|
||||||
__xdata uint8_t sfp_pins_last;
|
__xdata uint8_t sfp_pins_last;
|
||||||
__xdata char sfp_module_vendor[2][17];
|
__xdata char sfp_module_vendor[2][17];
|
||||||
__xdata char sfp_module_model[2][17];
|
__xdata char sfp_module_model[2][17];
|
||||||
__xdata char sfp_module_serial[2][17];
|
__xdata char sfp_module_serial[2][17];
|
||||||
__xdata uint8_t sfp_options[2];
|
__xdata uint8_t sfp_options[2];
|
||||||
|
__xdata uint8_t sfp_speed[2];
|
||||||
__xdata bool button_last;
|
__xdata bool button_last;
|
||||||
__xdata uint8_t button_sec_counter_last;
|
__xdata uint8_t button_sec_counter_last;
|
||||||
__sbit tx_buf_empty;
|
volatile __bit tx_buf_empty;
|
||||||
|
|
||||||
|
struct eth_in {
|
||||||
|
struct uip_eth_addr dst;
|
||||||
|
struct uip_eth_addr src;
|
||||||
|
struct rtl_tag rtl_tag;
|
||||||
|
struct vlan_tag vlan_tag;
|
||||||
|
u16_t ether_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Dot 1Q tag size is the size of tpid + tci
|
||||||
|
#define DOT_1Q_TAG_SIZE 4
|
||||||
|
|
||||||
|
struct q_frame {
|
||||||
|
uint8_t tx_seq;
|
||||||
|
uint8_t chksum_flags; // 0x7 enables Checksums for frame header, L2 and L3
|
||||||
|
uint8_t reserved_1 [2];
|
||||||
|
uint16_t len; // Length is Little Endian
|
||||||
|
uint8_t reserved_2 [2];
|
||||||
|
struct uip_eth_addr dst;
|
||||||
|
struct uip_eth_addr src;
|
||||||
|
uint16_t tpid;
|
||||||
|
uint16_t tci;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nonq_frame {
|
||||||
|
uint8_t padding[DOT_1Q_TAG_SIZE];
|
||||||
|
uint8_t tx_seq;
|
||||||
|
uint8_t chksum_flags; // 0x7 enables Checksums for frame header, L2 and L3
|
||||||
|
uint8_t reserved_1 [2];
|
||||||
|
uint16_t len; // Length is Little Endian
|
||||||
|
uint8_t reserved_2 [2];
|
||||||
|
struct uip_eth_addr dst;
|
||||||
|
struct uip_eth_addr src;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ETH_IN ((__xdata struct eth_in *)&uip_buf[0])
|
||||||
#define ETHERTYPE_OFFSET (12 + VLAN_TAG_SIZE + RTL_TAG_SIZE)
|
#define ETHERTYPE_OFFSET (12 + VLAN_TAG_SIZE + RTL_TAG_SIZE)
|
||||||
|
|
||||||
|
// The output frame structure with initial frame descriptor including padding
|
||||||
|
#define FRAME ((__xdata struct nonq_frame *)&uip_buf[0])
|
||||||
|
|
||||||
|
// The output frame structure with 802.1Q field and the padding moved before the buffer-start
|
||||||
|
#define FRAME_Q ((__xdata struct q_frame *)&uip_buf[0])
|
||||||
|
|
||||||
void isr_timer0(void) __interrupt(1)
|
void isr_timer0(void) __interrupt(1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -167,7 +217,7 @@ void isr_serial(void) __interrupt(4)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void write_char(char c)
|
void write_char_no_syslog(char c)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
} while (tx_buf_empty == 0);
|
} while (tx_buf_empty == 0);
|
||||||
@@ -181,6 +231,17 @@ void write_char(char c)
|
|||||||
SBUF = c;
|
SBUF = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void write_char(char c)
|
||||||
|
{
|
||||||
|
write_char_no_syslog(c);
|
||||||
|
|
||||||
|
if (syslog_state.enabled) {
|
||||||
|
logbuf[syslog_state.writeptr++] = c;
|
||||||
|
syslog_state.writeptr &= (LOGBUF_SIZE - 1);
|
||||||
|
if (c == '\n')
|
||||||
|
syslog_state.line_available = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void itoa(uint8_t v)
|
void itoa(uint8_t v)
|
||||||
{
|
{
|
||||||
@@ -204,6 +265,12 @@ void print_string(__code char *p)
|
|||||||
write_char(*p++);
|
write_char(*p++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_string_no_syslog(__code char *p)
|
||||||
|
{
|
||||||
|
while (*p)
|
||||||
|
write_char_no_syslog(*p++);
|
||||||
|
}
|
||||||
|
|
||||||
void print_string_x(__xdata char *p)
|
void print_string_x(__xdata char *p)
|
||||||
{
|
{
|
||||||
while (*p)
|
while (*p)
|
||||||
@@ -301,6 +368,11 @@ void print_byte(uint8_t a)
|
|||||||
write_char(low);
|
write_char(low);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_cmd_prompt(void)
|
||||||
|
{
|
||||||
|
print_string_no_syslog("\n> ");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* External IRQ 0 Service Routine: Called on link change?
|
* External IRQ 0 Service Routine: Called on link change?
|
||||||
* Note that all registers are being put on the STACK because of calling a subroutine
|
* Note that all registers are being put on the STACK because of calling a subroutine
|
||||||
@@ -459,7 +531,7 @@ void reg_bit_clear(uint16_t reg_addr, char bit)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This sets a bit in the 32bit wide switch register reg_addr
|
* This tests a bit in the 32bit wide switch register reg_addr
|
||||||
*/
|
*/
|
||||||
uint8_t reg_bit_test(uint16_t reg_addr, char bit)
|
uint8_t reg_bit_test(uint16_t reg_addr, char bit)
|
||||||
{
|
{
|
||||||
@@ -551,15 +623,38 @@ void nic_rx_packet(register uint16_t buffer, register uint16_t ring_ptr)
|
|||||||
*/
|
*/
|
||||||
void nic_tx_packet(uint16_t ring_ptr)
|
void nic_tx_packet(uint16_t ring_ptr)
|
||||||
{
|
{
|
||||||
// uint16_t buffer = (uint16_t) tx_buf;
|
uint16_t len;
|
||||||
uint16_t buffer = (uint16_t) uip_buf + VLAN_TAG_SIZE;
|
|
||||||
SFR_NIC_DATA_U16LE = buffer;
|
/* If we have a management VLAN, we have inserted a dot1Q-tag into the frame and
|
||||||
|
* the frame starts at the beginning of uip_buf with the RTL TX descriptor,
|
||||||
|
* otherwise the frame is a normal Ethernet frame which starts with
|
||||||
|
* an RTL TX descriptor being padded at the beginning, in the second case
|
||||||
|
* we need to skip the padding for the sending of the frame.
|
||||||
|
*/
|
||||||
|
if (management_vlan) {
|
||||||
|
SFR_NIC_DATA_U16LE = (uint16_t) uip_buf;
|
||||||
|
len = FRAME_Q->len;
|
||||||
|
/*
|
||||||
|
(__xdata struct rtl_dot1q_frame *)uip_buf
|
||||||
|
#define FRAME (((__xdata struct rtl_dot1q_frame *)&uip_buf[0]).nonq_frame)*/
|
||||||
|
} else {
|
||||||
|
SFR_NIC_DATA_U16LE = (uint16_t) uip_buf + VLAN_TAG_SIZE;
|
||||||
|
len = FRAME->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RXTXDBG
|
||||||
|
print_string("TX: \n");
|
||||||
|
for (uint8_t i = 0; i < 100; i++) {
|
||||||
|
print_byte(uip_buf[i]);
|
||||||
|
write_char(' ');
|
||||||
|
}
|
||||||
|
write_char('\n');
|
||||||
|
#endif
|
||||||
|
|
||||||
ring_ptr <<= 3;
|
ring_ptr <<= 3;
|
||||||
ring_ptr |= 0x8000;
|
ring_ptr |= 0x8000;
|
||||||
SFR_NIC_RING_U16LE = ring_ptr;
|
SFR_NIC_RING_U16LE = ring_ptr;
|
||||||
|
|
||||||
uint16_t len = (((uint16_t)uip_buf[VLAN_TAG_SIZE + 5]) << 8) | uip_buf[VLAN_TAG_SIZE + 4];
|
|
||||||
len += 0xf;
|
len += 0xf;
|
||||||
len >>= 3;
|
len >>= 3;
|
||||||
SFR_NIC_CTRL = len;
|
SFR_NIC_CTRL = len;
|
||||||
@@ -682,7 +777,7 @@ void cpy_4(__xdata uint8_t dest[], __xdata uint8_t source[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void read_reg_timer(uint32_t * tmr)
|
void read_reg_timer(__xdata uint32_t * tmr)
|
||||||
{
|
{
|
||||||
uint8_t * val = (uint8_t *)tmr;
|
uint8_t * val = (uint8_t *)tmr;
|
||||||
SFR_REG_ADDR_U16 = RTL837X_REG_SEC_COUNTER;
|
SFR_REG_ADDR_U16 = RTL837X_REG_SEC_COUNTER;
|
||||||
@@ -731,19 +826,78 @@ void delay(uint16_t t)
|
|||||||
PCON |= 1;
|
PCON |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void early_boot_handle_button(void)
|
||||||
|
{
|
||||||
|
if (machine.reset_pin == GPIO_NA)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gpio_input_setup(machine.reset_pin);
|
||||||
|
|
||||||
|
// Debounce after init
|
||||||
|
delay(100);
|
||||||
|
// If the button is not already held at boot, continue normally.
|
||||||
|
if (gpio_pin_test(machine.reset_pin))
|
||||||
|
return;
|
||||||
|
|
||||||
|
set_sys_led_state(SYS_LED_FAST);
|
||||||
|
print_string("\n[Reset button held at boot]\n");
|
||||||
|
|
||||||
|
if (gpio_pin_test(machine.reset_pin))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const __xdata uint32_t min_hold_ticks = 10UL * SYS_TICK_HZ;
|
||||||
|
const __xdata uint32_t max_hold_ticks = 30UL * SYS_TICK_HZ;
|
||||||
|
const __xdata uint32_t blink_ticks = SYS_TICK_HZ / 10; // 100 ms
|
||||||
|
const __xdata uint32_t pause_ticks = SYS_TICK_HZ / 2; // 500 ms
|
||||||
|
__xdata uint32_t start_ticks = ticks;
|
||||||
|
__xdata uint32_t last_blink_step = start_ticks;
|
||||||
|
__xdata uint8_t blink_step = 0;
|
||||||
|
|
||||||
|
set_sys_led_state(SYS_LED_ON);
|
||||||
|
|
||||||
|
while (!gpio_pin_test(machine.reset_pin)) {
|
||||||
|
__xdata uint32_t held_ticks = ticks - start_ticks;
|
||||||
|
|
||||||
|
if (held_ticks > max_hold_ticks) {
|
||||||
|
print_string("[Button held >30s at boot; continuing normal boot]\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Double blink pattern while button is held:
|
||||||
|
// ON (100ms), OFF (100ms), ON (100ms), OFF (500ms)
|
||||||
|
__xdata uint32_t step_ticks = (blink_step == 3) ? pause_ticks : blink_ticks;
|
||||||
|
if ((ticks - last_blink_step) >= step_ticks) {
|
||||||
|
blink_step = (blink_step + 1) & 0x3;
|
||||||
|
set_sys_led_state((blink_step == 0 || blink_step == 2) ? SYS_LED_ON : SYS_LED_OFF);
|
||||||
|
last_blink_step = ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
PCON |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_sys_led_state(SYS_LED_ON);
|
||||||
|
|
||||||
|
if ((ticks - start_ticks) >= min_hold_ticks) {
|
||||||
|
print_string("[Button held 10s-30s at boot; restoring default config]\n");
|
||||||
|
set_sys_led_state(SYS_LED_FAST);
|
||||||
|
flash_default_config();
|
||||||
|
delay(3UL * SYS_TICK_HZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure the SerDes of the SoC for a particular mode
|
* Configure the SerDes of the SoC for a particular mode
|
||||||
* to connect to an SFP module or a PHY
|
* to connect to an SFP module or a PHY
|
||||||
* Valid modes are SDS_10GR, SDS_QXGMII, SDS_HISGMII, SDS_HSG, SDS_SGMII and SDS_1000BX_FIBER
|
* Valid modes are SDS_10GR, SDS_QXGMII, SDS_HISGMII, SDS_HSG, SDS_SGMII and SDS_1000BX_FIBER
|
||||||
* The SerDes ID may be 0 or 1 for RTL8272 and 0-2 for RTL8373
|
* The SerDes ID may be 0 or 1 for RTL8272 and 0-2 for RTL8373
|
||||||
|
* SDS_QXGMII is used for 10G Fiber, RTL8224 and RTL8261BE
|
||||||
*/
|
*/
|
||||||
void sds_config(uint8_t sds, uint8_t mode)
|
void sds_config(uint8_t sds, uint8_t mode)
|
||||||
{
|
{
|
||||||
print_string("sds_config sds: "); print_byte(sds); print_string(", mode: "); print_byte(mode); write_char('\n');
|
print_string("sds_config sds: "); print_byte(sds); print_string(", mode: "); print_byte(mode); write_char('\n');
|
||||||
sds_config_mac(sds, mode);
|
sds_config_mac(sds, mode);
|
||||||
|
|
||||||
if (mode == SDS_10GR || mode == SDS_QXGMII) // 10G Fiber, 10G connection to RTL8224
|
if (mode == SDS_10GR || mode == SDS_QXGMII)
|
||||||
sds_write_v(sds, 0x21, 0x10, 0x4480); // Q002110:6480
|
sds_write_v(sds, 0x21, 0x10, 0x4480); // Q002110:6480
|
||||||
else
|
else
|
||||||
sds_write_v(sds, 0x21, 0x10, 0x6480); // Q002110:6480
|
sds_write_v(sds, 0x21, 0x10, 0x6480); // Q002110:6480
|
||||||
@@ -773,13 +927,17 @@ void sds_config(uint8_t sds, uint8_t mode)
|
|||||||
v = 0x0200;
|
v = 0x0200;
|
||||||
page = 0x2e;
|
page = 0x2e;
|
||||||
break;
|
break;
|
||||||
|
case SDS_100FX:
|
||||||
|
v = 0x0200;
|
||||||
|
page = 0x26;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
print_string("Error in SDS Mode\n");
|
print_string("Error in SDS Mode\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sds_write_v(sds, 0x36, 0x10, v); // Q003610:0200
|
sds_write_v(sds, 0x36, 0x10, v); // Q003610:0200
|
||||||
|
|
||||||
if (page == 0x2e) { // 10G Fiber
|
if (page == 0x2e) { // 10G Fiber / SDS_QXGMII
|
||||||
sds_write_v(sds, page, 0x04, 0x0080); // Q012e04:0080
|
sds_write_v(sds, page, 0x04, 0x0080); // Q012e04:0080
|
||||||
sds_write_v(sds, page, 0x06, 0x0408); // Q012e06:0408
|
sds_write_v(sds, page, 0x06, 0x0408); // Q012e06:0408
|
||||||
sds_write_v(sds, page, 0x07, 0x020d); // Q012e07:020d
|
sds_write_v(sds, page, 0x07, 0x020d); // Q012e07:020d
|
||||||
@@ -808,10 +966,34 @@ void sds_config(uint8_t sds, uint8_t mode)
|
|||||||
sds_write_v(sds, 0x07, 0x0c, 0x9401); // Q00070c:9401
|
sds_write_v(sds, 0x07, 0x0c, 0x9401); // Q00070c:9401
|
||||||
sds_write_v(sds, 0x1f, 0x0b, 0x0003); // Q001f0b:0003
|
sds_write_v(sds, 0x1f, 0x0b, 0x0003); // Q001f0b:0003
|
||||||
sds_write_v(sds, 0x06, 0x03, 0xc45c); // Q000603:c45c
|
sds_write_v(sds, 0x06, 0x03, 0xc45c); // Q000603:c45c
|
||||||
|
|
||||||
|
// RTL8261BE
|
||||||
|
if (machine.n_10g && mode == SDS_QXGMII) {
|
||||||
|
sds_write_v(sds, 0x06, 0x1f, 0x2100); // Q00061f:2100
|
||||||
|
sds_write_v(sds, 0x07, 0x11, 0x054f); // Q000711:054f
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0030); // Q002000:0030
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0010); // Q002000:0010
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0050); // Q002000:0050
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x00d0); // Q002000:00d0
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0cd0); // Q002000:0cd0
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x04d0); // Q002000:04d0
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x04d0); // Q002000:04d0
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0cd0); // Q002000:0cd0
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x00d0); // Q002000:00d0
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x00d0); // Q002000:00d0
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0050); // Q002000:0050
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0010); // Q002000:0010
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0010); // Q002000:0010
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0030); // Q002000:0030
|
||||||
|
sds_write_v(sds, 0x20, 0x00, 0x0000); // Q002000:0000
|
||||||
|
sds_write_v(sds, 0x1f, 0x00, 0x000b); // Q001f00:000b
|
||||||
|
sds_write_v(sds, 0x1f, 0x00, 0x0000); // Q001f00:0000
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (mode != SDS_QXGMII)
|
if (mode != SDS_QXGMII)
|
||||||
sds_write_v(sds, 0x06, 0x1f, 0x2100); // Q00061f:2100
|
sds_write_v(sds, 0x06, 0x1f, 0x2100); // Q00061f:2100
|
||||||
|
|
||||||
if (sds == 0 && mode == SDS_1000BX_FIBER) {
|
if (mode == SDS_1000BX_FIBER) {
|
||||||
sds_write_v(sds, 0x02, 0x04, 0x0020); // Q000204:0020
|
sds_write_v(sds, 0x02, 0x04, 0x0020); // Q000204:0020
|
||||||
sds_write_v(sds, 0x00, 0x02, 0x73d0); // Q000002:73d0
|
sds_write_v(sds, 0x00, 0x02, 0x73d0); // Q000002:73d0
|
||||||
sds_write_v(sds, 0x00, 0x04, 0x074d); // Q000004:074d
|
sds_write_v(sds, 0x00, 0x04, 0x074d); // Q000004:074d
|
||||||
@@ -828,9 +1010,9 @@ uint8_t sfp_read_reg(uint8_t slot, uint8_t reg)
|
|||||||
{
|
{
|
||||||
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) | 1, 0x51 >> 5, (0x51 << 3) & 0xff);
|
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 0, 0x51 >> 5, (0x51 << 3) & 0xff);
|
||||||
} else {
|
} else {
|
||||||
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 1, 0x50 >> 5, (0x50 << 3) & 0xff);
|
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 0, 0x50 >> 5, (0x50 << 3) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_read_m(RTL837X_REG_I2C_CTRL);
|
reg_read_m(RTL837X_REG_I2C_CTRL);
|
||||||
@@ -859,26 +1041,27 @@ uint8_t sfp_read_reg(uint8_t slot, uint8_t reg)
|
|||||||
void tcpip_output(void)
|
void tcpip_output(void)
|
||||||
{
|
{
|
||||||
// Add TX-TAG
|
// Add TX-TAG
|
||||||
uip_buf[VLAN_TAG_SIZE] = tx_seq++;
|
FRAME->tx_seq = tx_seq++;
|
||||||
uip_buf[VLAN_TAG_SIZE + 1] = 0x07; // Enable all checksums
|
FRAME->chksum_flags = 0x07; // Enable all checksums
|
||||||
uip_buf[VLAN_TAG_SIZE + 5] = uip_len >> 8;
|
FRAME->reserved_1[0] = 0x00; FRAME->reserved_1[1] = 0x00;
|
||||||
uip_buf[VLAN_TAG_SIZE + 4] = uip_len;
|
FRAME->len = uip_len;
|
||||||
uip_buf[VLAN_TAG_SIZE + 2] = uip_buf[VLAN_TAG_SIZE + 3] = 0;
|
FRAME->reserved_2[0] = 0x00; FRAME->reserved_2[1] = 0x00;
|
||||||
uip_buf[VLAN_TAG_SIZE + 6] = uip_buf[VLAN_TAG_SIZE + 7] = 0;
|
|
||||||
|
// For the management VLAN we insert an 802.1Q VLAN tag
|
||||||
|
if (management_vlan) {
|
||||||
|
// Shift the ethernet header before the HW type including the rtl_frame_desc to the beginning of uip_buf
|
||||||
|
// to allow space to insert the dot 1Q tag
|
||||||
|
for (uint8_t i = 0; i < sizeof(struct q_frame) - DOT_1Q_TAG_SIZE; i++)
|
||||||
|
uip_buf[i] = uip_buf[i + DOT_1Q_TAG_SIZE];
|
||||||
|
FRAME_Q->len += DOT_1Q_TAG_SIZE;
|
||||||
|
FRAME_Q->tpid = HTONS(0x8100); // Change ether-type to Dot1Q
|
||||||
|
FRAME_Q->tci = HTONS(management_vlan);
|
||||||
|
}
|
||||||
|
|
||||||
reg_read_m(RTL837X_REG_CPU_TX_CURR_PKT);
|
reg_read_m(RTL837X_REG_CPU_TX_CURR_PKT);
|
||||||
uint16_t ring_ptr = ((uint16_t)sfr_data[2]) << 8;
|
uint16_t ring_ptr = ((uint16_t)sfr_data[2]) << 8;
|
||||||
ring_ptr |= sfr_data[3];
|
ring_ptr |= sfr_data[3];
|
||||||
|
|
||||||
#ifdef RXTXDBG
|
|
||||||
print_string("TX: \n");
|
|
||||||
for (uint8_t i = 0; i < 120; i++) {
|
|
||||||
print_byte(uip_buf[i]);
|
|
||||||
write_char(' ');
|
|
||||||
}
|
|
||||||
write_char('\n');
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Move data over from xmem buffer to ASIC side using DMA
|
// Move data over from xmem buffer to ASIC side using DMA
|
||||||
nic_tx_packet(ring_ptr);
|
nic_tx_packet(ring_ptr);
|
||||||
|
|
||||||
@@ -922,14 +1105,13 @@ void handle_rx(void)
|
|||||||
REG_SET(RTL837X_REG_NIC_RXCMD, 1);
|
REG_SET(RTL837X_REG_NIC_RXCMD, 1);
|
||||||
uip_len = (((uint16_t)rx_headers[5]) << 8) | rx_headers[4];
|
uip_len = (((uint16_t)rx_headers[5]) << 8) | rx_headers[4];
|
||||||
|
|
||||||
// Retrieve VLAN from VLAN-tag
|
rx_packet_vlan = NTOHS(ETH_IN->vlan_tag.vlan) & 0x0fff;
|
||||||
rx_packet_vlan = uip_buf[2 * sizeof (struct uip_eth_addr) + RTL_TAG_SIZE + 2] & 0xf;
|
|
||||||
rx_packet_vlan <<= 8;
|
|
||||||
rx_packet_vlan |= uip_buf[2 * sizeof (struct uip_eth_addr) + RTL_TAG_SIZE + 3];
|
|
||||||
#ifdef RXTXDBG
|
#ifdef RXTXDBG
|
||||||
print_string(" RX-VLAN: "); print_short(rx_packet_vlan); write_char('\n');
|
print_string(" RX-VLAN: "); print_short(rx_packet_vlan); write_char('\n');
|
||||||
print_string(" RX dst: "); print_byte(uip_buf[0]); print_byte(uip_buf[1]); print_byte(uip_buf[2]);
|
print_string(" RX dst: "); print_byte(uip_buf[0]); print_byte(uip_buf[1]); print_byte(uip_buf[2]);
|
||||||
print_byte(uip_buf[3]); print_byte(uip_buf[4]); print_byte(uip_buf[5]); write_char('\n');
|
print_byte(uip_buf[3]); print_byte(uip_buf[4]); print_byte(uip_buf[5]); write_char('\n');
|
||||||
|
print_string(" MGMT-VLAN: "); print_short(management_vlan); write_char('\n');
|
||||||
#endif
|
#endif
|
||||||
if (stpEnabled && uip_buf[0] == 0x01 && uip_buf[1] == 0x80 && uip_buf[2] == 0xc2 // STP packet?
|
if (stpEnabled && uip_buf[0] == 0x01 && uip_buf[1] == 0x80 && uip_buf[2] == 0xc2 // STP packet?
|
||||||
&& uip_buf[3] == 0x00 && uip_buf[4] == 0x00 && uip_buf[5] == 0x00) {
|
&& uip_buf[3] == 0x00 && uip_buf[4] == 0x00 && uip_buf[5] == 0x00) {
|
||||||
@@ -944,12 +1126,12 @@ void handle_rx(void)
|
|||||||
if (uip_len) {
|
if (uip_len) {
|
||||||
tcpip_output();
|
tcpip_output();
|
||||||
}
|
}
|
||||||
} else if (uip_buf[ETHERTYPE_OFFSET] == 0x08 && uip_buf[ETHERTYPE_OFFSET + 1] == 0x06) { // ARP?
|
} else if (ETH_IN->ether_type == HTONS(0x0806)) { // ARP
|
||||||
uip_arp_arpin();
|
uip_arp_arpin();
|
||||||
if (uip_len) {
|
if (uip_len) {
|
||||||
tcpip_output();
|
tcpip_output();
|
||||||
}
|
}
|
||||||
} else if (uip_buf[ETHERTYPE_OFFSET] == 0x08 && uip_buf[ETHERTYPE_OFFSET + 1] == 0x00) { // TCP?
|
} else if (ETH_IN->ether_type == HTONS(0x0800)) { // IPv4
|
||||||
if (!management_vlan || management_vlan == rx_packet_vlan) {
|
if (!management_vlan || management_vlan == rx_packet_vlan) {
|
||||||
uip_arp_ipin(); // Learn MAC addresses in TCP packets
|
uip_arp_ipin(); // Learn MAC addresses in TCP packets
|
||||||
uip_input();
|
uip_input();
|
||||||
@@ -992,9 +1174,11 @@ void handle_tx(void)
|
|||||||
|
|
||||||
static inline uint8_t sfp_rate_to_sds_config(register uint8_t rate)
|
static inline uint8_t sfp_rate_to_sds_config(register uint8_t rate)
|
||||||
{
|
{
|
||||||
if (rate == 0xd)
|
if (rate == 0x1 || rate == 0x2)
|
||||||
|
return SDS_100FX;
|
||||||
|
if (rate == 0xc || rate == 0xd)
|
||||||
return SDS_1000BX_FIBER;
|
return SDS_1000BX_FIBER;
|
||||||
if (rate == 0x1f) // Ethernet 2.5 GBit
|
if (rate >= 0x19 && rate <= 0x20) // Ethernet 2.5 GBit
|
||||||
return SDS_HSG;
|
return SDS_HSG;
|
||||||
if (rate > 0x65 && rate < 0x70)
|
if (rate > 0x65 && rate < 0x70)
|
||||||
return SDS_10GR;
|
return SDS_10GR;
|
||||||
@@ -1057,6 +1241,14 @@ void handle_sfp(void)
|
|||||||
// Read Reg 12: Signalling rate (including overhead) in 100Mbit: 0xd: 1Gbit, 0x67:10Gbit
|
// Read Reg 12: Signalling rate (including overhead) in 100Mbit: 0xd: 1Gbit, 0x67:10Gbit
|
||||||
delay(100); // Delay, because some modules need time to wake up
|
delay(100); // Delay, because some modules need time to wake up
|
||||||
uint8_t rate = sfp_read_reg(sfp, 12);
|
uint8_t rate = sfp_read_reg(sfp, 12);
|
||||||
|
if (sfp_speed[sfp] == SFP_SPEED_100M)
|
||||||
|
rate = 0x1;
|
||||||
|
else if (sfp_speed[sfp] == SFP_SPEED_1G)
|
||||||
|
rate = 0xc;
|
||||||
|
else if (sfp_speed[sfp] == SFP_SPEED_2G5)
|
||||||
|
rate = 0x19;
|
||||||
|
else if (sfp_speed[sfp] == SFP_SPEED_10G)
|
||||||
|
rate = 0x69;
|
||||||
print_string(" Rate: "); print_byte(rate); // Normally 1, but 0 for DAC, can be ignored?
|
print_string(" Rate: "); print_byte(rate); // Normally 1, but 0 for DAC, can be ignored?
|
||||||
print_string(" Encoding: "); print_byte(sfp_read_reg(sfp, 11));
|
print_string(" Encoding: "); print_byte(sfp_read_reg(sfp, 11));
|
||||||
print_string(" Module: "); sfp_print_info(sfp);
|
print_string(" Module: "); sfp_print_info(sfp);
|
||||||
@@ -1212,13 +1404,17 @@ void idle(void)
|
|||||||
uint8_t p5 = sfr_data[2] >> 4;
|
uint8_t p5 = sfr_data[2] >> 4;
|
||||||
uint8_t p5_last = linkbits_last[2] >> 4;
|
uint8_t p5_last = linkbits_last[2] >> 4;
|
||||||
cpy_4(linkbits_last, sfr_data);
|
cpy_4(linkbits_last, sfr_data);
|
||||||
// Handle link change of the RTL8221 PHY, adjust SDS mode
|
// Handle link change of the RTL8221 PHY, adjust SDS mode, RTL8261BE always uses SDS_QXGMII
|
||||||
if (p5_last != p5) {
|
if (!machine.n_10g && p5_last != p5) {
|
||||||
if (p5 == 0x5) // 2.5GBit Mode
|
if (p5 == 0x5) // 2.5GBit Mode
|
||||||
sds_config(0, SDS_HISGMII);
|
sds_config(0, SDS_HISGMII);
|
||||||
else if (p5 == 0x2) // 1GBit
|
else if (p5 == 0x2) // 1GBit
|
||||||
sds_config(0, SDS_SGMII);
|
sds_config(0, SDS_SGMII);
|
||||||
}
|
}
|
||||||
|
if (machine.n_10g)
|
||||||
|
sds_config(0, SDS_QXGMII);
|
||||||
|
if (machine.n_10g == 2)
|
||||||
|
sds_config(1, SDS_QXGMII);
|
||||||
} else {
|
} else {
|
||||||
cpy_4(linkbits_last, sfr_data);
|
cpy_4(linkbits_last, sfr_data);
|
||||||
}
|
}
|
||||||
@@ -1243,9 +1439,10 @@ void idle(void)
|
|||||||
// Check whether a command is waiting in the cmd_buffer and execute
|
// Check whether a command is waiting in the cmd_buffer and execute
|
||||||
if (cmd_available) {
|
if (cmd_available) {
|
||||||
cmd_available = 0;
|
cmd_available = 0;
|
||||||
if (!cmd_tokenize())
|
cmd_tokenize();
|
||||||
|
if (err_status == ERR_OK)
|
||||||
cmd_parser();
|
cmd_parser();
|
||||||
print_string("\n> ");
|
print_cmd_prompt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1471,78 +1668,6 @@ void nic_setup(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Configure the PHY-Side of the SDS-SDS link between SoC and PHY
|
|
||||||
*/
|
|
||||||
void sds_init(void)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
p001e.000d:9535 R02f8-00009535 R02f4-0000953a P000001.1e00000d:953a
|
|
||||||
p001e.000d:953a p001e.000d:953a R02f8-0000953a R02f4-00009530 P000001.1e00000d:9530
|
|
||||||
|
|
||||||
RTL8373:
|
|
||||||
p001e.000d:0010 R02f8-00000010 R02f4-0000001a P000001.1e00000d:b7fe
|
|
||||||
p001e.000d:0010 p001e.000d:0010 R02f8-00000010 R02f4-00000010 P000001.1e00000d:b7fe
|
|
||||||
*/
|
|
||||||
phy_read(0, PHY_MMD30, 0xd);
|
|
||||||
uint16_t pval = SFR_DATA_U16;
|
|
||||||
|
|
||||||
// PHY Initialization:
|
|
||||||
REG_WRITE(0x2f8, 0, 0, pval >> 8, pval);
|
|
||||||
delay(20);
|
|
||||||
|
|
||||||
pval &= 0xfff0;
|
|
||||||
pval |= 0x0a;
|
|
||||||
REG_WRITE(0x2f4, 0, 0, pval >> 8, pval);
|
|
||||||
delay(10);
|
|
||||||
|
|
||||||
phy_write_mask(0x1, PHY_MMD30, 0xd, pval);
|
|
||||||
|
|
||||||
phy_read(0, PHY_MMD30, 0xd);
|
|
||||||
pval = SFR_DATA_U16;
|
|
||||||
|
|
||||||
REG_WRITE(0x2f8, 0, 0, pval >> 8, pval);
|
|
||||||
|
|
||||||
pval &= 0xfff0;
|
|
||||||
REG_WRITE(0x2f4, 0, 0, pval >> 8, pval);
|
|
||||||
|
|
||||||
phy_write_mask(0x1, PHY_MMD30, 0xd, pval);
|
|
||||||
|
|
||||||
if (machine_detected.isN) {
|
|
||||||
uint16_t pval;
|
|
||||||
|
|
||||||
print_string(" N-settings");
|
|
||||||
// Serdes 0 RX PN swap for 64B/66B
|
|
||||||
sds_read(1, 6, 2);
|
|
||||||
pval = SFR_DATA_U16;
|
|
||||||
sds_write_v(1, 6, 2, pval | 0x2000);
|
|
||||||
|
|
||||||
// Serdes 1 RX PN swap for 8B/10B
|
|
||||||
sds_read(1, 0, 0);
|
|
||||||
pval = SFR_DATA_U16;
|
|
||||||
sds_write_v(1, 0, 0, pval | 0x200);
|
|
||||||
|
|
||||||
// Serdes 0 RX PN swap for 64B/66B
|
|
||||||
sds_read(0, 6, 2);
|
|
||||||
pval = SFR_DATA_U16;
|
|
||||||
sds_write_v(0, 6, 2, pval | 0x2000);
|
|
||||||
|
|
||||||
if (machine_detected.isRTL8373) {
|
|
||||||
// RTL8224: Serdes 0 RX PN swap for 64B/66B
|
|
||||||
// We assume that RTL8373N always paired with RTL8224N.
|
|
||||||
// This sds register value is 0x0000 at reset.
|
|
||||||
// So only write to it.
|
|
||||||
RTL8224_SDS_WRITE(0, 6, 2, 0x2000);
|
|
||||||
} else {
|
|
||||||
// Serdes 0 RX PN swap for 8B/10B
|
|
||||||
sds_read(0, 0, 0);
|
|
||||||
pval = SFR_DATA_U16;
|
|
||||||
sds_write_v(0, 0, 0, pval | 0x200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void set_sys_led_state(uint8_t state)
|
void set_sys_led_state(uint8_t state)
|
||||||
{
|
{
|
||||||
reg_read_m(RTL837X_REG_LED_MODE);
|
reg_read_m(RTL837X_REG_LED_MODE);
|
||||||
@@ -1564,167 +1689,6 @@ void rtl8373_revision(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void rtl8373_init(void)
|
|
||||||
{
|
|
||||||
print_string("\nrtl8373_init called\n");
|
|
||||||
|
|
||||||
// r65d8:3ffbedff R65d8-3ffbedff
|
|
||||||
reg_bit_set(0x65d8, 0x1d);
|
|
||||||
|
|
||||||
sds_init();
|
|
||||||
// Disable all SERDES for configuration
|
|
||||||
REG_SET(RTL837X_REG_SDS_MODES, 0x000037ff);
|
|
||||||
|
|
||||||
// q000601:c800 Q000601:c804 q000601:c804 Q000601:c800
|
|
||||||
sds_read(0, 0x06, 0x01);
|
|
||||||
uint16_t pval = SFR_DATA_U16;
|
|
||||||
sds_write_v(0, 0x06, 0x01, pval | 0x04);
|
|
||||||
delay(50);
|
|
||||||
sds_read(0, 0x06, 0x01);
|
|
||||||
pval = SFR_DATA_U16;
|
|
||||||
sds_write_v(0, 0x06, 0x01, pval & 0xfffb);
|
|
||||||
|
|
||||||
phy_config_8224();
|
|
||||||
sds_config_mac(1, SDS_OFF); // Off for now until SFP+ port used
|
|
||||||
sds_config_mac(2, SDS_SGMII); // For RTL8224
|
|
||||||
sds_config(0, SDS_QXGMII);
|
|
||||||
|
|
||||||
// SDS 1 setup
|
|
||||||
// q012100:4902 Q012100:4906 q013605:0000 Q013605:4000 Q011f02:001f q011f15:0086
|
|
||||||
sds_write_v(1, 0x21, 0x00, 0x4906);
|
|
||||||
sds_write_v(1, 0x36, 0x05, 0x4000);
|
|
||||||
sds_write_v(1, 0x1f, 0x02, 0x001f);
|
|
||||||
sds_read(1, 0x1f, 0x15);
|
|
||||||
pval = SFR_DATA_U16;
|
|
||||||
|
|
||||||
// r0a90:000000f3 R0a90-000000fc
|
|
||||||
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
|
||||||
sfr_mask_data(0, 0x0f,0x0c);
|
|
||||||
reg_write_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
|
||||||
|
|
||||||
if (machine_detected.isN) {
|
|
||||||
print_string(" TX_POLARITY_SWAP\n");
|
|
||||||
// FOR N-Version: #TX_POLARITY_SWAP
|
|
||||||
reg_read_m(RTL837X_CFG_PHY_TX_POLARITY_SWAP);
|
|
||||||
sfr_data[2] = 0x59;
|
|
||||||
sfr_data[3] = 0x6a;
|
|
||||||
reg_write_m(RTL837X_CFG_PHY_TX_POLARITY_SWAP);
|
|
||||||
}
|
|
||||||
|
|
||||||
rtl8224_phy_enable();
|
|
||||||
|
|
||||||
// Disable PHYs for configuration
|
|
||||||
phy_write_mask(0xff,PHY_MMD31,0xa610,0x2858);
|
|
||||||
|
|
||||||
// Set bits 0x13 and 0x14 of 0x5fd4
|
|
||||||
// r5fd4:0002914a R5fd4-001a914a
|
|
||||||
reg_bit_set(0x5fd4, 0x13);
|
|
||||||
reg_bit_set(0x5fd4, 0x14);
|
|
||||||
|
|
||||||
// Configure ports
|
|
||||||
uint16_t reg = 0x1238; // Port base register for the bits we set
|
|
||||||
for (char i = 0; i < 9; i++) {
|
|
||||||
// Bit 7 (0x40) enables replacement of the RTL-VLAN tag with an 802.1Q VLAN tag
|
|
||||||
REG_SET(reg, 0xe77);
|
|
||||||
reg += 0x100;
|
|
||||||
}
|
|
||||||
|
|
||||||
// r0b7c:000000d8 R0b7c-000000f8 r6040:00000030 R6040-00000031
|
|
||||||
reg_bit_set(0xb7c, 5);
|
|
||||||
|
|
||||||
// R7124-00001050 R7128-00001050 R712c-00001050 R7130-00001050 R7134-00001050 R7138-00001050
|
|
||||||
// R713c-00001050 R7140-00001050 R7144-00001050 R7148-00001050
|
|
||||||
REG_SET(0x7124, 0x1050); REG_SET(0x7128, 0x1050); REG_SET(0x712c, 0x1050);
|
|
||||||
REG_SET(0x7130, 0x1050); REG_SET(0x7134, 0x1050); REG_SET(0x7138, 0x1050);
|
|
||||||
REG_SET(0x713c, 0x1050); REG_SET(0x7140, 0x1050); REG_SET(0x7144, 0x1050);
|
|
||||||
REG_SET(0x7148, 0x1050);
|
|
||||||
|
|
||||||
reg_bit_set(RTL837X_REG_HW_CONF, 0);
|
|
||||||
|
|
||||||
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
|
|
||||||
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
|
|
||||||
|
|
||||||
// TODO: patch the PHYs
|
|
||||||
|
|
||||||
// Re-enable PHY after configuration
|
|
||||||
phy_write_mask(0xff,PHY_MMD31,0xa610,0x2058);
|
|
||||||
|
|
||||||
// Enables MAC access
|
|
||||||
// Set bits 0xc-0x14 of 0x632c to 0x1f8, see rtl8372_init
|
|
||||||
// r632c:00000540 R632c-001f8540 // RTL8373: 001ff540
|
|
||||||
reg_read_m(0x632c);
|
|
||||||
sfr_mask_data(1, 0x70, 0xf0); // The ports of the RTL8824
|
|
||||||
sfr_mask_data(2, 0x10, 0x1f);
|
|
||||||
reg_write_m(0x632c);
|
|
||||||
|
|
||||||
print_string("\nrtl8373_init done\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void rtl8372_init(void)
|
|
||||||
{
|
|
||||||
print_string("\nrtl8372_init called\n");
|
|
||||||
|
|
||||||
sds_init();
|
|
||||||
phy_config(8); // PHY configuration: External 8221B?
|
|
||||||
phy_config(3); // PHY configuration: all internal PHYs?
|
|
||||||
// Set the MAC SerDes Modes Bits 0-4: SDS 0 = 0x2 (0x2), Bits 5-9: SDS 1: 1f (off)
|
|
||||||
// r7b20:00000bff R7b20-00000bff r7b20:00000bff R7b20-00000bff r7b20:00000bff R7b20-000003ff r7b20:000003ff R7b20-000003e2 r7b20:000003e2 R7b20-000003e2
|
|
||||||
reg_read_m(RTL837X_REG_SDS_MODES);
|
|
||||||
sfr_mask_data(1, 0, 0x03);
|
|
||||||
sfr_mask_data(0, 0, 0xe2);
|
|
||||||
reg_write_m(RTL837X_REG_SDS_MODES);
|
|
||||||
|
|
||||||
// r0a90:000000f3 R0a90-000000fc
|
|
||||||
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
|
||||||
sfr_mask_data(0, 0x0f, 0x0c);
|
|
||||||
reg_write_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
|
||||||
|
|
||||||
// Disable PHYs for configuration
|
|
||||||
phy_write_mask(0xf0,PHY_MMD31,0xa610,0x2858);
|
|
||||||
|
|
||||||
// Set bits 0x13 and 0x14 of 0x5fd4
|
|
||||||
// r5fd4:0002914a R5fd4-001a914a
|
|
||||||
reg_bit_set(0x5fd4, 0x13);
|
|
||||||
reg_bit_set(0x5fd4, 0x14);
|
|
||||||
|
|
||||||
// Configure ports 3-8:
|
|
||||||
//
|
|
||||||
// r1538:00000e33 R1538-00000e37 r1538:00000e37 R1538-00000e37 r1538:00000e37 R1538-00000f37
|
|
||||||
// [...]
|
|
||||||
///
|
|
||||||
uint16_t reg = 0x1238 + 0x300; // Port base register for the bits we set
|
|
||||||
for (char i = machine.min_port; i <= machine.max_port; i++) {
|
|
||||||
// Bit 7 (0x40) enables replacement of the RTL-VLAN tag with an 802.1Q VLAN tag
|
|
||||||
REG_SET(reg, 0xe77);
|
|
||||||
reg += 0x100;
|
|
||||||
}
|
|
||||||
|
|
||||||
// r0b7c:000000d8 R0b7c-000000f8 r6040:00000030 R6040-00000031
|
|
||||||
reg_bit_set(0xb7c, 5);
|
|
||||||
|
|
||||||
reg_bit_set(RTL837X_REG_HW_CONF, 0);
|
|
||||||
|
|
||||||
|
|
||||||
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
|
|
||||||
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
|
|
||||||
|
|
||||||
// TODO: patch the PHYs
|
|
||||||
|
|
||||||
// Re-enable PHY after configuration
|
|
||||||
phy_write_mask(0xf0,PHY_MMD31,0xa610,0x2058);
|
|
||||||
|
|
||||||
// Enables MAC access
|
|
||||||
// Set bits 0xc-0x14 of 0x632c to 0x1f8, see rtl8372_init
|
|
||||||
// r632c:00000540 R632c-001f8540 // RTL8373: 001ff540
|
|
||||||
reg_read_m(0x632c);
|
|
||||||
sfr_mask_data(1, 0x70, 0x80);
|
|
||||||
sfr_mask_data(2, 0x10, 0x1f);
|
|
||||||
reg_write_m(0x632c);
|
|
||||||
print_string("\nrtl8372_init done\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The SoC manages Link-State for steering the LEDs and can set PHY-settings
|
* The SoC manages Link-State for steering the LEDs and can set PHY-settings
|
||||||
* automatically through Realtek's SMI (Simple Managagement) Interface, a
|
* automatically through Realtek's SMI (Simple Managagement) Interface, a
|
||||||
@@ -1739,7 +1703,11 @@ void init_smi(void)
|
|||||||
/* Set the SMI(i.e.I2C) type for PHY polling, 0b01 is 2.5/10G PHY. Disable (0b00) for the SFP-ports
|
/* Set the SMI(i.e.I2C) type for PHY polling, 0b01 is 2.5/10G PHY. Disable (0b00) for the SFP-ports
|
||||||
* which are at port 8 and additionally at port 3 for a dual SFP device
|
* which are at port 8 and additionally at port 3 for a dual SFP device
|
||||||
*/
|
*/
|
||||||
REG_SET(RTL837X_REG_SMI_MAC_TYPE, machine.n_sfp == 2 ? 0x00005515 : 0x00005555);
|
if (machine.n_10g == 2) {
|
||||||
|
REG_SET(RTL837X_REG_SMI_MAC_TYPE, 0x00015555);
|
||||||
|
} else {
|
||||||
|
REG_SET(RTL837X_REG_SMI_MAC_TYPE, machine.n_sfp == 2 ? 0x00005515 : 0x00005555);
|
||||||
|
}
|
||||||
|
|
||||||
// Configure polling of all PHYs by the MAC to detect link-state changes
|
// Configure polling of all PHYs by the MAC to detect link-state changes
|
||||||
if (machine_detected.isRTL8373) {
|
if (machine_detected.isRTL8373) {
|
||||||
@@ -1766,6 +1734,11 @@ void init_smi(void)
|
|||||||
sfr_mask_data(1, 0x80, 0);
|
sfr_mask_data(1, 0x80, 0);
|
||||||
reg_write_m(RTL837X_REG_SMI_PORT0_5_ADDR);
|
reg_write_m(RTL837X_REG_SMI_PORT0_5_ADDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (machine.n_10g == 2) {
|
||||||
|
// Set address of second external PHY on port 8
|
||||||
|
REG_SET(RTL837X_REG_SMI_PORT6_9_ADDR, 0x000040e6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1910,7 +1883,7 @@ void check_and_flash_update_image(void)
|
|||||||
__xdata uint16_t i = 0;
|
__xdata uint16_t i = 0;
|
||||||
__xdata uint16_t j = 0;
|
__xdata uint16_t j = 0;
|
||||||
__xdata uint8_t * __xdata bptr;
|
__xdata uint8_t * __xdata bptr;
|
||||||
print_string("found update image! Checking integrity");
|
print_string("found update image!\nChecking integrity");
|
||||||
flash_init(0); // Re-initialize flash for non-DIO operation, otherwise flashing will fail
|
flash_init(0); // Re-initialize flash for non-DIO operation, otherwise flashing will fail
|
||||||
set_sys_led_state(SYS_LED_FAST);
|
set_sys_led_state(SYS_LED_FAST);
|
||||||
crc_value = 0x0000;
|
crc_value = 0x0000;
|
||||||
@@ -2038,6 +2011,8 @@ void main(void)
|
|||||||
// Print SW version
|
// Print SW version
|
||||||
print_sw_version();
|
print_sw_version();
|
||||||
|
|
||||||
|
// Set AUTONEG for SFP ports
|
||||||
|
sfp_speed[0] = sfp_speed[1] = SFP_SPEED_AUTO;
|
||||||
// Reset NIC
|
// Reset NIC
|
||||||
reg_bit_set(RTL837X_REG_RESET, RESET_NIC_BIT);
|
reg_bit_set(RTL837X_REG_RESET, RESET_NIC_BIT);
|
||||||
do {
|
do {
|
||||||
@@ -2087,6 +2062,8 @@ void main(void)
|
|||||||
|
|
||||||
check_and_flash_update_image();
|
check_and_flash_update_image();
|
||||||
|
|
||||||
|
syslog_init();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// This register seems to work on the RTL8373 only if also the SDS
|
// This register seems to work on the RTL8373 only if also the SDS
|
||||||
// Is correctly configured. Therefore, we can test it, here...
|
// Is correctly configured. Therefore, we can test it, here...
|
||||||
@@ -2114,11 +2091,10 @@ void main(void)
|
|||||||
uip_arp_init();
|
uip_arp_init();
|
||||||
httpd_init();
|
httpd_init();
|
||||||
|
|
||||||
management_vlan = 0; // Disabled
|
management_vlan = 1; // Default management VLAN is 1
|
||||||
|
|
||||||
setup_i2c();
|
setup_i2c();
|
||||||
setup_sfp_gpio();
|
setup_sfp_gpio();
|
||||||
|
|
||||||
print_string(greeting);
|
print_string(greeting);
|
||||||
|
|
||||||
print_string("\nClock register: ");
|
print_string("\nClock register: ");
|
||||||
@@ -2130,13 +2106,16 @@ void main(void)
|
|||||||
// p031f.a610:2058 p041f.a610:2058 p051f.a610:2058 r4f3c:00000000 p061f.a610:2058 p071f.a610:2058
|
// p031f.a610:2058 p041f.a610:2058 p051f.a610:2058 r4f3c:00000000 p061f.a610:2058 p071f.a610:2058
|
||||||
port_stats_print();
|
port_stats_print();
|
||||||
|
|
||||||
|
early_boot_handle_button();
|
||||||
|
|
||||||
execute_config();
|
execute_config();
|
||||||
print_string("\n> ");
|
print_cmd_prompt();
|
||||||
idle_ready = 1;
|
idle_ready = 1;
|
||||||
|
|
||||||
set_sys_led_state(SYS_LED_ON);
|
set_sys_led_state(SYS_LED_ON);
|
||||||
|
|
||||||
cmd_editor_init();
|
cmd_editor_init();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
cmd_edit();
|
cmd_edit();
|
||||||
idle(); // Enter Idle mode until interrupt occurs
|
idle(); // Enter Idle mode until interrupt occurs
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
#include "machine.h"
|
||||||
|
#include "syslog.h"
|
||||||
|
#include "uip/uip.h"
|
||||||
|
#include "rtl837x_common.h"
|
||||||
|
|
||||||
|
#pragma codeseg BANK2
|
||||||
|
#pragma constseg BANK2
|
||||||
|
|
||||||
|
#define SYSLOG_P ((__xdata uint8_t *)uip_appdata)
|
||||||
|
|
||||||
|
__xdata char logbuf[LOGBUF_SIZE];
|
||||||
|
__xdata struct syslog_state syslog_state;
|
||||||
|
__xdata uip_ipaddr_t server_ip;
|
||||||
|
|
||||||
|
#define state syslog_state
|
||||||
|
|
||||||
|
void syslog_init(void) __banked
|
||||||
|
{
|
||||||
|
state.enabled = 0;
|
||||||
|
state.syslog_conn = 0;
|
||||||
|
state.writeptr = 0;
|
||||||
|
state.readptr = 0;
|
||||||
|
state.line_available = 0;
|
||||||
|
state.server_ip[0] = 0; state.server_ip[1] = 0; state.server_ip[2] = 0; state.server_ip[3] = 0;// Default to 0.0.0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
void syslog_start(void) __banked
|
||||||
|
{
|
||||||
|
if (state.syslog_conn == 0) {
|
||||||
|
uip_ipaddr(server_ip, state.server_ip[0], state.server_ip[1], state.server_ip[2], state.server_ip[3]);
|
||||||
|
state.syslog_conn = uip_udp_new(&server_ip, HTONS(514));
|
||||||
|
if (state.syslog_conn == 0) {
|
||||||
|
print_string_no_syslog("Failed to create a new UDP client\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
print_string_no_syslog("Started syslog to IP ");
|
||||||
|
itoa(state.server_ip[0]); write_char('.'); itoa(state.server_ip[1]); write_char('.');
|
||||||
|
itoa(state.server_ip[2]); write_char('.'); itoa(state.server_ip[3]); write_char('\n');
|
||||||
|
state.enabled = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print_string_no_syslog("Syslog is already running\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void syslog_stop(void) __banked
|
||||||
|
{
|
||||||
|
state.enabled = 0;
|
||||||
|
if (state.syslog_conn != 0) {
|
||||||
|
uip_udp_remove(state.syslog_conn);
|
||||||
|
state.syslog_conn = 0;
|
||||||
|
print_string_no_syslog("Stopped syslog\n");
|
||||||
|
} else {
|
||||||
|
print_string_no_syslog("Syslog is not running\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void syslog_callback(uint16_t lport) __banked
|
||||||
|
{
|
||||||
|
if (lport != state.syslog_conn->lport)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((state.readptr != state.writeptr) && state.line_available)
|
||||||
|
{
|
||||||
|
int16_t log_size = state.writeptr - state.readptr;
|
||||||
|
if (log_size < 0)
|
||||||
|
log_size += LOGBUF_SIZE;
|
||||||
|
|
||||||
|
// Skipping linefeeds at the start of the log line
|
||||||
|
uint16_t log_start = state.readptr;
|
||||||
|
while (log_size > 0 && logbuf[log_start] == '\n') {
|
||||||
|
log_start = (log_start + 1) & (LOGBUF_SIZE - 1);
|
||||||
|
log_size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skipping linefeeds and whitespaces at the end of the log line
|
||||||
|
uint16_t log_end = state.writeptr;
|
||||||
|
while ( (log_size > 0) &&
|
||||||
|
((logbuf[(log_end-1) & (LOGBUF_SIZE - 1)] == '\n') ||
|
||||||
|
(logbuf[(log_end-1) & (LOGBUF_SIZE - 1)] == ' ')))
|
||||||
|
{
|
||||||
|
log_end = (log_end - 1) & (LOGBUF_SIZE - 1);
|
||||||
|
log_size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (log_size == 0) {
|
||||||
|
state.readptr = state.writeptr;
|
||||||
|
state.line_available = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpyc(SYSLOG_P, "<14>", 4); // Syslog priority prefix
|
||||||
|
|
||||||
|
if (log_end < log_start) {
|
||||||
|
memcpy(SYSLOG_P + 4, logbuf + log_start, LOGBUF_SIZE - log_start);
|
||||||
|
memcpy(SYSLOG_P + 4 + LOGBUF_SIZE - log_start, logbuf, log_end);
|
||||||
|
} else {
|
||||||
|
memcpy(SYSLOG_P + 4, logbuf + log_start, log_end - log_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
uip_udp_send(log_size+4);
|
||||||
|
state.readptr = state.writeptr;
|
||||||
|
state.line_available = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#ifndef _SYSLOG_H_
|
||||||
|
#define _SYSLOG_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define LOGBUF_SIZE 512
|
||||||
|
|
||||||
|
struct syslog_state {
|
||||||
|
uint8_t enabled;
|
||||||
|
uint8_t line_available;
|
||||||
|
uint16_t writeptr ;
|
||||||
|
uint16_t readptr;
|
||||||
|
uint8_t server_ip[4];
|
||||||
|
|
||||||
|
struct uip_udp_conn *syslog_conn;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern __xdata struct syslog_state syslog_state;
|
||||||
|
extern __xdata char logbuf[LOGBUF_SIZE];
|
||||||
|
|
||||||
|
void syslog_init(void) __banked;
|
||||||
|
void syslog_start(void) __banked;
|
||||||
|
void syslog_stop(void) __banked;
|
||||||
|
void syslog_callback(uint16_t lport) __banked;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,27 +1,27 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CCFLAGS = -Wall -o
|
CCFLAGS = -Wall -o
|
||||||
BUILDDIR = output/
|
BUILDDIR = output
|
||||||
|
|
||||||
all: create_build_dir $(BUILDDIR)injector $(BUILDDIR)fileadder $(BUILDDIR)httpd_sim\
|
all: create_build_dir $(BUILDDIR)/injector $(BUILDDIR)/fileadder $(BUILDDIR)/httpd_sim\
|
||||||
$(BUILDDIR)crc_calculator $(BUILDDIR)imagebuilder
|
$(BUILDDIR)/crc_calculator $(BUILDDIR)/imagebuilder
|
||||||
|
|
||||||
create_build_dir:
|
create_build_dir:
|
||||||
mkdir -p $(BUILDDIR)
|
mkdir -p $(BUILDDIR)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -r $(BUILDDIR)
|
rm -rf $(BUILDDIR)
|
||||||
|
|
||||||
$(BUILDDIR)injector: injector.c
|
$(BUILDDIR)/injector: injector.c
|
||||||
gcc $^ $(CCFLAGS) $@
|
gcc $^ $(CCFLAGS) $@
|
||||||
|
|
||||||
$(BUILDDIR)fileadder: fileadder.c
|
$(BUILDDIR)/fileadder: fileadder.c
|
||||||
gcc $^ $(CCFLAGS) $@
|
gcc $^ $(CCFLAGS) $@
|
||||||
|
|
||||||
$(BUILDDIR)crc_calculator: crc_calculator.c
|
$(BUILDDIR)/crc_calculator: crc_calculator.c
|
||||||
gcc $^ $(CCFLAGS) $@
|
gcc $^ $(CCFLAGS) $@
|
||||||
|
|
||||||
$(BUILDDIR)httpd_sim: httpd_sim.c httpd_sim.h
|
$(BUILDDIR)/httpd_sim: httpd_sim.c httpd_sim.h
|
||||||
gcc $< $(CCFLAGS) $@ -I/usr/include/json-c -ljson-c
|
gcc $< $(CCFLAGS) $@ -I/usr/include/json-c -ljson-c
|
||||||
|
|
||||||
$(BUILDDIR)imagebuilder: imagebuilder.c
|
$(BUILDDIR)/imagebuilder: imagebuilder.c
|
||||||
gcc $^ $(CCFLAGS) $@
|
gcc $^ $(CCFLAGS) $@
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int nbanks = (filesize - BANK0_SIZE) / BANK_STRIDE;
|
int nbanks = (filesize - BANK0_SIZE) / BANK_STRIDE;
|
||||||
printf("Input file contains %d banks\n", nbanks);
|
printf("Input file contains %d banks\n", nbanks+1);
|
||||||
|
|
||||||
/* Verify the size of banks in input file:
|
/* Verify the size of banks in input file:
|
||||||
* Bank 0: 0x00002 - 0x04000 <- 0x00000 - 0x03ffe
|
* Bank 0: 0x00002 - 0x04000 <- 0x00000 - 0x03ffe
|
||||||
@@ -112,15 +112,15 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
for (int b = BANK0_SIZE; b < BANK_STRIDE + BANK0_SIZE; b ++) {
|
for (int b = BANK0_SIZE; b < BANK_STRIDE + BANK0_SIZE; b ++) {
|
||||||
if (buffer[b]) {
|
if (buffer[b]) {
|
||||||
printf("WARNING: Bank 0: code segment too large at 0x%x!\n", b);
|
printf("Error: Bank 0: code segment too large at 0x%x!\n", b);
|
||||||
break;
|
return 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int bank = 1; bank <= nbanks; bank++) {
|
for (int bank = 1; bank <= nbanks; bank++) {
|
||||||
for (int b = (bank + 1) * BANK_STRIDE; b < (bank + 1) * BANK_STRIDE + BANK0_SIZE; b ++) {
|
for (int b = (bank + 1) * BANK_STRIDE; b < (bank + 1) * BANK_STRIDE + BANK0_SIZE; b ++) {
|
||||||
if (buffer[b]) {
|
if (buffer[b]) {
|
||||||
printf("WARNING: Bank %d: code segment too large at 0x%x!\n", bank, b);
|
printf("Error: Bank %d: code segment too large at 0x%x!\n", bank, b);
|
||||||
break;
|
return 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
#include "uip/uip.h"
|
||||||
|
#include "udp_apps.h"
|
||||||
|
|
||||||
|
void udp_callbacks(void)
|
||||||
|
{
|
||||||
|
dhcp_callback(uip_udp_conn->lport); // let the application decide if this is for it or not
|
||||||
|
syslog_callback(uip_udp_conn->lport); // let the application decide if this is for it or not
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef _UDPAPPS_H_
|
||||||
|
#define _UDPAPPS_H_
|
||||||
|
|
||||||
|
#include "dhcp.h"
|
||||||
|
#include "syslog.h"
|
||||||
|
|
||||||
|
void udp_callbacks(void);
|
||||||
|
|
||||||
|
#ifndef UIP_UDP_APPCALL
|
||||||
|
#define UIP_UDP_APPCALL udp_callbacks
|
||||||
|
#endif /* UIP_UDP_APPCALL */
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
CC = sdcc
|
|
||||||
CC_FLAGS = -mmcs51 -I. -I.. -I../httpd
|
|
||||||
ASM = sdas8051
|
|
||||||
AFLAGS= -plosgff
|
|
||||||
|
|
||||||
BUILDDIR = output/
|
|
||||||
|
|
||||||
SRCS = timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-neighbor.c uip-split.c
|
|
||||||
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel}
|
|
||||||
|
|
||||||
all: create_build_dir $(OBJS)
|
|
||||||
|
|
||||||
create_build_dir:
|
|
||||||
mkdir -p $(BUILDDIR)
|
|
||||||
|
|
||||||
$(BUILDDIR)%.rel: %.c
|
|
||||||
$(CC) $(CC_FLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
$(BUILDDIR)%.rel: $(BUILDDIR)%.asm
|
|
||||||
${ASM} ${AFLAGS} $^
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -r $(BUILDDIR)
|
|
||||||
|
|
||||||
.PHONY: all clean
|
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
timer_set(struct timer *t, clock_time_t interval)
|
timer_set(__xdata struct timer *t, clock_time_t interval)
|
||||||
{
|
{
|
||||||
t->interval = interval;
|
t->interval = interval;
|
||||||
t->start = clock_time();
|
t->start = clock_time();
|
||||||
@@ -84,7 +84,7 @@ timer_set(struct timer *t, clock_time_t interval)
|
|||||||
* \sa timer_restart()
|
* \sa timer_restart()
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
timer_reset(struct timer *t)
|
timer_reset(__xdata struct timer *t)
|
||||||
{
|
{
|
||||||
t->start += t->interval;
|
t->start += t->interval;
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ timer_reset(struct timer *t)
|
|||||||
* \sa timer_reset()
|
* \sa timer_reset()
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
timer_restart(struct timer *t)
|
timer_restart(__xdata struct timer *t)
|
||||||
{
|
{
|
||||||
t->start = clock_time();
|
t->start = clock_time();
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@ timer_restart(struct timer *t)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
timer_expired(struct timer *t)
|
timer_expired(__xdata struct timer *t)
|
||||||
{
|
{
|
||||||
return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval;
|
return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,10 +76,10 @@ struct timer {
|
|||||||
clock_time_t interval;
|
clock_time_t interval;
|
||||||
};
|
};
|
||||||
|
|
||||||
void timer_set(struct timer *t, clock_time_t interval);
|
void timer_set(__xdata struct timer *t, clock_time_t interval);
|
||||||
void timer_reset(struct timer *t);
|
void timer_reset(__xdata struct timer *t);
|
||||||
void timer_restart(struct timer *t);
|
void timer_restart(__xdata struct timer *t);
|
||||||
int timer_expired(struct timer *t);
|
int timer_expired(__xdata struct timer *t);
|
||||||
|
|
||||||
#endif /* __TIMER_H__ */
|
#endif /* __TIMER_H__ */
|
||||||
|
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ typedef unsigned short uip_stats_t;
|
|||||||
our project. */
|
our project. */
|
||||||
/*#include "smtp.h"*/
|
/*#include "smtp.h"*/
|
||||||
#include "httpd.h"
|
#include "httpd.h"
|
||||||
#include "dhcp.h"
|
#include "udp_apps.h"
|
||||||
/*#include "telnetd.h"*/
|
/*#include "telnetd.h"*/
|
||||||
/*#include "webserver.h" */
|
/*#include "webserver.h" */
|
||||||
/*#include "dhcpc.h"*/
|
/*#include "dhcpc.h"*/
|
||||||
|
|||||||
@@ -234,14 +234,14 @@ __xdata struct uip_stats uip_stat;
|
|||||||
#endif /* UIP_STATISTICS == 1 */
|
#endif /* UIP_STATISTICS == 1 */
|
||||||
|
|
||||||
#if UIP_LOGGING == 1
|
#if UIP_LOGGING == 1
|
||||||
#define UIP_LOG(m) print_string(m)
|
#define UIP_LOG(m) print_string_no_syslog(m);
|
||||||
#else
|
#else
|
||||||
#define UIP_LOG(m)
|
#define UIP_LOG(m)
|
||||||
#endif /* UIP_LOGGING == 1 */
|
#endif /* UIP_LOGGING == 1 */
|
||||||
|
|
||||||
#if ! UIP_ARCH_ADD32
|
#if ! UIP_ARCH_ADD32
|
||||||
void
|
void
|
||||||
uip_add32(u8_t *op32, u16_t op16)
|
uip_add32(u8_t __xdata * op32, u16_t op16)
|
||||||
{
|
{
|
||||||
uip_acc32[3] = op32[3] + (op16 & 0xff);
|
uip_acc32[3] = op32[3] + (op16 & 0xff);
|
||||||
uip_acc32[2] = op32[2] + (op16 >> 8);
|
uip_acc32[2] = op32[2] + (op16 >> 8);
|
||||||
@@ -465,8 +465,8 @@ uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banke
|
|||||||
#endif /* UIP_ACTIVE_OPEN */
|
#endif /* UIP_ACTIVE_OPEN */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if UIP_UDP
|
#if UIP_UDP
|
||||||
struct uip_udp_conn *
|
__xdata struct uip_udp_conn *
|
||||||
uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked
|
uip_udp_new(__xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banked
|
||||||
{
|
{
|
||||||
__xdata struct uip_udp_conn *conn;
|
__xdata struct uip_udp_conn *conn;
|
||||||
|
|
||||||
@@ -1901,7 +1901,7 @@ htons(u16_t val)
|
|||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_send(register __xdata const void *data, register uint16_t len) __banked
|
uip_send(__xdata const void *data, __xdata uint16_t len) __banked
|
||||||
{
|
{
|
||||||
if(len > 0) {
|
if(len > 0) {
|
||||||
uip_slen = len;
|
uip_slen = len;
|
||||||
|
|||||||
@@ -495,7 +495,7 @@ void uip_unlisten(u16_t port) __banked;
|
|||||||
* or NULL if no connection could be allocated.
|
* or NULL if no connection could be allocated.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
__xdata struct uip_conn *uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t port) __banked;
|
__xdata struct uip_conn *uip_connect(__xdata uip_ipaddr_t *ripaddr, __xdata u16_t port) __banked;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -535,7 +535,7 @@ __xdata struct uip_conn *uip_connect(register __xdata uip_ipaddr_t *ripaddr, __x
|
|||||||
*
|
*
|
||||||
* \hideinitializer
|
* \hideinitializer
|
||||||
*/
|
*/
|
||||||
void uip_send(register __xdata const void *data, register uint16_t len) __banked;
|
void uip_send(__xdata const void *data, __xdata uint16_t len) __banked;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The length of any incoming data that is currently avaliable (if avaliable)
|
* The length of any incoming data that is currently avaliable (if avaliable)
|
||||||
@@ -763,7 +763,7 @@ void uip_send(register __xdata const void *data, register uint16_t len) __banked
|
|||||||
* \return The uip_udp_conn structure for the new connection or NULL
|
* \return The uip_udp_conn structure for the new connection or NULL
|
||||||
* if no connection could be allocated.
|
* if no connection could be allocated.
|
||||||
*/
|
*/
|
||||||
struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked;
|
__xdata struct uip_udp_conn *uip_udp_new(__xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banked;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removed a UDP connection.
|
* Removed a UDP connection.
|
||||||
@@ -880,8 +880,8 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked;
|
|||||||
*/
|
*/
|
||||||
#if !UIP_CONF_IPV6
|
#if !UIP_CONF_IPV6
|
||||||
#define uip_ipaddr_copy(dest, src) do { \
|
#define uip_ipaddr_copy(dest, src) do { \
|
||||||
((u16_t *)dest)[0] = ((u16_t *)src)[0]; \
|
((__xdata u16_t *)dest)[0] = ((__xdata u16_t *)src)[0]; \
|
||||||
((u16_t *)dest)[1] = ((u16_t *)src)[1]; \
|
((__xdata u16_t *)dest)[1] = ((__xdata u16_t *)src)[1]; \
|
||||||
} while(0)
|
} while(0)
|
||||||
#else /* !UIP_CONF_IPV6 */
|
#else /* !UIP_CONF_IPV6 */
|
||||||
#define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t))
|
#define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t))
|
||||||
@@ -908,8 +908,8 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked;
|
|||||||
* \hideinitializer
|
* \hideinitializer
|
||||||
*/
|
*/
|
||||||
#if !UIP_CONF_IPV6
|
#if !UIP_CONF_IPV6
|
||||||
#define uip_ipaddr_cmp(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \
|
#define uip_ipaddr_cmp(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__xdata u16_t *)addr2)[0] && \
|
||||||
((__xdata u16_t *)addr1)[1] == ((u16_t *)addr2)[1])
|
((__xdata u16_t *)addr1)[1] == ((__xdata u16_t *)addr2)[1])
|
||||||
#define uip_ipaddr_cmpx(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__xdata u16_t *)addr2)[0] && \
|
#define uip_ipaddr_cmpx(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__xdata u16_t *)addr2)[0] && \
|
||||||
((__xdata u16_t *)addr1)[1] == ((__xdata u16_t *)addr2)[1])
|
((__xdata u16_t *)addr1)[1] == ((__xdata u16_t *)addr2)[1])
|
||||||
#define uip_ipaddr_cmpc(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__code u16_t *)addr2)[0] && \
|
#define uip_ipaddr_cmpc(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__code u16_t *)addr2)[0] && \
|
||||||
@@ -1070,8 +1070,10 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked;
|
|||||||
#ifndef HTONS
|
#ifndef HTONS
|
||||||
# if UIP_BYTE_ORDER == UIP_BIG_ENDIAN
|
# if UIP_BYTE_ORDER == UIP_BIG_ENDIAN
|
||||||
# define HTONS(n) (n)
|
# define HTONS(n) (n)
|
||||||
|
# define NTOHS(n) (n)
|
||||||
# else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
|
# else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
|
||||||
# define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))
|
# define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))
|
||||||
|
# define NTOHS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))
|
||||||
# endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
|
# endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
|
||||||
#else
|
#else
|
||||||
#error "HTONS already defined!"
|
#error "HTONS already defined!"
|
||||||
|
|||||||
@@ -81,7 +81,7 @@
|
|||||||
*
|
*
|
||||||
* \param op16 A 16-bit integer in host byte order.
|
* \param op16 A 16-bit integer in host byte order.
|
||||||
*/
|
*/
|
||||||
void uip_add32(u8_t *op32, u16_t op16);
|
void uip_add32(__xdata u8_t * op32, u16_t op16);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the Internet checksum over a buffer.
|
* Calculate the Internet checksum over a buffer.
|
||||||
|
|||||||
@@ -68,7 +68,8 @@
|
|||||||
|
|
||||||
struct arp_hdr_i {
|
struct arp_hdr_i {
|
||||||
struct uip_eth_hdr ethhdr;
|
struct uip_eth_hdr ethhdr;
|
||||||
uint8_t rtl_tag[RTL_TAG_SIZE + VLAN_TAG_SIZE];
|
struct rtl_tag rtl_tag;
|
||||||
|
struct vlan_tag vlan_tag;
|
||||||
u16_t hwtype;
|
u16_t hwtype;
|
||||||
u16_t protocol;
|
u16_t protocol;
|
||||||
u8_t hwlen;
|
u8_t hwlen;
|
||||||
@@ -131,8 +132,8 @@ static __xdata u8_t arptime;
|
|||||||
static __xdata u8_t tmpage;
|
static __xdata u8_t tmpage;
|
||||||
|
|
||||||
#define BUF ((__xdata struct arp_hdr_i *)&uip_buf[0])
|
#define BUF ((__xdata struct arp_hdr_i *)&uip_buf[0])
|
||||||
#define BUF_O ((__xdata struct arp_hdr_o *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE])
|
#define BUF_O ((__xdata struct arp_hdr_o *)&uip_buf[RTL_FRAME_DESC_SIZE])
|
||||||
#define IPBUF ((__xdata struct ethip_hdr *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE])
|
#define IPBUF ((__xdata struct ethip_hdr *)&uip_buf[RTL_FRAME_DESC_SIZE])
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* Initialize the ARP module.
|
* Initialize the ARP module.
|
||||||
|
|||||||
@@ -447,7 +447,7 @@ void uip_log(char *msg);
|
|||||||
#ifdef UIP_CONF_LLH_LEN
|
#ifdef UIP_CONF_LLH_LEN
|
||||||
#define UIP_LLH_LEN UIP_CONF_LLH_LEN
|
#define UIP_LLH_LEN UIP_CONF_LLH_LEN
|
||||||
#else /* UIP_CONF_LLH_LEN */
|
#else /* UIP_CONF_LLH_LEN */
|
||||||
#define UIP_LLH_LEN ETHER_HEADER_SIZE + RTL_TAG_SIZE + VLAN_TAG_SIZE
|
#define UIP_LLH_LEN ETHER_HEADER_SIZE + RTL_FRAME_DESC_SIZE
|
||||||
#endif /* UIP_CONF_LLH_LEN */
|
#endif /* UIP_CONF_LLH_LEN */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||