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 | ||
|
|
e849af4a70 | ||
|
|
812bf3bb67 | ||
|
|
da8ec8fe88 | ||
|
|
f7989cc737 | ||
|
|
2e48415c95 | ||
|
|
22f8b9a287 | ||
|
|
c91177d992 | ||
|
|
c1a414833d | ||
|
|
2a9c7d2828 | ||
|
|
d776118815 | ||
|
|
f7b8aed2f7 | ||
|
|
7eb3676aaf | ||
|
|
eaa21d5975 | ||
|
|
193eacf51b | ||
|
|
b60811b984 | ||
|
|
b85861347b | ||
|
|
b21bfac917 |
@@ -16,23 +16,31 @@ 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)/uip
|
||||||
mkdir -p $(BUILDDIR)/httpd
|
mkdir -p $(BUILDDIR)/httpd
|
||||||
mkdir -p $(BUILDDIR)/crypto
|
|
||||||
|
|
||||||
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
|
||||||
SRCS += rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c cmd_editor.c rtl837x_bandwidth.c rtl837x_init.c
|
SRCS += rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c cmd_editor.c rtl837x_bandwidth.c rtl837x_init.c syslog.c
|
||||||
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
|
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
|
||||||
SRCS += httpd/httpd.c httpd/page_impl.c
|
SRCS += httpd/httpd.c httpd/page_impl.c
|
||||||
SRCS += crypto/chacha20.c
|
|
||||||
OBJS = ${SRCS:%.c=$(BUILDDIR)/%.rel}
|
OBJS = ${SRCS:%.c=$(BUILDDIR)/%.rel}
|
||||||
DEPS := ${SRCS:%.c=$(BUILDDIR)/%.d}
|
DEPS := ${SRCS:%.c=$(BUILDDIR)/%.d}
|
||||||
HTML := $(shell find $(html) -name '*.js' -or -name '*.html' -or -name '*.svg')
|
HTML := $(shell find $(html) -name '*.js' -or -name '*.html' -or -name '*.svg')
|
||||||
@@ -43,7 +51,7 @@ html_data.c html_data.h: $(HTML) tools/$(BUILDDIR)/fileadder
|
|||||||
$(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)
|
||||||
|
|
||||||
@@ -54,28 +62,33 @@ $(SUBDIRS):
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -f html_data.c html_data.h $(VERSION_HEADER)
|
-rm -f html_data.c html_data.h $(VERSION_HEADER)
|
||||||
-rm -rf $(BUILDDIR)
|
-if [ -d $(BUILDDIR) ]; then find $(BUILDDIR) -type f ! -name "*.bin" -delete; fi
|
||||||
|
|
||||||
$(BUILDDIR)/%.rel: %.asm
|
distclean:
|
||||||
${ASM} ${AFLAGS} -o $@ $<
|
-rm -f html_data.c html_data.h $(VERSION_HEADER)
|
||||||
|
-rm -rf $(BUILDDIR)
|
||||||
|
|
||||||
$(BUILDDIR)/%.rel: %.c
|
$(BUILDDIR)/%.rel: %.c
|
||||||
$(CC) -MMD $(CC_FLAGS) -o $@ -c $<
|
$(CC) -MMD $(CC_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
$(BUILDDIR)/rtlplayground.ihx: $(OBJS) $(BUILDDIR)/crtstart.rel $(BUILDDIR)/crc16.rel $(BUILDDIR)/crypto/chacha_8051.rel
|
$(BUILDDIR)/%.rel: %.asm
|
||||||
|
${ASM} ${AFLAGS} -o $@ $<
|
||||||
|
# mv -f $(addprefix $(basename $^), .lst .rel .sym) .
|
||||||
|
|
||||||
|
$(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 -b BANK1 $@
|
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) $(VERSION_HEADER)
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "rtl837x_igmp.h"
|
#include "rtl837x_igmp.h"
|
||||||
#include "rtl837x_bandwidth.h"
|
#include "rtl837x_bandwidth.h"
|
||||||
#include "dhcp.h"
|
#include "dhcp.h"
|
||||||
|
#include "syslog.h"
|
||||||
#include "uip/uip.h"
|
#include "uip/uip.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
@@ -47,6 +48,8 @@ __xdata uint16_t vlan_ptr;
|
|||||||
__xdata char port_names[9][PORT_NAME_SIZE];
|
__xdata char port_names[9][PORT_NAME_SIZE];
|
||||||
|
|
||||||
extern __xdata uint16_t management_vlan;
|
extern __xdata uint16_t management_vlan;
|
||||||
|
extern __xdata uint8_t sfp_speed[2];
|
||||||
|
extern __xdata uint8_t sfp_pins_last;
|
||||||
__xdata uint8_t gpio_last_value[8] = { 0 };
|
__xdata uint8_t gpio_last_value[8] = { 0 };
|
||||||
|
|
||||||
// Temporatly for str to hex convertion value.
|
// Temporatly for str to hex convertion value.
|
||||||
@@ -661,6 +664,14 @@ void parse_port(void)
|
|||||||
else if (cmd_compare(3, "full"))
|
else if (cmd_compare(3, "full"))
|
||||||
phy_settings.duplex = PHY_DUPLEX_FULL;
|
phy_settings.duplex = PHY_DUPLEX_FULL;
|
||||||
phy_set_speed();
|
phy_set_speed();
|
||||||
|
} else if (cmd_compare(2, "10g")) {
|
||||||
|
print_string(" 10G\n");
|
||||||
|
phy_settings.speed = PHY_SPEED_10G;
|
||||||
|
phy_set_speed();
|
||||||
|
} else if (cmd_compare(2, "5g")) {
|
||||||
|
print_string(" 5G\n");
|
||||||
|
phy_settings.speed = PHY_SPEED_5G;
|
||||||
|
phy_set_speed();
|
||||||
} else if (cmd_compare(2, "2g5")) {
|
} else if (cmd_compare(2, "2g5")) {
|
||||||
print_string(" 2.5G\n");
|
print_string(" 2.5G\n");
|
||||||
phy_settings.speed = PHY_SPEED_2G5;
|
phy_settings.speed = PHY_SPEED_2G5;
|
||||||
@@ -684,9 +695,9 @@ void parse_port(void)
|
|||||||
} else if (cmd_compare(2, "duplex")) {
|
} else if (cmd_compare(2, "duplex")) {
|
||||||
print_string(" DUPLEX\n");
|
print_string(" DUPLEX\n");
|
||||||
if (cmd_compare(3, "full"))
|
if (cmd_compare(3, "full"))
|
||||||
phy_settings.speed = PHY_DUPLEX_FULL;
|
phy_settings.duplex = PHY_DUPLEX_FULL;
|
||||||
else
|
else
|
||||||
phy_settings.speed = PHY_DUPLEX_HALF;
|
phy_settings.duplex = PHY_DUPLEX_HALF;
|
||||||
phy_set_duplex();
|
phy_set_duplex();
|
||||||
} else {
|
} else {
|
||||||
print_string("Unknown port command\n");
|
print_string("Unknown port command\n");
|
||||||
@@ -739,6 +750,64 @@ void sfp_print_measurements(uint8_t sfp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void parse_sfp(void)
|
||||||
|
{
|
||||||
|
uint8_t slot;
|
||||||
|
|
||||||
|
if (cmd_words_len != 1 && cmd_words_len != 3)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (cmd_words_len == 1) {
|
||||||
|
for (slot = 0; slot < machine.n_sfp; slot++) {
|
||||||
|
print_string("\nSlot "); write_char('1' + slot);
|
||||||
|
if (gpio_pin_test(machine.sfp_port[slot].pin_detect)) {
|
||||||
|
print_string(" - empty\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
print_string(" - Rate: "); print_byte(sfp_read_reg(slot, 12));
|
||||||
|
print_string(" Encoding: "); print_byte(sfp_read_reg(slot, 11));
|
||||||
|
write_char('\n');
|
||||||
|
sfp_print_info(slot);
|
||||||
|
sfp_print_measurements(slot);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cmd_buffer[cmd_words_b[1]] < '1' || cmd_buffer[cmd_words_b[1]] > '2' || cmd_buffer[cmd_words_b[1] + 1] != ' ' ) {
|
||||||
|
print_string("Illegal SFP slot number\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
slot = cmd_buffer[cmd_words_b[1]] - '1';
|
||||||
|
if (slot >= machine.n_sfp) {
|
||||||
|
print_string("SFP slot not present\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd_compare(2, "10g")) {
|
||||||
|
print_string(" 10G\n");
|
||||||
|
sfp_speed[slot] = SFP_SPEED_10G;
|
||||||
|
} else if (cmd_compare(2, "2g5")) {
|
||||||
|
print_string(" 2.5G\n");
|
||||||
|
sfp_speed[slot] = SFP_SPEED_2G5;
|
||||||
|
} else if (cmd_compare(2, "1g")) {
|
||||||
|
print_string(" 1G\n");
|
||||||
|
sfp_speed[slot] = SFP_SPEED_1G;
|
||||||
|
} else if (cmd_compare(2, "100m")) {
|
||||||
|
print_string(" 100M\n");
|
||||||
|
sfp_speed[slot] = SFP_SPEED_100M;
|
||||||
|
} else if (cmd_compare(2, "auto")) {
|
||||||
|
print_string(" AUTO\n");
|
||||||
|
sfp_speed[slot] = SFP_SPEED_AUTO;
|
||||||
|
} else {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
sfp_pins_last |= 0x1 << (slot << 2);
|
||||||
|
handle_sfp();
|
||||||
|
return;
|
||||||
|
err:
|
||||||
|
print_string("\nUsage:\n\tsfp\n\tsfp [1|2] [1g|2g5|10g]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void parse_regget(void)
|
void parse_regget(void)
|
||||||
{
|
{
|
||||||
uint16_t reg = 0;
|
uint16_t reg = 0;
|
||||||
@@ -1062,6 +1131,9 @@ void parse_eee(void)
|
|||||||
__xdata int8_t port = -1;
|
__xdata int8_t port = -1;
|
||||||
__xdata uint8_t speed = EEE_2G5;
|
__xdata uint8_t speed = EEE_2G5;
|
||||||
__xdata uint8_t speed_word = 0;
|
__xdata uint8_t speed_word = 0;
|
||||||
|
|
||||||
|
if (machine.n_10g)
|
||||||
|
speed = EEE_10G;
|
||||||
// Check if word 2 is a speed (contains 'g' or 'm') or a port number
|
// Check if word 2 is a speed (contains 'g' or 'm') or a port number
|
||||||
if (cmd_words_len >= 3) {
|
if (cmd_words_len >= 3) {
|
||||||
uint8_t idx = cmd_words_b[2];
|
uint8_t idx = cmd_words_b[2];
|
||||||
@@ -1188,6 +1260,52 @@ err:
|
|||||||
print_string("usage: bw [in|out|status] <port> [<hexvalue>|off|drop|fc]\n");
|
print_string("usage: bw [in|out|status] <port> [<hexvalue>|off|drop|fc]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void parse_syslog(void)
|
||||||
|
{
|
||||||
|
if (cmd_words_len < 2) // no argument -> print status
|
||||||
|
{
|
||||||
|
print_string("Current syslog status: ");
|
||||||
|
if (syslog_state.enabled) {
|
||||||
|
print_string("enabled, sending to ");
|
||||||
|
itoa(syslog_state.server_ip[0]); write_char('.'); itoa(syslog_state.server_ip[1]); write_char('.');
|
||||||
|
itoa(syslog_state.server_ip[2]); write_char('.'); itoa(syslog_state.server_ip[3]);
|
||||||
|
write_char('\n');
|
||||||
|
} else {
|
||||||
|
print_string("disabled\n");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd_compare(1, "on")) {
|
||||||
|
syslog_start();
|
||||||
|
} else if (cmd_compare(1, "off")){
|
||||||
|
syslog_stop();
|
||||||
|
} else if (cmd_compare(1, "ip")) {
|
||||||
|
if (cmd_words_len < 3) { // no additional arguemnt -> print current ip
|
||||||
|
print_string("Current syslog IP: ");
|
||||||
|
itoa(syslog_state.server_ip[0]); write_char('.'); itoa(syslog_state.server_ip[1]); write_char('.');
|
||||||
|
itoa(syslog_state.server_ip[2]); write_char('.'); itoa(syslog_state.server_ip[3]);
|
||||||
|
return;
|
||||||
|
} else if (!parse_ip(cmd_words_b[2])) {
|
||||||
|
uint8_t was_enabled = syslog_state.enabled;
|
||||||
|
if (was_enabled)
|
||||||
|
syslog_stop();
|
||||||
|
print_string("Setting new syslog IP.\n");
|
||||||
|
syslog_state.server_ip[0] = ip[0]; syslog_state.server_ip[1] = ip[1];
|
||||||
|
syslog_state.server_ip[2] = ip[2]; syslog_state.server_ip[3] = ip[3];
|
||||||
|
if (was_enabled)
|
||||||
|
syslog_start();
|
||||||
|
} else {
|
||||||
|
print_string("Invalid IP address\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print_string("Error: syslog [on|off|ip [ip-address]]\n");
|
||||||
|
print_string(" on/off enables or disables syslog, ip sets the syslog server IP address\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Parse command into words
|
// Parse command into words
|
||||||
// cmd_words_len contains the number of words found.
|
// cmd_words_len contains the number of words found.
|
||||||
// cmd_words_b[] contains only start of a word offset.
|
// cmd_words_b[] contains only start of a word offset.
|
||||||
@@ -1297,18 +1415,7 @@ void cmd_parser(void) __banked
|
|||||||
print_string("\nRESET\n\n");
|
print_string("\nRESET\n\n");
|
||||||
reset_chip();
|
reset_chip();
|
||||||
} else if (cmd_compare(0, "sfp")) {
|
} else if (cmd_compare(0, "sfp")) {
|
||||||
print_string("\nSlot 1 - Rate: "); print_byte(sfp_read_reg(0, 12));
|
parse_sfp();
|
||||||
print_string(" Encoding: "); print_byte(sfp_read_reg(0, 11));
|
|
||||||
print_string("\n");
|
|
||||||
sfp_print_info(0);
|
|
||||||
sfp_print_measurements(0);
|
|
||||||
if (machine.n_sfp == 2) {
|
|
||||||
print_string("\nSlot 2 - Rate: "); print_byte(sfp_read_reg(1, 12));
|
|
||||||
print_string(" Encoding: "); print_byte(sfp_read_reg(1, 11));
|
|
||||||
print_string("\n");
|
|
||||||
sfp_print_info(1);
|
|
||||||
sfp_print_measurements(1);
|
|
||||||
}
|
|
||||||
} else if (cmd_compare(0, "stat")) {
|
} else if (cmd_compare(0, "stat")) {
|
||||||
port_stats_print();
|
port_stats_print();
|
||||||
} else if (cmd_compare(0, "flash") && cmd_words_len == 2) {
|
} else if (cmd_compare(0, "flash") && cmd_words_len == 2) {
|
||||||
@@ -1339,6 +1446,8 @@ void cmd_parser(void) __banked
|
|||||||
parse_port();
|
parse_port();
|
||||||
} else if (cmd_compare(0, "mtu")) {
|
} else if (cmd_compare(0, "mtu")) {
|
||||||
parse_mtu();
|
parse_mtu();
|
||||||
|
} else if (cmd_compare(0, "syslog")) {
|
||||||
|
parse_syslog();
|
||||||
} else if (cmd_compare(0, "ip")) {
|
} else if (cmd_compare(0, "ip")) {
|
||||||
if (cmd_compare(1, "dhcp")) {
|
if (cmd_compare(1, "dhcp")) {
|
||||||
dhcp_start();
|
dhcp_start();
|
||||||
@@ -1579,3 +1688,37 @@ config_done:
|
|||||||
clear_command_history();
|
clear_command_history();
|
||||||
save_cmd = 1;
|
save_cmd = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Execute multiple commands
|
||||||
|
// If a command is too long or can't be tokenized, remaining commands are not executed
|
||||||
|
// Returns the status via `err_status`-variable.
|
||||||
|
void execute_commands(__xdata uint8_t *p) __banked {
|
||||||
|
err_status = ERR_OK;
|
||||||
|
uint8_t cmd_idx = 0;
|
||||||
|
while (1) {
|
||||||
|
if (*p == 0 || *p == '\n' || *p == '\r') {
|
||||||
|
if (cmd_idx) {
|
||||||
|
cmd_buffer[cmd_idx] = '\0';
|
||||||
|
cmd_tokenize();
|
||||||
|
if (err_status != ERR_OK)
|
||||||
|
return;
|
||||||
|
cmd_parser();
|
||||||
|
}
|
||||||
|
if (*p == 0)
|
||||||
|
return;
|
||||||
|
cmd_idx = 0;
|
||||||
|
} else {
|
||||||
|
if (cmd_idx < (CMD_BUF_SIZE - 1)) {
|
||||||
|
cmd_buffer[cmd_idx++] = *p;
|
||||||
|
} else {
|
||||||
|
cmd_buffer[CMD_BUF_SIZE - 1] = '\0';
|
||||||
|
print_string("ERROR: Command too long: ");
|
||||||
|
print_string_x(cmd_buffer);
|
||||||
|
write_char('\n');
|
||||||
|
err_status = ERR_CMD_TOO_LONG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
void 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
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
#ifndef _CHACHA_H_
|
|
||||||
#define _CHACHA_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
struct chacha20_t {
|
|
||||||
uint8_t wstate[64]; // 64 bytes written here
|
|
||||||
uint8_t constant[16]; // 128 bit constant
|
|
||||||
uint8_t key[32]; // 256-bit secret key
|
|
||||||
uint32_t cnt; // 32-bit block counter 1, 2.. Big Endian!
|
|
||||||
uint8_t nonce[12]; // 96-bit nonce
|
|
||||||
__xdata uint8_t *plaintext;
|
|
||||||
uint16_t length;
|
|
||||||
__xdata uint8_t *cyphertext;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Encrypt a plaintext with ChaCha20 as per RFC7539
|
|
||||||
void chacha20_encrypt(void);
|
|
||||||
|
|
||||||
// Test ChaCha20 using the example from RFC7539
|
|
||||||
void chacha20_test(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
#include "rtl837x_common.h"
|
|
||||||
#include "chacha.h"
|
|
||||||
|
|
||||||
void chacha_20(void);
|
|
||||||
void chacha_update(void);
|
|
||||||
void chacha_count(void);
|
|
||||||
|
|
||||||
// generate a block of ChaCha20 keystream as per RFC7539
|
|
||||||
|
|
||||||
|
|
||||||
__xdata struct chacha20_t __at(0x7000) chacha20;
|
|
||||||
__xdata uint8_t plaintext[256];
|
|
||||||
__xdata uint8_t cyphertext[256];
|
|
||||||
|
|
||||||
void chacha20_print_block(void)
|
|
||||||
{
|
|
||||||
for (uint8_t i=0; i < 64; i++) {
|
|
||||||
print_byte(*(uint8_t * __xdata)(chacha20.wstate + i));
|
|
||||||
if (i%4 == 3)
|
|
||||||
write_char(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void chacha20_encrypt(void)
|
|
||||||
{
|
|
||||||
__xdata uint8_t *p = chacha20.plaintext;
|
|
||||||
|
|
||||||
while (chacha20.length) {
|
|
||||||
register uint8_t i;
|
|
||||||
chacha_count();
|
|
||||||
memcpy(chacha20.wstate, chacha20.wstate + 64, 64);
|
|
||||||
#ifdef DEBUG
|
|
||||||
chacha20_print_block(); write_char('\n');
|
|
||||||
#endif
|
|
||||||
chacha_20();
|
|
||||||
chacha_update();
|
|
||||||
#ifdef DEBUG
|
|
||||||
chacha20_print_block(); write_char('\n');
|
|
||||||
#endif
|
|
||||||
for (i = 0; i < ((chacha20.length > 64) ? 64 : chacha20.length); i++)
|
|
||||||
*chacha20.cyphertext++ = *p++ ^ chacha20.wstate[i];
|
|
||||||
chacha20.length -= chacha20.length > 64 ? 64 : chacha20.length;
|
|
||||||
#ifdef DEBUG
|
|
||||||
print_string("\n round done\n");
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Test the example of RFC 7539 Section 2.4.2
|
|
||||||
void chacha20_test(void)
|
|
||||||
{
|
|
||||||
__code uint8_t chacha_c[16] =
|
|
||||||
{ 0x61, 0x70, 0x78, 0x65, 0x33, 0x20, 0x64, 0x6e,
|
|
||||||
0x79, 0x62, 0x2d, 0x32, 0x6b, 0x20, 0x65, 0x74 };
|
|
||||||
|
|
||||||
__code uint8_t key[32] =
|
|
||||||
{ 0x03, 0x02, 0x01, 0x00, 0x07, 0x06, 0x05, 0x04,
|
|
||||||
0x0b, 0x0a, 0x09, 0x08, 0x0f, 0x0e, 0x0d, 0x0c,
|
|
||||||
0x13, 0x12, 0x11, 0x10, 0x17, 0x16, 0x15, 0x14,
|
|
||||||
0x1b, 0x1a, 0x19, 0x18, 0x1f, 0x1e, 0x1d, 0x1c };
|
|
||||||
|
|
||||||
__code uint8_t nonce[12] = {
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00 };
|
|
||||||
|
|
||||||
__code uint8_t sunscreen[] = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for " \
|
|
||||||
"the future, sunscreen would be it.";
|
|
||||||
|
|
||||||
/*
|
|
||||||
Ciphertext Sunscreen (from RFC 7539 Section 2.4.2):
|
|
||||||
000 6e 2e 35 9a 25 68 f9 80 41 ba 07 28 dd 0d 69 81 n.5.%h..A..(..i.
|
|
||||||
016 e9 7e 7a ec 1d 43 60 c2 0a 27 af cc fd 9f ae 0b .~z..C`..'......
|
|
||||||
032 f9 1b 65 c5 52 47 33 ab 8f 59 3d ab cd 62 b3 57 ..e.RG3..Y=..b.W
|
|
||||||
048 16 39 d6 24 e6 51 52 ab 8f 53 0c 35 9f 08 61 d8 .9.$.QR..S.5..a.
|
|
||||||
064 07 ca 0d bf 50 0d 6a 61 56 a3 8e 08 8a 22 b6 5e ....P.jaV....".^
|
|
||||||
080 52 bc 51 4d 16 cc f8 06 81 8c e9 1a b7 79 37 36 R.QM.........y76
|
|
||||||
096 5a f9 0b bf 74 a3 5b e6 b4 0b 8e ed f2 78 5e 42 Z...t.[......x^B
|
|
||||||
112 87 4d
|
|
||||||
*/
|
|
||||||
strcpy(plaintext, sunscreen);
|
|
||||||
memcpyc(chacha20.constant, chacha_c, 16);
|
|
||||||
memcpyc(chacha20.key, key, 32);
|
|
||||||
chacha20.cnt = 0;
|
|
||||||
memcpyc(chacha20.nonce, nonce, 12);
|
|
||||||
chacha20.plaintext = plaintext;
|
|
||||||
chacha20.length = strlen_x(plaintext);
|
|
||||||
chacha20.cyphertext = cyphertext;
|
|
||||||
|
|
||||||
print_string("Encrypting...\n");
|
|
||||||
chacha20_encrypt();
|
|
||||||
print_string("Cypertext:\n");
|
|
||||||
uint16_t len = strlen_x(plaintext);
|
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
|
||||||
print_byte(cyphertext[i]); write_char(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,489 +0,0 @@
|
|||||||
; ChaCha Quater-Round implementation in Assembler
|
|
||||||
.module chacha_8051
|
|
||||||
; Global variables:
|
|
||||||
.globl _chacha_20
|
|
||||||
.globl _chacha_test_1
|
|
||||||
.globl _chacha_qr_r
|
|
||||||
.globl _chacha_update
|
|
||||||
.globl _chacha_count
|
|
||||||
|
|
||||||
;#define CHACHA_QR(A, B, C, D) { \
|
|
||||||
; A += B; D ^= A; D = ROTL32(D, 16); \
|
|
||||||
; C += D; B ^= C; B = ROTL32(B, 12); \
|
|
||||||
; A += B; D ^= A; D = ROTL32(D, 8); \
|
|
||||||
; C += D; B ^= C; B = ROTL32(B, 7); \
|
|
||||||
;}
|
|
||||||
|
|
||||||
; r0 r1 r2 r3
|
|
||||||
; CHACHA_QR( v[ 0], v[ 4], v[ 8], v[12] );
|
|
||||||
|
|
||||||
.area HOME (CODE)
|
|
||||||
|
|
||||||
store_32:
|
|
||||||
ar7 = 0x07
|
|
||||||
ar6 = 0x06
|
|
||||||
ar5 = 0x05
|
|
||||||
ar4 = 0x04
|
|
||||||
ar3 = 0x03
|
|
||||||
ar2 = 0x02
|
|
||||||
ar1 = 0x01
|
|
||||||
ar0 = 0x00
|
|
||||||
|
|
||||||
mov a, r7
|
|
||||||
movx @dptr, a
|
|
||||||
dec dpl
|
|
||||||
mov a, r6
|
|
||||||
movx @dptr, a
|
|
||||||
dec dpl
|
|
||||||
mov a, r5
|
|
||||||
movx @dptr, a
|
|
||||||
dec dpl
|
|
||||||
mov a, r4
|
|
||||||
movx @dptr, a
|
|
||||||
ret
|
|
||||||
|
|
||||||
rol_b:
|
|
||||||
clr c
|
|
||||||
mov a, r7
|
|
||||||
rlc a
|
|
||||||
mov r7, a
|
|
||||||
mov a, r6
|
|
||||||
rlc a
|
|
||||||
mov r6, a
|
|
||||||
mov a, r5
|
|
||||||
rlc a
|
|
||||||
mov r5, a
|
|
||||||
mov a, r4
|
|
||||||
rlc a
|
|
||||||
mov r4, a
|
|
||||||
clr a
|
|
||||||
addc a, r7
|
|
||||||
mov r7, a
|
|
||||||
djnz dpl, rol_b
|
|
||||||
ret
|
|
||||||
|
|
||||||
print_regs:
|
|
||||||
push a
|
|
||||||
push ar6
|
|
||||||
push ar7
|
|
||||||
push dpl
|
|
||||||
mov dpl, a
|
|
||||||
lcall _print_byte
|
|
||||||
|
|
||||||
pop dpl
|
|
||||||
pop ar7
|
|
||||||
pop ar6
|
|
||||||
pop a
|
|
||||||
|
|
||||||
|
|
||||||
chacha_plus_xor:
|
|
||||||
; Load A into registers r4-r7, A pointed to by r0
|
|
||||||
mov dptr, #_chacha20
|
|
||||||
mov dpl, r0
|
|
||||||
movx a, @dptr
|
|
||||||
mov r7, a
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
mov r6, a
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
mov r5, a
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
mov r4, a
|
|
||||||
|
|
||||||
; A += B, B pointed to by r1
|
|
||||||
mov dpl, r1
|
|
||||||
movx a, @dptr
|
|
||||||
add a, r7
|
|
||||||
mov r7, a
|
|
||||||
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
addc a, r6
|
|
||||||
mov r6, a
|
|
||||||
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
addc a, r5
|
|
||||||
mov r5, a
|
|
||||||
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
addc a, r4
|
|
||||||
mov r4, a
|
|
||||||
|
|
||||||
mov dpl, r0 ; Store A back
|
|
||||||
mov a, r7
|
|
||||||
movx @dptr, a
|
|
||||||
dec dpl
|
|
||||||
mov a, r6
|
|
||||||
movx @dptr, a
|
|
||||||
dec dpl
|
|
||||||
mov a, r5
|
|
||||||
movx @dptr, a
|
|
||||||
dec dpl
|
|
||||||
mov a, r4
|
|
||||||
movx @dptr, a
|
|
||||||
|
|
||||||
; D ^= A
|
|
||||||
mov dpl, r3
|
|
||||||
movx a, @dptr
|
|
||||||
xrl a, r7
|
|
||||||
mov r7, a
|
|
||||||
dec dpl
|
|
||||||
|
|
||||||
movx a, @dptr
|
|
||||||
xrl a, r6
|
|
||||||
mov r6, a
|
|
||||||
dec dpl
|
|
||||||
|
|
||||||
movx a, @dptr
|
|
||||||
xrl a, r5
|
|
||||||
mov r5, a
|
|
||||||
dec dpl
|
|
||||||
|
|
||||||
movx a, @dptr
|
|
||||||
xrl a, r4
|
|
||||||
mov r4, a
|
|
||||||
dec dpl
|
|
||||||
ret
|
|
||||||
|
|
||||||
chacha_qr:
|
|
||||||
; QR Part: A += B; D ^= A; D = ROTL32(D, 16);
|
|
||||||
acall chacha_plus_xor
|
|
||||||
|
|
||||||
; rotate left 16. D is r4, r5, r6, r7 -> r6, r7, r4, r5
|
|
||||||
mov a, r6
|
|
||||||
xch a, r4
|
|
||||||
mov r6, a
|
|
||||||
mov a, r7
|
|
||||||
xch a, r5
|
|
||||||
mov r7, a
|
|
||||||
mov dpl, r3 ; Store D
|
|
||||||
acall store_32
|
|
||||||
|
|
||||||
;QR Part: C += D; B ^= C; B = ROTL32(B, 12);
|
|
||||||
; Swap A <-> C and D <-> B
|
|
||||||
mov a, r0
|
|
||||||
xch a, r2
|
|
||||||
mov r0, a
|
|
||||||
mov a, r1
|
|
||||||
xch a, r3
|
|
||||||
mov r1, a
|
|
||||||
acall chacha_plus_xor
|
|
||||||
|
|
||||||
; rotate left 12. D is r4, r5, r6, r7 -> r5, r6, r7, r4
|
|
||||||
mov a, r4
|
|
||||||
xch a, r7
|
|
||||||
xch a, r6
|
|
||||||
xch a, r5
|
|
||||||
mov r4, a
|
|
||||||
|
|
||||||
mov dpl, #4
|
|
||||||
acall rol_b
|
|
||||||
mov dpl, r3 ; Store D (being B)
|
|
||||||
acall store_32
|
|
||||||
|
|
||||||
; Swap A <-> C and D <-> B
|
|
||||||
mov a, r0
|
|
||||||
xch a, r2
|
|
||||||
mov r0, a
|
|
||||||
mov a, r1
|
|
||||||
xch a, r3
|
|
||||||
mov r1, a
|
|
||||||
|
|
||||||
mov dpl, r1 ; Store B
|
|
||||||
acall store_32
|
|
||||||
|
|
||||||
; QR Part A += B; D ^= A; D = ROTL32(D, 8);
|
|
||||||
acall chacha_plus_xor
|
|
||||||
mov a, r4
|
|
||||||
xch a, r7
|
|
||||||
xch a, r6
|
|
||||||
xch a, r5
|
|
||||||
mov r4, a
|
|
||||||
mov dpl, r3 ; Store D
|
|
||||||
acall store_32
|
|
||||||
|
|
||||||
; QR Part
|
|
||||||
; C += D; B ^= C; B = ROTL32(B, 7);
|
|
||||||
line4:
|
|
||||||
; Swap A <-> C and D <-> B
|
|
||||||
mov a, r0
|
|
||||||
xch a, r2
|
|
||||||
mov r0, a
|
|
||||||
mov a, r1
|
|
||||||
xch a, r3
|
|
||||||
mov r1, a
|
|
||||||
acall chacha_plus_xor
|
|
||||||
|
|
||||||
; Roll left 7 bits, start by rolling 8 bits left, then roll 1 to the right
|
|
||||||
mov a, r4
|
|
||||||
xch a, r7
|
|
||||||
xch a, r6
|
|
||||||
xch a, r5
|
|
||||||
mov r4, a
|
|
||||||
|
|
||||||
clr c
|
|
||||||
mov a, r4
|
|
||||||
rrc a
|
|
||||||
mov r4, a
|
|
||||||
mov a, r5
|
|
||||||
rrc a
|
|
||||||
mov r5, a
|
|
||||||
mov a, r6
|
|
||||||
rrc a
|
|
||||||
mov r6, a
|
|
||||||
mov a, r7
|
|
||||||
rrc a
|
|
||||||
mov r7, a
|
|
||||||
clr a
|
|
||||||
rrc a
|
|
||||||
add a, r4
|
|
||||||
mov r4, a
|
|
||||||
|
|
||||||
; Swap A <-> C and D <-> B
|
|
||||||
mov a, r0
|
|
||||||
xch a, r2
|
|
||||||
mov r0, a
|
|
||||||
mov a, r1
|
|
||||||
xch a, r3
|
|
||||||
mov r1, a
|
|
||||||
mov dpl, r1 ; Store B
|
|
||||||
acall store_32
|
|
||||||
ret
|
|
||||||
|
|
||||||
_chacha_test_1:
|
|
||||||
mov r0, #3
|
|
||||||
mov r1, #7
|
|
||||||
mov r2, #11
|
|
||||||
mov r3, #15
|
|
||||||
acall line4
|
|
||||||
ret
|
|
||||||
|
|
||||||
; QUARTERROUND(2,7,8,13)
|
|
||||||
_chacha_qr_r:
|
|
||||||
mov r0, #11
|
|
||||||
mov r1, #31
|
|
||||||
mov r2, #35
|
|
||||||
mov r3, #55
|
|
||||||
acall chacha_qr
|
|
||||||
ret
|
|
||||||
|
|
||||||
;
|
|
||||||
; Implementation of 20 ChaCha Rounds (10 Double Rounds)
|
|
||||||
;
|
|
||||||
_chacha_20:
|
|
||||||
push acc
|
|
||||||
push b
|
|
||||||
push dpl
|
|
||||||
push dph
|
|
||||||
push ar7
|
|
||||||
push ar6
|
|
||||||
push ar5
|
|
||||||
push ar4
|
|
||||||
push ar3
|
|
||||||
push ar2
|
|
||||||
push ar1
|
|
||||||
push ar0
|
|
||||||
push psw
|
|
||||||
|
|
||||||
mov b, #10 ; 10 Double rounds
|
|
||||||
chacha_20_loop:
|
|
||||||
; CHACHA_QR( v[ 0], v[ 4], v[ 8], v[12] );
|
|
||||||
mov r0, #3
|
|
||||||
mov r1, #19
|
|
||||||
mov r2, #35
|
|
||||||
mov r3, #51
|
|
||||||
acall chacha_qr
|
|
||||||
|
|
||||||
; CHACHA_QR( v[ 1], v[ 5], v[ 9], v[13] ); 7 23 39 55
|
|
||||||
mov r0, #7
|
|
||||||
mov r1, #23
|
|
||||||
mov r2, #39
|
|
||||||
mov r3, #55
|
|
||||||
acall chacha_qr
|
|
||||||
|
|
||||||
; CHACHA_QR( v[ 2], v[ 6], v[10], v[14] ); 11 27 43 59
|
|
||||||
mov r0, #11
|
|
||||||
mov r1, #27
|
|
||||||
mov r2, #43
|
|
||||||
mov r3, #59
|
|
||||||
acall chacha_qr
|
|
||||||
|
|
||||||
; CHACHA_QR( v[ 3], v[ 7], v[11], v[15] ); 15 31 47 63
|
|
||||||
mov r0, #15
|
|
||||||
mov r1, #31
|
|
||||||
mov r2, #47
|
|
||||||
mov r3, #63
|
|
||||||
acall chacha_qr
|
|
||||||
|
|
||||||
; CHACHA_QR( v[ 0], v[ 5], v[10], v[15] ); 3 23 43 63
|
|
||||||
mov r0, #3
|
|
||||||
mov r1, #23
|
|
||||||
mov r2, #43
|
|
||||||
mov r3, #63
|
|
||||||
acall chacha_qr
|
|
||||||
|
|
||||||
; CHACHA_QR( v[ 1], v[ 6], v[11], v[12] ); 7 27 47 51
|
|
||||||
mov r0, #7
|
|
||||||
mov r1, #27
|
|
||||||
mov r2, #47
|
|
||||||
mov r3, #51
|
|
||||||
acall chacha_qr
|
|
||||||
|
|
||||||
; CHACHA_QR( v[ 2], v[ 7], v[ 8], v[13] ); 11 31 35 55
|
|
||||||
mov r0, #11
|
|
||||||
mov r1, #31
|
|
||||||
mov r2, #35
|
|
||||||
mov r3, #55
|
|
||||||
acall chacha_qr
|
|
||||||
|
|
||||||
; CHACHA_QR( v[ 3], v[ 4], v[ 9], v[14] ); 15 19 39 59
|
|
||||||
mov r0, #15
|
|
||||||
mov r1, #19
|
|
||||||
mov r2, #39
|
|
||||||
mov r3, #59
|
|
||||||
acall chacha_qr
|
|
||||||
djnz b, chacha_20_loop
|
|
||||||
|
|
||||||
pop psw
|
|
||||||
pop ar0
|
|
||||||
pop ar1
|
|
||||||
pop ar2
|
|
||||||
pop ar3
|
|
||||||
pop ar4
|
|
||||||
pop ar5
|
|
||||||
pop ar6
|
|
||||||
pop ar7
|
|
||||||
pop dph
|
|
||||||
pop dpl
|
|
||||||
pop b
|
|
||||||
pop acc
|
|
||||||
ret
|
|
||||||
|
|
||||||
;
|
|
||||||
; Update ChaCHa state
|
|
||||||
;
|
|
||||||
_chacha_update:
|
|
||||||
push acc
|
|
||||||
push b
|
|
||||||
push dpl
|
|
||||||
push dph
|
|
||||||
push ar4
|
|
||||||
push ar3
|
|
||||||
push ar2
|
|
||||||
push ar1
|
|
||||||
push ar0
|
|
||||||
push psw
|
|
||||||
|
|
||||||
mov dptr, #_chacha20
|
|
||||||
mov b, #16 ; 16 uint32
|
|
||||||
update_loop:
|
|
||||||
mov a, b ; multiply by 4 and subtract 1
|
|
||||||
rl a
|
|
||||||
rl a
|
|
||||||
dec a
|
|
||||||
; Load Working State variable into registers r0-r3
|
|
||||||
mov dpl, a
|
|
||||||
|
|
||||||
orl a, #64 ; Save pointer to state
|
|
||||||
mov r4, a
|
|
||||||
|
|
||||||
movx a, @dptr
|
|
||||||
mov r3, a
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
mov r2, a
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
mov r1, a
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
mov r0, a
|
|
||||||
|
|
||||||
; Add to State variable
|
|
||||||
mov a, r4
|
|
||||||
mov dpl, a
|
|
||||||
movx a, @dptr
|
|
||||||
add a, r3
|
|
||||||
mov r3, a
|
|
||||||
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
addc a, r2
|
|
||||||
mov r2, a
|
|
||||||
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
addc a, r1
|
|
||||||
mov r1, a
|
|
||||||
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
addc a, r0
|
|
||||||
mov r0, a
|
|
||||||
|
|
||||||
; Store back state variable in LSB, first sequence (serialized)
|
|
||||||
mov a, r4
|
|
||||||
xrl a, #64 ; Save pointer to working state
|
|
||||||
mov dpl, a
|
|
||||||
mov a, r0
|
|
||||||
movx @dptr, a
|
|
||||||
dec dpl
|
|
||||||
mov a, r1
|
|
||||||
movx @dptr, a
|
|
||||||
dec dpl
|
|
||||||
mov a, r2
|
|
||||||
movx @dptr, a
|
|
||||||
dec dpl
|
|
||||||
mov a, r3
|
|
||||||
movx @dptr, a
|
|
||||||
|
|
||||||
djnz b, update_loop
|
|
||||||
|
|
||||||
pop psw
|
|
||||||
pop ar0
|
|
||||||
pop ar1
|
|
||||||
pop ar2
|
|
||||||
pop ar3
|
|
||||||
pop ar4
|
|
||||||
pop dph
|
|
||||||
pop dpl
|
|
||||||
pop b
|
|
||||||
pop acc
|
|
||||||
ret
|
|
||||||
|
|
||||||
;
|
|
||||||
; Increase counter in state
|
|
||||||
;
|
|
||||||
_chacha_count:
|
|
||||||
push acc
|
|
||||||
push dpl
|
|
||||||
push dph
|
|
||||||
mov dptr, #_chacha20
|
|
||||||
mov dpl, #112 + 3
|
|
||||||
movx a, @dptr
|
|
||||||
inc a
|
|
||||||
movx @dptr, a
|
|
||||||
jnc chacha_count_done
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
inc a
|
|
||||||
movx @dptr, a
|
|
||||||
jnc chacha_count_done
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
inc a
|
|
||||||
movx @dptr, a
|
|
||||||
jnc chacha_count_done
|
|
||||||
dec dpl
|
|
||||||
movx a, @dptr
|
|
||||||
inc a
|
|
||||||
movx @dptr, a
|
|
||||||
chacha_count_done:
|
|
||||||
pop dph
|
|
||||||
pop dpl
|
|
||||||
pop acc
|
|
||||||
ret
|
|
||||||
@@ -348,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 {
|
||||||
@@ -40,9 +40,4 @@ struct dhcp_state {
|
|||||||
|
|
||||||
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,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,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,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: 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: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 3.3 MiB |
|
After Width: | Height: | Size: 64 KiB |
@@ -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)
|
||||||
|
|||||||
@@ -79,6 +79,12 @@ vlan <VLAN-ID> d
|
|||||||
vlan show
|
vlan show
|
||||||
Dumps the current ingress vlan settings.
|
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
|
||||||
|
|
||||||
|
|||||||
@@ -164,7 +164,9 @@ function update(callback) {
|
|||||||
} 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";
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -227,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(':');
|
||||||
@@ -243,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('}');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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",
|
||||||
@@ -544,7 +596,6 @@ __code const struct machine machine = {
|
|||||||
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
||||||
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
.sfp_port[0].pin_los = GPIO37,
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
@@ -571,6 +622,162 @@ __code const struct machine machine = {
|
|||||||
|
|
||||||
void machine_custom_init(void) { }
|
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
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
/*
|
/*
|
||||||
* Select your machine type below
|
* Select your machine type below
|
||||||
*/
|
*/
|
||||||
#define MACHINE_KP_9000_6XHML_X2
|
// #define MACHINE_KP_9000_6XHML_X2
|
||||||
// #define MACHINE_KP_9000_6XH_X
|
// #define MACHINE_KP_9000_6XH_X
|
||||||
|
// #define MACHINE_KP_9000_6XH_X2
|
||||||
// #define MACHINE_KP_9000_9XH_X_EU
|
// #define MACHINE_KP_9000_9XH_X_EU
|
||||||
// #define MACHINE_KP_9000_9XHML_X_V2_2
|
// #define MACHINE_KP_9000_9XHML_X_V2_2
|
||||||
// #define MACHINE_KP_9000_9XHML_X_V3_1
|
// #define MACHINE_KP_9000_9XHML_X_V3_1
|
||||||
@@ -20,7 +21,10 @@
|
|||||||
// #define MACHINE_HI_K0402WS
|
// #define MACHINE_HI_K0402WS
|
||||||
// #define MACHINE_K0501W_V2_0
|
// #define MACHINE_K0501W_V2_0
|
||||||
// #define MACHINE_LIANGUO_ZX_SWTGW215AS
|
// #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
|
||||||
@@ -58,6 +62,7 @@ typedef struct machine {
|
|||||||
// Highest logical port number
|
// 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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -92,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.
|
||||||
*/
|
*/
|
||||||
@@ -110,6 +119,7 @@ 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);
|
||||||
@@ -118,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);
|
||||||
@@ -130,6 +141,7 @@ 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_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);
|
||||||
@@ -157,4 +169,5 @@ 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_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_mac(uint8_t sds, uint8_t mode);
|
||||||
void sds_config(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
|
||||||
|
|
||||||
|
|||||||
@@ -19,14 +19,6 @@ extern __xdata struct machine_runtime machine_detected;
|
|||||||
*/
|
*/
|
||||||
void static sds_init(void)
|
void static 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);
|
phy_read(0, PHY_MMD30, 0xd);
|
||||||
uint16_t pval = SFR_DATA_U16;
|
uint16_t pval = SFR_DATA_U16;
|
||||||
|
|
||||||
@@ -55,6 +47,8 @@ void static sds_init(void)
|
|||||||
uint16_t pval;
|
uint16_t pval;
|
||||||
|
|
||||||
print_string(" N-settings");
|
print_string(" N-settings");
|
||||||
|
if (machine.n_10g)
|
||||||
|
print_string(" - 10g");
|
||||||
// Serdes 0 RX PN swap for 64B/66B
|
// Serdes 0 RX PN swap for 64B/66B
|
||||||
sds_read(1, 6, 2);
|
sds_read(1, 6, 2);
|
||||||
pval = SFR_DATA_U16;
|
pval = SFR_DATA_U16;
|
||||||
@@ -70,19 +64,30 @@ void static sds_init(void)
|
|||||||
pval = SFR_DATA_U16;
|
pval = SFR_DATA_U16;
|
||||||
sds_write_v(0, 6, 2, pval | 0x2000);
|
sds_write_v(0, 6, 2, pval | 0x2000);
|
||||||
|
|
||||||
if (machine_detected.isRTL8373) {
|
if (!machine.n_10g) {
|
||||||
// RTL8224: Serdes 0 RX PN swap for 64B/66B
|
if (machine_detected.isRTL8373) {
|
||||||
// We assume that RTL8373N always paired with RTL8224N.
|
// RTL8224: Serdes 0 RX PN swap for 64B/66B
|
||||||
// This sds register value is 0x0000 at reset.
|
// We assume that RTL8373N always paired with RTL8224N.
|
||||||
// So only write to it.
|
// This sds register value is 0x0000 at reset.
|
||||||
RTL8224_SDS_WRITE(0, 6, 2, 0x2000);
|
// So only write to it.
|
||||||
} else {
|
RTL8224_SDS_WRITE(0, 6, 2, 0x2000);
|
||||||
// Serdes 0 RX PN swap for 8B/10B
|
} else {
|
||||||
sds_read(0, 0, 0);
|
// Serdes 0 RX PN swap for 8B/10B
|
||||||
pval = SFR_DATA_U16;
|
sds_read(0, 0, 0);
|
||||||
sds_write_v(0, 0, 0, pval | 0x200);
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -109,7 +114,7 @@ void rtl8373_init(void) __banked
|
|||||||
phy_config_8224();
|
phy_config_8224();
|
||||||
sds_config_mac(1, SDS_OFF); // Off for now until SFP+ port used
|
sds_config_mac(1, SDS_OFF); // Off for now until SFP+ port used
|
||||||
sds_config_mac(2, SDS_SGMII); // For RTL8224
|
sds_config_mac(2, SDS_SGMII); // For RTL8224
|
||||||
sds_config(0, SDS_QXGMII);
|
sds_config(0, SDS_QXGMII); // For RTL8224
|
||||||
|
|
||||||
// SDS 1 setup
|
// SDS 1 setup
|
||||||
// q012100:4902 Q012100:4906 q013605:0000 Q013605:4000 Q011f02:001f q011f15:0086
|
// q012100:4902 Q012100:4906 q013605:0000 Q013605:4000 Q011f02:001f q011f15:0086
|
||||||
@@ -163,7 +168,7 @@ void rtl8373_init(void) __banked
|
|||||||
|
|
||||||
reg_bit_set(RTL837X_REG_HW_CONF, 0);
|
reg_bit_set(RTL837X_REG_HW_CONF, 0);
|
||||||
|
|
||||||
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
|
// enable EEE for all ports at 2.5G, but don't reset the PHYs
|
||||||
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
|
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
|
||||||
|
|
||||||
// TODO: patch the PHYs
|
// TODO: patch the PHYs
|
||||||
@@ -188,14 +193,26 @@ void rtl8372_init(void) __banked
|
|||||||
print_string("\nrtl8372_init called\n");
|
print_string("\nrtl8372_init called\n");
|
||||||
|
|
||||||
sds_init();
|
sds_init();
|
||||||
phy_config(8); // PHY configuration: External 8221B?
|
if (machine.n_10g != 2)
|
||||||
phy_config(3); // PHY configuration: all internal PHYs?
|
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)
|
// 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
|
// 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);
|
if (machine.n_10g == 1) {
|
||||||
sfr_mask_data(1, 0, 0x03);
|
REG_SET(RTL837X_REG_SDS_MODES, 0x3ed); // Disable SFP for now, set RTL8261BE SDS 0 to 0xd
|
||||||
sfr_mask_data(0, 0, 0xe2);
|
} else if(machine.n_10g == 2) {
|
||||||
reg_write_m(RTL837X_REG_SDS_MODES);
|
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
|
// r0a90:000000f3 R0a90-000000fc
|
||||||
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
||||||
@@ -229,7 +246,7 @@ void rtl8372_init(void) __banked
|
|||||||
|
|
||||||
|
|
||||||
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
|
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
|
||||||
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
|
port_eee_enable_all(EEE_10G | EEE_NORESET);
|
||||||
|
|
||||||
// TODO: patch the PHYs
|
// TODO: patch the PHYs
|
||||||
|
|
||||||
|
|||||||
@@ -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');
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -442,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
|
||||||
|
|||||||
@@ -387,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');
|
||||||
|
|
||||||
@@ -440,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;
|
||||||
@@ -489,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
|
||||||
@@ -511,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
|
||||||
@@ -522,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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -532,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
|
||||||
@@ -552,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
|
||||||
@@ -570,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
|
||||||
@@ -599,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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,16 @@ struct vlan_settings {
|
|||||||
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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -24,11 +24,10 @@
|
|||||||
#include "uip/uip_arp.h"
|
#include "uip/uip_arp.h"
|
||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "phy.h"
|
#include "phy.h"
|
||||||
#include "crypto/chacha.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;
|
||||||
extern __xdata uint8_t err_status;
|
|
||||||
|
|
||||||
extern __xdata uint16_t crc_value;
|
extern __xdata uint16_t crc_value;
|
||||||
__xdata struct machine_runtime machine_detected;
|
__xdata struct machine_runtime machine_detected;
|
||||||
@@ -138,6 +137,7 @@ __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;
|
||||||
volatile __bit tx_buf_empty;
|
volatile __bit tx_buf_empty;
|
||||||
@@ -217,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);
|
||||||
@@ -231,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)
|
||||||
{
|
{
|
||||||
@@ -254,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)
|
||||||
@@ -351,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
|
||||||
@@ -868,13 +890,14 @@ void early_boot_handle_button(void)
|
|||||||
* 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
|
||||||
@@ -904,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
|
||||||
@@ -939,6 +966,30 @@ 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
|
||||||
|
|
||||||
@@ -1123,6 +1174,8 @@ 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 == 0x1 || rate == 0x2)
|
||||||
|
return SDS_100FX;
|
||||||
if (rate == 0xc || rate == 0xd)
|
if (rate == 0xc || rate == 0xd)
|
||||||
return SDS_1000BX_FIBER;
|
return SDS_1000BX_FIBER;
|
||||||
if (rate >= 0x19 && rate <= 0x20) // Ethernet 2.5 GBit
|
if (rate >= 0x19 && rate <= 0x20) // Ethernet 2.5 GBit
|
||||||
@@ -1188,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);
|
||||||
@@ -1343,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);
|
||||||
}
|
}
|
||||||
@@ -1377,7 +1442,7 @@ void idle(void)
|
|||||||
cmd_tokenize();
|
cmd_tokenize();
|
||||||
if (err_status == ERR_OK)
|
if (err_status == ERR_OK)
|
||||||
cmd_parser();
|
cmd_parser();
|
||||||
print_string("\n> ");
|
print_cmd_prompt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1638,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) {
|
||||||
@@ -1665,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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1937,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 {
|
||||||
@@ -1986,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...
|
||||||
@@ -2017,7 +2095,6 @@ void main(void)
|
|||||||
|
|
||||||
setup_i2c();
|
setup_i2c();
|
||||||
setup_sfp_gpio();
|
setup_sfp_gpio();
|
||||||
|
|
||||||
print_string(greeting);
|
print_string(greeting);
|
||||||
|
|
||||||
print_string("\nClock register: ");
|
print_string("\nClock register: ");
|
||||||
@@ -2032,7 +2109,7 @@ void main(void)
|
|||||||
early_boot_handle_button();
|
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);
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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,7 +234,7 @@ __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 */
|
||||||
|
|||||||