mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
Compare commits
94
Commits
e21ce4ce80
...
7621045de1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7621045de1 | ||
|
|
36a064d03d | ||
|
|
2d01b8b7d7 | ||
|
|
ff57084799 | ||
|
|
2dc5520928 | ||
|
|
7c11142a04 | ||
|
|
957a5b0e23 | ||
|
|
c773230a9b | ||
|
|
0e9c997d06 | ||
|
|
5ab247e996 | ||
|
|
d80717f3f0 | ||
|
|
2e24b24426 | ||
|
|
b71239f394 | ||
|
|
6e69f5bba3 | ||
|
|
1224335b66 | ||
|
|
e5b19bc594 | ||
|
|
89fcc6836d | ||
|
|
f9d4ab0074 | ||
|
|
6f68ccef28 | ||
|
|
8e687ef28e | ||
|
|
87db2dd4b8 | ||
|
|
aac1aed4c8 | ||
|
|
f0aea3dcac | ||
|
|
f10ab30f6d | ||
|
|
de431c6d84 | ||
|
|
26547f3e01 | ||
|
|
13b75a73c9 | ||
|
|
c6fceae724 | ||
|
|
068ec4c510 | ||
|
|
3a92459190 | ||
|
|
5ffeb3d16a | ||
|
|
de705380c9 | ||
|
|
e4f3315af3 | ||
|
|
07ab04e668 | ||
|
|
c5ce24ff78 | ||
|
|
bcb237158f | ||
|
|
f103daaafa | ||
|
|
168add47a3 | ||
|
|
423886dc54 | ||
|
|
4a9137387c | ||
|
|
2fc08f40d2 | ||
|
|
4a7fd7a098 | ||
|
|
19cd1200b4 | ||
|
|
333adbaf19 | ||
|
|
8051061fd7 | ||
|
|
8ae3f5e70f | ||
|
|
9ce328d155 | ||
|
|
2e463a2f30 | ||
|
|
422dc3f24d | ||
|
|
4b01ff9f8a | ||
|
|
456a4d9d3f | ||
|
|
02e9189f5f | ||
|
|
aff7d9c098 | ||
|
|
770926abd1 | ||
|
|
13f04d8acb | ||
|
|
49284fee15 | ||
|
|
db9ce7543e | ||
|
|
7a14c2d4a5 | ||
|
|
92948079a9 | ||
|
|
e406a3e82b | ||
|
|
c43b955db0 | ||
|
|
0321763e91 | ||
|
|
4bbbcd7d04 | ||
|
|
682ed861fa | ||
|
|
3a9045b97e | ||
|
|
4b9f6c319f | ||
|
|
6e2701bc8c | ||
|
|
ac3b4b17ae | ||
|
|
f87eb70c6a | ||
|
|
214cc6b737 | ||
|
|
40177f6318 | ||
|
|
d3dda09079 | ||
|
|
277e729f2c | ||
|
|
f778b9159b | ||
|
|
b6d6d2391d | ||
|
|
2c231fdf69 | ||
|
|
689751ffe6 | ||
|
|
340fdd97e5 | ||
|
|
675faf0471 | ||
|
|
175ca9464a | ||
|
|
94187461c6 | ||
|
|
fa0eb91586 | ||
|
|
2f872ea08e | ||
|
|
ab2d30a05b | ||
|
|
d37ce07119 | ||
|
|
52b1d1a4ea | ||
|
|
48f28ae7ff | ||
|
|
3c8de6da87 | ||
|
|
3a6f62b1d5 | ||
|
|
cdc84c75e4 | ||
|
|
6be1871bb4 | ||
|
|
4686515de3 | ||
|
|
3dcab09047 | ||
|
|
f0b311fc43 |
No files matched your search
@@ -26,3 +26,5 @@ jobs:
|
|||||||
run: make CI=1 MACHINE="KP_9000_6XHML_X2"
|
run: make CI=1 MACHINE="KP_9000_6XHML_X2"
|
||||||
- name: Make project (8x1/RTL8373)
|
- name: Make project (8x1/RTL8373)
|
||||||
run: make CI=1 MACHINE="KP_9000_9XHML_X_V3_1"
|
run: make CI=1 MACHINE="KP_9000_9XHML_X_V3_1"
|
||||||
|
- name: Make project with the health instrumentation
|
||||||
|
run: make clean && make CI=1 MACHINE="KP_9000_6XHML_X2" HEALTH=1
|
||||||
@@ -14,6 +14,12 @@
|
|||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
|
- Config
|
||||||
|
- A startup configuration line longer than the command buffer no longer stops the replay:
|
||||||
|
the offending line is skipped and the following lines are still applied.
|
||||||
|
- The web UI and the configuration upload now refuse a line the replay cannot take,
|
||||||
|
instead of writing it to flash.
|
||||||
|
|
||||||
## Breaking changes
|
## Breaking changes
|
||||||
|
|
||||||
- Config
|
- Config
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ ifeq ($(MACHINE),)
|
|||||||
else
|
else
|
||||||
CC_FLAGS += -DMACHINE_$(MACHINE)
|
CC_FLAGS += -DMACHINE_$(MACHINE)
|
||||||
endif
|
endif
|
||||||
|
# Health instrumentation and the "health" console command: HEALTH=1 gmake ...
|
||||||
|
ifneq ($(HEALTH),)
|
||||||
|
CC_FLAGS += -DHEALTH
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(CI),1)
|
ifeq ($(CI),1)
|
||||||
CC_FLAGS += --Werror
|
CC_FLAGS += --Werror
|
||||||
@@ -53,6 +57,7 @@ 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"
|
||||||
|
|
||||||
# Keep machine.c in first position to fail immediately on invalid $MACHINE value
|
# Keep machine.c in first position to fail immediately on invalid $MACHINE value
|
||||||
SRCS = \
|
SRCS = \
|
||||||
@@ -66,7 +71,8 @@ SRCS = \
|
|||||||
boot.c \
|
boot.c \
|
||||||
sfp.c \
|
sfp.c \
|
||||||
syslog.c \
|
syslog.c \
|
||||||
udp_apps.c
|
udp_apps.c \
|
||||||
|
crypto/chacha20.c
|
||||||
|
|
||||||
# RTL837x
|
# RTL837x
|
||||||
SRCS += \
|
SRCS += \
|
||||||
@@ -78,7 +84,8 @@ SRCS += \
|
|||||||
rtl837x_phy.c \
|
rtl837x_phy.c \
|
||||||
rtl837x_pins.c\
|
rtl837x_pins.c\
|
||||||
rtl837x_port.c \
|
rtl837x_port.c \
|
||||||
rtl837x_stp.c
|
rtl837x_stp.c \
|
||||||
|
rtl837x_storm.c
|
||||||
SRCS += \
|
SRCS += \
|
||||||
httpd/httpd.c \
|
httpd/httpd.c \
|
||||||
httpd/page_impl.c
|
httpd/page_impl.c
|
||||||
@@ -108,11 +115,14 @@ html_min: $(HTML)
|
|||||||
html_data.c html_data.h &: $(HTML) | tools html_min
|
html_data.c html_data.h &: $(HTML) | tools html_min
|
||||||
tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -z -d $(HTML_MIN) -p html_data
|
tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -z -d $(HTML_MIN) -p html_data
|
||||||
|
|
||||||
$(VERSION_HEADER):
|
$(VERSION_HEADER): FORCE
|
||||||
@printf '%s\n' "#ifndef VERSION_H" "#define VERSION_H" \
|
@printf '%s\n' "#ifndef VERSION_H" "#define VERSION_H" \
|
||||||
"#define VERSION_SW \"$(VERSION_EXTENSION)\"" \
|
"#define VERSION_SW \"$(VERSION_EXTENSION)\"" \
|
||||||
"#define BUILD_DATE \"$(BUILD_DATE)\"" \
|
"#define BUILD_DATE \"$(BUILD_DATE)\"" \
|
||||||
"#endif" > $(VERSION_HEADER)
|
"#endif" > $(VERSION_HEADER).tmp
|
||||||
|
@cmp -s $(VERSION_HEADER).tmp $(VERSION_HEADER) \
|
||||||
|
&& rm -f $(VERSION_HEADER).tmp \
|
||||||
|
|| mv $(VERSION_HEADER).tmp $(VERSION_HEADER)
|
||||||
|
|
||||||
httpd: html_data.h
|
httpd: html_data.h
|
||||||
|
|
||||||
@@ -130,14 +140,24 @@ distclean: $(SUBDIRSCLEAN)
|
|||||||
$(SUBDIRSCLEAN):
|
$(SUBDIRSCLEAN):
|
||||||
$(MAKE) -C $(@:clean=) clean
|
$(MAKE) -C $(@:clean=) clean
|
||||||
|
|
||||||
$(BUILDDIR)/%.rel: %.c | create_build_dir html_data.h
|
# Objects depend on the flags they were built with, through a stamp file that
|
||||||
|
# is rewritten only when CC_FLAGS actually changes.
|
||||||
|
CCFLAGS_STAMP := $(BUILDDIR)/.ccflags
|
||||||
|
|
||||||
|
.PHONY: FORCE
|
||||||
|
FORCE:
|
||||||
|
|
||||||
|
$(CCFLAGS_STAMP): FORCE | create_build_dir
|
||||||
|
@echo '$(CC_FLAGS)' | cmp -s - $@ 2>/dev/null || echo '$(CC_FLAGS)' > $@
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.rel: %.c $(CCFLAGS_STAMP) | create_build_dir html_data.h
|
||||||
$(CC) -MMD $(CC_FLAGS) -o $@ -c $<
|
$(CC) -MMD $(CC_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
$(BUILDDIR)/%.rel: %.asm | create_build_dir
|
$(BUILDDIR)/%.rel: %.asm $(CCFLAGS_STAMP) | create_build_dir
|
||||||
${ASM} ${AFLAGS} -o $@ $<
|
${ASM} ${AFLAGS} -o $@ $<
|
||||||
# mv -f $(addprefix $(basename $^), .lst .rel .sym) .
|
# mv -f $(addprefix $(basename $^), .lst .rel .sym) .
|
||||||
|
|
||||||
$(BUILDDIR)/rtlplayground.ihx: $(OBJS) $(BUILDDIR)/crtbank.rel $(BUILDDIR)/crc16.rel
|
$(BUILDDIR)/rtlplayground.ihx: $(OBJS) $(BUILDDIR)/crtbank.rel $(BUILDDIR)/crc16.rel $(BUILDDIR)/crypto/chacha_8051.rel
|
||||||
$(CC) $(CC_FLAGS) --xram-size 49151 -Wl-bHOME=0x00000 -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-bBANK3=0x34000 -Wl-r -o $@ $^
|
$(CC) $(CC_FLAGS) --xram-size 49151 -Wl-bHOME=0x00000 -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-bBANK3=0x34000 -Wl-r -o $@ $^
|
||||||
|
|
||||||
$(BUILDDIR)/rtlplayground.img: $(BUILDDIR)/rtlplayground.ihx
|
$(BUILDDIR)/rtlplayground.img: $(BUILDDIR)/rtlplayground.ihx
|
||||||
@@ -148,11 +168,11 @@ $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.i
|
|||||||
tools/output/imagebuilder -i $^ $@
|
tools/output/imagebuilder -i $^ $@
|
||||||
tools/output/fileadder -a $(DEFAULT_CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
tools/output/fileadder -a $(DEFAULT_CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
||||||
tools/output/fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
tools/output/fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
||||||
tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -z -d $(HTML_MIN) -p html_data -b BANK1 $@
|
tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -z -d $(HTML_MIN) -b BANK1 $@
|
||||||
tools/output/crc_calculator -u $@
|
tools/output/crc_calculator -u $@
|
||||||
ln -sf $(MACHINE)/rtlplayground-$(FILENAME_EXTENSION).bin output/rtlplayground.bin
|
ln -sf $(MACHINE)/rtlplayground-$(FILENAME_EXTENSION).bin output/rtlplayground.bin
|
||||||
|
|
||||||
.PHONY: clean distclean all $(SUBDIRS) $(SUBDIRSCLEAN) $(VERSION_HEADER) create_build_dir
|
.PHONY: clean distclean all $(SUBDIRS) $(SUBDIRSCLEAN) create_build_dir
|
||||||
|
|
||||||
.PHONY:
|
.PHONY:
|
||||||
machine_check:
|
machine_check:
|
||||||
|
|||||||
@@ -344,6 +344,7 @@ netmask zzz.zzz.zzz.zzz = Network mask of the switch
|
|||||||
port x name xxx = Name xxx the port number x
|
port x name xxx = Name xxx the port number x
|
||||||
port z 1g = Set 1g speed for port z
|
port z 1g = Set 1g speed for port z
|
||||||
igmp on/off = Turn IGMP on or off
|
igmp on/off = Turn IGMP on or off
|
||||||
|
session xxxx = Web session timeout in seconds (default 200)
|
||||||
```
|
```
|
||||||
[To be continue]
|
[To be continue]
|
||||||
|
|
||||||
@@ -359,4 +360,5 @@ The following documents give further documentation on specific features of the R
|
|||||||
- [SFP+ ports](doc/sfp.md)
|
- [SFP+ ports](doc/sfp.md)
|
||||||
- [Trunking aka. port aggregation](doc/trunking.md)
|
- [Trunking aka. port aggregation](doc/trunking.md)
|
||||||
- [VLAN](doc/vlan.md)
|
- [VLAN](doc/vlan.md)
|
||||||
|
- [Storm control](doc/storm_control.md)
|
||||||
- [Modifications and Flash replacement](doc/mods.md)
|
- [Modifications and Flash replacement](doc/mods.md)
|
||||||
@@ -21,6 +21,7 @@ extern __code const struct machine machine;
|
|||||||
extern __xdata struct machine_runtime machine_detected;
|
extern __xdata struct machine_runtime machine_detected;
|
||||||
extern __xdata uint8_t sfr_data[4];
|
extern __xdata uint8_t sfr_data[4];
|
||||||
extern volatile __xdata uint32_t ticks;
|
extern volatile __xdata uint32_t ticks;
|
||||||
|
__xdata uint32_t rtl8224_release_tick;
|
||||||
extern __xdata uint8_t tx_seq;
|
extern __xdata uint8_t tx_seq;
|
||||||
extern __code const uint8_t * __code const hex;
|
extern __code const uint8_t * __code const hex;
|
||||||
|
|
||||||
@@ -240,10 +241,10 @@ void rtl8224_enable(void) __banked
|
|||||||
reg_bit_clear(RTL837X_REG_GPIO_32_63_OUTPUT, 4);
|
reg_bit_clear(RTL837X_REG_GPIO_32_63_OUTPUT, 4);
|
||||||
// Configure Pin as output
|
// Configure Pin as output
|
||||||
reg_bit_set(RTL837X_REG_GPIO_32_63_DIRECTION, 4);
|
reg_bit_set(RTL837X_REG_GPIO_32_63_DIRECTION, 4);
|
||||||
delay(100);
|
delay(4);
|
||||||
// Set pin 4 high
|
// Set pin 4 high
|
||||||
reg_bit_set(RTL837X_REG_GPIO_32_63_OUTPUT, 4);
|
reg_bit_set(RTL837X_REG_GPIO_32_63_OUTPUT, 4);
|
||||||
delay(500);
|
rtl8224_release_tick = ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+290
-13
@@ -5,6 +5,8 @@
|
|||||||
// #define DEBUG
|
// #define DEBUG
|
||||||
// #define REGDBG 1
|
// #define REGDBG 1
|
||||||
|
|
||||||
|
#include <8051.h>
|
||||||
|
#include "cmd_parser.h"
|
||||||
#include "rtl837x_common.h"
|
#include "rtl837x_common.h"
|
||||||
#include "rtl837x_port.h"
|
#include "rtl837x_port.h"
|
||||||
#include "rtl837x_flash.h"
|
#include "rtl837x_flash.h"
|
||||||
@@ -14,6 +16,7 @@
|
|||||||
#include "rtl837x_stp.h"
|
#include "rtl837x_stp.h"
|
||||||
#include "rtl837x_igmp.h"
|
#include "rtl837x_igmp.h"
|
||||||
#include "rtl837x_bandwidth.h"
|
#include "rtl837x_bandwidth.h"
|
||||||
|
#include "rtl837x_storm.h"
|
||||||
#include "sfp.h"
|
#include "sfp.h"
|
||||||
#include "dhcp.h"
|
#include "dhcp.h"
|
||||||
#include "syslog.h"
|
#include "syslog.h"
|
||||||
@@ -41,6 +44,8 @@ extern __xdata struct flash_region_t flash_region;
|
|||||||
|
|
||||||
extern __xdata char passwd[21];
|
extern __xdata char passwd[21];
|
||||||
|
|
||||||
|
extern __xdata uint16_t session_timeout;
|
||||||
|
|
||||||
extern __xdata struct dhcp_state dhcp_state;
|
extern __xdata struct dhcp_state dhcp_state;
|
||||||
|
|
||||||
__xdata uint8_t vlan_names[VLAN_NAMES_SIZE];
|
__xdata uint8_t vlan_names[VLAN_NAMES_SIZE];
|
||||||
@@ -59,7 +64,6 @@ __xdata uint8_t hexvalue[4] = { 0 };
|
|||||||
|
|
||||||
// Buffer for writing to flash 0x1fd000, copy to 0x1fe000
|
// Buffer for writing to flash 0x1fd000, copy to 0x1fe000
|
||||||
__xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
__xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
||||||
__xdata uint8_t cmd_available;
|
|
||||||
|
|
||||||
__xdata char save_cmd;
|
__xdata char save_cmd;
|
||||||
|
|
||||||
@@ -893,10 +897,13 @@ void parse_port(void)
|
|||||||
print_string_x(port_names[phy_settings.port]);
|
print_string_x(port_names[phy_settings.port]);
|
||||||
if (!machine.is_sfp[phy_settings.port]) {
|
if (!machine.is_sfp[phy_settings.port]) {
|
||||||
phy_show(phy_settings.port);
|
phy_show(phy_settings.port);
|
||||||
|
} else {
|
||||||
|
write_char('\n');
|
||||||
}
|
}
|
||||||
|
port_media_show(phy_settings.port);
|
||||||
} else if (cmd_compare(2, "name")) {
|
} else if (cmd_compare(2, "name")) {
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
while ( (i < PORT_NAME_SIZE-1) && (cmd_buffer[cmd_words_b[3] + i] != NUL) ) {
|
while ( cmd_words_len > 3 && (i < PORT_NAME_SIZE-1) && (cmd_buffer[cmd_words_b[3] + i] != NUL) ) {
|
||||||
port_names[phy_settings.port][i] = name_char(cmd_buffer[cmd_words_b[3] + i]);
|
port_names[phy_settings.port][i] = name_char(cmd_buffer[cmd_words_b[3] + i]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -1165,6 +1172,32 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void print_temperature(uint16_t reg)
|
||||||
|
{
|
||||||
|
int16_t v;
|
||||||
|
|
||||||
|
reg_read(reg);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (v < 0) {
|
||||||
|
write_char('-');
|
||||||
|
v = -v;
|
||||||
|
}
|
||||||
|
itoa(v >> 7);
|
||||||
|
write_char('.');
|
||||||
|
itoa(((v & 0x7f) * 10) >> 7);
|
||||||
|
print_string(" C\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void parse_temp(void)
|
||||||
|
{
|
||||||
|
print_string("\nChip temperature: ");
|
||||||
|
print_temperature(RTL837X_TM_RESULT);
|
||||||
|
print_string("At power-on: ");
|
||||||
|
print_temperature(RTL837X_TM_RESULT_POWERON);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void parse_sdsget(void)
|
void parse_sdsget(void)
|
||||||
{
|
{
|
||||||
__xdata uint8_t sds_id, page, reg, hex_size;
|
__xdata uint8_t sds_id, page, reg, hex_size;
|
||||||
@@ -1541,6 +1574,57 @@ err:
|
|||||||
cmd_error("bw [in|out|status] <port> [<hexvalue>|off|drop|fc]\n");
|
cmd_error("bw [in|out|status] <port> [<hexvalue>|off|drop|fc]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __code const char * __code const storm_types[STORM_TYPES] = { "bcast", "mcast", "ucast", "umcast" };
|
||||||
|
|
||||||
|
void parse_storm(void)
|
||||||
|
{
|
||||||
|
uint8_t port, type, d;
|
||||||
|
__xdata uint32_t rate;
|
||||||
|
__xdata uint8_t *p;
|
||||||
|
|
||||||
|
if (cmd_words_len == 1)
|
||||||
|
return storm_show();
|
||||||
|
if (cmd_words_len < 4 || !cmd_parse_port_separator(cmd_words_b[1]))
|
||||||
|
goto err;
|
||||||
|
port = atoi_results_u8;
|
||||||
|
|
||||||
|
type = 0;
|
||||||
|
while (!cmd_compare(2, storm_types[type])) {
|
||||||
|
if (++type == STORM_TYPES)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd_words_len == 4 && cmd_compare(3, "off"))
|
||||||
|
return storm_off(port, type);
|
||||||
|
if (cmd_words_len != 5)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
rate = 0;
|
||||||
|
p = &cmd_buffer[cmd_words_b[3]];
|
||||||
|
do {
|
||||||
|
d = *p++ - '0';
|
||||||
|
if (d > 9 || rate > 99999999)
|
||||||
|
goto err;
|
||||||
|
rate = (rate << 3) + (rate << 1) + d;
|
||||||
|
} while (*p != ' ' && *p != NUL);
|
||||||
|
|
||||||
|
if (cmd_compare(4, "pps")) {
|
||||||
|
if (!rate || rate > 0xfffff)
|
||||||
|
goto err;
|
||||||
|
storm_set(port, type, rate, 1);
|
||||||
|
} else if (cmd_compare(4, "kbps")) {
|
||||||
|
if (!rate || rate > 10000000)
|
||||||
|
goto err;
|
||||||
|
storm_set(port, type, rate, 0);
|
||||||
|
} else {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
err:
|
||||||
|
print_string("usage: storm [<port> bcast|mcast|ucast|umcast <rate> pps|kbps|off]\n");
|
||||||
|
}
|
||||||
|
|
||||||
void parse_syslog(void)
|
void parse_syslog(void)
|
||||||
{
|
{
|
||||||
if (cmd_words_len < 2) // no argument -> print status
|
if (cmd_words_len < 2) // no argument -> print status
|
||||||
@@ -1609,6 +1693,25 @@ void parse_syslog(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void parse_session(void)
|
||||||
|
{
|
||||||
|
if (cmd_words_len >= 2) {
|
||||||
|
/* atoi_short() returns zero for no digits and for a value past
|
||||||
|
* 65535; a zero-second timeout is not useful either, so both
|
||||||
|
* tests are needed. */
|
||||||
|
if (!atoi_short(cmd_words_b[1]) || !atoi_results_short) {
|
||||||
|
print_string("Must be 1-65535 s\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
session_timeout = atoi_results_short;
|
||||||
|
}
|
||||||
|
/* Also the confirmation after setting: one message for both. */
|
||||||
|
print_string("Session timeout: ");
|
||||||
|
itoa_short(session_timeout);
|
||||||
|
print_string(" s\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.
|
||||||
@@ -1847,6 +1950,10 @@ void cmd_parser(void) __banked
|
|||||||
}
|
}
|
||||||
} else if (cmd_compare(0, "stp")) {
|
} else if (cmd_compare(0, "stp")) {
|
||||||
stp_parse();
|
stp_parse();
|
||||||
|
#ifdef HEALTH
|
||||||
|
} else if (cmd_compare(0, "health")) {
|
||||||
|
health_show();
|
||||||
|
#endif
|
||||||
} else if (cmd_compare(0, "pvid")) {
|
} else if (cmd_compare(0, "pvid")) {
|
||||||
if (cmd_words_len == 3 && cmd_parse_port_separator(cmd_words_b[1]) != 0
|
if (cmd_words_len == 3 && cmd_parse_port_separator(cmd_words_b[1]) != 0
|
||||||
&& atoi_short(cmd_words_b[2]) && atoi_results_short && atoi_results_short <= 4094)
|
&& atoi_short(cmd_words_b[2]) && atoi_results_short && atoi_results_short <= 4094)
|
||||||
@@ -1889,6 +1996,10 @@ void cmd_parser(void) __banked
|
|||||||
parse_eee();
|
parse_eee();
|
||||||
} else if (cmd_compare(0, "bw")) {
|
} else if (cmd_compare(0, "bw")) {
|
||||||
parse_bw();
|
parse_bw();
|
||||||
|
} else if (cmd_compare(0, "temp")) {
|
||||||
|
parse_temp();
|
||||||
|
} else if (cmd_compare(0, "storm")) {
|
||||||
|
parse_storm();
|
||||||
} else if (cmd_compare(0, "version")) {
|
} else if (cmd_compare(0, "version")) {
|
||||||
print_sw_version();
|
print_sw_version();
|
||||||
} else if (cmd_compare(0, "time")) {
|
} else if (cmd_compare(0, "time")) {
|
||||||
@@ -1911,6 +2022,8 @@ void cmd_parser(void) __banked
|
|||||||
}
|
}
|
||||||
} else if (cmd_compare(0, "ingress")) {
|
} else if (cmd_compare(0, "ingress")) {
|
||||||
parse_ingress();
|
parse_ingress();
|
||||||
|
} else if (cmd_compare(0, "session")) {
|
||||||
|
parse_session();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cmd_error("Unknown command\n");
|
cmd_error("Unknown command\n");
|
||||||
@@ -1962,6 +2075,7 @@ void execute_config(void) __banked
|
|||||||
save_cmd = 0;
|
save_cmd = 0;
|
||||||
|
|
||||||
uint8_t cmd_idx = 0;
|
uint8_t cmd_idx = 0;
|
||||||
|
uint8_t skipping = 0;
|
||||||
do {
|
do {
|
||||||
flash_region.addr = pos;
|
flash_region.addr = pos;
|
||||||
flash_region.len = FLASH_READ_BURST_SIZE;
|
flash_region.len = FLASH_READ_BURST_SIZE;
|
||||||
@@ -1972,20 +2086,23 @@ void execute_config(void) __banked
|
|||||||
do {
|
do {
|
||||||
if (cmd_idx >= (CMD_BUF_SIZE - 1)) {
|
if (cmd_idx >= (CMD_BUF_SIZE - 1)) {
|
||||||
cmd_buffer[cmd_idx] = NUL;
|
cmd_buffer[cmd_idx] = NUL;
|
||||||
print_string("ERROR: Command too long: ");
|
print_string("ERROR: Command too long, skipped: ");
|
||||||
print_string_x(cmd_buffer);
|
print_string_x(cmd_buffer);
|
||||||
write_char('\n');
|
write_char('\n');
|
||||||
err_status = ERR_CMD_TOO_LONG;
|
cmd_idx = 0;
|
||||||
goto config_done;
|
skipping = 1;
|
||||||
}
|
}
|
||||||
c = flash_buf[cfg_idx++];
|
c = flash_buf[cfg_idx++];
|
||||||
if (c == 0 || c == '\n') {
|
if (c == 0 || c == '\n') {
|
||||||
cmd_buffer[cmd_idx] = NUL;
|
if (skipping) {
|
||||||
if (cmd_idx) {
|
skipping = 0;
|
||||||
cmd_tokenize();
|
} else {
|
||||||
if (err_status != ERR_OK)
|
cmd_buffer[cmd_idx] = NUL;
|
||||||
goto config_done;
|
if (cmd_idx) {
|
||||||
cmd_parser();
|
cmd_tokenize();
|
||||||
|
if (err_status == ERR_OK)
|
||||||
|
cmd_parser();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
goto config_done;
|
goto config_done;
|
||||||
@@ -1993,8 +2110,10 @@ void execute_config(void) __banked
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_buffer[cmd_idx] = c;
|
if (!skipping) {
|
||||||
cmd_idx++;
|
cmd_buffer[cmd_idx] = c;
|
||||||
|
cmd_idx++;
|
||||||
|
}
|
||||||
} while (cfg_idx);
|
} while (cfg_idx);
|
||||||
|
|
||||||
pages_left--;
|
pages_left--;
|
||||||
@@ -2045,3 +2164,161 @@ void execute_commands(__xdata uint8_t *p) __banked {
|
|||||||
p++;
|
p++;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HEALTH
|
||||||
|
/*
|
||||||
|
* Health instrumentation. The counters live in xdata and are fed from the
|
||||||
|
* main loop through the banked entry points below; the "health" command
|
||||||
|
* prints everything in one go. All figures are raw hex, diffing two dumps
|
||||||
|
* gives the rates. Phase times are in system ticks (SYS_TICK_HZ = 200,
|
||||||
|
* 5 ms each); a phase counts as slow when it spans 2 or more ticks.
|
||||||
|
*/
|
||||||
|
extern __xdata uint16_t len_left; /* httpd: bytes still to send of the current file */
|
||||||
|
extern __xdata uint8_t entry; /* httpd: index of the file being sent */
|
||||||
|
|
||||||
|
static __xdata uint32_t health_loops;
|
||||||
|
__xdata uint16_t health_rx_frames;
|
||||||
|
|
||||||
|
static __xdata uint16_t ph_last_t;
|
||||||
|
static __xdata uint8_t ph_max[HEALTH_PHASES];
|
||||||
|
static __xdata uint16_t ph_slow[HEALTH_PHASES];
|
||||||
|
|
||||||
|
/* The ISR increments ticks between the two byte reads of a 16-bit load, so
|
||||||
|
* read until two loads agree. */
|
||||||
|
static uint16_t ticks_lo(void)
|
||||||
|
{
|
||||||
|
uint16_t a, b;
|
||||||
|
a = (uint16_t)ticks;
|
||||||
|
do {
|
||||||
|
b = a;
|
||||||
|
a = (uint16_t)ticks;
|
||||||
|
} while (a != b);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void health_loop_start(void) __banked
|
||||||
|
{
|
||||||
|
health_loops++;
|
||||||
|
ph_last_t = ticks_lo();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void health_phase(uint8_t id) __banked
|
||||||
|
{
|
||||||
|
__xdata uint16_t now = ticks_lo();
|
||||||
|
__xdata uint16_t d = now - ph_last_t;
|
||||||
|
ph_last_t = now;
|
||||||
|
if (d > 0xff)
|
||||||
|
d = 0xff;
|
||||||
|
if ((uint8_t)d > ph_max[id])
|
||||||
|
ph_max[id] = d;
|
||||||
|
if (d >= 2)
|
||||||
|
ph_slow[id]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Fill the stack area above the current frame with a pattern; the dump scans
|
||||||
|
* for how much of it survived. The 8051 stack grows upward, so everything
|
||||||
|
* above SP is free at this point. Interrupts are held off so an ISR does not
|
||||||
|
* push into the area mid-paint. */
|
||||||
|
void health_stack_paint(void) __banked
|
||||||
|
{
|
||||||
|
__xdata uint8_t from = SP + 4;
|
||||||
|
__xdata uint8_t ea = EA;
|
||||||
|
EA = 0;
|
||||||
|
for (uint8_t i = 0xff; i >= from; i--)
|
||||||
|
*(__idata uint8_t *)i = 0xa5;
|
||||||
|
EA = ea;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ph_line(__code const char *name, uint8_t id)
|
||||||
|
{
|
||||||
|
print_string(name);
|
||||||
|
print_string(" max ");
|
||||||
|
print_byte(ph_max[id]);
|
||||||
|
print_string(" slow ");
|
||||||
|
print_short(ph_slow[id]);
|
||||||
|
write_char('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void health_show(void) __banked
|
||||||
|
{
|
||||||
|
__xdata uint8_t i;
|
||||||
|
|
||||||
|
print_string("up ");
|
||||||
|
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
||||||
|
print_byte(sfr_data[0]); print_byte(sfr_data[1]);
|
||||||
|
print_byte(sfr_data[2]); print_byte(sfr_data[3]);
|
||||||
|
print_string(" ticks ");
|
||||||
|
print_long(ticks);
|
||||||
|
print_string(" loops ");
|
||||||
|
print_long(health_loops);
|
||||||
|
print_string(" rx ");
|
||||||
|
print_short(health_rx_frames);
|
||||||
|
write_char('\n');
|
||||||
|
|
||||||
|
/* Phase timing: max duration seen (ticks of 5 ms) and slow-pass count */
|
||||||
|
ph_line("link", HEALTH_PH_LINK);
|
||||||
|
ph_line("sfp ", HEALTH_PH_SFP);
|
||||||
|
ph_line("rx ", HEALTH_PH_RX);
|
||||||
|
ph_line("tx ", HEALTH_PH_TX);
|
||||||
|
ph_line("stp ", HEALTH_PH_STP);
|
||||||
|
ph_line("cmd ", HEALTH_PH_CMD);
|
||||||
|
|
||||||
|
/* Stack: current depth plus how much of the painted area is untouched */
|
||||||
|
print_string("sp ");
|
||||||
|
print_byte(SP);
|
||||||
|
print_string(" untouched ");
|
||||||
|
i = 0;
|
||||||
|
while (*(__idata uint8_t *)(0xff - i) == 0xa5 && i < 0x86)
|
||||||
|
i++;
|
||||||
|
print_byte(i);
|
||||||
|
write_char('\n');
|
||||||
|
|
||||||
|
/* The TCP connection slot. One on this configuration; a build with more
|
||||||
|
* has to say which slot each line is, so make that a visible decision. */
|
||||||
|
#if UIP_CONNS != 1
|
||||||
|
#error "health: the tcp dump prints a single slot, extend it for UIP_CONNS > 1"
|
||||||
|
#endif
|
||||||
|
i = 0;
|
||||||
|
{
|
||||||
|
print_string("tcp ");
|
||||||
|
print_string("st ");
|
||||||
|
print_byte(uip_conns[i].tcpstateflags);
|
||||||
|
print_string(" tmr ");
|
||||||
|
print_byte(uip_conns[i].timer);
|
||||||
|
print_string(" rtx ");
|
||||||
|
print_byte(uip_conns[i].nrtx);
|
||||||
|
print_string(" rto ");
|
||||||
|
print_byte(uip_conns[i].rto);
|
||||||
|
print_string(" len ");
|
||||||
|
print_short(uip_conns[i].len);
|
||||||
|
print_string(" mss ");
|
||||||
|
print_short(uip_conns[i].mss);
|
||||||
|
write_char('\n');
|
||||||
|
print_string(" lport ");
|
||||||
|
print_short(HTONS(uip_conns[i].lport));
|
||||||
|
print_string(" rport ");
|
||||||
|
print_short(HTONS(uip_conns[i].rport));
|
||||||
|
print_string(" rip ");
|
||||||
|
print_short(HTONS(uip_conns[i].ripaddr[0]));
|
||||||
|
write_char(' ');
|
||||||
|
print_short(HTONS(uip_conns[i].ripaddr[1]));
|
||||||
|
write_char('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* httpd transfer state and the protocol flags */
|
||||||
|
print_string("httpd left ");
|
||||||
|
print_short(len_left);
|
||||||
|
print_string(" entry ");
|
||||||
|
print_byte(entry);
|
||||||
|
print_string(" stp ");
|
||||||
|
print_byte(stp_enabled);
|
||||||
|
print_string(" mvlan ");
|
||||||
|
print_short(management_vlan);
|
||||||
|
write_char('\n');
|
||||||
|
}
|
||||||
|
#endif
|
||||||
+27
-1
@@ -6,9 +6,35 @@
|
|||||||
#include "rtl837x_common.h"
|
#include "rtl837x_common.h"
|
||||||
|
|
||||||
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 __bit __at(0x03) cmd_available;
|
||||||
extern __xdata uint8_t err_status;
|
extern __xdata uint8_t err_status;
|
||||||
|
|
||||||
|
/* Health instrumentation, built with HEALTH=1. Without it the hooks below
|
||||||
|
* compile to nothing and the "health" command does not exist. */
|
||||||
|
#ifdef HEALTH
|
||||||
|
/* Phase ids, in main-loop order */
|
||||||
|
#define HEALTH_PH_LINK 0
|
||||||
|
#define HEALTH_PH_SFP 1
|
||||||
|
#define HEALTH_PH_RX 2
|
||||||
|
#define HEALTH_PH_TX 3
|
||||||
|
#define HEALTH_PH_STP 4
|
||||||
|
#define HEALTH_PH_CMD 5
|
||||||
|
#define HEALTH_PHASES 6
|
||||||
|
|
||||||
|
extern __xdata uint16_t health_rx_frames;
|
||||||
|
#define health_rx_frame() health_rx_frames++
|
||||||
|
|
||||||
|
void health_loop_start(void) __banked; /* once per idle() pass, resets the phase baseline */
|
||||||
|
void health_phase(uint8_t id) __banked; /* after each phase; accounts ticks since last checkpoint */
|
||||||
|
void health_stack_paint(void) __banked; /* paint the unused stack area once at boot */
|
||||||
|
void health_show(void) __banked; /* "health" CLI dump */
|
||||||
|
#else
|
||||||
|
#define health_rx_frame()
|
||||||
|
#define health_loop_start()
|
||||||
|
#define health_phase(id)
|
||||||
|
#define health_stack_paint()
|
||||||
|
#endif
|
||||||
|
|
||||||
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;
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#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
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
#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(0xbf00) 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(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,455 @@
|
|||||||
|
; ChaCha Quater-Round implementation in Assembler
|
||||||
|
.module chacha_8051
|
||||||
|
; Global variables:
|
||||||
|
.globl _chacha_20
|
||||||
|
.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
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
; 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
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; 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
|
||||||
|
jnz chacha_count_done
|
||||||
|
dec dpl
|
||||||
|
movx a, @dptr
|
||||||
|
inc a
|
||||||
|
movx @dptr, a
|
||||||
|
jnz chacha_count_done
|
||||||
|
dec dpl
|
||||||
|
movx a, @dptr
|
||||||
|
inc a
|
||||||
|
movx @dptr, a
|
||||||
|
jnz chacha_count_done
|
||||||
|
dec dpl
|
||||||
|
movx a, @dptr
|
||||||
|
inc a
|
||||||
|
movx @dptr, a
|
||||||
|
chacha_count_done:
|
||||||
|
pop dph
|
||||||
|
pop dpl
|
||||||
|
pop acc
|
||||||
|
ret
|
||||||
@@ -139,7 +139,6 @@ void dhcp_addopt_request_ip(void)
|
|||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[1];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[1];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[2];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[2];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[3];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[3];
|
||||||
memcpy(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -151,13 +150,11 @@ void dhcp_addopt_server_id(void)
|
|||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[1];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[1];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[2];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[2];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[3];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[3];
|
||||||
memcpy(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dhcp_send_discover(void)
|
void dhcp_send_discover(void)
|
||||||
{
|
{
|
||||||
print_string("dhcp_send_discover called\n");
|
|
||||||
dhcp_prepare_request();
|
dhcp_prepare_request();
|
||||||
|
|
||||||
dhcp_state.opt_ptr = 0;
|
dhcp_state.opt_ptr = 0;
|
||||||
@@ -193,7 +190,6 @@ void dhcp_send_discover(void)
|
|||||||
|
|
||||||
void dhcp_send_request(void)
|
void dhcp_send_request(void)
|
||||||
{
|
{
|
||||||
print_string("dhcp_send_request called\n");
|
|
||||||
dhcp_prepare_request();
|
dhcp_prepare_request();
|
||||||
|
|
||||||
dhcp_state.opt_ptr = 0;
|
dhcp_state.opt_ptr = 0;
|
||||||
@@ -232,19 +228,21 @@ void ip_opt(__xdata uint8_t * ip)
|
|||||||
{
|
{
|
||||||
dhcp_state.opt_ptr++;
|
dhcp_state.opt_ptr++;
|
||||||
uint8_t len = DHCP_OPT[dhcp_state.opt_ptr++];
|
uint8_t len = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
if (len >= 4)
|
||||||
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
memcpy(ip, &DHCP_OPT[dhcp_state.opt_ptr], 4);
|
||||||
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
|
||||||
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
|
||||||
// There may be more than one IP option, such as 2 DNS servers advertised
|
// There may be more than one IP option, such as 2 DNS servers advertised
|
||||||
dhcp_state.opt_ptr += len - 4;
|
dhcp_state.opt_ptr += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void long_opt(void)
|
uint8_t long_opt(void)
|
||||||
{
|
{
|
||||||
dhcp_state.opt_ptr++;
|
dhcp_state.opt_ptr++;
|
||||||
dhcp_state.opt_ptr++;
|
uint8_t len = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
|
if (len < 4) {
|
||||||
|
dhcp_state.opt_ptr += len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
long_value = DHCP_OPT[dhcp_state.opt_ptr++];
|
long_value = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
long_value <<= 8;
|
long_value <<= 8;
|
||||||
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
@@ -252,6 +250,8 @@ void long_opt(void)
|
|||||||
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
long_value <<= 8;
|
long_value <<= 8;
|
||||||
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
|
dhcp_state.opt_ptr += len - 4;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -275,16 +275,16 @@ void parse_opts(void)
|
|||||||
ip_opt(&dhcp_state.broadcast[0]);
|
ip_opt(&dhcp_state.broadcast[0]);
|
||||||
break;
|
break;
|
||||||
case DHCP_LEASE:
|
case DHCP_LEASE:
|
||||||
long_opt();
|
if (long_opt())
|
||||||
dhcp_state.lease = long_value;
|
dhcp_state.lease = long_value;
|
||||||
break;
|
break;
|
||||||
case DHCP_REBIND:
|
case DHCP_REBIND:
|
||||||
long_opt();
|
if (long_opt())
|
||||||
dhcp_state.rebind = long_value;
|
dhcp_state.rebind = long_value;
|
||||||
break;
|
break;
|
||||||
case DHCP_RENEWAL:
|
case DHCP_RENEWAL:
|
||||||
long_opt();
|
if (long_opt())
|
||||||
dhcp_state.renewal = long_value;
|
dhcp_state.renewal = long_value;
|
||||||
break;
|
break;
|
||||||
case DHCP_END:
|
case DHCP_END:
|
||||||
break;
|
break;
|
||||||
@@ -376,13 +376,11 @@ void dhcp_start(void) __banked
|
|||||||
*tid++ = SFR_DATA_8;
|
*tid++ = SFR_DATA_8;
|
||||||
*tid = SFR_DATA_0;
|
*tid = SFR_DATA_0;
|
||||||
dhcp_state.state = DHCP_START;
|
dhcp_state.state = DHCP_START;
|
||||||
print_string("dhcp_start done\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dhcp_stop(void) __banked
|
void dhcp_stop(void) __banked
|
||||||
{
|
{
|
||||||
print_string("dhcp_stop called\n");
|
|
||||||
uip_udp_remove(dhcp_state.conn);
|
uip_udp_remove(dhcp_state.conn);
|
||||||
dhcp_state.state = DHCP_OFF;
|
dhcp_state.state = DHCP_OFF;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
### 2M-PCB23-V3.2
|
||||||
|
|
||||||
|
## Brands
|
||||||
|
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| keepLINK | KP-9000-9XHML-X | Yes| 2M-PCB23-V3.2 | 2M (Winbond 25Q) | |
|
||||||
|
|
||||||
|
The original web interface reports this board as hardware version V3.2
|
||||||
|
(original firmware V100.9.25, January 2026).
|
||||||
|
|
||||||
|
## PCB
|
||||||
|
|
||||||
|
<img src="photos/2M-PCB23-V3.2-managed/2M-PCB23-V3.2-top.jpeg" width="300" />
|
||||||
|
|
||||||
|
## Compared to V3.1
|
||||||
|
|
||||||
|
The component placement matches [2M-PCB23-V3.1](2M-PCB23-V3_1.md): same
|
||||||
|
positions for the flash (U8), the T7/T8/T9/T10 headers, the SFP cage and its
|
||||||
|
LED, and the unpopulated U7/U9 footprints. Build with
|
||||||
|
`MACHINE=KP_9000_9XHML_X_V3_2`, which uses the V3.1 machine definition and
|
||||||
|
only differs in the reported name.
|
||||||
|
|
||||||
|
## Tested
|
||||||
|
|
||||||
|
Installed from the original firmware through its web interface with
|
||||||
|
`installer/output/rtlplayground_oem_upgrade.bin`, then:
|
||||||
|
|
||||||
|
- RJ45 ports link at 2.5G; LEDs: orange at 2.5G, green below
|
||||||
|
- SFP port: module detected with vendor/model/serial and DOM readings
|
||||||
|
(temperature, Vcc, TX bias, TX/RX power), link up at 10G
|
||||||
|
- factory MAC read from flash (0x1FC000)
|
||||||
|
- reset button (GPIO48): held for more than 10 s it restores the default config
|
||||||
|
|
||||||
|
## Flash access
|
||||||
|
|
||||||
|
Reading the flash in-circuit with a SOIC-8 clip did not work: the chip ID
|
||||||
|
comes back as `EF FF FF` (only the manufacturer byte is right) and reads
|
||||||
|
return 0xff, the same as on a V3.1 board. The switch chip is powered through
|
||||||
|
the clip and keeps driving the SPI lines. Make sure a way back is acceptable
|
||||||
|
before installing, or hold the switch chip in reset while reading.
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
# Hasivo S1100WP-8GT-1SX-SE
|
||||||
|
|
||||||
|
RTL8373-based 8×2.5G PoE + 1×SFP switch.
|
||||||
|
|
||||||
|
### Label specifications
|
||||||
|
|
||||||
|
- **Manufacturer**: Hasivo
|
||||||
|
- **Model**: S1100WP-8GT-1SX-SE
|
||||||
|
- **Ports**:
|
||||||
|
- 8 × RJ45: 10/100/1000/2500 Mbps with PoE
|
||||||
|
- 1 × SFP: 1G / 2.5G / 10G
|
||||||
|
- **Power input**: DC 52V 2.5A
|
||||||
|
- **Stock firmware defaults**: IP 192.168.0.1, user/password `admin`/`admin`
|
||||||
|
|
||||||
|
### What works
|
||||||
|
|
||||||
|
- All eight 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps (PoE is not configurable via RTLPlayground)
|
||||||
|
- SFP port supporting 1G, 2.5G and 10G modules
|
||||||
|
- LEDs: green (2.5G) and amber (1G/100M/10M) per copper port; combined link/act on the SFP port
|
||||||
|
|
||||||
|
### Photos
|
||||||
|
|
||||||
|
Front panel:
|
||||||
|
|
||||||
|
<img src="photos/HASIVO_S1100WP-8GT-1SX-SE/front.jpg" width="600" />
|
||||||
|
|
||||||
|
Label:
|
||||||
|
|
||||||
|
<img src="photos/HASIVO_S1100WP-8GT-1SX-SE/label.jpg" width="600" />
|
||||||
|
|
||||||
|
### PCB overview
|
||||||
|
|
||||||
|
Top side:
|
||||||
|
|
||||||
|
<img src="photos/HASIVO_S1100WP-8GT-1SX-SE/pcb_top.jpg" width="600" />
|
||||||
|
|
||||||
|
Bottom side:
|
||||||
|
|
||||||
|
<img src="photos/HASIVO_S1100WP-8GT-1SX-SE/pcb_bottom.jpg" width="600" />
|
||||||
|
|
||||||
|
### Port layout
|
||||||
|
|
||||||
|
| Logical port | Physical port | Type |
|
||||||
|
|--------------|---------------|--------|
|
||||||
|
| 1-8 | 1-8 | Copper |
|
||||||
|
| 9 | 9 | SFP |
|
||||||
|
|
||||||
|
### LED configuration
|
||||||
|
|
||||||
|
Copper ports use LED SET0, the SFP port uses LED SET1.
|
||||||
|
|
||||||
|
| SET | LED0 | LED2 |
|
||||||
|
|------|-----------------------------------------------|------------------------------------------------------|
|
||||||
|
| SET0 | Green — lights on 2.5G link with activity | Amber — lights on 1G / 100M / 10M link with activity |
|
||||||
|
| SET1 | All speeds — lights on any link with activity | — |
|
||||||
|
|
||||||
|
### SFP GPIO assignments
|
||||||
|
|
||||||
|
| SFP (logical 9) | pin_detect (ModAbs) | pin_los | pin_tx_disable | SerDes | I2C SDA | I2C SCL |
|
||||||
|
|-----------------|---------------------|---------|----------------|--------|-----------------|---------------------|
|
||||||
|
| SFP | GPIO30_ACL_BIT3_EN | GPIO37 | GPIO_NA | SDS1 | GPIO39_I2C_SDA4 | GPIO40_I2C_SCL3_MDC1 |
|
||||||
|
|
||||||
|
### Machine configuration
|
||||||
|
|
||||||
|
- `reset_pin`: GPIO54_ACL_BIT2_EN
|
||||||
|
- High LEDs (pads 27-29): mux = `LED_27 | LED_28_SYS | LED_29`, enable = `LED_28_SYS | LED_29`
|
||||||
|
|
||||||
|
### PoE
|
||||||
|
|
||||||
|
The 8 copper ports support PoE powered by a DC 52V 2.5A input. Power management is handled by two HS104PTI chipsets over I2C (GPIO47_I2C_SDA0, GPIO46_I2C_SCL0):
|
||||||
|
|
||||||
|
* Chip 1 (I2C address 0x1A): 2.5G Ports 1–4
|
||||||
|
* Chip 2 (I2C address 0x2A): 2.5G Ports 5–8
|
||||||
|
|
||||||
|
Note: The current implementation does not yet support PoE management. Consequently, PoE currently operates in standalone mode without software control.
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
# SWTG018AS-A V2.0
|
# SWTG018AS-A V2.0
|
||||||
## Brands
|
## Brands
|
||||||
| Brand | Type |Managed| PCB | Flash | Chip RTL |
|
| Brand | Type |Managed| PCB | Flash | Chip RTL |
|
||||||
|--------|------------------|-------|------------------|-----------------|---------------|
|
|---------|------------------|-------|------------------|-----------------|---------------|
|
||||||
| Ampcom | SWTG018AS-A V2.0 | No | SWTG018AS-A V2.0 | 2MB | 8273N + 8224N |
|
| Ampcom | SWTG018AS-A V2.0 | No | SWTG018AS-A V2.0 | 2MB | 8273N + 8224N |
|
||||||
| Horaco | HC-SWTGW218AS-A | Yes | SWTG018AS-A V2.0 | 2MB(25Q16JVSIQ) | 8273N + 8224N |
|
| Horaco | HC-SWTGW218AS-A | Yes | SWTG018AS-A V2.0 | 2MB(25Q16JVSIQ) | 8273N + 8224N |
|
||||||
|
| GoodTop | GT-ST018M | Yes | SWTG018AS-A V2.0 | ? | 8273N + 8224N |
|
||||||
|
|
||||||
|
|
||||||
The following is a documentation for the unmanaged switch marked as `SWTG018AS-A V2.0`.
|
The following is a documentation for the unmanaged switch marked as `SWTG018AS-A V2.0`.
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 480 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 93 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 220 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 273 KiB |
@@ -0,0 +1,79 @@
|
|||||||
|
# The health command
|
||||||
|
|
||||||
|
`health` prints a one-page snapshot of the firmware's vital signs on the
|
||||||
|
serial console. It exists for the situations where the switch misbehaves and
|
||||||
|
every probe from the network measures the network instead of the device: the
|
||||||
|
dump is taken from inside, costs one command, and works while HTTP does not.
|
||||||
|
|
||||||
|
```
|
||||||
|
> health
|
||||||
|
up 0000001f ticks 0x00001f4c loops 0x000016da rx 0x024e
|
||||||
|
link max 01 slow 0x0000
|
||||||
|
sfp max 74 slow 0x0001
|
||||||
|
rx max 00 slow 0x0000
|
||||||
|
tx max 00 slow 0x0000
|
||||||
|
stp max 04 slow 0x0001
|
||||||
|
cmd max 02 slow 0x0001
|
||||||
|
sp 80 untouched 62
|
||||||
|
tcp st 00 tmr 00 rtx 00 rto 00 len 0x0000 mss 0x05b4
|
||||||
|
lport 0x0000 rport 0x0000 rip 0x0000 0x0000
|
||||||
|
httpd left 0x0000 entry 00 stp 01 mvlan 0x0002
|
||||||
|
```
|
||||||
|
|
||||||
|
The instrumentation is not part of a default build. It costs about 1.1 kB
|
||||||
|
of bank 2, a few bytes of xdata and seven banked calls per main-loop pass,
|
||||||
|
which is nothing a user needs unless they are chasing a problem, so it is
|
||||||
|
switched on at build time:
|
||||||
|
|
||||||
|
```
|
||||||
|
make MACHINE=SWTGW218AS HEALTH=1
|
||||||
|
```
|
||||||
|
|
||||||
|
Without it the hooks compile to nothing and `health` is not a command.
|
||||||
|
|
||||||
|
All figures are raw hex. The counters are cumulative: take two dumps a known
|
||||||
|
time apart and the differences give the rates.
|
||||||
|
|
||||||
|
## The first line
|
||||||
|
|
||||||
|
`up` is the seconds counter, `ticks` the system tick (200 per second),
|
||||||
|
`loops` the number of main-loop passes and `rx` the frames handle_rx has
|
||||||
|
taken off the NIC. A healthy loop completes one pass per tick, so the
|
||||||
|
difference in `loops` tracks the difference in `ticks`; a loop that falls
|
||||||
|
behind is being held up by one of the phases below. The `rx` rate separates
|
||||||
|
a flooded CPU port from a stalled loop, which look identical from outside.
|
||||||
|
|
||||||
|
## Phases
|
||||||
|
|
||||||
|
Each line is one section of the main loop: the link poll, SFP handling,
|
||||||
|
frame reception, TCP transmission, the STP timers and the command dispatch.
|
||||||
|
`max` is the worst time that section has taken, in ticks of 5 ms; `slow`
|
||||||
|
counts the passes that took two ticks or more. A misbehaving subsystem
|
||||||
|
names itself here, which is the difference between knowing that the loop is
|
||||||
|
slow and knowing why.
|
||||||
|
|
||||||
|
A dump of its own output takes the console some milliseconds, so running
|
||||||
|
`health` repeatedly increments the `cmd` counters by itself. That is the
|
||||||
|
instrument observing itself, not a fault.
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
|
||||||
|
At boot the free stack area is painted with a pattern. `sp` is the live
|
||||||
|
stack pointer; `untouched` counts the painted bytes still intact at the top,
|
||||||
|
which is the closest thing to a high-water mark this hardware offers. A
|
||||||
|
shrinking `untouched` across dumps means something is reaching deeper than
|
||||||
|
anything before it.
|
||||||
|
|
||||||
|
## The TCP slot
|
||||||
|
|
||||||
|
The connection table is printed whole, one slot per pair of lines: TCP
|
||||||
|
state (3 is ESTABLISHED, 0 closed), retransmission timer and counter, bytes
|
||||||
|
in flight, negotiated MSS, then the ports and the peer address. With a
|
||||||
|
single slot serving the entire web interface, one glance answers the
|
||||||
|
question every management outage starts with: who is holding it. A slot
|
||||||
|
showing state 3 with nothing in flight and a peer that no longer answers is
|
||||||
|
a connection whose owner went away.
|
||||||
|
|
||||||
|
`httpd left` and `entry` describe the file transfer the web server believes
|
||||||
|
it is in the middle of, and the trailing flags show whether STP is running
|
||||||
|
and which VLAN carries management.
|
||||||
+6
-2
@@ -69,7 +69,7 @@ The code currently provides the following functions:
|
|||||||
void igmp_setup(void) __banked;
|
void igmp_setup(void) __banked;
|
||||||
void igmp_enable(void) __banked;
|
void igmp_enable(void) __banked;
|
||||||
void igmp_router_port_set(uint16_t pmask) __banked;
|
void igmp_router_port_set(uint16_t pmask) __banked;
|
||||||
void igmp_packet_handler(void) __banked;
|
uint8_t igmp_packet_handler(void) __banked;
|
||||||
void igmp_show(void) __banked;
|
void igmp_show(void) __banked;
|
||||||
```c
|
```c
|
||||||
`igmp_setup()` is called at boot-time and configures flooding of all IP-MC packets by
|
`igmp_setup()` is called at boot-time and configures flooding of all IP-MC packets by
|
||||||
@@ -80,7 +80,11 @@ of IP-MC packets to be limited to only subscribed ports.
|
|||||||
|
|
||||||
`igmp_router_port_set()`configures forwarding ports for IGMP messages.
|
`igmp_router_port_set()`configures forwarding ports for IGMP messages.
|
||||||
|
|
||||||
`igmp_packet_handler()` implements handling of trapped IGMP packets by the CPU.
|
`igmp_packet_handler()` implements handling of trapped IGMP packets by the CPU. It is called
|
||||||
|
for frames to 01:00:5e:xx:xx:xx and returns 0 when the frame is not a trapped IGMP packet,
|
||||||
|
so that it is passed on to the IP stack. IGMPv1/v2 reports (0x12, 0x16) join the group given
|
||||||
|
in the IGMP header, IGMPv2 leaves (0x17) leave it, IGMPv3 reports use the first group record
|
||||||
|
(type 4 joins, type 3 leaves). Trapped IGMP frames arrive without a VLAN tag.
|
||||||
|
|
||||||
`igmp_show()` prints out the IGMP configuration on the CLI.
|
`igmp_show()` prints out the IGMP configuration on the CLI.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# Storm Control
|
||||||
|
Storm control limits the rate at which a port admits broadcast, multicast,
|
||||||
|
unknown unicast and unknown multicast frames. Frames of a type above its limit
|
||||||
|
are dropped at ingress, so a loop or a misbehaving host cannot flood the rest
|
||||||
|
of the network through that port. Known unicast traffic is not affected.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
```
|
||||||
|
storm <port> bcast|mcast|ucast|umcast <rate> pps
|
||||||
|
storm <port> bcast|mcast|ucast|umcast <rate> kbps
|
||||||
|
storm <port> bcast|mcast|ucast|umcast off
|
||||||
|
storm
|
||||||
|
```
|
||||||
|
`ucast` is unicast to a MAC address the switch has not learned yet, and
|
||||||
|
`umcast` is multicast without an entry in the address table. Multicast groups
|
||||||
|
get their entries from IGMP snooping, so without `igmp on` all multicast is
|
||||||
|
unknown and only the `umcast` limit applies to it; `mcast` covers the groups
|
||||||
|
IGMP has learned. A limit in
|
||||||
|
packets per second goes from 1 to 1048575, a limit in kbit/s from 1 to
|
||||||
|
10000000. `storm` without arguments prints the limits of every port. The
|
||||||
|
limits are kept in the configuration like any other setting, and the Bandwidth
|
||||||
|
page of the web interface has a Storm control card to set them.
|
||||||
|
|
||||||
|
## Registers
|
||||||
|
Each port and type has an enable bit and a meter index, and each limit uses
|
||||||
|
one of the 64 shared meters of the switch. RTLPlayground gives every port and
|
||||||
|
type its own meter, index `24 + port * 4 + type`, so one port's storm does not
|
||||||
|
eat into the limit of another. Storm control uses meters 24 to 63 and leaves
|
||||||
|
0 to 23 to the ACL. The limit of a meter is in `RTL837X_METER_RATE + 4 *
|
||||||
|
meter`, and bit `meter % 32` of `RTL837X_METER_MODE + 4 * (meter / 32)`
|
||||||
|
selects pps instead of kbit/s.
|
||||||
|
```
|
||||||
|
#define RTL837X_STORM_CTRL 0x54e4 /* + 4 * type, bit = port */
|
||||||
|
#define RTL837X_STORM_MIDX 0x54f4 /* + 8 * type + 4 * (port / 5), 6 bits per port */
|
||||||
|
#define RTL837X_METER_RATE 0x5cf0 /* + 4 * meter, 24 bits, kbit/s or pps */
|
||||||
|
#define RTL837X_METER_MODE 0x5ef0 /* + 4 * (meter / 32), bit set = pps */
|
||||||
|
```
|
||||||
|
In kbit/s mode one step of the rate is 1 kbit/s. Measured with 100 and 1000 byte
|
||||||
|
frames, the meter counts a frame with its FCS, but without preamble and
|
||||||
|
interframe gap. Every meter has a bit that adds them, in `0x5f08 + 4 * (meter
|
||||||
|
/ 32)`, which storm control leaves cleared. `IGBW_INC_IFG` and `EGBW_INC_IFG`
|
||||||
|
are the matching bits of the bandwidth control.
|
||||||
|
|
||||||
|
An ingress bandwidth limit on the same port works on the same arriving frames
|
||||||
|
as the storm limit rather than after it, and the two together pass far less
|
||||||
|
than either one: a 1 Mbit/s `umcast` limit with a 10 Mbit/s ingress limit let
|
||||||
|
0.12 to 0.16 Mbit/s of a 1.4 Gbit/s stream through, where each alone passed
|
||||||
|
1.17 and 10.2 Mbit/s.
|
||||||
|
|
||||||
|
The type is 0 for broadcast, 1 for multicast, 2 for unknown unicast and 3 for
|
||||||
|
unknown multicast. The burst size of a meter (0x5df0 + 4 * meter) counts packets
|
||||||
|
in pps mode; its default of 0x2000 lets 8192 frames through before a pps limit
|
||||||
|
bites, so a pps limit sets the burst to one second of traffic. A kbit/s limit
|
||||||
|
puts back the default.
|
||||||
@@ -7,6 +7,8 @@ The following devices have been tested and are fully working:
|
|||||||
| Davuaz | Da-K6501W | No | [PCB-K0501W-V2.0](devices/K0501W_V2_0.md) | | 5 + 1 |
|
| Davuaz | Da-K6501W | No | [PCB-K0501W-V2.0](devices/K0501W_V2_0.md) | | 5 + 1 |
|
||||||
| FOXNEO | FNS-1200P | No | [PCB-K0402W-U13-V2.0](devices/FNS-1200P.md) | 2M | 4 + 2 |
|
| FOXNEO | FNS-1200P | No | [PCB-K0402W-U13-V2.0](devices/FNS-1200P.md) | 2M | 4 + 2 |
|
||||||
| Goalake | IG108 | No | [PB-2132](devices/PB-2132.md) | 4M | 8 + 1 |
|
| Goalake | IG108 | No | [PB-2132](devices/PB-2132.md) | 4M | 8 + 1 |
|
||||||
|
| GoodTop | GT-ST018M | Yes | [SWTG018AS-A V2.0](devices/SWTG018AS_A_V2_0.md) | ? | 8 + 1 |
|
||||||
|
| Hasivo | S1100WP_8GT_1SX_SE | Yes | [S1100WP_8GT_1SX_SE-V1.05](devices/HASIVO_S1100WP_8GT_1SX_SE.md) | 2M | 8 + 1 |
|
||||||
| Hisource | Hi-K0402WS | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
|
| Hisource | Hi-K0402WS | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
|
||||||
| Hisource | Hi-K0402WS | No | [PCB-K0402WS-V2.0](devices/PCB-K0402WS-V2.0.md) | 2M | 4 + 2 |
|
| Hisource | Hi-K0402WS | No | [PCB-K0402WS-V2.0](devices/PCB-K0402WS-V2.0.md) | 2M | 4 + 2 |
|
||||||
| Hisource | Hi-K0801WS | No | [PCB-KO801W-V2.0](devices/HI-K0801WS.md) | | 8 + 1 |
|
| Hisource | Hi-K0801WS | No | [PCB-KO801W-V2.0](devices/HI-K0801WS.md) | | 8 + 1 |
|
||||||
@@ -20,6 +22,7 @@ The following devices have been tested and are fully working:
|
|||||||
| Keeplink | KP-9000-6XH-X2 / KP-9000-6XHML-X2 | No/Yes | [2M-PCB43-V1.2 / V2.1](devices/KP-9000-6XH-X2.md) | | 4 + 2 |
|
| Keeplink | KP-9000-6XH-X2 / KP-9000-6XHML-X2 | No/Yes | [2M-PCB43-V1.2 / V2.1](devices/KP-9000-6XH-X2.md) | | 4 + 2 |
|
||||||
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V2.2](devices/2M-PCB23-V2_2.md) | 2M | 8 + 1 |
|
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V2.2](devices/2M-PCB23-V2_2.md) | 2M | 8 + 1 |
|
||||||
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V3.1](devices/2M-PCB23-V3_1.md) | 2M | 8 + 1 |
|
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V3.1](devices/2M-PCB23-V3_1.md) | 2M | 8 + 1 |
|
||||||
|
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V3.2](devices/2M-PCB23-V3_2.md) | 2M | 8 + 1 |
|
||||||
| LIANGUO | SWTG024AS | No | [SWTG024AS-v2.0-17452](devices/SWTG024AS.md) | 0.5M | 4 + 2 |
|
| LIANGUO | SWTG024AS | No | [SWTG024AS-v2.0-17452](devices/SWTG024AS.md) | 0.5M | 4 + 2 |
|
||||||
| Lianguo | ZX-SWTGW215AS | Yes | [PCB-SWTG115AS-V2.0 / PCB-SWTG115AS-V2.1](devices/SWTGW215AS.md) | 2M | 5 + 1 |
|
| Lianguo | ZX-SWTGW215AS | Yes | [PCB-SWTG115AS-V2.0 / PCB-SWTG115AS-V2.1](devices/SWTGW215AS.md) | 2M | 5 + 1 |
|
||||||
| Lianguo | HYWS-SGT0108S | No | [2G5F_20G_V1.01](devices/HYWS-SGT0108S.md) | 0.5M | 8 + 1 |
|
| Lianguo | HYWS-SGT0108S | No | [2G5F_20G_V1.01](devices/HYWS-SGT0108S.md) | 0.5M | 8 + 1 |
|
||||||
|
|||||||
+420
-24
@@ -2,7 +2,7 @@
|
|||||||
var LANG={
|
var LANG={
|
||||||
en:{
|
en:{
|
||||||
nav_dash:"Dashboard",nav_ports:"Ports",nav_stp:"Spanning tree",nav_stats:"Statistics",
|
nav_dash:"Dashboard",nav_ports:"Ports",nav_stp:"Spanning tree",nav_stats:"Statistics",
|
||||||
nav_vlan:"VLANs",nav_l2:"MAC table",nav_mirror:"Mirroring",nav_lag:"LAG",nav_eee:"EEE",
|
nav_vlan:"VLANs",nav_l2:"MAC table",nav_mirror:"Mirroring",nav_isolate:"Isolation",nav_lag:"LAG",nav_eee:"EEE",
|
||||||
nav_bw:"Bandwidth",nav_system:"System",nav_fw:"Firmware",
|
nav_bw:"Bandwidth",nav_system:"System",nav_fw:"Firmware",
|
||||||
hdr_dirty:"unsaved changes",hdr_dirty_t:"Running config differs from startup config",
|
hdr_dirty:"unsaved changes",hdr_dirty_t:"Running config differs from startup config",
|
||||||
hdr_save:"Save to flash",hdr_save_t:"Persist running configuration to flash",
|
hdr_save:"Save to flash",hdr_save_t:"Persist running configuration to flash",
|
||||||
@@ -15,7 +15,7 @@ c_full:"full",c_half:"half",c_devices:"devices",c_yes:"yes",c_no:"no",
|
|||||||
d_ports:"Ports",d_ports_h:"click a port for details",d_system:"System",d_traffic:"Traffic",
|
d_ports:"Ports",d_ports_h:"click a port for details",d_system:"System",d_traffic:"Traffic",
|
||||||
d_traffic_h:"packets/s, live",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX bad",d_rxbad:"RX bad",
|
d_traffic_h:"packets/s, live",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX bad",d_rxbad:"RX bad",
|
||||||
i_host:"Hostname",i_ip:"IP address",i_mask:"Netmask",i_gw:"Gateway",i_mac:"MAC",i_fw:"Firmware",
|
i_host:"Hostname",i_ip:"IP address",i_mask:"Netmask",i_gw:"Gateway",i_mac:"MAC",i_fw:"Firmware",
|
||||||
i_built:"Built",i_hw:"Hardware",i_flash:"Flash",i_syslog:"Syslog",
|
i_built:"Built",i_hw:"Hardware",i_temp:"Temperature",i_flash:"Flash",i_syslog:"Syslog",
|
||||||
p_state:"State",p_disabled:"disabled",p_up:"up",p_txgb:"TX good / bad",p_rxgb:"RX good / bad",
|
p_state:"State",p_disabled:"disabled",p_up:"up",p_txgb:"TX good / bad",p_rxgb:"RX good / bad",
|
||||||
p_pkts:"pkts",p_module:"Module",p_temp:"Temperature",p_vcc:"Vcc",p_txbias:"TX bias",p_txpower:"TX power",
|
p_pkts:"pkts",p_module:"Module",p_temp:"Temperature",p_vcc:"Vcc",p_txbias:"TX bias",p_txpower:"TX power",
|
||||||
p_rxpower:"RX power",p_txfault:"TX fault",p_txdis:"TX disabled",p_rxlos:"RX LOS",p_adv:"Advertising",
|
p_rxpower:"RX power",p_txfault:"TX fault",p_txdis:"TX disabled",p_rxlos:"RX LOS",p_adv:"Advertising",
|
||||||
@@ -62,6 +62,9 @@ l2_learned:"learned",l2_loading:"loading...",l2_failed:"load failed",l2_entries:
|
|||||||
l2_del_t:"Delete entry",l2_flush_q:"Flush all learned MAC entries?",
|
l2_del_t:"Delete entry",l2_flush_q:"Flush all learned MAC entries?",
|
||||||
m_title:"Port mirroring",m_active:"active",m_monitor:"Monitor port",m_mirror:"Mirror",m_both:"Both",
|
m_title:"Port mirroring",m_active:"active",m_monitor:"Monitor port",m_mirror:"Mirror",m_both:"Both",
|
||||||
m_note:"Both = mirror RX and TX of the port to the monitor port.",m_none:"Select at least one mirrored port",
|
m_note:"Both = mirror RX and TX of the port to the monitor port.",m_none:"Select at least one mirrored port",
|
||||||
|
iso_title:"Port isolation",iso_from:"From port",iso_to:"To port",iso_all:"Allow all",
|
||||||
|
iso_intro:"A frame entering a port may only leave through the ports ticked in its row. Isolation is decided before forwarding, so a port that is not ticked is unreachable directly, whatever the address table says.",
|
||||||
|
iso_legend:"The cell of the port itself is always allowed. A port number in red marks a port that is not fully open.",
|
||||||
lag_hash:"Hash:",lag_note:"A LAG needs at least one member to be saved in the startup config; applying an empty group clears it.",
|
lag_hash:"Hash:",lag_note:"A LAG needs at least one member to be saved in the startup config; applying an empty group clears it.",
|
||||||
lag_clear_q:"Clear LAG {n}?",lag_clear_d:"All member ports return to normal operation.",
|
lag_clear_q:"Clear LAG {n}?",lag_clear_d:"All member ports return to normal operation.",
|
||||||
e_title:"Energy Efficient Ethernet",e_adv:"Advertised",e_lp:"Link partner",e_active:"Active",e_enable:"Enable",
|
e_title:"Energy Efficient Ethernet",e_adv:"Advertised",e_lp:"Link partner",e_active:"Active",e_enable:"Enable",
|
||||||
@@ -70,8 +73,12 @@ e_idle:"idle",e_na:"n/a",
|
|||||||
bw_title:"Bandwidth limits",bw_h:"Mbit/s, 0.016-10000",bw_in:"Ingress limit",bw_out:"Egress limit",
|
bw_title:"Bandwidth limits",bw_h:"Mbit/s, 0.016-10000",bw_in:"Ingress limit",bw_out:"Egress limit",
|
||||||
bw_exceed:"When exceeded",bw_fc:"Flow control",bw_drop:"Drop",
|
bw_exceed:"When exceeded",bw_fc:"Flow control",bw_drop:"Drop",
|
||||||
bw_in_err:"Ingress limit must be 0.016-10000 Mbit/s",bw_out_err:"Egress limit must be 0.016-10000 Mbit/s",
|
bw_in_err:"Ingress limit must be 0.016-10000 Mbit/s",bw_out_err:"Egress limit must be 0.016-10000 Mbit/s",
|
||||||
|
sc_title:"Storm control",sc_h:"per port and traffic type, empty = off",sc_bcast:"Broadcast",sc_mcast:"Multicast",
|
||||||
|
sc_ucast:"Unknown unicast",sc_umcast:"Unknown multicast",sc_err:"Storm limit must be 1-1048575 pps or 1-10000000 kbit/s",
|
||||||
|
sc_note:"Frames of a type above its limit are dropped where they enter the switch.",
|
||||||
sy_network:"Network",sy_dhcp:"Use DHCP",sy_dhcp_t:"Request address via DHCP",sy_services:"Services",
|
sy_network:"Network",sy_dhcp:"Use DHCP",sy_dhcp_t:"Request address via DHCP",sy_services:"Services",
|
||||||
sy_igmp:"IGMP snooping",sy_sysip:"server IP",sy_server:"Server",sy_port:"Port",
|
sy_igmp:"IGMP snooping",sy_sysip:"server IP",sy_server:"Server",sy_port:"Port",
|
||||||
|
sy_sesstmo:"Session timeout (s)",sy_sesstmo_err:"Session timeout must be 1-65535 s",
|
||||||
sy_services_note:"Service state reflects the startup config; runtime state is not readable.",
|
sy_services_note:"Service state reflects the startup config; runtime state is not readable.",
|
||||||
sy_password:"Admin password",sy_newpw:"New password",sy_repeat:"Repeat",sy_pwapply:"Change password",
|
sy_password:"Admin password",sy_newpw:"New password",sy_repeat:"Repeat",sy_pwapply:"Change password",
|
||||||
sy_pw_note:"Takes effect immediately; save to flash to keep it after reboot.",sy_console:"Console",
|
sy_pw_note:"Takes effect immediately; save to flash to keep it after reboot.",sy_console:"Console",
|
||||||
@@ -90,6 +97,7 @@ sy_rebooting:"Rebooting, reconnect in about 20 s",sy_bytes:"bytes",
|
|||||||
cw_title:"Write this startup configuration?",cw_save_title:"Save running configuration to flash?",
|
cw_title:"Write this startup configuration?",cw_save_title:"Save running configuration to flash?",
|
||||||
cw_info:"{n} / 2048 bytes, replayed line by line on every boot",
|
cw_info:"{n} / 2048 bytes, replayed line by line on every boot",
|
||||||
cw_toolarge:"Too large: the config sector accepts at most 2048 bytes. Remove lines first.",
|
cw_toolarge:"Too large: the config sector accepts at most 2048 bytes. Remove lines first.",
|
||||||
|
cw_longline:"Line {n} is {m} bytes long: the switch can only replay lines up to 126 bytes and would skip it on boot, so the write is refused. Shorten it first.",
|
||||||
cw_unknown:"Not in the known config grammar (will still be written): ",cw_empty:"(empty)",
|
cw_unknown:"Not in the known config grammar (will still be written): ",cw_empty:"(empty)",
|
||||||
cw_writing:"Writing configuration...",cw_failed:"config write failed: HTTP {n}",
|
cw_writing:"Writing configuration...",cw_failed:"config write failed: HTTP {n}",
|
||||||
cw_verify_fail:"Verification failed: flash content differs from what was sent. Command log NOT cleared.",
|
cw_verify_fail:"Verification failed: flash content differs from what was sent. Command log NOT cleared.",
|
||||||
@@ -126,7 +134,7 @@ c_full:"全二重",c_half:"半二重",c_devices:"デバイス",c_yes:"はい",c_
|
|||||||
d_ports:"ポート",d_ports_h:"ポートをクリックすると詳細を表示",d_system:"システム",d_traffic:"トラフィック",
|
d_ports:"ポート",d_ports_h:"ポートをクリックすると詳細を表示",d_system:"システム",d_traffic:"トラフィック",
|
||||||
d_traffic_h:"パケット/秒、リアルタイム",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX 異常",d_rxbad:"RX 異常",
|
d_traffic_h:"パケット/秒、リアルタイム",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX 異常",d_rxbad:"RX 異常",
|
||||||
i_host:"ホスト名",i_ip:"IP アドレス",i_mask:"ネットマスク",i_gw:"ゲートウェイ",i_mac:"MAC",i_fw:"ファームウェア",
|
i_host:"ホスト名",i_ip:"IP アドレス",i_mask:"ネットマスク",i_gw:"ゲートウェイ",i_mac:"MAC",i_fw:"ファームウェア",
|
||||||
i_built:"ビルド日",i_hw:"ハードウェア",i_flash:"フラッシュ",i_syslog:"Syslog",
|
i_built:"ビルド日",i_hw:"ハードウェア",i_temp:"温度",i_flash:"フラッシュ",i_syslog:"Syslog",
|
||||||
p_state:"状態",p_disabled:"無効",p_up:"アップ",p_txgb:"TX 正常 / 異常",p_rxgb:"RX 正常 / 異常",
|
p_state:"状態",p_disabled:"無効",p_up:"アップ",p_txgb:"TX 正常 / 異常",p_rxgb:"RX 正常 / 異常",
|
||||||
p_pkts:"pkts",p_module:"モジュール",p_temp:"温度",p_vcc:"電圧",p_txbias:"TX バイアス",p_txpower:"TX 電力",
|
p_pkts:"pkts",p_module:"モジュール",p_temp:"温度",p_vcc:"電圧",p_txbias:"TX バイアス",p_txpower:"TX 電力",
|
||||||
p_rxpower:"RX 電力",p_txfault:"TX 障害",p_txdis:"TX 無効",p_rxlos:"RX 信号ロス",p_adv:"アドバタイズ",
|
p_rxpower:"RX 電力",p_txfault:"TX 障害",p_txdis:"TX 無効",p_rxlos:"RX 信号ロス",p_adv:"アドバタイズ",
|
||||||
@@ -183,6 +191,7 @@ bw_exceed:"超過時の動作",bw_fc:"フロー制御",bw_drop:"破棄",
|
|||||||
bw_in_err:"入力制限は 0.016〜10000 Mbit/s の範囲で指定してください",bw_out_err:"出力制限は 0.016〜10000 Mbit/s の範囲で指定してください",
|
bw_in_err:"入力制限は 0.016〜10000 Mbit/s の範囲で指定してください",bw_out_err:"出力制限は 0.016〜10000 Mbit/s の範囲で指定してください",
|
||||||
sy_network:"ネットワーク",sy_dhcp:"DHCP を使用",sy_dhcp_t:"DHCP でアドレスを取得",sy_services:"サービス",
|
sy_network:"ネットワーク",sy_dhcp:"DHCP を使用",sy_dhcp_t:"DHCP でアドレスを取得",sy_services:"サービス",
|
||||||
sy_igmp:"IGMP スヌーピング",sy_sysip:"サーバー IP",sy_server:"サーバー",sy_port:"ポート",
|
sy_igmp:"IGMP スヌーピング",sy_sysip:"サーバー IP",sy_server:"サーバー",sy_port:"ポート",
|
||||||
|
sy_sesstmo:"セッションタイムアウト (秒)",sy_sesstmo_err:"セッションタイムアウトは 1〜65535 秒で指定してください",
|
||||||
sy_services_note:"サービスの状態は起動設定を反映しています。実行時の状態は読み取れません。",
|
sy_services_note:"サービスの状態は起動設定を反映しています。実行時の状態は読み取れません。",
|
||||||
sy_password:"管理者パスワード",sy_newpw:"新しいパスワード",sy_repeat:"再入力",sy_pwapply:"パスワードを変更",
|
sy_password:"管理者パスワード",sy_newpw:"新しいパスワード",sy_repeat:"再入力",sy_pwapply:"パスワードを変更",
|
||||||
sy_pw_note:"即時に反映されます。再起動後も保持するにはフラッシュに保存してください。",sy_console:"コンソール",
|
sy_pw_note:"即時に反映されます。再起動後も保持するにはフラッシュに保存してください。",sy_console:"コンソール",
|
||||||
@@ -201,6 +210,7 @@ sy_rebooting:"再起動中です。約 20 秒後に再接続してください",
|
|||||||
cw_title:"この起動設定を書き込みますか?",cw_save_title:"実行中の設定をフラッシュに保存しますか?",
|
cw_title:"この起動設定を書き込みますか?",cw_save_title:"実行中の設定をフラッシュに保存しますか?",
|
||||||
cw_info:"{n} / 2048 バイト、起動のたびに 1 行ずつ実行されます",
|
cw_info:"{n} / 2048 バイト、起動のたびに 1 行ずつ実行されます",
|
||||||
cw_toolarge:"サイズ超過: 設定セクタは最大 2048 バイトです。先に行を削除してください。",
|
cw_toolarge:"サイズ超過: 設定セクタは最大 2048 バイトです。先に行を削除してください。",
|
||||||
|
cw_longline:"{n} 行目は {m} バイトです: スイッチが起動時に実行できる行は 126 バイトまでで、この行は読み飛ばされるため、書き込みを拒否します。先に短くしてください。",
|
||||||
cw_unknown:"既知の設定文法に含まれない行 (そのまま書き込まれます): ",cw_empty:"(空)",
|
cw_unknown:"既知の設定文法に含まれない行 (そのまま書き込まれます): ",cw_empty:"(空)",
|
||||||
cw_writing:"設定を書き込み中...",cw_failed:"設定の書き込みに失敗しました: HTTP {n}",
|
cw_writing:"設定を書き込み中...",cw_failed:"設定の書き込みに失敗しました: HTTP {n}",
|
||||||
cw_verify_fail:"検証失敗: フラッシュの内容が送信内容と異なります。コマンドログは消去されていません。",
|
cw_verify_fail:"検証失敗: フラッシュの内容が送信内容と異なります。コマンドログは消去されていません。",
|
||||||
@@ -237,7 +247,7 @@ c_full:"全双工",c_half:"半双工",c_devices:"台设备",c_yes:"是",c_no:"
|
|||||||
d_ports:"端口",d_ports_h:"点击端口查看详情",d_system:"系统",d_traffic:"流量",
|
d_ports:"端口",d_ports_h:"点击端口查看详情",d_system:"系统",d_traffic:"流量",
|
||||||
d_traffic_h:"包/秒,实时",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX 错误",d_rxbad:"RX 错误",
|
d_traffic_h:"包/秒,实时",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX 错误",d_rxbad:"RX 错误",
|
||||||
i_host:"主机名",i_ip:"IP 地址",i_mask:"子网掩码",i_gw:"网关",i_mac:"MAC",i_fw:"固件",
|
i_host:"主机名",i_ip:"IP 地址",i_mask:"子网掩码",i_gw:"网关",i_mac:"MAC",i_fw:"固件",
|
||||||
i_built:"构建日期",i_hw:"硬件",i_flash:"Flash",i_syslog:"Syslog",
|
i_built:"构建日期",i_hw:"硬件",i_temp:"温度",i_flash:"Flash",i_syslog:"Syslog",
|
||||||
p_state:"状态",p_disabled:"已禁用",p_up:"已连接",p_txgb:"TX 正常 / 错误",p_rxgb:"RX 正常 / 错误",
|
p_state:"状态",p_disabled:"已禁用",p_up:"已连接",p_txgb:"TX 正常 / 错误",p_rxgb:"RX 正常 / 错误",
|
||||||
p_pkts:"个包",p_module:"模块",p_temp:"温度",p_vcc:"供电电压",p_txbias:"TX 偏置电流",p_txpower:"TX 光功率",
|
p_pkts:"个包",p_module:"模块",p_temp:"温度",p_vcc:"供电电压",p_txbias:"TX 偏置电流",p_txpower:"TX 光功率",
|
||||||
p_rxpower:"RX 光功率",p_txfault:"TX 故障",p_txdis:"TX 禁用",p_rxlos:"RX 信号丢失",p_adv:"通告能力",
|
p_rxpower:"RX 光功率",p_txfault:"TX 故障",p_txdis:"TX 禁用",p_rxlos:"RX 信号丢失",p_adv:"通告能力",
|
||||||
@@ -294,6 +304,7 @@ bw_exceed:"超限动作",bw_fc:"流量控制",bw_drop:"丢弃",
|
|||||||
bw_in_err:"入方向限速范围为 0.016-10000 Mbit/s",bw_out_err:"出方向限速范围为 0.016-10000 Mbit/s",
|
bw_in_err:"入方向限速范围为 0.016-10000 Mbit/s",bw_out_err:"出方向限速范围为 0.016-10000 Mbit/s",
|
||||||
sy_network:"网络",sy_dhcp:"使用 DHCP",sy_dhcp_t:"通过 DHCP 获取地址",sy_services:"服务",
|
sy_network:"网络",sy_dhcp:"使用 DHCP",sy_dhcp_t:"通过 DHCP 获取地址",sy_services:"服务",
|
||||||
sy_igmp:"IGMP 侦听",sy_sysip:"服务器 IP",sy_server:"服务器",sy_port:"端口",
|
sy_igmp:"IGMP 侦听",sy_sysip:"服务器 IP",sy_server:"服务器",sy_port:"端口",
|
||||||
|
sy_sesstmo:"会话超时(秒)",sy_sesstmo_err:"会话超时必须为 1-65535 秒",
|
||||||
sy_services_note:"服务状态反映启动配置;运行时状态无法读取。",
|
sy_services_note:"服务状态反映启动配置;运行时状态无法读取。",
|
||||||
sy_password:"管理员密码",sy_newpw:"新密码",sy_repeat:"重复输入",sy_pwapply:"修改密码",
|
sy_password:"管理员密码",sy_newpw:"新密码",sy_repeat:"重复输入",sy_pwapply:"修改密码",
|
||||||
sy_pw_note:"立即生效;如需重启后保留请保存到 Flash。",sy_console:"控制台",
|
sy_pw_note:"立即生效;如需重启后保留请保存到 Flash。",sy_console:"控制台",
|
||||||
@@ -312,6 +323,7 @@ sy_rebooting:"正在重启,约 20 秒后重新连接",sy_bytes:"字节",
|
|||||||
cw_title:"写入此启动配置?",cw_save_title:"将运行配置保存到 Flash?",
|
cw_title:"写入此启动配置?",cw_save_title:"将运行配置保存到 Flash?",
|
||||||
cw_info:"{n} / 2048 字节,每次启动时逐行执行",
|
cw_info:"{n} / 2048 字节,每次启动时逐行执行",
|
||||||
cw_toolarge:"过大: 配置扇区最多容纳 2048 字节。请先删除部分行。",
|
cw_toolarge:"过大: 配置扇区最多容纳 2048 字节。请先删除部分行。",
|
||||||
|
cw_longline:"第 {n} 行有 {m} 字节: 交换机启动时只能执行不超过 126 字节的行,该行会被跳过,因此拒绝写入。请先缩短该行。",
|
||||||
cw_unknown:"不属于已知配置语法的行 (仍会写入): ",cw_empty:"(空)",
|
cw_unknown:"不属于已知配置语法的行 (仍会写入): ",cw_empty:"(空)",
|
||||||
cw_writing:"正在写入配置...",cw_failed:"配置写入失败: HTTP {n}",
|
cw_writing:"正在写入配置...",cw_failed:"配置写入失败: HTTP {n}",
|
||||||
cw_verify_fail:"校验失败: Flash 内容与发送内容不一致。命令日志未清除。",
|
cw_verify_fail:"校验失败: Flash 内容与发送内容不一致。命令日志未清除。",
|
||||||
@@ -405,6 +417,7 @@ bw_exceed:"Al excederse",bw_fc:"Control de flujo",bw_drop:"Descartar",
|
|||||||
bw_in_err:"El límite de entrada debe estar entre 0.016 y 10000 Mbit/s",bw_out_err:"El límite de salida debe estar entre 0.016 y 10000 Mbit/s",
|
bw_in_err:"El límite de entrada debe estar entre 0.016 y 10000 Mbit/s",bw_out_err:"El límite de salida debe estar entre 0.016 y 10000 Mbit/s",
|
||||||
sy_network:"Red",sy_dhcp:"Usar DHCP",sy_dhcp_t:"Solicitar dirección mediante DHCP",sy_services:"Servicios",
|
sy_network:"Red",sy_dhcp:"Usar DHCP",sy_dhcp_t:"Solicitar dirección mediante DHCP",sy_services:"Servicios",
|
||||||
sy_igmp:"IGMP snooping",sy_sysip:"IP del servidor",sy_server:"Servidor",sy_port:"Puerto",
|
sy_igmp:"IGMP snooping",sy_sysip:"IP del servidor",sy_server:"Servidor",sy_port:"Puerto",
|
||||||
|
sy_sesstmo:"Tiempo de sesión (s)",sy_sesstmo_err:"El tiempo de sesión debe estar entre 1 y 65535 s",
|
||||||
sy_services_note:"El estado del servicio refleja la configuración de inicio; el estado en ejecución no es legible.",
|
sy_services_note:"El estado del servicio refleja la configuración de inicio; el estado en ejecución no es legible.",
|
||||||
sy_password:"Contraseña de administrador",sy_newpw:"Nueva contraseña",sy_repeat:"Repetir",sy_pwapply:"Cambiar contraseña",
|
sy_password:"Contraseña de administrador",sy_newpw:"Nueva contraseña",sy_repeat:"Repetir",sy_pwapply:"Cambiar contraseña",
|
||||||
sy_pw_note:"Toma efecto inmediatamente; guarda en flash para conservarla tras el reinicio.",sy_console:"Consola",
|
sy_pw_note:"Toma efecto inmediatamente; guarda en flash para conservarla tras el reinicio.",sy_console:"Consola",
|
||||||
@@ -443,6 +456,235 @@ fw_applied:"actualización aplicada",fw_done_t:"Firmware actualizado",
|
|||||||
fw_done:"El switch verificó la imagen y se reinició con ella. La sesión se restableció, así que se te pedirá que vuelvas a iniciar sesión.",
|
fw_done:"El switch verificó la imagen y se reinició con ella. La sesión se restableció, así que se te pedirá que vuelvas a iniciar sesión.",
|
||||||
fw_login:"Ir al inicio de sesión",fw_rebooting:"el switch se está reiniciando...",
|
fw_login:"Ir al inicio de sesión",fw_rebooting:"el switch se está reiniciando...",
|
||||||
fw_timeout:"el switch no ha vuelto tras 150 s: comprueba la alimentación / consola serie"
|
fw_timeout:"el switch no ha vuelto tras 150 s: comprueba la alimentación / consola serie"
|
||||||
|
},
|
||||||
|
fr:{
|
||||||
|
nav_dash:"Tableau de bord",nav_ports:"Ports",nav_stp:"Arborescence",nav_stats:"Statistiques",
|
||||||
|
nav_vlan:"LANs virtuels",nav_l2:"Table MAC",nav_mirror:"Mise en mirroir",nav_lag:"Aggrégation",nav_eee:"Energie",
|
||||||
|
nav_bw:"Bande passante",nav_system:"Système",nav_fw:"Micro logiciel",
|
||||||
|
hdr_dirty:"Changements non sauvegardés",hdr_dirty_t:"La configuration utilisée diffère de celle au démarrage",
|
||||||
|
hdr_save:"Sauvegarder en flash",hdr_save_t:"Maintenir la configuration actuelle en flash",
|
||||||
|
th_auto:"Système",th_auto_sel:"Système (sélénisé)",sy_display:"Affichage",sy_theme:"Thème",sy_display_note:"Enregistré seulement dans ce navigateur.",th_light:"Clair",th_dark:"Sombre",
|
||||||
|
th_sel_light:"Clair (sélénisé)",th_sel_dark:"Sombre (sélénisé)",
|
||||||
|
c_port:"Port",c_name:"Nom",c_link:"Lien",c_apply:"Appliquer",c_cancel:"Annuler",c_confirm:"Confirmer",
|
||||||
|
c_close:"Fermer",c_refresh:"Raffraichir",c_off:"arrêt",c_offc:"Arrêt",c_down:"arrêt",c_on:"Marche",c_auto:"Auto",c_delete:"Supprimer",
|
||||||
|
c_type:"Type",c_state:"Etat",c_enabled:"Activé",c_load:"Charger",c_disable:"Désactivé",c_sfp:"SFP",
|
||||||
|
c_full:"full",c_half:"half",c_devices:"Equipements",c_yes:"oui",c_no:"non",
|
||||||
|
d_ports:"Ports",d_ports_h:"Cliquez ou survollez pour plus de détails",d_system:"Système",d_traffic:"Trafic",
|
||||||
|
d_traffic_h:"paquets/s (en direct)",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX KO",d_rxbad:"RX KO",
|
||||||
|
i_host:"Nom d'hote",i_ip:"Adresse IP",i_mask:"Masque réseau",i_gw:"Passerelle",i_mac:"Adresse MAC",i_fw:"Micro logiciel",
|
||||||
|
i_built:"Compilé le",i_hw:"Matériel",i_temp:"Température",i_flash:"Taille Flash",i_syslog:"Journal système",
|
||||||
|
p_state:"Etat",p_disabled:"Inactif",p_up:"Actif",p_txgb:"TX bon / mauvais",p_rxgb:"RX bon / mauvais",
|
||||||
|
p_pkts:"paquets",p_module:"Module",p_temp:"Température",p_vcc:"Vcc",p_txbias:"TX biais",p_txpower:"TX puissance",
|
||||||
|
p_rxpower:"RX puissance",p_txfault:"TX erreur",p_txdis:"TX désactivé",p_rxlos:"RX pertes de signaux",p_adv:"Capacités",
|
||||||
|
pt_title:"Configuration du port",pt_conn:"Connecté à",pt_speed:"Vitesse",pt_mtu:"MTU",
|
||||||
|
pt_sfp_note:"La vitesse SFP est paramétrée pour le port et n'est pas enregistrée dans la configuration de démarrage.",
|
||||||
|
pt_name_err:"Nom du port: 1 à 15 caractères, sans espaces",pt_mtu_err:"MTU doit être comrpis entre 64 et 16383",
|
||||||
|
stp_title:"Arborescence",stp_h:"RSTP, 802.1w",stp_version:"Protocole",stp_v_stp:"Compatible STP",
|
||||||
|
stp_prio:"Priorité",stp_hello:"Bonjour [s]",stp_maxage:"Age max [s]",stp_fwd:"Délai de transmission [s]",
|
||||||
|
stp_txhold:"TX en attente",stp_bridge_apply:"Appliquer les paramètres du pont",
|
||||||
|
stp_off_msg:"Arborescence désactivée: Tous les ports sont retransmis.",stp_bridge:"Pont",stp_root:"Racine",
|
||||||
|
stp_root_self:"Ce pont est la racine",stp_via:"via le port",stp_cost:"coût du chemin",stp_tc:"changements de topologie",
|
||||||
|
stp_prio_note:"La priorité la plus basse devient la racine (défaut 8 à 32768). Les paramètres s'appliquent immediatement; utiliser Sauvegarder en flash pour les conserver.",
|
||||||
|
stp_portcfg:"Configuration du port",stp_edge:"Port terminal",stp_pcost:"Coût du chemin",stp_pprio:"Priorité",
|
||||||
|
stp_guard:"Protection",stp_filter:"Filtre BPDU",stp_p2p:"Point-à-point",
|
||||||
|
stp_port_note:"Les ports en bordure sont transmis immediatemment et ne change pas la topologie; Auto traite le port comme une bordure après 3s sans BPDUs, et chaque BPDU reçu le révoque. Le coût du chemin 0 = automatique.",
|
||||||
|
stp_status:"Statut du port",stp_role:"Rôle",stp_db:"Pont désigné",stp_dp:"Port désigné",
|
||||||
|
stp_dc:"Coût désigné",stp_oedge:"Oper. terminales",stp_op2p:"Oper. en P2P",
|
||||||
|
stp_s0:"désactivé",stp_s1:"bloquage",stp_s2:"apprentissage",stp_s3:"retransmission",
|
||||||
|
stp_r1:"Racine",stp_r2:"Designé",stp_r3:"Alternatif",stp_trip:"protection déclenchée",
|
||||||
|
stp_g_none:"Aucun",stp_g_bpdu:"BPDU",stp_g_root:"Racine",
|
||||||
|
stp_en_q:"Activer l'arbrescence?",
|
||||||
|
stp_en_d:"Les ports sont d'abord bloqués et cela prend deux fois le délai de retransmission pour atteindre l'état de retransmission; les ports en bordures recouvrent immédiatement leur état.",
|
||||||
|
stp_dis_q:"Désactiver l'arborescence ?",stp_dis_d:"Tous les ports vont être retransmis; la protection de boucles est perdue.",
|
||||||
|
stp_cost_err:"Le coût du chemin doit être compris entre 0 et 200000000",
|
||||||
|
st_title:"Statiqtique du port",st_h:"cumul depuis le démarrage",st_txg:"TX OK",st_txb:"TX KO",st_rxg:"RX OK",
|
||||||
|
st_rxb:"RX KO",st_details:"Détails",st_counters:"Compteur MIB",st_nonzero:"non-zero seulement",
|
||||||
|
st_autoref:"rafraichissement automatique",st_counter:"Compteur",st_value:"Valeur",st_fail:"Erreur au chargement des compteurs",
|
||||||
|
v_title:"VLANs",v_vid:"VID",v_members:"Membres",v_tagged:"Tagué",v_untagged:"Détagué",v_pvid_on:"PVID on",
|
||||||
|
v_empty:"Aucun VLANs configuré.",v_mgmt:"VLAN de management",v_mgmt_none:"détagué",v_editor:"Editeur de VLAN",
|
||||||
|
v_optional:"optionel",v_setmgmt:"Mette en VLAN de management",v_setmgmt_t:"Mettre celui-ci en VLAN de management",
|
||||||
|
v_member:"Membre",v_pvid:"PVID",
|
||||||
|
v_legend:"U = Membre détagué (UnTagged), T = membre tagué (Tagged), - = non membre. PVID (Port VLan ID) assigne ce VLAN au trafic entrant non tagué.",
|
||||||
|
v_ingress:"Filtrage entrant",v_ingress_h:"en ériture seule: cet état n'est pas lisible depuis le communtateur réseau",
|
||||||
|
v_accept:"Accepté",v_ing_all:"Tous",v_ing_apply:"Appliquer les filtes",v_del_t:"Supprimer le VLAN",
|
||||||
|
v_del_q:"Supprimer le VLAN {n}?",v_del_d:"Les ports conservent leur PVID tant qu'ils ne sont pas réassignés.",
|
||||||
|
v_vid_err:"Entrez un identifiant VLAN (1-4094)",v_name_err:"Le nom doit commencer par une lettre (lettre, chiffres, _)",
|
||||||
|
v_loaded:"VLAN chargés {n}",v_notfound:"VLAN {n} non trouvé (un nouveau peut toutefois être créé)",
|
||||||
|
v_nomember:"Selectionnez au moins un port membre (ou supprimez le VLAN)",
|
||||||
|
v_ing_none:"Sélectionnez le mode entrant pour au moins un port",v_vid_first:"Entrez un identifiant VLAN d'abord",
|
||||||
|
v_mgmt_q:"Mettre ce VLAN {n} en tant que VLAN de management?",
|
||||||
|
v_mgmt_d:"Ce commutateur commencera par taguer son propre trafic avec ce VLAN. Si le port avec lequel vous êtes connecté ne le permet pas, cette page deviendra inaccessible et les paramètres ne pourront plus être changés que via la console.",
|
||||||
|
l2_title:"Table des adresses MAC",l2_filter:"filtre...",l2_flush:"Effacer les entrées apprises",l2_static:"static",
|
||||||
|
l2_learned:"appris",l2_loading:"chargement...",l2_failed:"chargement non réussi",l2_entries:"entrées",
|
||||||
|
l2_del_t:"Supprimer l'entrée",l2_flush_q:"Effacer toutes les entrées MAC apprises?",
|
||||||
|
m_title:"Duplication de ports",m_active:"actif",m_monitor:"Port de supervision",m_mirror:"Mirroir",m_both:"RX&TX",
|
||||||
|
m_note:"RX&TX = duplique RX et TX du port vers le port de supervision.",m_none:"Selectionnez au moins un port à dupliquer",
|
||||||
|
lag_hash:"Hachage:",lag_note:"Un groupe d'agrégation de Lien (LAG) nécessite au moins un membre pour être sauvegardé dans la configuration de démarrage; Utiliser un groupe vide fait office de remise à zero.",
|
||||||
|
lag_clear_q:"Effacer l'agrégation {n}?",lag_clear_d:"Tous les ports membres vont redevenir normaux.",
|
||||||
|
e_title:"Gestion énergétique des ports",e_adv:"Capacités",e_lp:"Capacité du partenaire",e_active:"Actif",e_enable:"Basse consommation",
|
||||||
|
e_note:"Capacité de l'hôte et des partenaires : 100M, 1G, 2.5G. Les ports SFP ne peuvent pas bénéficier de l'EEE.",
|
||||||
|
e_idle:"Inactif",e_na:"N/A",
|
||||||
|
bw_title:"Limitations de bande passante",bw_h:"Mbit/s, 0.016-10000",bw_in:"Limite entrante",bw_out:"Limite sortante",
|
||||||
|
bw_exceed:"Lorsque dépassé",bw_fc:"Limiter",bw_drop:"Rejetter",
|
||||||
|
bw_in_err:"La limite entrante doit être comprise entre 0.016 et 10000 Mbit/s",bw_out_err:"La limite sortante doit être comprise entre 0.016 et 10000 Mbit/s",
|
||||||
|
sy_network:"Réseau",sy_dhcp:"Uiliser DHCP",sy_dhcp_t:"Aquérir l'adresse via le protocole DHCP",sy_services:"Services",
|
||||||
|
sy_igmp:"Surveillance IGMP",sy_sysip:"IP du serveur...",sy_server:"Serveur",sy_port:"Port",
|
||||||
|
sy_sesstmo:"Temps mort de session (s)",sy_sesstmo_err:"Le temps morts de session doit être compris en 1-65535 s",
|
||||||
|
sy_services_note:"L'état de service dépend de la configuration de démarrage; Le temps de fonctionnement n'est pas consultable.",
|
||||||
|
sy_password:"Gestion de l'accès",sy_newpw:"Mot de passe",sy_repeat:"Confirmation",sy_pwapply:"Changer le mot de passe",
|
||||||
|
sy_pw_note:"Prends effet immédiatement; Sauvegardez en flash afin de conserver la configuration lors du redémarrage.",sy_console:"Console",
|
||||||
|
sy_cmd:"Ligne de commande...",sy_send:"Envoyer",sy_startup:"Configuration de démarrage",sy_replayed:"Rejouée à chaque redémarrage",
|
||||||
|
sy_reload:"Recharger depuis la mémoire flash",sy_write:"Ecrire en mémoire flash",sy_unknown_note:"Les lignes incorrectes sont mises en évidence avant l'écriture.",
|
||||||
|
sy_maint:"Maintenance",sy_reboot:"Redémarre le commutateur",sy_lang:"Langage",
|
||||||
|
sy_ip_err:"Erreur d'IP / masque réseau / passerelle",sy_host_err:"Nom d'hôte : 1 à 23 caractères, sans espace ni apostrophes",
|
||||||
|
sy_net_q:"Appliquer les paramètres réseau?",sy_net_d:"L'adresse IP de management va devenir {ip}: merci de réouvrir le page depuis cette adresse.",
|
||||||
|
sy_ip_changed:"L'adresse IP a changée, reconnectez-vous à http://{ip}/",sy_dhcp_q:"Passer en DHCP?",
|
||||||
|
sy_dhcp_d:"Le commutateur va demander une addresse via le DHCP. Vous devrez rechercher sa prochaine adresse IP pour vous reconnecter.",
|
||||||
|
sy_sysip_err:"Adresse IP du serveur Syslog invalide",sy_sysport_err:"Le port Syslog doit être compris entre 1 et 65535",
|
||||||
|
sy_pw_len:"Mot de passe : 1 à 20 caractères",sy_pw_space:"Le mot de passe ne doit pas contenir d'espaces",sy_pw_match:"Les mots de passe ne correspondent pas",
|
||||||
|
sy_pw_q:"Changer le mot de passe d'administration?",sy_pw_d:"Cela prend effet immédiatement dès la prochaine connection. Enregistrez en Flash pour rendre la modification persistante.",
|
||||||
|
sy_reboot_q:"Redémarrer le commutateur ?",sy_reboot_d:"Il y a des paramètres NON SAUVEGARDES qui vont être perdus. Sauvegardez-les au préalable en mémoire flash si vous souhaitez les conserver.",
|
||||||
|
sy_rebooting:"Redémarrage, reconnectez-vous d'ici 20s",sy_bytes:"bytes",
|
||||||
|
cw_title:"Enregistrer cette configuration de démarrage?",cw_save_title:"Enregistrer la configuration active en mémoire flash?",
|
||||||
|
cw_info:"{n} / 2048 bytes, qui seront rejouées ligne par ligne à chaque redémarrage",
|
||||||
|
cw_toolarge:"Trop grand : La quota du secteur de démarrage ne peut excéder 2048 bytes. Supprimez des lignes.",
|
||||||
|
cw_longline:"La ligne {n} est longue de {m} bytes: Le commutateur ne peut exécuter des lignes de plus de 126 bytes et les omettra donc au démarragee, l'écriture est refusé. Raccourcissez les d'abord.",
|
||||||
|
cw_unknown:"Ne respecte pas la grammaire de configuration (sera néanmoins sauvegardé): ",cw_empty:"(vide)",
|
||||||
|
cw_writing:"Configuration enregistrée...",cw_failed:"Echec de l'enregistrement de la configuration: HTTP {n}",
|
||||||
|
cw_verify_fail:"Verification erronée: La mémoire flash présente des différences par rapport à ce qui a été transmis. Le log de commande ne sera pas éffacé.",
|
||||||
|
cw_saved:"Configuration de démarrage sauvegardée et vérifiée",cw_collect:"Récolement des modification des paramètres courants...",
|
||||||
|
t_applied:"Appliqué: {c}",t_cmds:"{n} commande(s) appliquée(s)",t_rejected:"commandes rejetées: {c}",t_failed:"échecs: {c}",
|
||||||
|
fw_title:"Mise à jour du micro-logiciel",
|
||||||
|
fw_intro:"Charge une image RTLPlayground (512 KiB .bin). L'image est envoée en mémoire flash, analysée et sa somme de contrôle est vérifiée; en cas de succès le commutateur va redémarrer, re-verifiez l'image et appliquez-là. LA configuration de démarrage est conservée.",
|
||||||
|
fw_upload:"Charger",fw_checking:"{f}: {n} bytes. Vérification...",fw_size_err:"la taille est {n} alors que nous attendons 524288 (512 KiB)",
|
||||||
|
fw_magic_err:"Entête de banque de donnée manquant / contrôle LJMP: ce n'est pas une image de firmware",fw_crc_err:"Somme de contrôle erronée: image corrompue",
|
||||||
|
fw_valid:"Image RTLPlayground valide (taille, LJMP et somme de contrôle OK)",fw_q:"Chargement du firmware?",
|
||||||
|
fw_d:"Si la somme de contrôle est correcte, le commutateur va redémarrer tout seul et charger la nouvelle image lors du démarrage (la configuration est préservée). Ne pas éteindre l'appareil avant que les voyants ne s'éteignent.",
|
||||||
|
fw_finishing:"Fin d'écriture en mémoire flash... {s} s",fw_uploading:"Chargement... {p}% / {s} s",
|
||||||
|
fw_verified:"Somme de contrôle vérifiée, le commutateur redémarre...",
|
||||||
|
fw_rejected:"L'image est rejettée en raison d'une somme de contrôle incorrecte, rien n'a été appliqué",
|
||||||
|
fw_lost:"Erreur lors du chargement: connection perdue à mi-transfert",
|
||||||
|
fw_noreboot:"Pas de redemarrage détecté: l'image a certainement été refusée. Si vous chargesz un ancien firmware, verifiez la version affichée après l'écran de connection.",
|
||||||
|
fw_applied:"Mise à jour effectuée",fw_done_t:"Firmware mis à jour",
|
||||||
|
fw_done:"Le commutateur a vérifié l'image et vient de redémarrer. La session a été remise à zero, vous devez vous reconnecter.",
|
||||||
|
fw_login:"Vers l'écran de connection",fw_rebooting:"Le commutateur redémarre...",
|
||||||
|
fw_timeout:"Le commutateur n'est plus joignable depuis 150 s: verifiez l'alimentation ou utilisez la console série"
|
||||||
|
},
|
||||||
|
de:{
|
||||||
|
nav_dash:"Übersicht",nav_ports:"Ports",nav_stp:"Spanning Tree",nav_stats:"Statistik",
|
||||||
|
nav_vlan:"VLANs",nav_l2:"MAC-Tabelle",nav_mirror:"Spiegelung",nav_lag:"LAG",nav_eee:"EEE",
|
||||||
|
nav_bw:"Bandbreite",nav_system:"System",nav_fw:"Firmware",
|
||||||
|
hdr_dirty:"ungespeicherte Änderungen",hdr_dirty_t:"Laufende Konfiguration weicht von der Startkonfiguration ab",
|
||||||
|
hdr_save:"Im Flash speichern",hdr_save_t:"Laufende Konfiguration dauerhaft im Flash speichern",
|
||||||
|
th_auto:"System",th_auto_sel:"System (Selenized)",sy_display:"Anzeige",sy_theme:"Farbschema",sy_display_note:"Wird nur in diesem Browser gespeichert.",th_light:"Hell",th_dark:"Dunkel",
|
||||||
|
th_sel_light:"Selenized Hell",th_sel_dark:"Selenized Dunkel",
|
||||||
|
c_port:"Port",c_name:"Name",c_link:"Link",c_apply:"Übernehmen",c_cancel:"Abbrechen",c_confirm:"Bestätigen",
|
||||||
|
c_close:"Schliessen",c_refresh:"Aktualisieren",c_off:"aus",c_offc:"Aus",c_down:"getrennt",c_on:"Ein",c_auto:"Auto",c_delete:"Löschen",
|
||||||
|
c_type:"Typ",c_state:"Zustand",c_enabled:"Aktiviert",c_load:"Laden",c_disable:"Deaktivieren",c_sfp:"SFP",
|
||||||
|
c_full:"voll",c_half:"halb",c_devices:"Geräte",c_yes:"ja",c_no:"nein",
|
||||||
|
d_ports:"Ports",d_ports_h:"Port anklicken für Details",d_system:"System",d_traffic:"Datenverkehr",
|
||||||
|
d_traffic_h:"Pakete/s, live",d_txpps:"TX Pakete/s",d_rxpps:"RX Pakete/s",d_txbad:"TX fehlerhaft",d_rxbad:"RX fehlerhaft",
|
||||||
|
i_host:"Hostname",i_ip:"IP-Adresse",i_mask:"Netzmaske",i_gw:"Gateway",i_mac:"MAC",i_fw:"Firmware",
|
||||||
|
i_built:"Erstellt",i_hw:"Hardware",i_temp:"Temperatur",i_flash:"Flash",i_syslog:"Syslog",
|
||||||
|
p_state:"Zustand",p_disabled:"deaktiviert",p_up:"verbunden",p_txgb:"TX gut / fehlerhaft",p_rxgb:"RX gut / fehlerhaft",
|
||||||
|
p_pkts:"Pakete",p_module:"Modul",p_temp:"Temperatur",p_vcc:"Vcc",p_txbias:"TX-Bias",p_txpower:"Sendeleistung",
|
||||||
|
p_rxpower:"Empfangsleistung",p_txfault:"TX-Fehler",p_txdis:"TX deaktiviert",p_rxlos:"RX LOS",p_adv:"Angeboten",
|
||||||
|
pt_title:"Port-Konfiguration",pt_conn:"Verbunden",pt_speed:"Geschwindigkeit",pt_mtu:"MTU",
|
||||||
|
pt_sfp_note:"Die SFP-Geschwindigkeit wird pro Steckplatz gesetzt und nicht in der Startkonfiguration gespeichert.",
|
||||||
|
pt_name_err:"Port-Name: 1-15 Zeichen, keine Leerzeichen",pt_mtu_err:"MTU muss zwischen 64 und 16383 liegen",
|
||||||
|
stp_title:"Spanning Tree",stp_h:"RSTP, 802.1w",stp_version:"Version",stp_v_stp:"STP-kompatibel",
|
||||||
|
stp_prio:"Bridge-Priorität",stp_hello:"Hello [s]",stp_maxage:"Max. Alter [s]",stp_fwd:"Forward Delay [s]",
|
||||||
|
stp_txhold:"TX Hold",stp_bridge_apply:"Bridge-Einstellungen übernehmen",
|
||||||
|
stp_off_msg:"Spanning Tree ist deaktiviert: Alle Ports leiten weiter.",stp_bridge:"Bridge",stp_root:"Root",
|
||||||
|
stp_root_self:"diese Bridge ist Root",stp_via:"über Port",stp_cost:"Pfadkosten",stp_tc:"Topologieänderungen",
|
||||||
|
stp_prio_note:"Die niedrigere Priorität gewinnt die Root-Wahl (Standard 8 = 32768). Einstellungen wirken sofort; mit „Im Flash speichern“ bleiben sie erhalten.",
|
||||||
|
stp_portcfg:"Port-Konfiguration",stp_edge:"Edge",stp_pcost:"Pfadkosten",stp_pprio:"Priorität",
|
||||||
|
stp_guard:"Guard",stp_filter:"BPDU-Filter",stp_p2p:"Punkt-zu-Punkt",
|
||||||
|
stp_port_note:"Edge-Ports leiten sofort weiter und lösen keine Topologieänderung aus; bei Auto gilt ein Port nach 3 s ohne BPDUs als Edge, jede empfangene BPDU hebt das wieder auf. Pfadkosten 0 = automatisch.",
|
||||||
|
stp_status:"Port-Status",stp_role:"Rolle",stp_db:"Designated Bridge",stp_dp:"Designated Port",
|
||||||
|
stp_dc:"Designated Cost",stp_oedge:"Edge (aktiv)",stp_op2p:"P2P (aktiv)",
|
||||||
|
stp_s0:"deaktiviert",stp_s1:"blockiert",stp_s2:"lernt",stp_s3:"leitet weiter",
|
||||||
|
stp_r1:"Root",stp_r2:"Designated",stp_r3:"Alternate",stp_trip:"Guard ausgelöst",
|
||||||
|
stp_g_none:"Keiner",stp_g_bpdu:"BPDU",stp_g_root:"Root",
|
||||||
|
stp_en_q:"Spanning Tree aktivieren?",
|
||||||
|
stp_en_d:"Die Ports starten blockiert und brauchen bis zum doppelten Forward Delay, bis sie weiterleiten; Edge-Ports sind sofort wieder aktiv.",
|
||||||
|
stp_dis_q:"Spanning Tree deaktivieren?",stp_dis_d:"Alle Ports leiten sofort weiter; der Schutz vor Netzwerkschleifen entfällt.",
|
||||||
|
stp_cost_err:"Pfadkosten müssen zwischen 0 und 200000000 liegen",
|
||||||
|
st_title:"Port-Statistik",st_h:"Summen seit dem Start",st_txg:"TX gut",st_txb:"TX fehlerhaft",st_rxg:"RX gut",
|
||||||
|
st_rxb:"RX fehlerhaft",st_details:"Details",st_counters:"MIB-Zähler",st_nonzero:"nur ungleich null",
|
||||||
|
st_autoref:"automatisch aktualisieren",st_counter:"Zähler",st_value:"Wert",st_fail:"Zähler konnten nicht geladen werden",
|
||||||
|
v_title:"VLANs",v_vid:"VID",v_members:"Mitglieder",v_tagged:"Tagged",v_untagged:"Untagged",v_pvid_on:"PVID auf",
|
||||||
|
v_empty:"Keine VLANs konfiguriert.",v_mgmt:"Management-VLAN",v_mgmt_none:"untagged",v_editor:"VLAN-Editor",
|
||||||
|
v_optional:"optional",v_setmgmt:"Als Management-VLAN",v_setmgmt_t:"Dieses VLAN zum Management-VLAN machen",
|
||||||
|
v_member:"Mitglied",v_pvid:"PVID",
|
||||||
|
v_legend:"U = Mitglied untagged, T = Mitglied tagged, - = kein Mitglied. PVID ordnet eingehenden Verkehr ohne Tag diesem VLAN zu.",
|
||||||
|
v_ingress:"Ingress-Filter",v_ingress_h:"nur schreibbar: der Zustand lässt sich vom Switch nicht auslesen",
|
||||||
|
v_accept:"Annehmen",v_ing_all:"Alle",v_ing_apply:"Ingress-Modi übernehmen",v_del_t:"VLAN löschen",
|
||||||
|
v_del_q:"VLAN {n} löschen?",v_del_d:"Die Ports behalten ihre PVID, bis sie neu zugewiesen wird.",
|
||||||
|
v_vid_err:"VLAN-ID eingeben (1-4094)",v_name_err:"Der Name muss mit einem Buchstaben beginnen (Buchstaben, Ziffern, _)",
|
||||||
|
v_loaded:"VLAN {n} geladen",v_notfound:"VLAN {n} nicht gefunden (es kann neu angelegt werden)",
|
||||||
|
v_nomember:"Mindestens einen Mitglieds-Port wählen (oder das VLAN stattdessen löschen)",
|
||||||
|
v_ing_none:"Für mindestens einen Port einen Ingress-Modus wählen",v_vid_first:"Zuerst eine VLAN-ID eingeben",
|
||||||
|
v_mgmt_q:"VLAN {n} als Management-VLAN setzen?",
|
||||||
|
v_mgmt_d:"Der Switch versieht dann seinen eigenen Verkehr mit diesem VLAN-Tag. Führt der Port, über den du verbunden bist, dieses VLAN nicht, ist diese Seite nicht mehr erreichbar und die Einstellung lässt sich nur noch über die serielle Konsole zurücknehmen.",
|
||||||
|
l2_title:"MAC-Adresstabelle",l2_filter:"filtern...",l2_flush:"Gelernte Einträge löschen",l2_static:"statisch",
|
||||||
|
l2_learned:"gelernt",l2_loading:"lädt...",l2_failed:"Laden fehlgeschlagen",l2_entries:"Einträge",
|
||||||
|
l2_del_t:"Eintrag löschen",l2_flush_q:"Alle gelernten MAC-Einträge löschen?",
|
||||||
|
m_title:"Port-Spiegelung",m_active:"aktiv",m_monitor:"Monitor-Port",m_mirror:"Spiegeln",m_both:"Beide",
|
||||||
|
m_note:"Beide = RX und TX des Ports auf den Monitor-Port spiegeln.",m_none:"Mindestens einen zu spiegelnden Port wählen",
|
||||||
|
lag_hash:"Hash:",lag_note:"Eine LAG braucht mindestens ein Mitglied, um in der Startkonfiguration gespeichert zu werden; eine leere Gruppe zu übernehmen löscht sie.",
|
||||||
|
lag_clear_q:"LAG {n} auflösen?",lag_clear_d:"Alle Mitglieds-Ports kehren in den Normalbetrieb zurück.",
|
||||||
|
e_title:"Energy Efficient Ethernet",e_adv:"Angeboten",e_lp:"Gegenstelle",e_active:"Aktiv",e_enable:"Aktivieren",
|
||||||
|
e_note:"Angebotene und von der Gegenstelle unterstützte Stufen je Geschwindigkeit: 100M, 1G, 2.5G. SFP-Ports unterstützen kein EEE.",
|
||||||
|
e_idle:"inaktiv",e_na:"k. A.",
|
||||||
|
bw_title:"Bandbreitenbegrenzung",bw_h:"Mbit/s, 0.016-10000",bw_in:"Eingangslimit",bw_out:"Ausgangslimit",
|
||||||
|
bw_exceed:"Bei Überschreitung",bw_fc:"Flusskontrolle",bw_drop:"Verwerfen",
|
||||||
|
bw_in_err:"Eingangslimit muss zwischen 0.016 und 10000 Mbit/s liegen",bw_out_err:"Ausgangslimit muss zwischen 0.016 und 10000 Mbit/s liegen",
|
||||||
|
sc_title:"Storm Control",sc_h:"pro Port und Verkehrsart, leer = aus",sc_bcast:"Broadcast",sc_mcast:"Multicast",
|
||||||
|
sc_ucast:"Unbekannter Unicast",sc_umcast:"Unbekannter Multicast",sc_err:"Grenzwert muss 1-1048575 pps oder 1-10000000 kbit/s betragen",
|
||||||
|
sc_note:"Pakete einer Verkehrsart über ihrem Grenzwert werden beim Eintritt in den Switch verworfen.",
|
||||||
|
sy_network:"Netzwerk",sy_dhcp:"DHCP verwenden",sy_dhcp_t:"Adresse per DHCP beziehen",sy_services:"Dienste",
|
||||||
|
sy_igmp:"IGMP Snooping",sy_sysip:"Server-IP",sy_server:"Server",sy_port:"Port",
|
||||||
|
sy_sesstmo:"Sitzungs-Timeout (s)",sy_sesstmo_err:"Sitzungs-Timeout muss zwischen 1 und 65535 s liegen",
|
||||||
|
sy_services_note:"Der Dienststatus entspricht der Startkonfiguration; der laufende Zustand ist nicht auslesbar.",
|
||||||
|
sy_password:"Admin-Passwort",sy_newpw:"Neues Passwort",sy_repeat:"Wiederholen",sy_pwapply:"Passwort ändern",
|
||||||
|
sy_pw_note:"Wirkt sofort; im Flash speichern, damit es nach einem Neustart erhalten bleibt.",sy_console:"Konsole",
|
||||||
|
sy_cmd:"CLI-Befehl...",sy_send:"Senden",sy_startup:"Startkonfiguration",sy_replayed:"wird bei jedem Start ausgeführt",
|
||||||
|
sy_reload:"Aus dem Flash neu laden",sy_write:"In den Flash schreiben",sy_unknown_note:"Unbekannte Zeilen werden vor dem Schreiben hervorgehoben.",
|
||||||
|
sy_maint:"Wartung",sy_reboot:"Switch neu starten",sy_lang:"Sprache",
|
||||||
|
sy_ip_err:"Ungültige IP / Netzmaske / Gateway",sy_host_err:"Hostname: 1-23 druckbare Zeichen, keine Leerzeichen oder Anführungszeichen",
|
||||||
|
sy_net_q:"Netzwerkeinstellungen übernehmen?",sy_net_d:"Die Management-IP ändert sich auf {ip}: Diese Seite muss dort neu geöffnet werden.",
|
||||||
|
sy_ip_changed:"IP geändert, neu verbinden unter http://{ip}/",sy_dhcp_q:"Auf DHCP umstellen?",
|
||||||
|
sy_dhcp_d:"Der Switch bezieht seine Adresse per DHCP. Du musst seine neue IP herausfinden, um dich wieder zu verbinden.",
|
||||||
|
sy_sysip_err:"Ungültige IP des Syslog-Servers",sy_sysport_err:"Syslog-Port muss zwischen 1 und 65535 liegen",
|
||||||
|
sy_pw_len:"Passwort: 1-20 Zeichen",sy_pw_space:"Das Passwort darf keine Leerzeichen enthalten",sy_pw_match:"Die Passwörter stimmen nicht überein",
|
||||||
|
sy_pw_q:"Admin-Passwort ändern?",sy_pw_d:"Gilt sofort für neue Anmeldungen. Im Flash speichern, damit es erhalten bleibt.",
|
||||||
|
sy_reboot_q:"Switch neu starten?",sy_reboot_d:"Es gibt UNGESPEICHERTE Änderungen, sie gehen verloren. Zuerst im Flash speichern, wenn du sie behalten willst.",
|
||||||
|
sy_rebooting:"Neustart läuft, in etwa 20 s neu verbinden",sy_bytes:"Bytes",
|
||||||
|
cw_title:"Diese Startkonfiguration schreiben?",cw_save_title:"Laufende Konfiguration im Flash speichern?",
|
||||||
|
cw_info:"{n} / 2048 Bytes, wird bei jedem Start Zeile für Zeile ausgeführt",
|
||||||
|
cw_toolarge:"Zu gross: Der Konfigurationssektor fasst höchstens 2048 Bytes. Zuerst Zeilen entfernen.",
|
||||||
|
cw_longline:"Zeile {n} ist {m} Bytes lang: Der Switch kann beim Start nur Zeilen bis 126 Bytes ausführen und würde sie überspringen, deshalb wird das Schreiben abgelehnt. Zuerst kürzen.",
|
||||||
|
cw_unknown:"Nicht in der bekannten Konfigurationssyntax (wird trotzdem geschrieben): ",cw_empty:"(leer)",
|
||||||
|
cw_writing:"Konfiguration wird geschrieben...",cw_failed:"Schreiben der Konfiguration fehlgeschlagen: HTTP {n}",
|
||||||
|
cw_verify_fail:"Prüfung fehlgeschlagen: Der Flash-Inhalt weicht vom Gesendeten ab. Befehlsprotokoll wurde NICHT gelöscht.",
|
||||||
|
cw_saved:"Startkonfiguration gespeichert und geprüft",cw_collect:"Laufende Änderungen werden gesammelt...",
|
||||||
|
t_applied:"Übernommen: {c}",t_cmds:"{n} Befehl(e) übernommen",t_rejected:"Befehl abgelehnt: {c}",t_failed:"fehlgeschlagen: {c}",
|
||||||
|
fw_title:"Firmware-Update",
|
||||||
|
fw_intro:"Ein RTLPlayground-Image hochladen (.bin, 512 KiB). Das Image wird im Flash abgelegt und per CRC geprüft; ist es in Ordnung, startet der Switch neu, prüft das Image erneut und übernimmt es. Die Startkonfiguration bleibt erhalten.",
|
||||||
|
fw_upload:"Hochladen",fw_checking:"{f}: {n} Bytes. Wird geprüft...",fw_size_err:"Grösse ist {n}, erwartet 524288 (512 KiB)",
|
||||||
|
fw_magic_err:"Bank-Header / LJMP-Kennung fehlt: kein Firmware-Image",fw_crc_err:"CRC16-Prüfung fehlgeschlagen: Image beschädigt",
|
||||||
|
fw_valid:"gültiges RTLPlayground-Image (Grösse, Kennung und CRC16 in Ordnung)",fw_q:"Firmware hochladen?",
|
||||||
|
fw_d:"Ist die Prüfsumme korrekt, startet der Switch neu und übernimmt das Image beim Hochfahren (die Startkonfiguration bleibt erhalten). Nicht vom Strom trennen, bis er wieder erreichbar ist.",
|
||||||
|
fw_finishing:"Flash wird fertig beschrieben... {s} s",fw_uploading:"wird hochgeladen... {p}% / {s} s",
|
||||||
|
fw_verified:"Prüfsumme bestätigt, der Switch startet neu...",
|
||||||
|
fw_rejected:"der Switch hat das Image abgelehnt (falsche Prüfsumme), es wurde nichts übernommen",
|
||||||
|
fw_lost:"Hochladen fehlgeschlagen: Verbindung während der Übertragung abgebrochen",
|
||||||
|
fw_noreboot:"kein Neustart erkannt: Das Image wurde sehr wahrscheinlich abgelehnt. Bei einem Update von alter Firmware nach dem erneuten Anmelden die Version in der Seitenleiste prüfen.",
|
||||||
|
fw_applied:"Update übernommen",fw_done_t:"Firmware aktualisiert",
|
||||||
|
fw_done:"Der Switch hat das Image geprüft und damit neu gestartet. Die Sitzung wurde zurückgesetzt, du wirst erneut zur Anmeldung aufgefordert.",
|
||||||
|
fw_login:"Zur Anmeldung",fw_rebooting:"Switch startet neu...",
|
||||||
|
fw_timeout:"Der Switch ist nach 150 s nicht zurück: Stromversorgung / serielle Konsole prüfen"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var rtlLang=(function(){
|
var rtlLang=(function(){
|
||||||
@@ -538,6 +780,7 @@ var CONF_CMDS=[
|
|||||||
/^ip\s+(\d{1,3}\.){3}\d{1,3}$/,/^ip\s+dhcp$/,
|
/^ip\s+(\d{1,3}\.){3}\d{1,3}$/,/^ip\s+dhcp$/,
|
||||||
/^gw\s+(\d{1,3}\.){3}\d{1,3}$/,/^netmask\s+(\d{1,3}\.){3}\d{1,3}$/,
|
/^gw\s+(\d{1,3}\.){3}\d{1,3}$/,/^netmask\s+(\d{1,3}\.){3}\d{1,3}$/,
|
||||||
/^syslog\s+(on|off)$/,/^syslog\s+ip\s+(\d{1,3}\.){3}\d{1,3}$/,/^syslog\s+port\s+\d{1,5}$/,
|
/^syslog\s+(on|off)$/,/^syslog\s+ip\s+(\d{1,3}\.){3}\d{1,3}$/,/^syslog\s+port\s+\d{1,5}$/,
|
||||||
|
/^session\s+\d{1,5}$/,
|
||||||
/^passwd\s+\S+$/,/^hostname\s+\S{1,23}$/,
|
/^passwd\s+\S+$/,/^hostname\s+\S{1,23}$/,
|
||||||
/^vlan\s+\d{1,4}\s+d$/,/^vlan\s+\d{1,4}\s+mgmt$/,
|
/^vlan\s+\d{1,4}\s+d$/,/^vlan\s+\d{1,4}\s+mgmt$/,
|
||||||
/^vlan\s+\d{1,4}(\s+[a-zA-Z]\w*)?(\s+\d{1,2}t?)+$/,
|
/^vlan\s+\d{1,4}(\s+[a-zA-Z]\w*)?(\s+\d{1,2}t?)+$/,
|
||||||
@@ -557,6 +800,7 @@ var CONF_CMDS=[
|
|||||||
/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+p2p\s+(auto|on|off)$/,
|
/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+p2p\s+(auto|on|off)$/,
|
||||||
/^igmp\s+(on|off)$/,/^mtu\s+\d{1,2}\s+\d+$/,
|
/^igmp\s+(on|off)$/,/^mtu\s+\d{1,2}\s+\d+$/,
|
||||||
/^bw\s+(in|out)\s+\d{1,2}\s+\S+$/,
|
/^bw\s+(in|out)\s+\d{1,2}\s+\S+$/,
|
||||||
|
/^storm\s+\d{1,2}\s+(bcast|mcast|ucast|umcast)\s+(off|\d{1,8}\s+(pps|kbps))$/,
|
||||||
];
|
];
|
||||||
function isConfCmd(line){
|
function isConfCmd(line){
|
||||||
for(var i=0;i<CONF_CMDS.length;i++)if(CONF_CMDS[i].test(line))return true;
|
for(var i=0;i<CONF_CMDS.length;i++)if(CONF_CMDS[i].test(line))return true;
|
||||||
@@ -614,6 +858,7 @@ var TABS=[
|
|||||||
{id:"vlan", icon:"M12 3v6M12 9l-7 5M12 9l7 5M5 14v5M19 14v5M3 21h4M17 21h4"},
|
{id:"vlan", icon:"M12 3v6M12 9l-7 5M12 9l7 5M5 14v5M19 14v5M3 21h4M17 21h4"},
|
||||||
{id:"l2", icon:"M4 5h16M4 12h16M4 19h10"},
|
{id:"l2", icon:"M4 5h16M4 12h16M4 19h10"},
|
||||||
{id:"mirror",icon:"M12 3v18M7 8l-4 4 4 4M17 8l4 4-4 4"},
|
{id:"mirror",icon:"M12 3v18M7 8l-4 4 4 4M17 8l4 4-4 4"},
|
||||||
|
{id:"isolate",icon:"M4 4h6v6H4zM14 14h6v6h-6zM14 4h6v6h-6zM4 14h6v6H4z"},
|
||||||
{id:"lag", icon:"M7 8a4 4 0 100 8h3M17 8a4 4 0 110 8h-3M9 12h6"},
|
{id:"lag", icon:"M7 8a4 4 0 100 8h3M17 8a4 4 0 110 8h-3M9 12h6"},
|
||||||
{id:"eee", icon:"M13 2L4 14h6l-1 8 9-12h-6z"},
|
{id:"eee", icon:"M13 2L4 14h6l-1 8 9-12h-6z"},
|
||||||
{id:"bw", icon:"M4 18a8 8 0 0116 0M12 18l4-6"},
|
{id:"bw", icon:"M4 18a8 8 0 0116 0M12 18l4-6"},
|
||||||
@@ -796,7 +1041,7 @@ function portDetail(i){
|
|||||||
function renderInfo(){
|
function renderInfo(){
|
||||||
var m=[["i_host","hostname"],["i_ip","ip_address"],["i_mask","ip_netmask"],
|
var m=[["i_host","hostname"],["i_ip","ip_address"],["i_mask","ip_netmask"],
|
||||||
["i_gw","ip_gateway"],["i_mac","mac_address"],["i_fw","sw_ver"],["i_built","build_date"],
|
["i_gw","ip_gateway"],["i_mac","mac_address"],["i_fw","sw_ver"],["i_built","build_date"],
|
||||||
["i_hw","hw_ver"],["i_flash","flash_size"],["i_syslog","syslog_server"]];
|
["i_hw","hw_ver"],["i_temp","chip_temp"],["i_flash","flash_size"],["i_syslog","syslog_server"]];
|
||||||
var tb=$("sysinfo");tb.innerHTML="";
|
var tb=$("sysinfo");tb.innerHTML="";
|
||||||
m.forEach(function(r){
|
m.forEach(function(r){
|
||||||
var v=S.info[r[1]];
|
var v=S.info[r[1]];
|
||||||
@@ -1469,6 +1714,76 @@ $("moff").addEventListener("click",function(){
|
|||||||
});
|
});
|
||||||
tabHooks.mirror={enter:function(){needPorts(function(){buildMirror();mirrorLoad().catch(function(){})})}};
|
tabHooks.mirror={enter:function(){needPorts(function(){buildMirror();mirrorLoad().catch(function(){})})}};
|
||||||
|
|
||||||
|
var isoAllow=[];
|
||||||
|
function isoBox(r,c){return $("iso"+r+"_"+c)}
|
||||||
|
function isoMark(){
|
||||||
|
for(var r=1;r<=S.n;r++){
|
||||||
|
var full=true;
|
||||||
|
for(var c=1;c<=S.n+1;c++){var b=isoBox(r,c);if(b&&!b.checked)full=false;}
|
||||||
|
$("isoh"+r).style.color=full?"":"var(--bad)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function isoTouch(){$("isotbl").dataset.dirty="1";isoMark()}
|
||||||
|
function isoTh(row,txt,attrs){var e=h("th",attrs);e.textContent=txt;row.appendChild(e);return e}
|
||||||
|
function buildIso(){
|
||||||
|
var tb=$("isotbl");
|
||||||
|
if(tb.tBodies[0].rows.length)return;
|
||||||
|
var h1=tb.tHead.insertRow(),h2=tb.tHead.insertRow();
|
||||||
|
isoTh(h1,t("iso_from"),{rowspan:"2"});isoTh(h1,t("iso_to"),{colspan:String(S.n),style:"text-align:center"});isoTh(h1,"CPU",{rowspan:"2"});
|
||||||
|
for(var c=1;c<=S.n;c++)isoTh(h2,String(c),{style:"text-align:center"});
|
||||||
|
for(var r=1;r<=S.n;r++){
|
||||||
|
var tr=tb.tBodies[0].insertRow();
|
||||||
|
isoTh(tr,String(r),{id:"isoh"+r});
|
||||||
|
for(c=1;c<=S.n+1;c++){
|
||||||
|
var td=tr.insertCell();
|
||||||
|
td.style.textAlign="center";
|
||||||
|
if(r===c){td.className="mut";td.textContent="\u2022";continue;}
|
||||||
|
td.appendChild(h("input",{type:"checkbox",id:"iso"+r+"_"+c,onchange:isoTouch}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function isoLoad(){
|
||||||
|
return getJSON("/isolation.json").then(function(s){
|
||||||
|
isoAllow=s;
|
||||||
|
if($("isotbl").dataset.dirty)return;
|
||||||
|
s.forEach(function(e){
|
||||||
|
var m=parseInt(e.allow,16);
|
||||||
|
for(var c=1;c<=S.n;c++){var b=isoBox(e.portNum,c);if(b)b.checked=!!((m>>S.physToLog[c-1])&1);}
|
||||||
|
var cpu=isoBox(e.portNum,S.n+1);
|
||||||
|
if(cpu)cpu.checked=!!(m&0x200);
|
||||||
|
});
|
||||||
|
isoMark();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function isoMask(r){
|
||||||
|
var m=0;
|
||||||
|
for(var c=1;c<=S.n;c++){var b=isoBox(r,c);if(r===c||(b&&b.checked))m|=1<<S.physToLog[c-1];}
|
||||||
|
var cpu=isoBox(r,S.n+1);
|
||||||
|
if(cpu&&cpu.checked)m|=0x200;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
$("isoapply").addEventListener("click",function(){
|
||||||
|
var cmds=[];
|
||||||
|
for(var r=1;r<=S.n;r++){
|
||||||
|
var cur=-1;
|
||||||
|
isoAllow.forEach(function(e){if(e.portNum===r)cur=parseInt(e.allow,16)});
|
||||||
|
if(isoMask(r)===cur)continue;
|
||||||
|
var cmd="isolate "+r;
|
||||||
|
for(var c=1;c<=S.n;c++){var b=isoBox(r,c);if(r===c||(b&&b.checked))cmd+=" "+c;}
|
||||||
|
var cpu=isoBox(r,S.n+1);
|
||||||
|
if(cpu&&cpu.checked)cmd+=" 0";
|
||||||
|
cmds.push(cmd);
|
||||||
|
}
|
||||||
|
delete $("isotbl").dataset.dirty;
|
||||||
|
if(!cmds.length){isoLoad().catch(function(){});return;}
|
||||||
|
postCmds(cmds).then(isoLoad).catch(function(){});
|
||||||
|
});
|
||||||
|
$("isoall").addEventListener("click",function(){
|
||||||
|
for(var r=1;r<=S.n;r++)for(var c=1;c<=S.n+1;c++){var b=isoBox(r,c);if(b)b.checked=true;}
|
||||||
|
isoTouch();
|
||||||
|
});
|
||||||
|
tabHooks.isolate={enter:function(){needPorts(function(){buildIso();isoLoad().catch(function(){})})}};
|
||||||
|
|
||||||
var HASHF=["spa","smac","dmac","sip","dip","sport","dport"];
|
var HASHF=["spa","smac","dmac","sip","dip","sport","dport"];
|
||||||
function buildLag(){
|
function buildLag(){
|
||||||
var w=$("lagwrap");
|
var w=$("lagwrap");
|
||||||
@@ -1605,7 +1920,61 @@ function bwApply(n){
|
|||||||
}else cmds.push("bw out "+n+" off");
|
}else cmds.push("bw out "+n+" off");
|
||||||
postCmds(cmds).then(bwLoad).catch(function(){});
|
postCmds(cmds).then(bwLoad).catch(function(){});
|
||||||
}
|
}
|
||||||
tabHooks.bw={enter:function(){needPorts(function(){bwLoad().catch(function(){})})}};
|
var SC_TYPES=["bcast","mcast","ucast","umcast"],scSig="";
|
||||||
|
function scLoad(){
|
||||||
|
return getJSON("/storm.json").then(function(s){
|
||||||
|
var tb=$("sctable").tBodies[0];
|
||||||
|
byPort(s);
|
||||||
|
var sig=s.map(function(p){return p.portNum}).join();
|
||||||
|
if(sig!==scSig){
|
||||||
|
scSig=sig;tb.innerHTML="";
|
||||||
|
s.forEach(function(p){
|
||||||
|
var n=p.portNum,tr=tb.insertRow();
|
||||||
|
tr.id="scr"+n;
|
||||||
|
tr.addEventListener("input",function(){tr.dataset.dirty="1"});
|
||||||
|
tr.addEventListener("change",function(){tr.dataset.dirty="1"});
|
||||||
|
tr.insertCell().textContent=n;
|
||||||
|
SC_TYPES.forEach(function(ty){
|
||||||
|
tr.insertCell().appendChild(h("span",{style:"display:flex;gap:4px"},[
|
||||||
|
h("input",{class:"in sm",id:"scv"+ty+n,type:"number",min:"1",step:"1"}),
|
||||||
|
h("select",{class:"in",id:"scu"+ty+n},[
|
||||||
|
h("option",{value:"pps",text:"pps"}),
|
||||||
|
h("option",{value:"kbps",text:"kbit/s"}),
|
||||||
|
]),
|
||||||
|
]));
|
||||||
|
});
|
||||||
|
tr.insertCell().appendChild(h("button",{class:"ctl",text:t("c_apply"),onclick:function(){scApply(n)}}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
s.forEach(function(p){
|
||||||
|
var n=p.portNum;
|
||||||
|
if($("scr"+n).dataset.dirty)return;
|
||||||
|
SC_TYPES.forEach(function(ty,k){
|
||||||
|
var on=p.en.charAt(k)==="1",pps=p.pps.charAt(k)==="1",raw=parseInt(p.rate.substr(k*6,6),16);
|
||||||
|
var inp=$("scv"+ty+n),sel=$("scu"+ty+n);
|
||||||
|
inp.value=on?raw:"";
|
||||||
|
sel.value=on&&!pps?"kbps":"pps";
|
||||||
|
inp.dataset.cur=on?inp.value+" "+sel.value:"off";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function scApply(n){
|
||||||
|
var cmds=[];
|
||||||
|
for(var k=0;k<SC_TYPES.length;k++){
|
||||||
|
var ty=SC_TYPES[k],inp=$("scv"+ty+n),u=$("scu"+ty+n).value,v=inp.value.trim(),want="off";
|
||||||
|
if(v!==""&&v!=="0"){
|
||||||
|
var x=Number(v);
|
||||||
|
if(!Number.isInteger(x)||x<1||(u==="pps"&&x>1048575)||(u==="kbps"&&x>10000000)){toast(t("sc_err"),"err");return;}
|
||||||
|
want=x+" "+u;
|
||||||
|
}
|
||||||
|
if(want!==inp.dataset.cur)cmds.push("storm "+n+" "+ty+" "+want);
|
||||||
|
}
|
||||||
|
delete $("scr"+n).dataset.dirty;
|
||||||
|
if(!cmds.length)return;
|
||||||
|
postCmds(cmds).then(scLoad).catch(function(){});
|
||||||
|
}
|
||||||
|
tabHooks.bw={enter:function(){needPorts(function(){bwLoad().then(scLoad).catch(function(){})})}};
|
||||||
|
|
||||||
var IPRE=/^(\d{1,3}\.){3}\d{1,3}$/;
|
var IPRE=/^(\d{1,3}\.){3}\d{1,3}$/;
|
||||||
function okIp(s){
|
function okIp(s){
|
||||||
@@ -1621,6 +1990,7 @@ function sysLoad(){
|
|||||||
var sl=(S.info.syslog_server||"").split(":");
|
var sl=(S.info.syslog_server||"").split(":");
|
||||||
if(sl[0]&&sl[0]!=="0.0.0.0")$("sy-sysip").value=sl[0];
|
if(sl[0]&&sl[0]!=="0.0.0.0")$("sy-sysip").value=sl[0];
|
||||||
if(sl[1])$("sy-sysport").value=sl[1];
|
if(sl[1])$("sy-sysport").value=sl[1];
|
||||||
|
if(S.info.session_timeout)$("sy-sesstmo").value=S.info.session_timeout;
|
||||||
}).catch(function(){});
|
}).catch(function(){});
|
||||||
cfgReload();
|
cfgReload();
|
||||||
}
|
}
|
||||||
@@ -1645,7 +2015,7 @@ $("sy-apply").addEventListener("click",function(){
|
|||||||
if(!/^[\x21-\x7e]{1,23}$/.test(hn)||/["\\]/.test(hn)){toast(t("sy_host_err"),"err");return;}
|
if(!/^[\x21-\x7e]{1,23}$/.test(hn)||/["\\]/.test(hn)){toast(t("sy_host_err"),"err");return;}
|
||||||
cmds.push("hostname "+hn);
|
cmds.push("hostname "+hn);
|
||||||
}
|
}
|
||||||
cmds.push("ip "+ip,"netmask "+mask,"gw "+gw);
|
cmds.push("ip "+ip+"\nnetmask "+mask+"\ngw "+gw);
|
||||||
var changingIp=ip!==S.info.ip_address;
|
var changingIp=ip!==S.info.ip_address;
|
||||||
confirmModal(t("sy_net_q"),changingIp?t("sy_net_d",{ip:ip}):"",function(){
|
confirmModal(t("sy_net_q"),changingIp?t("sy_net_d",{ip:ip}):"",function(){
|
||||||
postCmds(cmds).then(function(){
|
postCmds(cmds).then(function(){
|
||||||
@@ -1673,6 +2043,11 @@ $("sy-syslog").addEventListener("change",function(){
|
|||||||
}else cmds.push("syslog off");
|
}else cmds.push("syslog off");
|
||||||
postCmds(cmds).catch(function(){});
|
postCmds(cmds).catch(function(){});
|
||||||
});
|
});
|
||||||
|
$("sy-sesstmo").addEventListener("change",function(){
|
||||||
|
var v=+this.value;
|
||||||
|
if(!(v>=1&&v<=65535)){toast(t("sy_sesstmo_err"),"err");sysLoad();return;}
|
||||||
|
postCmd("session "+v).catch(function(){sysLoad()});
|
||||||
|
});
|
||||||
$("sy-pwapply").addEventListener("click",function(){
|
$("sy-pwapply").addEventListener("click",function(){
|
||||||
var a=$("sy-pw1").value,b=$("sy-pw2").value;
|
var a=$("sy-pw1").value,b=$("sy-pw2").value;
|
||||||
if(a.length<1||a.length>20){toast(t("sy_pw_len"),"err");return;}
|
if(a.length<1||a.length>20){toast(t("sy_pw_len"),"err");return;}
|
||||||
@@ -1715,11 +2090,16 @@ function cfgReload(){
|
|||||||
cfgParseKnown(x);
|
cfgParseKnown(x);
|
||||||
}).catch(function(){});
|
}).catch(function(){});
|
||||||
}
|
}
|
||||||
|
function cfgLongLine(v){
|
||||||
|
var ls=v.split("\n");
|
||||||
|
for(var i=0;i<ls.length;i++){var n=new Blob([ls[i]]).size;if(n>126)return{n:i+1,m:n};}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
function cfgBytes(){
|
function cfgBytes(){
|
||||||
var n=new Blob([$("cfgedit").value]).size;
|
var v=$("cfgedit").value,n=new Blob([v]).size;
|
||||||
var el=$("cfgbytes");
|
var el=$("cfgbytes");
|
||||||
el.textContent=n+" / 2048 "+t("sy_bytes");
|
el.textContent=n+" / 2048 "+t("sy_bytes");
|
||||||
el.style.color=n>2048?"var(--bad)":"";
|
el.style.color=(n>2048||cfgLongLine(v))?"var(--bad)":"";
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
$("cfgedit").addEventListener("input",cfgBytes);
|
$("cfgedit").addEventListener("input",cfgBytes);
|
||||||
@@ -1731,15 +2111,15 @@ tabHooks.system={enter:sysLoad};
|
|||||||
|
|
||||||
var CONF_OVERWRITE=[
|
var CONF_OVERWRITE=[
|
||||||
/^ip\b/,/^gw\b/,/^netmask\b/,/^hostname\b/,
|
/^ip\b/,/^gw\b/,/^netmask\b/,/^hostname\b/,
|
||||||
/^syslog\s+ip\b/,/^syslog\s+port\b/,/^passwd\b/,
|
/^syslog\s+ip\b/,/^syslog\s+port\b/,/^passwd\b/,/^session\b/,
|
||||||
/^vlan\s+\d{1,4}\s+mgmt$/,/^vlan\s+\d{1,4}(?!\s+mgmt\b)/,
|
/^vlan\s+\d{1,4}\s+mgmt$/,/^vlan\s+\d{1,4}(?!\s+mgmt\b)/,
|
||||||
/^pvid\s+\d{1,2}\b/,/^ingress\b/,
|
/^pvid\s+\d{1,2}\b/,
|
||||||
/^port\s+\d{1,2}(?!\s+name\b)/,/^port\s+\d{1,2}\s+name\b/,
|
/^port\s+\d{1,2}(?!\s+name\b)/,/^port\s+\d{1,2}\s+name\b/,
|
||||||
/^mirror\b/,
|
/^mirror\b/,
|
||||||
/^lag\s+\d\b/,/^laghash\s+\d\b/,/^isolate\s+\d{1,2}\b/,
|
/^lag\s+\d\b/,/^laghash\s+\d\b/,/^isolate\s+\d{1,2}\b/,
|
||||||
/^stp\s+(prio|hello|maxage|fwd|txhold|version)\b/,
|
/^stp\s+(prio|hello|maxage|fwd|txhold|version)\b/,
|
||||||
/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+(edge|cost|prio|guard|filter|p2p)\b/,
|
/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+(edge|cost|prio|guard|filter|p2p)\b/,
|
||||||
/^igmp\b/,/^mtu\s+\d{1,2}\b/,
|
/^igmp\b/,/^mtu\s+\d{1,2}\b/,/^storm\s+\d{1,2}\s+(bcast|mcast|ucast|umcast)\b/,
|
||||||
];
|
];
|
||||||
var CONF_TOGGLE=[/^(syslog)\s+(on|off)$/,/^(stp)\s+(on|off)$/,/^(stp\s+(port\s+\d{1,2}|lag\s+[1-4]))\s+(on|off)$/];
|
var CONF_TOGGLE=[/^(syslog)\s+(on|off)$/,/^(stp)\s+(on|off)$/,/^(stp\s+(port\s+\d{1,2}|lag\s+[1-4]))\s+(on|off)$/];
|
||||||
function mergeConf(base,texts){
|
function mergeConf(base,texts){
|
||||||
@@ -1759,6 +2139,21 @@ function mergeConf(base,texts){
|
|||||||
}
|
}
|
||||||
if(line==="mirror off"){drop(/^mirror /);return;}
|
if(line==="mirror off"){drop(/^mirror /);return;}
|
||||||
if(!isConfCmd(line))return;
|
if(!isConfCmd(line))return;
|
||||||
|
if((m=line.match(/^ingress (.+)$/))){
|
||||||
|
if(/^[tua]$/.test(m[1])){drop(/^ingress /);conf.push(line);return;}
|
||||||
|
var ports={},order=[],last=-1;
|
||||||
|
conf.forEach(function(c,i){if(/^ingress [tua]$/.test(c))last=i;});
|
||||||
|
conf.forEach(function(c,i){
|
||||||
|
var cm=c.match(/^ingress (.+)$/);
|
||||||
|
if(!cm||/^[tua]$/.test(cm[1])||i<last)return;
|
||||||
|
cm[1].split(" ").forEach(function(tk){var n=tk.slice(0,-1);if(!(n in ports))order.push(n);ports[n]=tk;});
|
||||||
|
});
|
||||||
|
m[1].split(" ").forEach(function(tk){var n=tk.slice(0,-1);if(!(n in ports))order.push(n);ports[n]=tk;});
|
||||||
|
conf=conf.filter(function(c){var cm=c.match(/^ingress (.+)$/);return!cm||/^[tua]$/.test(cm[1])});
|
||||||
|
order.sort(function(a,b){return a-b});
|
||||||
|
conf.push("ingress "+order.map(function(n){return ports[n]}).join(" "));
|
||||||
|
return;
|
||||||
|
}
|
||||||
if((m=line.match(/^bw (in|out) (\d{1,2}) (\S+)$/))){
|
if((m=line.match(/^bw (in|out) (\d{1,2}) (\S+)$/))){
|
||||||
var pre="^bw "+m[1]+" "+m[2]+" ";
|
var pre="^bw "+m[1]+" "+m[2]+" ";
|
||||||
if(m[1]==="out"||m[3]==="off")drop(new RegExp(pre));
|
if(m[1]==="out"||m[3]==="off")drop(new RegExp(pre));
|
||||||
@@ -1786,18 +2181,18 @@ function mergeConf(base,texts){
|
|||||||
});
|
});
|
||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
function writeConfig(txt,title){
|
function writeConfig(txt,title,fromLog){
|
||||||
var info=h("p",{class:"small mut"}),warn=h("p",{class:"small"});
|
var info=h("p",{class:"small mut"}),warn=h("p",{class:"small"});
|
||||||
var ed=h("textarea",{class:"cfg",spellcheck:"false",placeholder:t("cw_empty"),style:"min-height:45vh"});
|
var ed=h("textarea",{class:"cfg",spellcheck:"false",placeholder:t("cw_empty"),style:"min-height:45vh"});
|
||||||
ed.value=txt.replace(/\r\n/g,"\n");
|
ed.value=txt.replace(/\r\n/g,"\n");
|
||||||
var ok=h("button",{class:"ctl pri",text:t("sy_write"),onclick:function(){closeModal();doWriteConfig(cfgText(ed.value))}});
|
var ok=h("button",{class:"ctl pri",text:t("sy_write"),onclick:function(){closeModal();doWriteConfig(cfgText(ed.value),fromLog)}});
|
||||||
function refresh(){
|
function refresh(){
|
||||||
var v=cfgText(ed.value),bytes=new Blob([v]).size;
|
var v=cfgText(ed.value),bytes=new Blob([v]).size,long=cfgLongLine(v);
|
||||||
var unknown=v.split("\n").filter(function(l){return l.trim()&&!isConfCmd(l.trim().replace(/\s+/g," "))});
|
var unknown=v.split("\n").filter(function(l){return l.trim()&&!isConfCmd(l.trim().replace(/\s+/g," "))});
|
||||||
info.textContent=t("cw_info",{n:bytes});
|
info.textContent=t("cw_info",{n:bytes});
|
||||||
ok.disabled=bytes>2048;
|
ok.disabled=bytes>2048||!!long;
|
||||||
warn.style.color=ok.disabled?"var(--bad)":"var(--warn)";
|
warn.style.color=ok.disabled?"var(--bad)":"var(--warn)";
|
||||||
warn.textContent=ok.disabled?t("cw_toolarge"):(unknown.length?t("cw_unknown")+unknown.join(" | "):"");
|
warn.textContent=bytes>2048?t("cw_toolarge"):long?t("cw_longline",long):(unknown.length?t("cw_unknown")+unknown.join(" | "):"");
|
||||||
}
|
}
|
||||||
ed.addEventListener("input",refresh);refresh();
|
ed.addEventListener("input",refresh);refresh();
|
||||||
modal(title,h("div",null,[info,warn,ed]),[h("button",{class:"ctl",text:t("c_cancel"),onclick:closeModal}),ok]);
|
modal(title,h("div",null,[info,warn,ed]),[h("button",{class:"ctl",text:t("c_cancel"),onclick:closeModal}),ok]);
|
||||||
@@ -1806,7 +2201,7 @@ function cfgText(txt){
|
|||||||
txt=txt.replace(/\r\n/g,"\n");
|
txt=txt.replace(/\r\n/g,"\n");
|
||||||
return txt&&txt.slice(-1)!=="\n"?txt+"\n":txt;
|
return txt&&txt.slice(-1)!=="\n"?txt+"\n":txt;
|
||||||
}
|
}
|
||||||
function doWriteConfig(txt){
|
function doWriteConfig(txt,fromLog){
|
||||||
var form=new FormData();
|
var form=new FormData();
|
||||||
form.append("configuration",new Blob([txt],{type:"application/octet-stream"}),"config.txt");
|
form.append("configuration",new Blob([txt],{type:"application/octet-stream"}),"config.txt");
|
||||||
toast(t("cw_writing"));
|
toast(t("cw_writing"));
|
||||||
@@ -1816,9 +2211,10 @@ function doWriteConfig(txt){
|
|||||||
}).then(function(back){
|
}).then(function(back){
|
||||||
back=back.replace(/\0[\s\S]*$/,"").replace(/\r\n/g,"\n").trim();
|
back=back.replace(/\0[\s\S]*$/,"").replace(/\r\n/g,"\n").trim();
|
||||||
if(back!==txt.trim())throw new Error(t("cw_verify_fail"));
|
if(back!==txt.trim())throw new Error(t("cw_verify_fail"));
|
||||||
return api("/cmd_log_clear").catch(function(){});
|
if(!fromLog)return false;
|
||||||
}).then(function(){
|
return api("/cmd_log_clear").then(function(){return true},function(){return true});
|
||||||
setDirty(false);
|
}).then(function(cleared){
|
||||||
|
if(cleared)setDirty(false);
|
||||||
$("cfgedit").value=txt;cfgBytes();cfgParseKnown(txt);
|
$("cfgedit").value=txt;cfgBytes();cfgParseKnown(txt);
|
||||||
toast(t("cw_saved"),"ok");
|
toast(t("cw_saved"),"ok");
|
||||||
}).catch(function(e){toast(e.message||String(e),"err")});
|
}).catch(function(e){toast(e.message||String(e),"err")});
|
||||||
@@ -1829,9 +2225,9 @@ $("saveBtn").addEventListener("click",function(){
|
|||||||
getText("/config").catch(function(){return""}),
|
getText("/config").catch(function(){return""}),
|
||||||
getText("/cmd_log").catch(function(){return""}),
|
getText("/cmd_log").catch(function(){return""}),
|
||||||
]).then(function(r){
|
]).then(function(r){
|
||||||
var cur=r[0].replace(/\0[\s\S]*$/,"");
|
var cur=r[0].replace(/\0[\s\S]*$/,"").split(/\r?\n/).map(function(l){return l.trim().replace(/\s+/g," ")}).filter(Boolean);
|
||||||
var merged=mergeConf([],[cur,r[1].replace(/\0[\s\S]*$/,"")]);
|
var merged=mergeConf(cur,[r[1].replace(/\0[\s\S]*$/,"")]);
|
||||||
writeConfig(merged.join("\n"),t("cw_save_title"));
|
writeConfig(merged.join("\n"),t("cw_save_title"),true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+24
-1
@@ -331,6 +331,18 @@ button.danger{background:var(--bad);color:#fff;border-color:transparent}
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section class="tab" id="tab-isolate">
|
||||||
|
<div class="card"><h2 data-i18n="iso_title">Port isolation</h2>
|
||||||
|
<p class="small mut" style="margin-bottom:10px" data-i18n="iso_intro">A frame entering a port may only leave through the ports ticked in its row.</p>
|
||||||
|
<div class="scrollx"><table class="t" id="isotbl" style="width:auto"><thead></thead><tbody></tbody></table></div>
|
||||||
|
<p class="small mut" style="margin-top:6px" data-i18n="iso_legend">The cell of the port itself is always allowed.</p>
|
||||||
|
<div style="display:flex;gap:12px;margin-top:10px">
|
||||||
|
<button class="ctl pri" id="isoapply" data-i18n="c_apply">Apply</button>
|
||||||
|
<button class="ctl" id="isoall" data-i18n="iso_all">Allow all</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section class="tab" id="tab-lag">
|
<section class="tab" id="tab-lag">
|
||||||
<div id="lagwrap" class="grid2"></div>
|
<div id="lagwrap" class="grid2"></div>
|
||||||
<p class="small mut" style="margin-top:10px" data-i18n="lag_note">A LAG needs at least one member to be saved in the startup config; applying an empty group clears it.</p>
|
<p class="small mut" style="margin-top:10px" data-i18n="lag_note">A LAG needs at least one member to be saved in the startup config; applying an empty group clears it.</p>
|
||||||
@@ -351,6 +363,12 @@ button.danger{background:var(--bad);color:#fff;border-color:transparent}
|
|||||||
<thead><tr><th data-i18n="c_port">Port</th><th data-i18n="bw_in">Ingress limit</th><th>Mbit/s</th><th data-i18n="bw_exceed">When exceeded</th><th data-i18n="bw_out">Egress limit</th><th>Mbit/s</th><th></th></tr></thead>
|
<thead><tr><th data-i18n="c_port">Port</th><th data-i18n="bw_in">Ingress limit</th><th>Mbit/s</th><th data-i18n="bw_exceed">When exceeded</th><th data-i18n="bw_out">Egress limit</th><th>Mbit/s</th><th></th></tr></thead>
|
||||||
<tbody></tbody></table></div>
|
<tbody></tbody></table></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card"><h2><span data-i18n="sc_title">Storm control</span> <span class="hint" data-i18n="sc_h">per port and traffic type, empty = off</span></h2>
|
||||||
|
<div class="scrollx"><table class="t" id="sctable">
|
||||||
|
<thead><tr><th data-i18n="c_port">Port</th><th data-i18n="sc_bcast">Broadcast</th><th data-i18n="sc_mcast">Multicast</th><th data-i18n="sc_ucast">Unknown unicast</th><th data-i18n="sc_umcast">Unknown multicast</th><th></th></tr></thead>
|
||||||
|
<tbody></tbody></table></div>
|
||||||
|
<p class="small mut" style="margin-top:8px" data-i18n="sc_note">Frames of a type above its limit are dropped where they enter the switch.</p>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="tab" id="tab-system">
|
<section class="tab" id="tab-system">
|
||||||
@@ -375,6 +393,8 @@ button.danger{background:var(--bad);color:#fff;border-color:transparent}
|
|||||||
<input class="in" id="sy-sysip" style="flex:1;min-width:0;width:0" data-i18n-p="sy_sysip">
|
<input class="in" id="sy-sysip" style="flex:1;min-width:0;width:0" data-i18n-p="sy_sysip">
|
||||||
<span class="small mut" data-i18n="sy_port">Port</span>
|
<span class="small mut" data-i18n="sy_port">Port</span>
|
||||||
<input class="in" id="sy-sysport" style="width:64px" type="number" min="1" max="65535"></div>
|
<input class="in" id="sy-sysport" style="width:64px" type="number" min="1" max="65535"></div>
|
||||||
|
<label class="row" style="justify-content:space-between"><span data-i18n="sy_sesstmo">Session timeout (s)</span>
|
||||||
|
<input class="in" id="sy-sesstmo" style="width:80px" type="number" min="1" max="65535"></label>
|
||||||
<p class="small mut" data-i18n="sy_services_note">Service state reflects the startup config; runtime state is not readable.</p>
|
<p class="small mut" data-i18n="sy_services_note">Service state reflects the startup config; runtime state is not readable.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card"><h2 data-i18n="sy_password">Admin password</h2>
|
<div class="card"><h2 data-i18n="sy_password">Admin password</h2>
|
||||||
@@ -393,10 +413,13 @@ button.danger{background:var(--bad);color:#fff;border-color:transparent}
|
|||||||
<div class="card"><h2 data-i18n="sy_display">Display</h2>
|
<div class="card"><h2 data-i18n="sy_display">Display</h2>
|
||||||
<label class="row"><span class="lb" data-i18n="sy_lang">Language</span>
|
<label class="row"><span class="lb" data-i18n="sy_lang">Language</span>
|
||||||
<select class="in" id="langSel">
|
<select class="in" id="langSel">
|
||||||
|
<option value="de">Deutsch</option>
|
||||||
<option value="en">English</option>
|
<option value="en">English</option>
|
||||||
|
<option value="es">Español</option>
|
||||||
|
<option value="fr">Français</option>
|
||||||
<option value="ja">日本語</option>
|
<option value="ja">日本語</option>
|
||||||
<option value="zh">中文</option>
|
<option value="zh">中文</option>
|
||||||
<option value="es">Español</option>
|
|
||||||
</select></label>
|
</select></label>
|
||||||
<label class="row"><span class="lb" data-i18n="sy_theme">Theme</span>
|
<label class="row"><span class="lb" data-i18n="sy_theme">Theme</span>
|
||||||
<select class="in" id="themeSel">
|
<select class="in" id="themeSel">
|
||||||
|
|||||||
+3
-1
@@ -81,10 +81,12 @@ button:hover{filter:brightness(1.1)}
|
|||||||
<script>
|
<script>
|
||||||
(function(){
|
(function(){
|
||||||
var L={
|
var L={
|
||||||
|
de:["Switch-Anmeldung","RTLPlayground-Verwaltungsoberfläche","Passwort","Anmelden","Falsches Passwort, bitte erneut versuchen."],
|
||||||
en:["Switch Login","RTLPlayground management interface","Password","Sign in","Wrong password, try again."],
|
en:["Switch Login","RTLPlayground management interface","Password","Sign in","Wrong password, try again."],
|
||||||
ja:["スイッチ ログイン","RTLPlayground 管理インターフェース","パスワード","ログイン","パスワードが違います。もう一度お試しください。"],
|
ja:["スイッチ ログイン","RTLPlayground 管理インターフェース","パスワード","ログイン","パスワードが違います。もう一度お試しください。"],
|
||||||
zh:["交换机登录","RTLPlayground 管理界面","密码","登录","密码错误,请重试。"],
|
zh:["交换机登录","RTLPlayground 管理界面","密码","登录","密码错误,请重试。"],
|
||||||
es:["Inicio de sesión del switch","Interfaz de gestión de RTLPlayground","Contraseña","Iniciar sesión","Contraseña incorrecta, inténtalo de nuevo."]
|
es:["Inicio de sesión del switch","Interfaz de gestión de RTLPlayground","Contraseña","Iniciar sesión","Contraseña incorrecta, inténtalo de nuevo."],
|
||||||
|
fr:["Utilisateur du commutateur","Interface de management RTLPlayground","Mot de passe","Se connecter","Mot de passe erronné, essayez à nouveau."]
|
||||||
};
|
};
|
||||||
var l=null;
|
var l=null;
|
||||||
try{l=localStorage.getItem("rtl_lang");}catch(e){}
|
try{l=localStorage.getItem("rtl_lang");}catch(e){}
|
||||||
|
|||||||
+19
-4
@@ -12,7 +12,11 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define SESSION_ID_LENGTH 12
|
#define SESSION_ID_LENGTH 12
|
||||||
#define SESSION_TIMEOUT 200
|
#define SESSION_TIMEOUT_DEFAULT 200
|
||||||
|
|
||||||
|
/* Seconds of inactivity after which a session cookie stops validating.
|
||||||
|
* Configurable with the "session" command, see cmd_parser.c. */
|
||||||
|
__xdata uint16_t session_timeout = SESSION_TIMEOUT_DEFAULT;
|
||||||
|
|
||||||
#define CMARK_S 6
|
#define CMARK_S 6
|
||||||
|
|
||||||
@@ -342,7 +346,7 @@ __xdata uint8_t *scan_header(__xdata uint8_t * __xdata p)
|
|||||||
read_reg_timer(&now);
|
read_reg_timer(&now);
|
||||||
|
|
||||||
if (session && session_id[0]) {
|
if (session && session_id[0]) {
|
||||||
if (now - last_session_use > SESSION_TIMEOUT) {
|
if (now - last_session_use > session_timeout) {
|
||||||
dbg_string("Session expired\n");
|
dbg_string("Session expired\n");
|
||||||
} else {
|
} else {
|
||||||
if (is_word_x(session, session_id)) {
|
if (is_word_x(session, session_id)) {
|
||||||
@@ -377,8 +381,8 @@ void gen_random_hex_chars(__xdata uint8_t * b, __xdata uint8_t bytes)
|
|||||||
static uint8_t config_take(void)
|
static uint8_t config_take(void)
|
||||||
{
|
{
|
||||||
// #386: needs static, otherwise it still lands in SRAM/DSEG
|
// #386: needs static, otherwise it still lands in SRAM/DSEG
|
||||||
static __xdata uint16_t cfg_pos, cfg_hdr, cfg_body, cfg_end, cfg_last;
|
static __xdata uint16_t cfg_pos, cfg_hdr, cfg_body, cfg_end, cfg_last, cfg_i;
|
||||||
__xdata uint8_t cfg_bl;
|
__xdata uint8_t cfg_bl, cfg_run;
|
||||||
|
|
||||||
cfg_bl = strlen_x(boundary);
|
cfg_bl = strlen_x(boundary);
|
||||||
|
|
||||||
@@ -420,6 +424,13 @@ static uint8_t config_take(void)
|
|||||||
// the payload plus its terminator must fit the sector
|
// the payload plus its terminator must fit the sector
|
||||||
if (cfg_end - cfg_body + 1 > CONFIG_LEN)
|
if (cfg_end - cfg_body + 1 > CONFIG_LEN)
|
||||||
return 2;
|
return 2;
|
||||||
|
cfg_run = 0;
|
||||||
|
for (cfg_i = cfg_body; cfg_i < cfg_end; cfg_i++) {
|
||||||
|
if (config_buf[cfg_i] == '\n')
|
||||||
|
cfg_run = 0;
|
||||||
|
else if (++cfg_run >= CMD_BUF_SIZE - 1)
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
config_buf[cfg_end] = 0;
|
config_buf[cfg_end] = 0;
|
||||||
flash_region.addr = CONFIG_START;
|
flash_region.addr = CONFIG_START;
|
||||||
flash_sector_erase();
|
flash_sector_erase();
|
||||||
@@ -1005,6 +1016,8 @@ void httpd_appcall(void)
|
|||||||
send_eee();
|
send_eee();
|
||||||
} else if (is_word(q, "/bandwidth.json")) {
|
} else if (is_word(q, "/bandwidth.json")) {
|
||||||
send_bandwidth();
|
send_bandwidth();
|
||||||
|
} else if (is_word(q, "/storm.json")) {
|
||||||
|
send_storm();
|
||||||
} else if (is_word(q, "/l2.json")) {
|
} else if (is_word(q, "/l2.json")) {
|
||||||
parse_short(q + 13); // e.g.: /l2.json?idx=10
|
parse_short(q + 13); // e.g.: /l2.json?idx=10
|
||||||
send_l2(short_parsed);
|
send_l2(short_parsed);
|
||||||
@@ -1013,6 +1026,8 @@ void httpd_appcall(void)
|
|||||||
l2_delete(short_parsed);
|
l2_delete(short_parsed);
|
||||||
} else if (is_word(q, "/mirror.json")) {
|
} else if (is_word(q, "/mirror.json")) {
|
||||||
send_mirror();
|
send_mirror();
|
||||||
|
} else if (is_word(q, "/isolation.json")) {
|
||||||
|
send_isolation();
|
||||||
} else if (is_word(q, "/mtu.json")) {
|
} else if (is_word(q, "/mtu.json")) {
|
||||||
send_mtu();
|
send_mtu();
|
||||||
} else if (is_word(q, "/lag.json")) {
|
} else if (is_word(q, "/lag.json")) {
|
||||||
|
|||||||
+87
-6
@@ -3,6 +3,7 @@
|
|||||||
#include "rtl837x_sfr.h"
|
#include "rtl837x_sfr.h"
|
||||||
#include "rtl837x_common.h"
|
#include "rtl837x_common.h"
|
||||||
#include "rtl837x_regs.h"
|
#include "rtl837x_regs.h"
|
||||||
|
#include "rtl837x_storm.h"
|
||||||
#include "rtl837x_port.h"
|
#include "rtl837x_port.h"
|
||||||
#include "rtl837x_flash.h"
|
#include "rtl837x_flash.h"
|
||||||
#include "rtl837x_pins.h"
|
#include "rtl837x_pins.h"
|
||||||
@@ -28,6 +29,7 @@ extern __code const struct machine machine;
|
|||||||
extern __xdata uint8_t outbuf[TCP_OUTBUF_SIZE];
|
extern __xdata uint8_t outbuf[TCP_OUTBUF_SIZE];
|
||||||
extern __xdata uint16_t slen;
|
extern __xdata uint16_t slen;
|
||||||
extern __xdata uint16_t management_vlan;
|
extern __xdata uint16_t management_vlan;
|
||||||
|
extern __xdata uint16_t session_timeout;
|
||||||
extern __xdata uint16_t cont_len;
|
extern __xdata uint16_t cont_len;
|
||||||
extern __xdata uint32_t cont_addr;
|
extern __xdata uint32_t cont_addr;
|
||||||
extern __code const uint8_t * __code const hex;
|
extern __code const uint8_t * __code const hex;
|
||||||
@@ -114,12 +116,14 @@ void itoa_html(uint8_t v)
|
|||||||
char_to_html('0' + (v % 10));
|
char_to_html('0' + (v % 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
void itoa16_html(uint16_t v) /* sufficient for VLAN IDs (max 4094) */
|
void itoa16_html(uint16_t v) /* up to five digits (65535) */
|
||||||
{
|
{
|
||||||
uint8_t print_zeros = 0;
|
uint8_t print_zeros = 0;
|
||||||
uint8_t d;
|
uint8_t d;
|
||||||
d = v / 1000;
|
d = v / 10000;
|
||||||
if (d) { char_to_html('0' + d); print_zeros = 1; }
|
if (d) { char_to_html('0' + d); print_zeros = 1; }
|
||||||
|
d = (v / 1000) % 10;
|
||||||
|
if (d || print_zeros) { char_to_html('0' + d); print_zeros = 1; }
|
||||||
d = (v / 100) % 10;
|
d = (v / 100) % 10;
|
||||||
if (d || print_zeros) { char_to_html('0' + d); print_zeros = 1; }
|
if (d || print_zeros) { char_to_html('0' + d); print_zeros = 1; }
|
||||||
d = (v / 10) % 10;
|
d = (v / 10) % 10;
|
||||||
@@ -132,6 +136,23 @@ void string_to_html(__code const char *s)
|
|||||||
while (*s) char_to_html(*s++);
|
while (*s) char_to_html(*s++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void temp_to_html(void)
|
||||||
|
{
|
||||||
|
int16_t v;
|
||||||
|
|
||||||
|
reg_read(RTL837X_TM_RESULT);
|
||||||
|
v = SFR_DATA_U16;
|
||||||
|
if (v < 0) {
|
||||||
|
char_to_html('-');
|
||||||
|
v = -v;
|
||||||
|
}
|
||||||
|
itoa_html(v >> 7);
|
||||||
|
char_to_html('.');
|
||||||
|
itoa_html(((v & 0x7f) * 10) >> 7);
|
||||||
|
char_to_html(' ');
|
||||||
|
char_to_html('C');
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t stat_content(void)
|
uint16_t stat_content(void)
|
||||||
{
|
{
|
||||||
dbg_string("stat_content called\n");
|
dbg_string("stat_content called\n");
|
||||||
@@ -258,7 +279,9 @@ void send_basic_info(void)
|
|||||||
itoa_html(syslog_state.server_ip[2]); char_to_html('.');
|
itoa_html(syslog_state.server_ip[2]); char_to_html('.');
|
||||||
itoa_html(syslog_state.server_ip[3]); char_to_html(':');
|
itoa_html(syslog_state.server_ip[3]); char_to_html(':');
|
||||||
itoa16_html(syslog_state.server_port);
|
itoa16_html(syslog_state.server_port);
|
||||||
slen += strtox(outbuf + slen, "\",\"mac_address\":\"");
|
slen += strtox(outbuf + slen, "\",\"session_timeout\":");
|
||||||
|
itoa16_html(session_timeout);
|
||||||
|
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(':');
|
||||||
byte_to_html(uip_ethaddr.addr[2]); char_to_html(':');
|
byte_to_html(uip_ethaddr.addr[2]); char_to_html(':');
|
||||||
@@ -277,6 +300,8 @@ void send_basic_info(void)
|
|||||||
slen += strtox(outbuf + slen, BUILD_DATE);
|
slen += strtox(outbuf + slen, BUILD_DATE);
|
||||||
slen += strtox(outbuf + slen, "\",\"hw_ver\":\"");
|
slen += strtox(outbuf + slen, "\",\"hw_ver\":\"");
|
||||||
slen += strtox(outbuf + slen, machine.machine_name);
|
slen += strtox(outbuf + slen, machine.machine_name);
|
||||||
|
slen += strtox(outbuf + slen, "\",\"chip_temp\":\"");
|
||||||
|
temp_to_html();
|
||||||
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());
|
||||||
|
|
||||||
@@ -804,6 +829,63 @@ void send_bandwidth(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void send_storm(void)
|
||||||
|
{
|
||||||
|
__xdata uint8_t i, t, idx;
|
||||||
|
|
||||||
|
slen = strtox(outbuf, HTTP_RESPONCE_JSON);
|
||||||
|
char_to_html('[');
|
||||||
|
for (i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
|
slen += strtox(outbuf + slen, "{\"portNum\":");
|
||||||
|
itoa_html(machine.log_to_phys_port[i]);
|
||||||
|
slen += strtox(outbuf + slen, ",\"en\":\"");
|
||||||
|
for (t = 0; t < STORM_TYPES; t++)
|
||||||
|
char_to_html(reg_bit_test(RTL837X_STORM_CTRL + (t << 2), i) ? '1' : '0');
|
||||||
|
slen += strtox(outbuf + slen, "\",\"pps\":\"");
|
||||||
|
for (t = 0; t < STORM_TYPES; t++) {
|
||||||
|
idx = STORM_METER(i, t);
|
||||||
|
char_to_html(reg_bit_test(RTL837X_METER_MODE + ((idx >> 5) << 2), idx & 0x1f) ? '1' : '0');
|
||||||
|
}
|
||||||
|
slen += strtox(outbuf + slen, "\",\"rate\":\"");
|
||||||
|
for (t = 0; t < STORM_TYPES; t++) {
|
||||||
|
reg_read_m(RTL837X_METER_RATE + (STORM_METER(i, t) << 2));
|
||||||
|
byte_to_html(sfr_data[1]);
|
||||||
|
byte_to_html(sfr_data[2]);
|
||||||
|
byte_to_html(sfr_data[3]);
|
||||||
|
}
|
||||||
|
char_to_html('"');
|
||||||
|
char_to_html('}');
|
||||||
|
if (i < machine.max_port)
|
||||||
|
char_to_html(',');
|
||||||
|
else
|
||||||
|
char_to_html(']');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void send_isolation(void)
|
||||||
|
{
|
||||||
|
__xdata uint16_t allow;
|
||||||
|
|
||||||
|
dbg_string("send_isolation called\n");
|
||||||
|
slen = strtox(outbuf, HTTP_RESPONCE_JSON);
|
||||||
|
char_to_html('[');
|
||||||
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
|
slen += strtox(outbuf + slen, "{\"portNum\":");
|
||||||
|
itoa_html(machine.log_to_phys_port[i]);
|
||||||
|
slen += strtox(outbuf + slen, ",\"allow\":\"");
|
||||||
|
allow = port_isolation_get(i);
|
||||||
|
byte_to_html(allow >> 8);
|
||||||
|
byte_to_html(allow & 0xff);
|
||||||
|
char_to_html('"');
|
||||||
|
char_to_html('}');
|
||||||
|
if (i < machine.max_port)
|
||||||
|
char_to_html(',');
|
||||||
|
}
|
||||||
|
char_to_html(']');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void send_mtu(void)
|
void send_mtu(void)
|
||||||
{
|
{
|
||||||
dbg_string("send_mtu called\n");
|
dbg_string("send_mtu called\n");
|
||||||
@@ -1011,7 +1093,7 @@ void send_cmd_log(void)
|
|||||||
__xdata uint8_t found_begin = 0;
|
__xdata uint8_t found_begin = 0;
|
||||||
dbg_string("History ptr: ");
|
dbg_string("History ptr: ");
|
||||||
dbg_short(cmd_history_ptr); dbg_char('\n');
|
dbg_short(cmd_history_ptr); dbg_char('\n');
|
||||||
while (p != cmd_history_ptr) {
|
while (p != cmd_history_ptr && slen < TCP_OUTBUF_SIZE) {
|
||||||
if (!cmd_history[p] || cmd_history[p] == '\n')
|
if (!cmd_history[p] || cmd_history[p] == '\n')
|
||||||
found_begin = 1;
|
found_begin = 1;
|
||||||
if (found_begin && cmd_history[p])
|
if (found_begin && cmd_history[p])
|
||||||
@@ -1036,8 +1118,7 @@ void send_vlanlist(void)
|
|||||||
slen += strtox(outbuf + slen, ",\"vlan\":[");
|
slen += strtox(outbuf + slen, ",\"vlan\":[");
|
||||||
|
|
||||||
for (i = 1; i < 4095; i++) {
|
for (i = 1; i < 4095; i++) {
|
||||||
if (vlan_get(i) < 0)
|
vlan_get(i);
|
||||||
continue;
|
|
||||||
if (!(sfr_data[0] & 0x02)) /* bit 1: VLAN table entry valid */
|
if (!(sfr_data[0] & 0x02)) /* bit 1: VLAN table entry valid */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -5,16 +5,20 @@
|
|||||||
|
|
||||||
extern __code const uint8_t * __code const HTTP_RESPONCE_TXT;
|
extern __code const uint8_t * __code const HTTP_RESPONCE_TXT;
|
||||||
|
|
||||||
|
void itoa16_html(uint16_t v);
|
||||||
|
|
||||||
bool send_counters(uint8_t phys_port);
|
bool send_counters(uint8_t phys_port);
|
||||||
void send_status(void);
|
void send_status(void);
|
||||||
void send_vlan(uint16_t vlan);
|
void send_vlan(uint16_t vlan);
|
||||||
void send_basic_info(void);
|
void send_basic_info(void);
|
||||||
void send_bandwidth(void);
|
void send_bandwidth(void);
|
||||||
|
void send_storm(void);
|
||||||
void send_eee(void);
|
void send_eee(void);
|
||||||
void send_l2(uint16_t idx);
|
void send_l2(uint16_t idx);
|
||||||
void l2_delete(uint16_t idx);
|
void l2_delete(uint16_t idx);
|
||||||
void send_mirror(void);
|
void send_mirror(void);
|
||||||
void send_mtu(void);
|
void send_mtu(void);
|
||||||
|
void send_isolation(void);
|
||||||
void send_config(void);
|
void send_config(void);
|
||||||
void send_cmd_log(void);
|
void send_cmd_log(void);
|
||||||
void send_lag(void);
|
void send_lag(void);
|
||||||
|
|||||||
@@ -237,9 +237,14 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#elif defined MACHINE_KP_9000_9XHML_X_V3_1
|
#elif defined(MACHINE_KP_9000_9XHML_X_V3_1) || defined(MACHINE_KP_9000_9XHML_X_V3_2)
|
||||||
|
// 2M-PCB23-V3.2 is wired like V3.1 (SFP detection, LEDs, factory MAC location)
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
|
#if defined(MACHINE_KP_9000_9XHML_X_V3_2)
|
||||||
|
.machine_name = "keepLink KP-9000-9XHML-X V3.2",
|
||||||
|
#else
|
||||||
.machine_name = "keepLink KP-9000-9XHML-X V3.1",
|
.machine_name = "keepLink KP-9000-9XHML-X V3.1",
|
||||||
|
#endif
|
||||||
.isRTL8373 = 1,
|
.isRTL8373 = 1,
|
||||||
.min_port = 0,
|
.min_port = 0,
|
||||||
.max_port = 8,
|
.max_port = 8,
|
||||||
@@ -1325,6 +1330,37 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
#elif defined MACHINE_HASIVO_S1100WP_8GT_1SX_SE
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = "Hasivo S1100WP-8GT-1SX-SE",
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.mac_flash_offset = 0x1FC000,
|
||||||
|
.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 = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO54_ACL_BIT2_EN,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.led_sets = { { LEDS_2G5 | LEDS_LINK | LEDS_ACT, // Green LED (right)
|
||||||
|
0,
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // Amber LED (left)
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{ LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT, // SFP LED
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
#elif defined MACHINE_F7008_2_5
|
#elif defined MACHINE_F7008_2_5
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "F7008-2.5 8+1 SFP Port Switch",
|
.machine_name = "F7008-2.5 8+1 SFP Port Switch",
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
// #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
|
||||||
|
// #define MACHINE_KP_9000_9XHML_X_V3_2
|
||||||
// #define MACHINE_SWGT024_V2_0_MANAGED
|
// #define MACHINE_SWGT024_V2_0_MANAGED
|
||||||
// #define MACHINE_SWGT024_V2_0_UNMANAGED
|
// #define MACHINE_SWGT024_V2_0_UNMANAGED
|
||||||
// #define MACHINE_TRENDNET_TEG_S562
|
// #define MACHINE_TRENDNET_TEG_S562
|
||||||
@@ -48,6 +49,7 @@
|
|||||||
// #define MACHINE_POE_2G080110GS
|
// #define MACHINE_POE_2G080110GS
|
||||||
// #define MACHINE_PB_2132
|
// #define MACHINE_PB_2132
|
||||||
// #define MACHINE_HASIVO_S600W_4GT_2XGT_SE
|
// #define MACHINE_HASIVO_S600W_4GT_2XGT_SE
|
||||||
|
// #define MACHINE_HASIVO_S1100WP_8GT_1SX_SE
|
||||||
// #define MACHINE_F7008_2_5
|
// #define MACHINE_F7008_2_5
|
||||||
|
|
||||||
#define LED_27 1
|
#define LED_27 1
|
||||||
|
|||||||
+7
-34
@@ -15,7 +15,11 @@
|
|||||||
|
|
||||||
#if defined(MACHINE_KP_9000_6XH_X2) || \
|
#if defined(MACHINE_KP_9000_6XH_X2) || \
|
||||||
defined(MACHINE_KP_9000_6XH_X2_V2_1) || \
|
defined(MACHINE_KP_9000_6XH_X2_V2_1) || \
|
||||||
defined(MACHINE_KP_9000_6XHML_X2_V2_1)
|
defined(MACHINE_KP_9000_6XHML_X2_V2_1) || \
|
||||||
|
defined(MACHINE_HI_K0402WS) || \
|
||||||
|
defined(MACHINE_PCB_K0402WS_V2) || \
|
||||||
|
defined(MACHINE_PCB_K0402WS_V3) || \
|
||||||
|
defined(MACHINE_FNS1200P)
|
||||||
void machine_custom_init(void) __banked
|
void machine_custom_init(void) __banked
|
||||||
{
|
{
|
||||||
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
|
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
|
||||||
@@ -42,18 +46,6 @@ void machine_custom_init(void) __banked
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(MACHINE_PCB_K0402WS_V3) || defined(MACHINE_HI_K0402WS)
|
|
||||||
void machine_custom_init(void) __banked
|
|
||||||
{
|
|
||||||
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(MACHINE_PCB_K0402WS_V2) || defined(MACHINE_FNS1200P)
|
|
||||||
void machine_custom_init(void) __banked
|
|
||||||
{
|
|
||||||
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined MACHINE_PCB_SWTG024AS_A_2_0_1
|
#elif defined MACHINE_PCB_SWTG024AS_A_2_0_1
|
||||||
void machine_custom_init(void) __banked
|
void machine_custom_init(void) __banked
|
||||||
{
|
{
|
||||||
@@ -63,27 +55,8 @@ void machine_custom_init(void) __banked
|
|||||||
reg_bit_clear(RTL837X_REG_LED_MODE, 7);
|
reg_bit_clear(RTL837X_REG_LED_MODE, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined MACHINE_SWTG024AS_A_2_0_1_5C_1SFP
|
#elif defined(MACHINE_SWTG024AS_A_2_0_1_5C_1SFP) || \
|
||||||
void machine_custom_init(void) __banked
|
defined(MACHINE_SWTG024AS_V2_0)
|
||||||
{
|
|
||||||
uint16_t pval;
|
|
||||||
|
|
||||||
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
|
|
||||||
reg_bit_set(RTL837X_REG_LED_MODE, 17);
|
|
||||||
reg_bit_clear(RTL837X_REG_LED_MODE, 9);
|
|
||||||
reg_bit_clear(RTL837X_REG_LED_MODE, 7);
|
|
||||||
|
|
||||||
// OEM firmware sets these companion SDS0 polarity bits for the RTL8221B.
|
|
||||||
sds_read(0, 0, 0);
|
|
||||||
pval = SFR_DATA_U16;
|
|
||||||
sds_write_v(0, 0, 0, pval | 0x100);
|
|
||||||
|
|
||||||
sds_read(0, 6, 2);
|
|
||||||
pval = SFR_DATA_U16;
|
|
||||||
sds_write_v(0, 6, 2, pval | 0x4000);
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined MACHINE_SWTG024AS_V2_0
|
|
||||||
void machine_custom_init(void) __banked
|
void machine_custom_init(void) __banked
|
||||||
{
|
{
|
||||||
uint16_t pval;
|
uint16_t pval;
|
||||||
|
|||||||
+9
-1
@@ -7,6 +7,14 @@
|
|||||||
|
|
||||||
#define SYS_TICK_HZ 200
|
#define SYS_TICK_HZ 200
|
||||||
|
|
||||||
|
/* Timers of the main loop count system ticks, not loop passes: a pass is as
|
||||||
|
* long as the packets it handles, and since #483 the loop no longer sleeps
|
||||||
|
* while packets wait, so passes can outrun the tick as well as lag it. `last`
|
||||||
|
* is the low byte of ticks when the timer last ran; the byte arithmetic wraps
|
||||||
|
* every 256 ticks, so a pass longer than 1.28 s loses time rather than
|
||||||
|
* running the timer 64 times to catch up. */
|
||||||
|
#define TICKS_DUE(last, period) ((uint8_t)((uint8_t)ticks - (last)) >= (period))
|
||||||
|
|
||||||
#define CPU_PORT 9
|
#define CPU_PORT 9
|
||||||
#define NUL '\0'
|
#define NUL '\0'
|
||||||
|
|
||||||
@@ -98,7 +106,7 @@ struct vlan_tag {
|
|||||||
#define FIRMWARE_UPLOAD_START 0x80000
|
#define FIRMWARE_UPLOAD_START 0x80000
|
||||||
|
|
||||||
// Constants for the circular command buffer, the size must be 2^n
|
// Constants for the circular command buffer, the size must be 2^n
|
||||||
#define CMD_HISTORY_SIZE 0x400
|
#define CMD_HISTORY_SIZE 0x800
|
||||||
#define CMD_HISTORY_MASK (CMD_HISTORY_SIZE - 1)
|
#define CMD_HISTORY_MASK (CMD_HISTORY_SIZE - 1)
|
||||||
|
|
||||||
enum sfp_speeds {
|
enum sfp_speeds {
|
||||||
|
|||||||
+44
-18
@@ -9,6 +9,7 @@
|
|||||||
#define IPMC_USES_L3MC
|
#define IPMC_USES_L3MC
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include "rtl837x_common.h"
|
#include "rtl837x_common.h"
|
||||||
#include "rtl837x_sfr.h"
|
#include "rtl837x_sfr.h"
|
||||||
#include "rtl837x_regs.h"
|
#include "rtl837x_regs.h"
|
||||||
@@ -19,6 +20,7 @@ extern __code const struct machine machine;
|
|||||||
extern __xdata uint8_t igmpEnabled;
|
extern __xdata uint8_t igmpEnabled;
|
||||||
|
|
||||||
#include "uip.h"
|
#include "uip.h"
|
||||||
|
#include "uip_arp.h"
|
||||||
|
|
||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK1
|
||||||
#pragma constseg BANK1
|
#pragma constseg BANK1
|
||||||
@@ -29,6 +31,13 @@ extern __xdata struct machine_runtime machine_detected;
|
|||||||
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE + 2];
|
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE + 2];
|
||||||
|
|
||||||
__xdata uint16_t idx;
|
__xdata uint16_t idx;
|
||||||
|
#define IGMP_IP_HDR offsetof(struct igmp_pkt, hlen)
|
||||||
|
#define IGMP_IP_IHL 0x0f
|
||||||
|
#define IGMP_GROUP_OFS 4
|
||||||
|
#define IGMP_V3_RECORD_OFS 8
|
||||||
|
|
||||||
|
static __xdata uint8_t igmp_grp;
|
||||||
|
static __xdata uint8_t igmp_join;
|
||||||
|
|
||||||
#ifdef IPMC_USES_L3MC
|
#ifdef IPMC_USES_L3MC
|
||||||
struct ipmc_table_entry {
|
struct ipmc_table_entry {
|
||||||
@@ -198,8 +207,10 @@ void entry_to_l2mc(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void igmp_packet_handler(void) __banked
|
uint8_t igmp_packet_handler(void) __banked
|
||||||
{
|
{
|
||||||
|
if (IGMP_I->ipv4_tag != HTONS(UIP_ETHTYPE_IP) || IGMP_I->protocol != IGMP_PROTO)
|
||||||
|
return 0;
|
||||||
// By default we do not send anything out
|
// By default we do not send anything out
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
|
|
||||||
@@ -211,24 +222,40 @@ void igmp_packet_handler(void) __banked
|
|||||||
}
|
}
|
||||||
write_char('\n');
|
write_char('\n');
|
||||||
#endif
|
#endif
|
||||||
if (IGMP_I->protocol != 2)
|
igmp_grp = IGMP_IP_HDR + ((IGMP_I->hlen & IGMP_IP_IHL) << 2);
|
||||||
return;
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print_string("Found IGMP, type: "); print_byte(IGMP_I->igmp_type); write_char('\n');
|
print_string("Found IGMP, type: "); print_byte(uip_buf[igmp_grp]); write_char('\n');
|
||||||
#endif
|
#endif
|
||||||
// We react to IGMPv1/v2 and v3 membership reports
|
switch (uip_buf[igmp_grp]) {
|
||||||
if (!(IGMP_I->igmp_type == 0x12 || IGMP_I->igmp_type == 0x16 || IGMP_I->igmp_type == 0x22))
|
case IGMP_V1_REPORT:
|
||||||
return;
|
case IGMP_V2_REPORT:
|
||||||
|
igmp_join = 1;
|
||||||
|
break;
|
||||||
|
case IGMP_V2_LEAVE:
|
||||||
|
igmp_join = 0;
|
||||||
|
break;
|
||||||
|
case IGMP_V3_REPORT:
|
||||||
|
igmp_grp += IGMP_V3_RECORD_OFS;
|
||||||
|
if (uip_buf[igmp_grp] == IGMP_V3_TO_EXCLUDE)
|
||||||
|
igmp_join = 1;
|
||||||
|
else if (uip_buf[igmp_grp] == IGMP_V3_TO_INCLUDE)
|
||||||
|
igmp_join = 0;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
igmp_grp += IGMP_GROUP_OFS;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print_string("IGMP membership report, type "); print_byte(IGMP_I->igmp_rtype); write_char('\n');
|
print_string("IGMP join "); print_byte(igmp_join); write_char('\n');
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IPMC_USES_L3MC
|
#ifdef IPMC_USES_L3MC
|
||||||
memset((__xdata uint8_t *)&entry, 0, sizeof(struct ipmc_table_entry));
|
memset((__xdata uint8_t *)&entry, 0, sizeof(struct ipmc_table_entry));
|
||||||
// For IPv4 MC, the Source-IP is 0.0.0.0
|
// For IPv4 MC, the Source-IP is 0.0.0.0
|
||||||
entry.sip[0] = 0x00; entry.sip[1] = 0x00; entry.sip[2] = 0x00; entry.sip[3] = 0x00;
|
|
||||||
// For IPv4 MC, the Destination-IP is the IPv4 MC address
|
// For IPv4 MC, the Destination-IP is the IPv4 MC address
|
||||||
entry.dip[0] = IGMP_I->mc_ip[0]; entry.dip[1] = IGMP_I->mc_ip[1]; entry.dip[2] = IGMP_I->mc_ip[2]; entry.dip[3] = IGMP_I->mc_ip[3];
|
memcpy(entry.dip, &uip_buf[igmp_grp], sizeof(entry.dip));
|
||||||
entry_to_l3mc();
|
entry_to_l3mc();
|
||||||
#else
|
#else
|
||||||
/* The L2 Multicast MAC for IP-Multicast is 01:00:5e:xx:yy:zz, where
|
/* The L2 Multicast MAC for IP-Multicast is 01:00:5e:xx:yy:zz, where
|
||||||
@@ -238,7 +265,7 @@ void igmp_packet_handler(void) __banked
|
|||||||
*/
|
*/
|
||||||
memset((__xdata uint8_t *)&entry, 0, sizeof(struct l2mc_table_entry));
|
memset((__xdata uint8_t *)&entry, 0, sizeof(struct l2mc_table_entry));
|
||||||
entry.mac[0] = 0x01; entry.mac[1] = 0x00; entry.mac[2] = 0x5e;
|
entry.mac[0] = 0x01; entry.mac[1] = 0x00; entry.mac[2] = 0x5e;
|
||||||
entry.mac[3] = IGMP_I->mc_ip[1] & 0x7f; entry.mac[4] = IGMP_I->mc_ip[2]; entry.mac[5] = IGMP_I->mc_ip[3];
|
entry.mac[3] = uip_buf[igmp_grp + 1] & 0x7f; entry.mac[4] = uip_buf[igmp_grp + 2]; entry.mac[5] = uip_buf[igmp_grp + 3];
|
||||||
entry.vlan = 1; //TODO: Get this out of the packet and compare with VLAN table!
|
entry.vlan = 1; //TODO: Get this out of the packet and compare with VLAN table!
|
||||||
entry_to_ipmc();
|
entry_to_ipmc();
|
||||||
#endif
|
#endif
|
||||||
@@ -286,7 +313,7 @@ void igmp_packet_handler(void) __banked
|
|||||||
print_sfr_data();
|
print_sfr_data();
|
||||||
#endif
|
#endif
|
||||||
idx = ((sfr_data[2] & 0xf) << 8) | sfr_data[3];
|
idx = ((sfr_data[2] & 0xf) << 8) | sfr_data[3];
|
||||||
if (IGMP_I->igmp_rtype == 0x4) {// Join group
|
if (igmp_join) {// Join group
|
||||||
if (sfr_data[2] & 0x10) {
|
if (sfr_data[2] & 0x10) {
|
||||||
print_string("\nIGMP-Entry FOUND\n");
|
print_string("\nIGMP-Entry FOUND\n");
|
||||||
reg_read_m(RTL837x_L2_DATA_OUT_B);
|
reg_read_m(RTL837x_L2_DATA_OUT_B);
|
||||||
@@ -297,7 +324,7 @@ void igmp_packet_handler(void) __banked
|
|||||||
// Update (found) entry with portmask from trapped Packet
|
// Update (found) entry with portmask from trapped Packet
|
||||||
entry.pmask |= ((uint16_t)1) << ((IGMP_I->rtl_tag.pmask >> 8) & 0x0f); // Swap bytes from network order, only 4 LSB count
|
entry.pmask |= ((uint16_t)1) << ((IGMP_I->rtl_tag.pmask >> 8) & 0x0f); // Swap bytes from network order, only 4 LSB count
|
||||||
// print_string("\nPort-Mask: "); print_short(entry.pmask); write_char('\n');
|
// print_string("\nPort-Mask: "); print_short(entry.pmask); write_char('\n');
|
||||||
} else if (IGMP_I->igmp_rtype == 0x3){ // Leave group
|
} else { // Leave group
|
||||||
if (sfr_data[2] & 0x10) {
|
if (sfr_data[2] & 0x10) {
|
||||||
print_string("\nIGMP_Entry FOUND\n");
|
print_string("\nIGMP_Entry FOUND\n");
|
||||||
reg_read_m(RTL837x_L2_DATA_OUT_B);
|
reg_read_m(RTL837x_L2_DATA_OUT_B);
|
||||||
@@ -316,7 +343,7 @@ void igmp_packet_handler(void) __banked
|
|||||||
// print_string("\nPort-Mask: "); print_short(entry.pmask); write_char('\n');
|
// print_string("\nPort-Mask: "); print_short(entry.pmask); write_char('\n');
|
||||||
} else {
|
} else {
|
||||||
print_string("IGMP Entry already deleted\n");
|
print_string("IGMP Entry already deleted\n");
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!entry.pmask && idx) { // No more ports in that group and an actual entry?
|
if (!entry.pmask && idx) { // No more ports in that group and an actual entry?
|
||||||
// Delete Entry
|
// Delete Entry
|
||||||
@@ -328,14 +355,12 @@ void igmp_packet_handler(void) __banked
|
|||||||
reg_read_m(RTL837X_TBL_CTRL);
|
reg_read_m(RTL837X_TBL_CTRL);
|
||||||
} while (sfr_data[3] & 0x1);
|
} while (sfr_data[3] & 0x1);
|
||||||
print_string("IGMP Entry deleted\n");
|
print_string("IGMP Entry deleted\n");
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
} else { // Unknown message: ignore.
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!entry.pmask)
|
if (!entry.pmask)
|
||||||
return;
|
return 1;
|
||||||
print_string("Updating IGMP entry\n");
|
print_string("Updating IGMP entry\n");
|
||||||
// Write the updated entry
|
// Write the updated entry
|
||||||
#ifdef IPMC_USES_L3MC
|
#ifdef IPMC_USES_L3MC
|
||||||
@@ -372,4 +397,5 @@ void igmp_packet_handler(void) __banked
|
|||||||
reg_read_m(RTL837x_TBL_DATA_0);
|
reg_read_m(RTL837x_TBL_DATA_0);
|
||||||
print_sfr_data();
|
print_sfr_data();
|
||||||
#endif
|
#endif
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
+9
-1
@@ -3,10 +3,18 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define IGMP_PROTO 2
|
||||||
|
#define IGMP_V1_REPORT 0x12
|
||||||
|
#define IGMP_V2_REPORT 0x16
|
||||||
|
#define IGMP_V2_LEAVE 0x17
|
||||||
|
#define IGMP_V3_REPORT 0x22
|
||||||
|
#define IGMP_V3_TO_INCLUDE 3
|
||||||
|
#define IGMP_V3_TO_EXCLUDE 4
|
||||||
|
|
||||||
void igmp_setup(void) __banked;
|
void igmp_setup(void) __banked;
|
||||||
void igmp_enable(void) __banked;
|
void igmp_enable(void) __banked;
|
||||||
void igmp_router_port_set(uint16_t pmask) __banked;
|
void igmp_router_port_set(uint16_t pmask) __banked;
|
||||||
void igmp_packet_handler(void) __banked;
|
uint8_t igmp_packet_handler(void) __banked;
|
||||||
void igmp_show(void) __banked;
|
void igmp_show(void) __banked;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -92,8 +92,18 @@ void static sds_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void static tm_init(void)
|
||||||
|
{
|
||||||
|
reg_read_m(RTL837X_TM_CTRL2);
|
||||||
|
sfr_mask_data(0, TM_CTRL2_EN_LATCH, 0);
|
||||||
|
reg_write_m(RTL837X_TM_CTRL2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void rtl8373_init(void) __banked
|
void rtl8373_init(void) __banked
|
||||||
{
|
{
|
||||||
|
tm_init();
|
||||||
|
|
||||||
print_string("\nrtl8373_init called\n");
|
print_string("\nrtl8373_init called\n");
|
||||||
|
|
||||||
// r65d8:3ffbedff R65d8-3ffbedff
|
// r65d8:3ffbedff R65d8-3ffbedff
|
||||||
@@ -191,6 +201,8 @@ void rtl8373_init(void) __banked
|
|||||||
|
|
||||||
void rtl8372_init(void) __banked
|
void rtl8372_init(void) __banked
|
||||||
{
|
{
|
||||||
|
tm_init();
|
||||||
|
|
||||||
print_string("\nrtl8372_init called\n");
|
print_string("\nrtl8372_init called\n");
|
||||||
|
|
||||||
sds_init();
|
sds_init();
|
||||||
|
|||||||
+20
-3
@@ -23,6 +23,8 @@
|
|||||||
extern __code const uint16_t bit_mask[16];
|
extern __code const uint16_t bit_mask[16];
|
||||||
extern __code const struct machine machine;
|
extern __code const struct machine machine;
|
||||||
extern __xdata struct machine_runtime machine_detected;
|
extern __xdata struct machine_runtime machine_detected;
|
||||||
|
extern volatile __xdata uint32_t ticks;
|
||||||
|
extern __xdata uint32_t rtl8224_release_tick;
|
||||||
|
|
||||||
__xdata struct phy_settings phy_settings;
|
__xdata struct phy_settings phy_settings;
|
||||||
|
|
||||||
@@ -214,9 +216,20 @@ void phy_config(uint8_t phy) __banked
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void rtl8224_wait_ready(void) __banked
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
rtl8224_read_reg_u16(RTL837X_REG_CHIP_ID + 1);
|
||||||
|
if (SFR_DATA_U16 == 0x8224)
|
||||||
|
return;
|
||||||
|
} while ((ticks - rtl8224_release_tick) < (SYS_TICK_HZ * 5 / 2));
|
||||||
|
print_string("\r\nRTL8224 not responding\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
void phy_config_8224(void) __banked
|
void phy_config_8224(void) __banked
|
||||||
{
|
{
|
||||||
uint16_t pval;
|
uint16_t pval;
|
||||||
|
uint16_t tries;
|
||||||
print_string("\r\nphy_config_8224 called\r\nRTL8224 ID: ");
|
print_string("\r\nphy_config_8224 called\r\nRTL8224 ID: ");
|
||||||
|
|
||||||
// Print RTL8224 chip id
|
// Print RTL8224 chip id
|
||||||
@@ -244,9 +257,12 @@ void phy_config_8224(void) __banked
|
|||||||
i++;
|
i++;
|
||||||
rtl8224_write_reg_u16(RTL837X_SDS_INDACS_CMD, rtl8224_sds0_setttings[i]);
|
rtl8224_write_reg_u16(RTL837X_SDS_INDACS_CMD, rtl8224_sds0_setttings[i]);
|
||||||
i++;
|
i++;
|
||||||
|
tries = 0xffff;
|
||||||
do {
|
do {
|
||||||
rtl8224_read_reg_u16(0x3f8);
|
rtl8224_read_reg_u16(0x3f8);
|
||||||
} while (SFR_DATA_8 & 0x80);
|
} while ((SFR_DATA_8 & 0x80) && --tries);
|
||||||
|
if (SFR_DATA_8 & 0x80)
|
||||||
|
print_string("\r\nRTL8224 SerDes access timed out\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
print_string("\r\nphy_config_8224 done\r\n");
|
print_string("\r\nphy_config_8224 done\r\n");
|
||||||
@@ -354,8 +370,9 @@ void phy_set_speed(void) __banked
|
|||||||
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 {
|
} else {
|
||||||
// AN Advertisement Register (MMD 7.0x0010)
|
// AN Advertisement Register (MMD 7.0x0010)
|
||||||
// bits 0-4: 0x1 (802.3 supported), Extended Next Page format used
|
// bits 0-4: 0x1 (802.3 supported), bit 10: PAUSE,
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1001);
|
// Extended Next Page format used
|
||||||
|
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1401);
|
||||||
if (phy_settings.speed == PHY_SPEED_1G) {
|
if (phy_settings.speed == PHY_SPEED_1G) {
|
||||||
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
||||||
// bit 14: SLAVE, bit 13: Multi-Port device, 1: LD Loop timin enableed
|
// bit 14: SLAVE, bit 13: Multi-Port device, 1: LD Loop timin enableed
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ extern __xdata struct phy_settings phy_settings;
|
|||||||
void rtl8224_phy_enable(void) __banked;
|
void rtl8224_phy_enable(void) __banked;
|
||||||
void phy_config(uint8_t phy) __banked;
|
void phy_config(uint8_t phy) __banked;
|
||||||
void phy_config_8224(void) __banked;
|
void phy_config_8224(void) __banked;
|
||||||
|
void rtl8224_wait_ready(void) __banked;
|
||||||
void phy_set_speed(void) __banked;
|
void phy_set_speed(void) __banked;
|
||||||
void phy_set_duplex(void) __banked;
|
void phy_set_duplex(void) __banked;
|
||||||
void phy_show(uint8_t port) __banked;
|
void phy_show(uint8_t port) __banked;
|
||||||
|
|||||||
+33
-12
@@ -40,7 +40,6 @@ static void wait_table_ready(void)
|
|||||||
|
|
||||||
void port_mirror_set(uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked
|
void port_mirror_set(uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked
|
||||||
{
|
{
|
||||||
print_string("\nport_mirror_set called \n");
|
|
||||||
print_string("Mirroring port: "); print_byte(port); print_string(" with rx-mask: ");
|
print_string("Mirroring port: "); print_byte(port); print_string(" with rx-mask: ");
|
||||||
print_short(rx_pmask); print_string(", tx mask: "); print_short(tx_pmask);
|
print_short(rx_pmask); print_string(", tx mask: "); print_short(tx_pmask);
|
||||||
write_char('\n');
|
write_char('\n');
|
||||||
@@ -52,7 +51,6 @@ void port_mirror_set(uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t t
|
|||||||
|
|
||||||
void port_mirror_del(void) __banked
|
void port_mirror_del(void) __banked
|
||||||
{
|
{
|
||||||
print_string("\nport_mirror_del called \n");
|
|
||||||
REG_SET(RTL837x_MIRROR_CTRL, 0);
|
REG_SET(RTL837x_MIRROR_CTRL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +110,6 @@ void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked
|
|||||||
{
|
{
|
||||||
uint8_t lag = port_lag_of(port);
|
uint8_t lag = port_lag_of(port);
|
||||||
|
|
||||||
print_string("\nport_pvid_set called \n");
|
|
||||||
if (lag == PORT_LAG_NONE) {
|
if (lag == PORT_LAG_NONE) {
|
||||||
port_pvid_write(port, pvid);
|
port_pvid_write(port, pvid);
|
||||||
return;
|
return;
|
||||||
@@ -141,7 +138,6 @@ void vlan_delete(uint16_t vlan) __banked
|
|||||||
if (!vlan || vlan >= 0xfff)
|
if (!vlan || vlan >= 0xfff)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
print_string("\nvlan_delete called \n"); print_short(vlan);
|
|
||||||
vlan_name_remove(vlan);
|
vlan_name_remove(vlan);
|
||||||
REG_WRITE(RTL837x_TBL_DATA_IN_A, 0, 0, 0, 0);
|
REG_WRITE(RTL837x_TBL_DATA_IN_A, 0, 0, 0, 0);
|
||||||
REG_WRITE(RTL837X_TBL_CTRL, vlan >> 8, vlan, TBL_VLAN, TBL_WRITE | TBL_EXECUTE);
|
REG_WRITE(RTL837X_TBL_CTRL, vlan >> 8, vlan, TBL_VLAN, TBL_WRITE | TBL_EXECUTE);
|
||||||
@@ -232,7 +228,7 @@ void vlan_create(void) __banked
|
|||||||
vlan_settings.members |= 0x0200; // Set 10th bit
|
vlan_settings.members |= 0x0200; // Set 10th bit
|
||||||
vlan_settings.tagged |= 0x0200;
|
vlan_settings.tagged |= 0x0200;
|
||||||
|
|
||||||
print_string("\nvlan_create called\nvlan: "); print_short(vlan_settings.vlan);
|
print_string("vlan: "); print_short(vlan_settings.vlan);
|
||||||
print_string(", members: "); print_short(vlan_settings.members);
|
print_string(", members: "); print_short(vlan_settings.members);
|
||||||
print_string(", tagged: "); print_short(vlan_settings.tagged); write_char('\n');
|
print_string(", tagged: "); print_short(vlan_settings.tagged); write_char('\n');
|
||||||
|
|
||||||
@@ -250,7 +246,6 @@ void vlan_create(void) __banked
|
|||||||
|
|
||||||
wait_table_ready();
|
wait_table_ready();
|
||||||
|
|
||||||
print_string("vlan_create done \n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -263,7 +258,6 @@ void vlan_create(void) __banked
|
|||||||
*/
|
*/
|
||||||
void vlan_setup(void) __banked
|
void vlan_setup(void) __banked
|
||||||
{
|
{
|
||||||
print_string("\nvlan_setup called \n");
|
|
||||||
|
|
||||||
// No VLAN names set up so far
|
// No VLAN names set up so far
|
||||||
vlan_ptr = 0;
|
vlan_ptr = 0;
|
||||||
@@ -331,7 +325,6 @@ void vlan_setup(void) __banked
|
|||||||
print_string("\nvlan_setup, REG 0x4f4c: "); print_reg(0x4f4c);
|
print_string("\nvlan_setup, REG 0x4f4c: "); print_reg(0x4f4c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
print_string("vlan_setup done \n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -354,7 +347,6 @@ void port_l2_forget_port(uint8_t port) __banked
|
|||||||
*/
|
*/
|
||||||
uint8_t port_l2_forget(void) __banked
|
uint8_t port_l2_forget(void) __banked
|
||||||
{
|
{
|
||||||
print_string("\nport_l2_forget called\n");
|
|
||||||
// Configure the entries to be flushed:
|
// Configure the entries to be flushed:
|
||||||
// port-based (bits 0-1 are 0 and dynamic entries, bit 2 specifies dynamic entries
|
// port-based (bits 0-1 are 0 and dynamic entries, bit 2 specifies dynamic entries
|
||||||
REG_SET(RTL837x_L2_TBL_FLUSH_CNF, 0x0);
|
REG_SET(RTL837x_L2_TBL_FLUSH_CNF, 0x0);
|
||||||
@@ -370,7 +362,6 @@ uint8_t port_l2_forget(void) __banked
|
|||||||
reg_read_m(RTL837x_L2_TBL_FLUSH_CTRL);
|
reg_read_m(RTL837x_L2_TBL_FLUSH_CTRL);
|
||||||
} while (sfr_data[1]);
|
} while (sfr_data[1]);
|
||||||
|
|
||||||
print_string("port_l2_forget done\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,7 +456,6 @@ void port_l2mc_set(uint8_t mac_last, __xdata uint16_t vid, __xdata uint16_t pmas
|
|||||||
*/
|
*/
|
||||||
void port_l2_setup(void) __banked
|
void port_l2_setup(void) __banked
|
||||||
{
|
{
|
||||||
print_string("\nport_l2_setup called\n");
|
|
||||||
|
|
||||||
port_l2_forget();
|
port_l2_forget();
|
||||||
|
|
||||||
@@ -483,7 +473,38 @@ void port_l2_setup(void) __banked
|
|||||||
// When maximim entries learned, then simply flood the packet
|
// When maximim entries learned, then simply flood the packet
|
||||||
reg_bit_set(RTL837X_L2_LRN_PORT_CONSTRT_ACT, 0);
|
reg_bit_set(RTL837X_L2_LRN_PORT_CONSTRT_ACT, 0);
|
||||||
|
|
||||||
print_string("\nport_l2_setup done\n");
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void port_media_show(uint8_t port) __banked
|
||||||
|
{
|
||||||
|
uint8_t pause;
|
||||||
|
|
||||||
|
if (!machine.is_sfp[port]) {
|
||||||
|
reg_read_m(RTL837X_REG_LINKS_STS);
|
||||||
|
if (sfr_data[(port / 8) + 1] >> (port % 8) & 1) {
|
||||||
|
print_string("Link role: ");
|
||||||
|
reg_read_m(RTL837X_MAC_MSTR_SLV_STS);
|
||||||
|
if (sfr_data[3 - (port >> 3)] & (1 << (port & 7)))
|
||||||
|
print_string("master\n");
|
||||||
|
else
|
||||||
|
print_string("slave\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_string("Pause negotiated:");
|
||||||
|
reg_read_m(RTL837X_MAC_TX_PAUSE_STS);
|
||||||
|
pause = sfr_data[3 - (port >> 3)] & (1 << (port & 7));
|
||||||
|
if (pause)
|
||||||
|
print_string(" TX");
|
||||||
|
reg_read_m(RTL837X_MAC_RX_PAUSE_STS);
|
||||||
|
if (sfr_data[3 - (port >> 3)] & (1 << (port & 7))) {
|
||||||
|
print_string(" RX");
|
||||||
|
pause = 1;
|
||||||
|
}
|
||||||
|
if (!pause)
|
||||||
|
print_string(" none");
|
||||||
|
write_char('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ extern __xdata struct vlan_settings vlan_settings;
|
|||||||
uint8_t port_l2_forget(void) __banked;
|
uint8_t port_l2_forget(void) __banked;
|
||||||
void port_l2_learned(void) __banked;
|
void port_l2_learned(void) __banked;
|
||||||
void port_stats_print(void) __banked;
|
void port_stats_print(void) __banked;
|
||||||
|
void port_media_show(uint8_t port) __banked;
|
||||||
int8_t vlan_get(uint16_t vlan) __banked;
|
int8_t vlan_get(uint16_t vlan) __banked;
|
||||||
__xdata uint16_t vlan_name(uint16_t vlan) __banked;
|
__xdata uint16_t vlan_name(uint16_t vlan) __banked;
|
||||||
void vlan_name_remove(uint16_t vlan) __banked;
|
void vlan_name_remove(uint16_t vlan) __banked;
|
||||||
|
|||||||
@@ -9,6 +9,13 @@
|
|||||||
#define RESET_SOC_BIT 0
|
#define RESET_SOC_BIT 0
|
||||||
#define RESET_NIC_BIT 2
|
#define RESET_NIC_BIT 2
|
||||||
|
|
||||||
|
#define RTL837X_TM_CTRL2 0x0338
|
||||||
|
#define TM_CTRL2_EN_LATCH 0x04
|
||||||
|
#define RTL837X_TM_RESULT 0x0340
|
||||||
|
#define RTL837X_TM_RESULT_POWERON 0x0350
|
||||||
|
// Temperature: 19 bit value, bits 18:3 in the low 16 bits of the register,
|
||||||
|
// bits 2:0 in bits 18:16. Bit 18 signed, bits 17:10 degrees C, bits 9:0 fraction.
|
||||||
|
|
||||||
#define RTL837X_REG_HW_CONF 0x6040
|
#define RTL837X_REG_HW_CONF 0x6040
|
||||||
// Bits 4 & 5: CLOCK DIVIDER from 125MHz for Timer
|
// Bits 4 & 5: CLOCK DIVIDER from 125MHz for Timer
|
||||||
|
|
||||||
@@ -83,6 +90,10 @@
|
|||||||
#define RTL837X_REG_LINKS 0x63f0
|
#define RTL837X_REG_LINKS 0x63f0
|
||||||
#define RTL837X_REG_LINKS_89 0x63f4
|
#define RTL837X_REG_LINKS_89 0x63f4
|
||||||
#define RTL837X_REG_LINKS_STS 0x63E8
|
#define RTL837X_REG_LINKS_STS 0x63E8
|
||||||
|
/* Per-port status bits: bit N is chip port N */
|
||||||
|
#define RTL837X_MAC_TX_PAUSE_STS 0x63FC
|
||||||
|
#define RTL837X_MAC_RX_PAUSE_STS 0x6400
|
||||||
|
#define RTL837X_MAC_MSTR_SLV_STS 0x6408
|
||||||
|
|
||||||
/* Each nibble encodes the link state of a port.
|
/* Each nibble encodes the link state of a port.
|
||||||
Port 0 appears to be the CPU port
|
Port 0 appears to be the CPU port
|
||||||
@@ -141,6 +152,10 @@
|
|||||||
#define RTL837X_REG_RX_CTRL 0x785c
|
#define RTL837X_REG_RX_CTRL 0x785c
|
||||||
#define RTL837X_REG_TX_CTRL 0x7860
|
#define RTL837X_REG_TX_CTRL 0x7860
|
||||||
#define RTL837X_REG_NIC_RX_BUFF_DATA 0x7874
|
#define RTL837X_REG_NIC_RX_BUFF_DATA 0x7874
|
||||||
|
#define RTL837X_NIC_INT_STS 0x7854
|
||||||
|
#define RTL837X_NIC_INT_MSK 0x7858
|
||||||
|
#define NIC_INT_RXIS 0x02
|
||||||
|
#define NIC_INT_RXIE 0x02
|
||||||
#define RTL837X_REG_CPU_RX_CURR_PKT 0x787c
|
#define RTL837X_REG_CPU_RX_CURR_PKT 0x787c
|
||||||
#define RTL837X_REG_NIC_TX_CURR_PKT 0x7884
|
#define RTL837X_REG_NIC_TX_CURR_PKT 0x7884
|
||||||
#define RTL837X_REG_CPU_TX_CURR_PKT 0x7890
|
#define RTL837X_REG_CPU_TX_CURR_PKT 0x7890
|
||||||
@@ -270,6 +285,9 @@
|
|||||||
*/
|
*/
|
||||||
#define RTL8373_RLDP_TIMER 0x1074
|
#define RTL8373_RLDP_TIMER 0x1074
|
||||||
#define RTL837X_RMA0_CONF 0x4ecc
|
#define RTL837X_RMA0_CONF 0x4ecc
|
||||||
|
#define RTL837X_IMR_INT_PORT_LINK_STS_CHG 0x5f34
|
||||||
|
#define RTL837X_ISR_SW_INT_MODE 0x5f84
|
||||||
|
#define RTL837X_ISR_INT_PORT_LINK_CHG 0x5f88
|
||||||
#define RTL837X_RMA_CONF 0x4f1c
|
#define RTL837X_RMA_CONF 0x4f1c
|
||||||
#define RTL837X_MSTP_STATES 0x5310
|
#define RTL837X_MSTP_STATES 0x5310
|
||||||
#define RTL837X_REG_LED_RLDP_1 0x65F8
|
#define RTL837X_REG_LED_RLDP_1 0x65F8
|
||||||
@@ -309,6 +327,11 @@
|
|||||||
#define RTL837X_IGBW_PORT_FC_CTRL 0x4C8C
|
#define RTL837X_IGBW_PORT_FC_CTRL 0x4C8C
|
||||||
#define RTL837X_EGBW_PORT_CTRL 0x1c34
|
#define RTL837X_EGBW_PORT_CTRL 0x1c34
|
||||||
#define RTL837X_EGBW_CTRL 0x447c
|
#define RTL837X_EGBW_CTRL 0x447c
|
||||||
|
#define RTL837X_STORM_CTRL 0x54e4
|
||||||
|
#define RTL837X_STORM_MIDX 0x54f4
|
||||||
|
#define RTL837X_METER_RATE 0x5cf0
|
||||||
|
#define RTL837X_METER_BURST 0x5df0
|
||||||
|
#define RTL837X_METER_MODE 0x5ef0
|
||||||
#define EGBW_INC_IFG 0x02
|
#define EGBW_INC_IFG 0x02
|
||||||
#define EGBW_CPUMODE 0x01
|
#define EGBW_CPUMODE 0x01
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include "rtl837x_common.h"
|
||||||
|
#include "rtl837x_sfr.h"
|
||||||
|
#include "rtl837x_regs.h"
|
||||||
|
#include "rtl837x_storm.h"
|
||||||
|
#include "machine.h"
|
||||||
|
|
||||||
|
#pragma codeseg BANK3
|
||||||
|
#pragma constseg BANK3
|
||||||
|
|
||||||
|
extern __code const struct machine machine;
|
||||||
|
extern __xdata uint8_t sfr_data[4];
|
||||||
|
|
||||||
|
/* RTL837X_STORM_MIDX words, row type * 2 + half: half 0 holds ports 0-4, half 1 ports 5-9,
|
||||||
|
* 6 bits per port, each set to STORM_METER(port, type) */
|
||||||
|
static const __code uint8_t storm_midx[8][4] = {
|
||||||
|
{ 0x28, 0x92, 0x07, 0x18 }, { 0x3c, 0xe3, 0x4c, 0x2c },
|
||||||
|
{ 0x29, 0x96, 0x17, 0x59 }, { 0x3d, 0xe7, 0x5c, 0x6d },
|
||||||
|
{ 0x2a, 0x9a, 0x27, 0x9a }, { 0x3e, 0xeb, 0x6c, 0xae },
|
||||||
|
{ 0x2b, 0x9e, 0x37, 0xdb }, { 0x3f, 0xef, 0x7c, 0xef },
|
||||||
|
};
|
||||||
|
|
||||||
|
static __code const char * __code const storm_names[STORM_TYPES] = { " bcast ", " mcast ", " ucast ", " umcast " };
|
||||||
|
|
||||||
|
|
||||||
|
void storm_set(uint8_t port, __xdata uint8_t type, __xdata uint32_t rate, __xdata uint8_t pps) __banked
|
||||||
|
{
|
||||||
|
__xdata uint8_t idx = STORM_METER(port, type);
|
||||||
|
__xdata uint8_t row = (type << 1) | (port >= 5 ? 1 : 0);
|
||||||
|
__xdata uint8_t * __xdata r = (uint8_t *)&rate;
|
||||||
|
|
||||||
|
sfr_data[0] = 0;
|
||||||
|
sfr_data[1] = r[2];
|
||||||
|
sfr_data[2] = r[1];
|
||||||
|
sfr_data[3] = r[0];
|
||||||
|
reg_write_m(RTL837X_METER_RATE + (idx << 2));
|
||||||
|
|
||||||
|
if (!pps) {
|
||||||
|
sfr_data[1] = 0;
|
||||||
|
sfr_data[2] = 0x20;
|
||||||
|
sfr_data[3] = 0;
|
||||||
|
}
|
||||||
|
reg_write_m(RTL837X_METER_BURST + (idx << 2));
|
||||||
|
|
||||||
|
if (pps)
|
||||||
|
reg_bit_set(RTL837X_METER_MODE + ((idx >> 5) << 2), idx & 0x1f);
|
||||||
|
else
|
||||||
|
reg_bit_clear(RTL837X_METER_MODE + ((idx >> 5) << 2), idx & 0x1f);
|
||||||
|
|
||||||
|
sfr_data[0] = storm_midx[row][0];
|
||||||
|
sfr_data[1] = storm_midx[row][1];
|
||||||
|
sfr_data[2] = storm_midx[row][2];
|
||||||
|
sfr_data[3] = storm_midx[row][3];
|
||||||
|
reg_write_m(RTL837X_STORM_MIDX + (row << 2));
|
||||||
|
|
||||||
|
reg_bit_set(RTL837X_STORM_CTRL + (type << 2), port);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void storm_off(uint8_t port, __xdata uint8_t type) __banked
|
||||||
|
{
|
||||||
|
reg_bit_clear(RTL837X_STORM_CTRL + (type << 2), port);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void storm_show(void) __banked
|
||||||
|
{
|
||||||
|
uint8_t i, t, idx;
|
||||||
|
|
||||||
|
for (i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
|
print_string("port ");
|
||||||
|
write_char('0' + machine.log_to_phys_port[i]);
|
||||||
|
for (t = 0; t < STORM_TYPES; t++) {
|
||||||
|
print_string(storm_names[t]);
|
||||||
|
if (!reg_bit_test(RTL837X_STORM_CTRL + (t << 2), i)) {
|
||||||
|
print_string("off");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
idx = STORM_METER(i, t);
|
||||||
|
reg_read_m(RTL837X_METER_RATE + (idx << 2));
|
||||||
|
print_byte(sfr_data[1]); print_byte(sfr_data[2]); print_byte(sfr_data[3]);
|
||||||
|
if (reg_bit_test(RTL837X_METER_MODE + ((idx >> 5) << 2), idx & 0x1f))
|
||||||
|
print_string(" pps");
|
||||||
|
else
|
||||||
|
print_string(" kbps");
|
||||||
|
}
|
||||||
|
write_char('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef _RTL837X_STORM_H_
|
||||||
|
#define _RTL837X_STORM_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define STORM_TYPES 4
|
||||||
|
#define STORM_METER_BASE 24
|
||||||
|
#define STORM_METER(port, type) (STORM_METER_BASE + (((port) << 2) | (type)))
|
||||||
|
|
||||||
|
void storm_set(uint8_t port, __xdata uint8_t type, __xdata uint32_t rate, __xdata uint8_t pps) __banked;
|
||||||
|
void storm_off(uint8_t port, __xdata uint8_t type) __banked;
|
||||||
|
void storm_show(void) __banked;
|
||||||
|
|
||||||
|
#endif
|
||||||
+135
-78
@@ -28,6 +28,7 @@
|
|||||||
#include "httpd/page_impl.h"
|
#include "httpd/page_impl.h"
|
||||||
#include "boot.h"
|
#include "boot.h"
|
||||||
#include "sfp.h"
|
#include "sfp.h"
|
||||||
|
#include "crypto/chacha.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;
|
||||||
@@ -88,11 +89,14 @@ __xdata struct uip_eth_addr uip_ethaddr;
|
|||||||
volatile __xdata uint32_t ticks;
|
volatile __xdata uint32_t ticks;
|
||||||
volatile __xdata uint8_t sec_counter;
|
volatile __xdata uint8_t sec_counter;
|
||||||
volatile __xdata uint16_t sleep_ticks;
|
volatile __xdata uint16_t sleep_ticks;
|
||||||
__xdata uint8_t stp_clock;
|
__xdata uint8_t stp_tick_last;
|
||||||
__xdata uint8_t arp_age_secs;
|
__xdata uint8_t arp_age_secs;
|
||||||
extern __xdata struct dhcp_state dhcp_state;
|
extern __xdata struct dhcp_state dhcp_state;
|
||||||
|
|
||||||
#define STP_TICK_DIVIDER 3
|
#define STP_TICK_STEP (SYS_TICK_HZ / STP_HZ)
|
||||||
|
#define STP_CATCH_UP 8
|
||||||
|
#define SFP_TICK_STEP 10
|
||||||
|
__xdata uint8_t sfp_tick_last;
|
||||||
|
|
||||||
/* Buffer for serial input, SBUF_SIZE must be power of 2 < 256
|
/* Buffer for serial input, SBUF_SIZE must be power of 2 < 256
|
||||||
* Writing to this buffer is under the sole control of the serial ISR
|
* Writing to this buffer is under the sole control of the serial ISR
|
||||||
@@ -134,6 +138,11 @@ __code const uint16_t bit_mask[16] = {
|
|||||||
|
|
||||||
__xdata uint8_t linkbits_last[4];
|
__xdata uint8_t linkbits_last[4];
|
||||||
__xdata uint8_t linkbits_last_p89;
|
__xdata uint8_t linkbits_last_p89;
|
||||||
|
__data __at(0x20) volatile uint8_t evflags;
|
||||||
|
volatile __bit __at(0x00) link_irq;
|
||||||
|
volatile __bit __at(0x01) rx_irq;
|
||||||
|
volatile __bit __at(0x02) tick_pending;
|
||||||
|
__bit __at(0x03) cmd_available;
|
||||||
// Last known state of the SFP detection/Loss of Signal pins
|
// Last known state of the SFP detection/Loss of Signal pins
|
||||||
__xdata bool button_last;
|
__xdata bool button_last;
|
||||||
__xdata uint8_t button_sec_counter_last;
|
__xdata uint8_t button_sec_counter_last;
|
||||||
@@ -195,6 +204,7 @@ void isr_timer0(void) __interrupt(1)
|
|||||||
void isr_timer2(void) __interrupt(5)
|
void isr_timer2(void) __interrupt(5)
|
||||||
{
|
{
|
||||||
ticks++;
|
ticks++;
|
||||||
|
tick_pending = 1;
|
||||||
if (sleep_ticks > 0)
|
if (sleep_ticks > 0)
|
||||||
sleep_ticks--;
|
sleep_ticks--;
|
||||||
sec_counter++;
|
sec_counter++;
|
||||||
@@ -401,6 +411,16 @@ uint16_t strlen_x(__xdata const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t strcpy(__xdata uint8_t *dst, const char *s)
|
||||||
|
{
|
||||||
|
__xdata uint8_t *b = dst;
|
||||||
|
while (*s)
|
||||||
|
*dst++ = *s++;
|
||||||
|
*dst = 0;
|
||||||
|
return dst - b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char strcmp(__xdata const uint8_t *a, __code const uint8_t *b)
|
char strcmp(__xdata const uint8_t *a, __code const uint8_t *b)
|
||||||
{
|
{
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
@@ -489,14 +509,14 @@ void print_cmd_prompt(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* External IRQ 0 Service Routine: Called on link change?
|
* External IRQ 0 Service Routine: the switch reports a link change. The
|
||||||
* Note that all registers are being put on the STACK because of calling a subroutine
|
* register access macros share the SFR data bytes with the main loop, so
|
||||||
|
* the handler only latches the event; idle() reads and clears it.
|
||||||
*/
|
*/
|
||||||
void isr_ext0(void) __interrupt(0)
|
void isr_ext0(void) __interrupt(0)
|
||||||
{
|
{
|
||||||
EX0 = 0; // Disable interrupt for the moment
|
EX0 = 0;
|
||||||
IT0 = 1; // Trigger on falling edge of external interrupt
|
link_irq = 1;
|
||||||
EX0 = 1; // Re-enable interrupt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -505,9 +525,8 @@ void isr_ext0(void) __interrupt(0)
|
|||||||
*/
|
*/
|
||||||
void isr_ext1(void) __interrupt(2)
|
void isr_ext1(void) __interrupt(2)
|
||||||
{
|
{
|
||||||
// This flag should only be reset after all packets have been read
|
|
||||||
EX1 = 0;
|
EX1 = 0;
|
||||||
EX1 = 1;
|
rx_irq = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1015,6 +1034,7 @@ void handle_rx(void)
|
|||||||
REG_SET(RTL837X_REG_NIC_RXCMD, 1);
|
REG_SET(RTL837X_REG_NIC_RXCMD, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
health_rx_frame();
|
||||||
|
|
||||||
#ifdef RXTXDBG
|
#ifdef RXTXDBG
|
||||||
print_string("\n<< ");
|
print_string("\n<< ");
|
||||||
@@ -1043,8 +1063,7 @@ void handle_rx(void)
|
|||||||
tcpip_output();
|
tcpip_output();
|
||||||
}
|
}
|
||||||
} else if (igmpEnabled && uip_buf[0] == 0x01 && uip_buf[1] == 0x00 && uip_buf[2] == 0x5e // IPv4-MC packet?
|
} else if (igmpEnabled && uip_buf[0] == 0x01 && uip_buf[1] == 0x00 && uip_buf[2] == 0x5e // IPv4-MC packet?
|
||||||
&& uip_buf[3] == 0x00 && uip_buf[4] == 0x00 && uip_buf[5] == 0x16) {
|
&& igmp_packet_handler()) {
|
||||||
igmp_packet_handler();
|
|
||||||
if (uip_len) {
|
if (uip_len) {
|
||||||
tcpip_output();
|
tcpip_output();
|
||||||
}
|
}
|
||||||
@@ -1168,56 +1187,8 @@ void handle_button(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
void check_links(void)
|
||||||
// An idle function that sleeps for 1 tick and does all the house-keeping
|
|
||||||
//
|
|
||||||
void idle(void)
|
|
||||||
{
|
{
|
||||||
reg_read(RTL837X_REG_NIC_RX_BUFF_DATA);
|
|
||||||
if (!SFR_DATA_U16)
|
|
||||||
PCON |= 1;
|
|
||||||
if (sec_counter >= SYS_TICK_HZ) {
|
|
||||||
sec_counter -= SYS_TICK_HZ;
|
|
||||||
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
|
||||||
uint8_t v = sfr_data[3];
|
|
||||||
#ifdef DEBUG
|
|
||||||
print_string(" Tick counter: "); print_long(ticks); write_char('\n');
|
|
||||||
#endif
|
|
||||||
v++;
|
|
||||||
sfr_data[3] = v;
|
|
||||||
if (!v) {
|
|
||||||
v = sfr_data[2];
|
|
||||||
v++;
|
|
||||||
sfr_data[2] = v;
|
|
||||||
if (!v) {
|
|
||||||
v = sfr_data[1];
|
|
||||||
v++;
|
|
||||||
sfr_data[1] = v;
|
|
||||||
if (!v) {
|
|
||||||
v = sfr_data[0];
|
|
||||||
v++;
|
|
||||||
sfr_data[0] = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reg_write_m(RTL837X_REG_SEC_COUNTER);
|
|
||||||
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
|
||||||
|
|
||||||
// Check for button presses once a second
|
|
||||||
handle_button();
|
|
||||||
// Age the ARP cache: uip_arp_timer() expects a 10 s cadence
|
|
||||||
if (++arp_age_secs >= 10) {
|
|
||||||
arp_age_secs = 0;
|
|
||||||
uip_arp_timer();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
print_sfr_data();
|
|
||||||
write_char('\n');
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for Link changes
|
|
||||||
reg_read_m(RTL837X_REG_LINKS_89);
|
reg_read_m(RTL837X_REG_LINKS_89);
|
||||||
__xdata uint8_t linkbits_p89 = sfr_data[3];
|
__xdata uint8_t linkbits_p89 = sfr_data[3];
|
||||||
|
|
||||||
@@ -1250,24 +1221,102 @@ void idle(void)
|
|||||||
cpy_4(linkbits_last, sfr_data);
|
cpy_4(linkbits_last, sfr_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check for changes with SFP modules
|
|
||||||
handle_sfp();
|
|
||||||
|
|
||||||
// Check new Packets RX
|
//
|
||||||
handle_rx();
|
// An idle function that sleeps for 1 tick and does all the house-keeping
|
||||||
// Check UIP for packets to transmit
|
//
|
||||||
|
static void handle_tick(void)
|
||||||
|
{
|
||||||
|
if (sec_counter >= SYS_TICK_HZ) {
|
||||||
|
sec_counter -= SYS_TICK_HZ;
|
||||||
|
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
||||||
|
uint8_t v = sfr_data[3];
|
||||||
|
#ifdef DEBUG
|
||||||
|
print_string(" Tick counter: "); print_long(ticks); write_char('\n');
|
||||||
|
#endif
|
||||||
|
v++;
|
||||||
|
sfr_data[3] = v;
|
||||||
|
if (!v) {
|
||||||
|
v = sfr_data[2];
|
||||||
|
v++;
|
||||||
|
sfr_data[2] = v;
|
||||||
|
if (!v) {
|
||||||
|
v = sfr_data[1];
|
||||||
|
v++;
|
||||||
|
sfr_data[1] = v;
|
||||||
|
if (!v) {
|
||||||
|
v = sfr_data[0];
|
||||||
|
v++;
|
||||||
|
sfr_data[0] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reg_write_m(RTL837X_REG_SEC_COUNTER);
|
||||||
|
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
||||||
|
|
||||||
|
// Check for button presses once a second
|
||||||
|
handle_button();
|
||||||
|
link_irq = 1;
|
||||||
|
// Age the ARP cache: uip_arp_timer() expects a 10 s cadence
|
||||||
|
if (++arp_age_secs >= 10) {
|
||||||
|
arp_age_secs = 0;
|
||||||
|
uip_arp_timer();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
print_sfr_data();
|
||||||
|
write_char('\n');
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
health_phase(HEALTH_PH_LINK);
|
||||||
|
if (TICKS_DUE(sfp_tick_last, SFP_TICK_STEP)) {
|
||||||
|
sfp_tick_last += SFP_TICK_STEP;
|
||||||
|
handle_sfp();
|
||||||
|
}
|
||||||
|
health_phase(HEALTH_PH_SFP);
|
||||||
handle_tx();
|
handle_tx();
|
||||||
// If STP protocol enabled, decrease STP timers to trigger actions
|
health_phase(HEALTH_PH_TX);
|
||||||
if (stp_enabled) {
|
if (stp_enabled) {
|
||||||
if (!stp_clock) {
|
uint8_t n = STP_CATCH_UP;
|
||||||
stp_clock = STP_TICK_DIVIDER;
|
while (n-- && TICKS_DUE(stp_tick_last, STP_TICK_STEP)) {
|
||||||
|
stp_tick_last += STP_TICK_STEP;
|
||||||
stp_timers();
|
stp_timers();
|
||||||
} else {
|
|
||||||
stp_clock--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check whether a command is waiting in the cmd_buffer and execute
|
health_phase(HEALTH_PH_STP);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void idle(void)
|
||||||
|
{
|
||||||
|
if (!evflags)
|
||||||
|
PCON |= 1;
|
||||||
|
health_loop_start();
|
||||||
|
if (tick_pending) {
|
||||||
|
tick_pending = 0;
|
||||||
|
handle_tick();
|
||||||
|
}
|
||||||
|
if (link_irq) {
|
||||||
|
link_irq = 0;
|
||||||
|
REG_SET(RTL837X_ISR_INT_PORT_LINK_CHG, 0x3ff);
|
||||||
|
EX0 = 1;
|
||||||
|
check_links();
|
||||||
|
}
|
||||||
|
health_phase(HEALTH_PH_LINK);
|
||||||
|
if (rx_irq) {
|
||||||
|
rx_irq = 0;
|
||||||
|
handle_rx();
|
||||||
|
REG_SET(RTL837X_NIC_INT_STS, NIC_INT_RXIS);
|
||||||
|
reg_read(RTL837X_REG_NIC_RX_BUFF_DATA);
|
||||||
|
if (SFR_DATA_U16)
|
||||||
|
rx_irq = 1;
|
||||||
|
else
|
||||||
|
EX1 = 1;
|
||||||
|
}
|
||||||
|
health_phase(HEALTH_PH_RX);
|
||||||
if (cmd_available) {
|
if (cmd_available) {
|
||||||
cmd_available = 0;
|
cmd_available = 0;
|
||||||
cmd_tokenize();
|
cmd_tokenize();
|
||||||
@@ -1275,6 +1324,7 @@ void idle(void)
|
|||||||
cmd_parser();
|
cmd_parser();
|
||||||
print_cmd_prompt();
|
print_cmd_prompt();
|
||||||
}
|
}
|
||||||
|
health_phase(HEALTH_PH_CMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1300,14 +1350,16 @@ void reset_chip(void)
|
|||||||
|
|
||||||
void setup_external_irqs(void)
|
void setup_external_irqs(void)
|
||||||
{
|
{
|
||||||
REG_SET(0x5f84, 0x42);
|
REG_SET(RTL837X_ISR_SW_INT_MODE, 0x42);
|
||||||
REG_SET(0x5f34, 0x3ff);
|
REG_SET(RTL837X_ISR_INT_PORT_LINK_CHG, 0x3ff);
|
||||||
|
REG_SET(RTL837X_IMR_INT_PORT_LINK_STS_CHG, 0x3ff);
|
||||||
|
|
||||||
// EX0 = 1; // Enable external IRQ 0 (Link-change)
|
link_irq = 1;
|
||||||
EX0 = 0;
|
IT0 = 1; // External IRQ 0 on falling edge (link change)
|
||||||
IT0 = 1; // External IRQ on falling edge
|
EX0 = 1;
|
||||||
|
|
||||||
EX1 = 1; // External IRQ 1 enable
|
rx_irq = 1;
|
||||||
|
EX1 = 1; // External IRQ 1: the NIC has received a packet
|
||||||
EX2 = 1; // External IRQ 2 enable: bit EIE.0
|
EX2 = 1; // External IRQ 2 enable: bit EIE.0
|
||||||
EX3 = 1; // External IRQ 3 enable: bit EIE.1
|
EX3 = 1; // External IRQ 3 enable: bit EIE.1
|
||||||
PX3 = 1; // Set EIP.1 = 1: External IRQ 3 set to high priority
|
PX3 = 1; // Set EIP.1 = 1: External IRQ 3 set to high priority
|
||||||
@@ -1588,7 +1640,8 @@ void check_and_flash_update_image(void)
|
|||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
ticks = 0;
|
ticks = 0;
|
||||||
stp_clock = STP_TICK_DIVIDER;
|
stp_tick_last = (uint8_t)ticks;
|
||||||
|
sfp_tick_last = (uint8_t)ticks;
|
||||||
dhcp_state.state = DHCP_OFF;
|
dhcp_state.state = DHCP_OFF;
|
||||||
sbuf_ptr = 0;
|
sbuf_ptr = 0;
|
||||||
|
|
||||||
@@ -1692,6 +1745,8 @@ void main(void)
|
|||||||
|
|
||||||
REG_SET(RTL837X_PIN_MUX_2, 0x0); // Disable pins for ACL
|
REG_SET(RTL837X_PIN_MUX_2, 0x0); // Disable pins for ACL
|
||||||
init_smi();
|
init_smi();
|
||||||
|
if (machine_detected.isRTL8373)
|
||||||
|
rtl8224_wait_ready();
|
||||||
|
|
||||||
rtl8373_revision();
|
rtl8373_revision();
|
||||||
|
|
||||||
@@ -1732,6 +1787,7 @@ void main(void)
|
|||||||
stp_enabled = 0;
|
stp_enabled = 0;
|
||||||
stp_defaults(); /* 802.1D/w default config before any "stp ..." replay */
|
stp_defaults(); /* 802.1D/w default config before any "stp ..." replay */
|
||||||
nic_setup();
|
nic_setup();
|
||||||
|
REG_SET(RTL837X_NIC_INT_MSK, NIC_INT_RXIE);
|
||||||
vlan_setup();
|
vlan_setup();
|
||||||
port_l2_setup();
|
port_l2_setup();
|
||||||
igmp_setup();
|
igmp_setup();
|
||||||
@@ -1769,6 +1825,7 @@ void main(void)
|
|||||||
|
|
||||||
cmd_editor_init();
|
cmd_editor_init();
|
||||||
|
|
||||||
|
health_stack_paint();
|
||||||
while (1) {
|
while (1) {
|
||||||
cmd_edit();
|
cmd_edit();
|
||||||
idle(); // Enter Idle mode until interrupt occurs
|
idle(); // Enter Idle mode until interrupt occurs
|
||||||
|
|||||||
+5
-1
@@ -27,7 +27,8 @@ BUILDDIR = build
|
|||||||
TESTS = $(BUILDDIR)/test_cmd_editor \
|
TESTS = $(BUILDDIR)/test_cmd_editor \
|
||||||
$(BUILDDIR)/test_port_tables \
|
$(BUILDDIR)/test_port_tables \
|
||||||
$(BUILDDIR)/test_page_json \
|
$(BUILDDIR)/test_page_json \
|
||||||
$(BUILDDIR)/test_httpd_tx
|
$(BUILDDIR)/test_httpd_tx \
|
||||||
|
$(BUILDDIR)/test_tick_gate
|
||||||
|
|
||||||
# The table tests link the register mock and one environment file; stub/
|
# The table tests link the register mock and one environment file; stub/
|
||||||
# stands in for the two headers a firmware build generates.
|
# stands in for the two headers a firmware build generates.
|
||||||
@@ -47,6 +48,9 @@ $(BUILDDIR)/test_cmd_editor: test_cmd_editor.c support.c $(SRCROOT)/cmd_editor.c
|
|||||||
$(BUILDDIR)/test_port_tables: test_port_tables.c $(TABLE_ENV) hw_mock.h | $(BUILDDIR)
|
$(BUILDDIR)/test_port_tables: test_port_tables.c $(TABLE_ENV) hw_mock.h | $(BUILDDIR)
|
||||||
$(CC) $(CFLAGS) $(filter %.c,$^) -o $@ $(LDFLAGS)
|
$(CC) $(CFLAGS) $(filter %.c,$^) -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
|
$(BUILDDIR)/test_tick_gate: test_tick_gate.c support.c $(SRCROOT)/cmd_editor.c | $(BUILDDIR)
|
||||||
|
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
$(BUILDDIR)/test_page_json: test_page_json.c $(TABLE_ENV) hw_mock.h | $(BUILDDIR)
|
$(BUILDDIR)/test_page_json: test_page_json.c $(TABLE_ENV) hw_mock.h | $(BUILDDIR)
|
||||||
$(CC) $(CFLAGS) $(filter %.c,$^) -o $@ $(LDFLAGS)
|
$(CC) $(CFLAGS) $(filter %.c,$^) -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ uint8_t cmd_available;
|
|||||||
uint8_t err_status;
|
uint8_t err_status;
|
||||||
uint8_t cmd_history[CMD_HISTORY_SIZE];
|
uint8_t cmd_history[CMD_HISTORY_SIZE];
|
||||||
uint16_t cmd_history_ptr;
|
uint16_t cmd_history_ptr;
|
||||||
|
__xdata uint16_t session_timeout = 200; /* httpd global, referenced by page_impl.c */
|
||||||
|
|
||||||
/* editor-internal read pointer (defined in cmd_editor.c, external linkage) */
|
/* editor-internal read pointer (defined in cmd_editor.c, external linkage) */
|
||||||
extern __xdata uint8_t l;
|
extern __xdata uint8_t l;
|
||||||
|
|||||||
@@ -139,6 +139,8 @@ void send_status(void) { }
|
|||||||
void send_vlan(uint16_t vlan) { (void)vlan; }
|
void send_vlan(uint16_t vlan) { (void)vlan; }
|
||||||
void send_basic_info(void) { }
|
void send_basic_info(void) { }
|
||||||
void send_bandwidth(void) { }
|
void send_bandwidth(void) { }
|
||||||
|
void send_storm(void) { }
|
||||||
|
void send_isolation(void) { }
|
||||||
void send_eee(void) { }
|
void send_eee(void) { }
|
||||||
void send_l2(uint16_t idx) { (void)idx; }
|
void send_l2(uint16_t idx) { (void)idx; }
|
||||||
void l2_delete(uint16_t idx) { (void)idx; }
|
void l2_delete(uint16_t idx) { (void)idx; }
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* test_tick_gate.c - the timers of the main loop keep time by the system
|
||||||
|
* tick, however often the loop passes. The gate is the TICKS_DUE macro from
|
||||||
|
* rtl837x_common.h; the loop bodies of idle() and handle_tx() are restated
|
||||||
|
* here, so this checks the arithmetic, not those functions.
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "rtl837x_common.h"
|
||||||
|
#include "rtl837x_stp.h"
|
||||||
|
#include "support.h"
|
||||||
|
|
||||||
|
volatile uint32_t ticks;
|
||||||
|
|
||||||
|
#define STP_TICK_STEP (SYS_TICK_HZ / STP_HZ)
|
||||||
|
#define STP_CATCH_UP 8
|
||||||
|
|
||||||
|
static uint8_t stp_tick_last, tx_tick_last;
|
||||||
|
static unsigned stp_calls, tx_calls;
|
||||||
|
|
||||||
|
/* One pass of the loop: the STP block of idle() and the gate of handle_tx() */
|
||||||
|
static void pass(void)
|
||||||
|
{
|
||||||
|
uint8_t n = STP_CATCH_UP;
|
||||||
|
while (n-- && TICKS_DUE(stp_tick_last, STP_TICK_STEP)) {
|
||||||
|
stp_tick_last += STP_TICK_STEP;
|
||||||
|
stp_calls++;
|
||||||
|
}
|
||||||
|
if (TICKS_DUE(tx_tick_last, 1)) {
|
||||||
|
tx_tick_last = (uint8_t)ticks;
|
||||||
|
tx_calls++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run `seconds` of wall clock with one pass every `pass_us` microseconds. */
|
||||||
|
static void run(double pass_us, unsigned seconds)
|
||||||
|
{
|
||||||
|
double t = 0, next_tick = 0, tick_us = 1e6 / SYS_TICK_HZ, end = seconds * 1e6;
|
||||||
|
ticks = 0;
|
||||||
|
stp_tick_last = tx_tick_last = 0;
|
||||||
|
stp_calls = tx_calls = 0;
|
||||||
|
while (t < end) {
|
||||||
|
while (next_tick <= t) { ticks++; next_tick += tick_us; }
|
||||||
|
pass();
|
||||||
|
t += pass_us;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void t_rates(void)
|
||||||
|
{
|
||||||
|
printf("[test] STP time follows the tick whatever the loop does\n");
|
||||||
|
run(5000, 10);
|
||||||
|
CHECK(stp_calls == 10 * STP_HZ, "one pass per tick: 500 STP steps in 10 s");
|
||||||
|
CHECK(tx_calls == 10 * SYS_TICK_HZ, "and 2000 TX periodics");
|
||||||
|
run(16000, 10);
|
||||||
|
CHECK(stp_calls >= 10 * STP_HZ - 1 && stp_calls <= 10 * STP_HZ, "a 16 ms pass, as under an IPv4 stream: still 500 (was 156 when the clock counted passes)");
|
||||||
|
CHECK(tx_calls == 625, "TX periodic once per pass when passes are slower than the tick");
|
||||||
|
run(600, 10);
|
||||||
|
CHECK(stp_calls == 10 * STP_HZ, "a 0.6 ms pass, the loop no longer sleeping: still 500 (was 4166)");
|
||||||
|
CHECK(tx_calls == 10 * SYS_TICK_HZ, "TX periodic capped at the tick rate");
|
||||||
|
run(1300000, 13);
|
||||||
|
CHECK(stp_calls <= 10 * STP_CATCH_UP, "a 1.3 s pass loses time instead of firing 65 steps at once");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void t_wrap(void)
|
||||||
|
{
|
||||||
|
printf("[test] the byte arithmetic survives the tick counter wrapping\n");
|
||||||
|
ticks = 0xfffffffeUL;
|
||||||
|
stp_tick_last = (uint8_t)ticks;
|
||||||
|
stp_calls = 0;
|
||||||
|
for (int i = 0; i < 8; i++) { ticks++; pass(); }
|
||||||
|
CHECK(stp_calls == 2, "two STP steps across 0xffffffff -> 0x00000006");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
printf("== tick gate tests ==\n");
|
||||||
|
t_rates();
|
||||||
|
t_wrap();
|
||||||
|
printf("\n%d checks, %d failed\n", tests_run, tests_failed);
|
||||||
|
return tests_failed ? 1 : 0;
|
||||||
|
}
|
||||||
+9
-5
@@ -338,15 +338,16 @@ int main(int argc, char **argv)
|
|||||||
if (stat(arguments.data_file, &s) == 0 && s.st_mode & S_IFDIR) {
|
if (stat(arguments.data_file, &s) == 0 && s.st_mode & S_IFDIR) {
|
||||||
printf("Adding entries in directory %s\n", arguments.data_file);
|
printf("Adding entries in directory %s\n", arguments.data_file);
|
||||||
addsDir = true;
|
addsDir = true;
|
||||||
DIR *dirptr = opendir(arguments.data_file);
|
struct dirent **entries;
|
||||||
if (!dirptr) {
|
int n_entries = scandir(arguments.data_file, &entries, NULL, alphasort);
|
||||||
|
if (n_entries < 0) {
|
||||||
fprintf(stderr, "%s: ", arguments.data_file);
|
fprintf(stderr, "%s: ", arguments.data_file);
|
||||||
perror("Error opening directory");
|
perror("Error opening directory");
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
struct dirent *in_file;
|
|
||||||
int addr = arguments.address;
|
int addr = arguments.address;
|
||||||
while ( (in_file = readdir(dirptr)) ) {
|
for (int e = 0; e < n_entries; e++) {
|
||||||
|
struct dirent *in_file = entries[e];
|
||||||
snprintf(pathbuffer, PATH_SIZE, "%s/%s", arguments.data_file, in_file->d_name);
|
snprintf(pathbuffer, PATH_SIZE, "%s/%s", arguments.data_file, in_file->d_name);
|
||||||
if (stat(pathbuffer, &s) < 0) {
|
if (stat(pathbuffer, &s) < 0) {
|
||||||
fprintf(stderr, "%s: ", pathbuffer);
|
fprintf(stderr, "%s: ", pathbuffer);
|
||||||
@@ -377,6 +378,9 @@ int main(int argc, char **argv)
|
|||||||
addidx(in_file->d_name, addr, data_read);
|
addidx(in_file->d_name, addr, data_read);
|
||||||
addr += data_read;
|
addr += data_read;
|
||||||
}
|
}
|
||||||
|
for (int e = 0; e < n_entries; e++)
|
||||||
|
free(entries[e]);
|
||||||
|
free(entries);
|
||||||
} else {
|
} else {
|
||||||
size_t data_read = addfile(arguments.data_file, arguments.address);
|
size_t data_read = addfile(arguments.data_file, arguments.address);
|
||||||
|
|
||||||
@@ -437,7 +441,7 @@ int main(int argc, char **argv)
|
|||||||
fputs(xbuf, ofile);
|
fputs(xbuf, ofile);
|
||||||
fputs(fbuf, ofile);
|
fputs(fbuf, ofile);
|
||||||
fclose(ofile);
|
fclose(ofile);
|
||||||
} else if (addsDir){
|
} else if (addsDir && !argv[arg_index]) {
|
||||||
puts(dbuf);
|
puts(dbuf);
|
||||||
puts(xbuf);
|
puts(xbuf);
|
||||||
puts(ibuf);
|
puts(ibuf);
|
||||||
|
|||||||
@@ -64,6 +64,8 @@
|
|||||||
|
|
||||||
#include "../rtl837x_common.h"
|
#include "../rtl837x_common.h"
|
||||||
|
|
||||||
|
#if UIP_FORWARDING
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The list of registered network interfaces.
|
* The list of registered network interfaces.
|
||||||
*/
|
*/
|
||||||
@@ -535,3 +537,5 @@ uip_fw_periodic(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif /* UIP_FORWARDING */
|
||||||
@@ -43,6 +43,8 @@
|
|||||||
#include "uip-neighbor.h"
|
#include "uip-neighbor.h"
|
||||||
#include "../rtl837x_common.h"
|
#include "../rtl837x_common.h"
|
||||||
|
|
||||||
|
#if UIP_CONF_IPV6
|
||||||
|
|
||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK1
|
||||||
#pragma constseg BANK1
|
#pragma constseg BANK1
|
||||||
|
|
||||||
@@ -170,3 +172,5 @@ uip_neighbor_lookup(__xdata uip_ipaddr_t ipaddr)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif /* UIP_CONF_IPV6 */
|
||||||
@@ -464,6 +464,20 @@ extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
|
|||||||
#define UIP_BROADCAST UIP_CONF_BROADCAST
|
#define UIP_BROADCAST UIP_CONF_BROADCAST
|
||||||
#endif /* UIP_CONF_BROADCAST */
|
#endif /* UIP_CONF_BROADCAST */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the IP forwarding module.
|
||||||
|
*
|
||||||
|
* uip-fw.c forwards packets between several network interfaces. A
|
||||||
|
* single-interface device does not call it and should not pay for it.
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
#ifndef UIP_CONF_FORWARDING
|
||||||
|
#define UIP_FORWARDING 0
|
||||||
|
#else /* UIP_CONF_FORWARDING */
|
||||||
|
#define UIP_FORWARDING UIP_CONF_FORWARDING
|
||||||
|
#endif /* UIP_CONF_FORWARDING */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print out a uIP log message.
|
* Print out a uIP log message.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in new issue
Block a user