mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8e437f3a4 | ||
|
|
82dfb8f789 | ||
|
|
8224b06f9e | ||
|
|
69151362a0 | ||
|
|
24e83d5b74 | ||
|
|
3d81df0cad | ||
|
|
2481810906 | ||
|
|
03311debe6 | ||
|
|
e4adec9c11 | ||
|
|
d525229b42 | ||
|
|
73b23808cf | ||
|
|
4a14f50932 | ||
|
|
1bfe632174 | ||
|
|
265a80bb25 | ||
|
|
64efd3fb9f | ||
|
|
2e6425f5e6 | ||
|
|
1856aeba28 | ||
|
|
4e4a2ea4db | ||
|
|
4ccbf51976 | ||
|
|
0df48fbb1c | ||
|
|
25040070e5 | ||
|
|
edf6351d85 | ||
|
|
c3b4cc893b | ||
|
|
b83b67d234 | ||
|
|
efd61be64e | ||
|
|
da7909f422 | ||
|
|
14b2ce1c49 | ||
|
|
84d9408151 | ||
|
|
05c0571154 | ||
|
|
8790f0dca4 | ||
|
|
98af999304 | ||
|
|
0a996fa6d0 | ||
|
|
441e575661 | ||
|
|
a27118a428 | ||
|
|
01709431dc | ||
|
|
de0d413c0c | ||
|
|
b3ac10cae7 | ||
|
|
24c0a95734 | ||
|
|
f88f655f5a | ||
|
|
a6b0918885 | ||
|
|
1d6fe690a4 | ||
|
|
4f009539b0 | ||
|
|
bb90e0c9ba | ||
|
|
3cd6d60e0b | ||
|
|
67b8c718fb |
No files matched your search
@@ -20,7 +20,7 @@ jobs:
|
|||||||
apt install make gcc sdcc xxd python-is-python3 libjson-c-dev zlib1g-dev -y
|
apt install make gcc sdcc xxd python-is-python3 libjson-c-dev zlib1g-dev -y
|
||||||
- name: Run the host-side unit tests
|
- name: Run the host-side unit tests
|
||||||
run: make -C test
|
run: make -C test
|
||||||
- name: Check if machine.c can be compiled for all machines
|
- name: Check that every machine definition can be compiled
|
||||||
run: make machine_check
|
run: make machine_check
|
||||||
- name: Make project (4x2/RTL8372)
|
- name: Make project (4x2/RTL8372)
|
||||||
run: make CI=1 MACHINE="KP_9000_6XHML_X2"
|
run: make CI=1 MACHINE="KP_9000_6XHML_X2"
|
||||||
|
|||||||
@@ -7,17 +7,20 @@ HTML_LOCATION = 262144
|
|||||||
ifeq ($(origin CC),default)
|
ifeq ($(origin CC),default)
|
||||||
CC = sdcc
|
CC = sdcc
|
||||||
endif
|
endif
|
||||||
CC_FLAGS = -mmcs51 -I. -Ihttpd -Iuip
|
CC_FLAGS = -mmcs51 -I. -Imachine -Ihttpd -Iuip
|
||||||
ASM ?= sdas8051
|
ASM ?= sdas8051
|
||||||
AFLAGS= -plosgff
|
AFLAGS= -plosgff
|
||||||
|
|
||||||
SUBDIRS := tools
|
SUBDIRS := tools
|
||||||
SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS))
|
SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS))
|
||||||
|
|
||||||
ifeq ($(MACHINE),)
|
# $MACHINE selects machine/$(MACHINE).c as the board definition and is passed
|
||||||
MACHINE:= $(shell grep "^\s*#define MACHINE_" machine.h | sed "s/^\s*#define MACHINE_//")
|
# on as -DMACHINE_$(MACHINE), which the rest of the firmware tests with
|
||||||
else
|
# #if defined(MACHINE_...), and as -DMACHINE_NAME, which machine.h uses to
|
||||||
|
# include machine/$(MACHINE).h. Both take the same value, so they cannot drift.
|
||||||
|
ifneq ($(MACHINE),)
|
||||||
CC_FLAGS += -DMACHINE_$(MACHINE)
|
CC_FLAGS += -DMACHINE_$(MACHINE)
|
||||||
|
CC_FLAGS += -DMACHINE_NAME=$(MACHINE)
|
||||||
endif
|
endif
|
||||||
# Health instrumentation and the "health" console command: HEALTH=1 gmake ...
|
# Health instrumentation and the "health" console command: HEALTH=1 gmake ...
|
||||||
ifneq ($(HEALTH),)
|
ifneq ($(HEALTH),)
|
||||||
@@ -28,6 +31,9 @@ ifeq ($(CI),1)
|
|||||||
CC_FLAGS += --Werror
|
CC_FLAGS += --Werror
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# The board definition being built: one file per MACHINE_* symbol in machine.h.
|
||||||
|
MACHINE_SRC = machine/$(MACHINE).c
|
||||||
|
|
||||||
BUILDDIR = output/$(MACHINE)
|
BUILDDIR = output/$(MACHINE)
|
||||||
VERSION_HEADER := version.h
|
VERSION_HEADER := version.h
|
||||||
|
|
||||||
@@ -51,16 +57,31 @@ BUILD_DATE := $(shell date -u -d @$(SOURCE_DATE_EPOCH) +"%Y-%m-%d %H:%M:%S" 2>/d
|
|||||||
|| date -u -r $(SOURCE_DATE_EPOCH) +"%Y-%m-%d %H:%M:%S")
|
|| date -u -r $(SOURCE_DATE_EPOCH) +"%Y-%m-%d %H:%M:%S")
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all: create_build_dir $(VERSION_HEADER) $(SUBDIRS) $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin
|
# $(MACHINE_SRC) is listed here so an unknown $MACHINE fails before anything else
|
||||||
|
# is built, including the tools/ subdirectory.
|
||||||
|
all: create_build_dir $(VERSION_HEADER) $(MACHINE_SRC) $(SUBDIRS) $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin
|
||||||
|
|
||||||
create_build_dir:
|
create_build_dir:
|
||||||
mkdir -p "$(BUILDDIR)"
|
mkdir -p "$(BUILDDIR)"
|
||||||
mkdir -p "$(BUILDDIR)/uip"
|
mkdir -p "$(BUILDDIR)/uip"
|
||||||
mkdir -p "$(BUILDDIR)/httpd"
|
mkdir -p "$(BUILDDIR)/httpd"
|
||||||
|
mkdir -p "$(BUILDDIR)/machine"
|
||||||
|
mkdir -p "$(BUILDDIR)/crypto"
|
||||||
|
|
||||||
# Keep machine.c in first position to fail immediately on invalid $MACHINE value
|
# Every machine is a pair machine/<MACHINE>.c + machine/<MACHINE>.h. Selecting
|
||||||
|
# them by name means no #if/#elif chain, so an unknown or empty $MACHINE is
|
||||||
|
# caught here instead of by a #error further down the build.
|
||||||
|
$(MACHINE_SRC):
|
||||||
|
@echo "ERROR: MACHINE='$(MACHINE)' has no definition (expected $(MACHINE_SRC))." >&2
|
||||||
|
@echo " Every machine is one file pair under machine/, named after the" >&2
|
||||||
|
@echo " MACHINE_* symbol it defines; see machine/*.c for the full list." >&2
|
||||||
|
@echo " Example: make MACHINE=KP_9000_6XHML_X2" >&2
|
||||||
|
@false
|
||||||
|
|
||||||
|
# Keep the per-machine definition in first position to fail immediately on an
|
||||||
|
# invalid $MACHINE value
|
||||||
SRCS = \
|
SRCS = \
|
||||||
machine.c \
|
$(MACHINE_SRC) \
|
||||||
machine_init.c \
|
machine_init.c \
|
||||||
cmd_editor.c \
|
cmd_editor.c \
|
||||||
cmd_parser.c \
|
cmd_parser.c \
|
||||||
@@ -69,8 +90,13 @@ SRCS = \
|
|||||||
rtlplayground.c \
|
rtlplayground.c \
|
||||||
boot.c \
|
boot.c \
|
||||||
sfp.c \
|
sfp.c \
|
||||||
|
dns.c \
|
||||||
|
dns_cli.c \
|
||||||
|
ntp.c \
|
||||||
|
ntp_cli.c \
|
||||||
syslog.c \
|
syslog.c \
|
||||||
udp_apps.c
|
udp_apps.c \
|
||||||
|
crypto/chacha20.c
|
||||||
|
|
||||||
# RTL837x
|
# RTL837x
|
||||||
SRCS += \
|
SRCS += \
|
||||||
@@ -85,7 +111,9 @@ SRCS += \
|
|||||||
rtl837x_port.c \
|
rtl837x_port.c \
|
||||||
rtl837x_stp.c \
|
rtl837x_stp.c \
|
||||||
rtl837x_lldp.c \
|
rtl837x_lldp.c \
|
||||||
rtl837x_storm.c
|
rtl837x_storm.c \
|
||||||
|
rtl837x_lacp.c \
|
||||||
|
rtl837x_trap.c
|
||||||
SRCS += \
|
SRCS += \
|
||||||
httpd/httpd.c \
|
httpd/httpd.c \
|
||||||
httpd/page_impl.c
|
httpd/page_impl.c
|
||||||
@@ -157,8 +185,8 @@ $(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 48896 -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
|
||||||
objcopy --input-target=ihex -O binary $< $@
|
objcopy --input-target=ihex -O binary $< $@
|
||||||
@@ -174,15 +202,22 @@ $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.i
|
|||||||
|
|
||||||
.PHONY: clean distclean all $(SUBDIRS) $(SUBDIRSCLEAN) create_build_dir
|
.PHONY: clean distclean all $(SUBDIRS) $(SUBDIRSCLEAN) create_build_dir
|
||||||
|
|
||||||
|
# Every machine/ definition is compiled, so a machine added to machine/ is
|
||||||
|
# covered without registering it anywhere. The machine-specific defines are
|
||||||
|
# filtered out of $(CC_FLAGS) and supplied per iteration instead, so this also
|
||||||
|
# works as "make machine_check MACHINE=...".
|
||||||
|
MACHINE_DEFS := $(sort $(patsubst machine/%.c,%,$(wildcard machine/*.c)))
|
||||||
|
MACHINE_LESS_CC_FLAGS = $(filter-out -DMACHINE_%,$(CC_FLAGS))
|
||||||
|
|
||||||
.PHONY:
|
.PHONY:
|
||||||
machine_check:
|
machine_check:
|
||||||
@mkdir -p $(BUILDDIR)/tmp
|
@mkdir -p $(BUILDDIR)/tmp
|
||||||
@set -eo pipefail; \
|
@set -eo pipefail; \
|
||||||
for MACHINE in `grep -E '^[[:space:]]*(//[[:space:]]*)?#define MACHINE_' machine.h | sed -E 's%^[[:space:]]*(//[[:space:]]*)?#define MACHINE_%%' | awk '{print $$1}' | sort -u`; \
|
for MACHINE in $(MACHINE_DEFS); \
|
||||||
do \
|
do \
|
||||||
echo "Checking $${MACHINE}"; \
|
echo "Checking $${MACHINE}"; \
|
||||||
$(CC) $(CC_FLAGS) -DMACHINE_$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine.c; \
|
$(CC) $(MACHINE_LESS_CC_FLAGS) -DMACHINE_$${MACHINE} -DMACHINE_NAME=$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine/$${MACHINE}.c; \
|
||||||
$(CC) $(CC_FLAGS) -DMACHINE_$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine_init.c; \
|
$(CC) $(MACHINE_LESS_CC_FLAGS) -DMACHINE_$${MACHINE} -DMACHINE_NAME=$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine_init.c; \
|
||||||
done
|
done
|
||||||
@rm -rf $(BUILDDIR)/tmp
|
@rm -rf $(BUILDDIR)/tmp
|
||||||
|
|
||||||
|
|||||||
@@ -359,6 +359,7 @@ The following documents give further documentation on specific features of the R
|
|||||||
- [IGMP (IP-MC streaming)](doc/igmp.md)
|
- [IGMP (IP-MC streaming)](doc/igmp.md)
|
||||||
- [SFP+ ports](doc/sfp.md)
|
- [SFP+ ports](doc/sfp.md)
|
||||||
- [Trunking aka. port aggregation](doc/trunking.md)
|
- [Trunking aka. port aggregation](doc/trunking.md)
|
||||||
|
- [LACP (802.3ad link aggregation)](doc/lacp.md)
|
||||||
- [VLAN](doc/vlan.md)
|
- [VLAN](doc/vlan.md)
|
||||||
- [Storm control](doc/storm_control.md)
|
- [Storm control](doc/storm_control.md)
|
||||||
- [Modifications and Flash replacement](doc/mods.md)
|
- [Modifications and Flash replacement](doc/mods.md)
|
||||||
+39
-11
@@ -14,13 +14,17 @@
|
|||||||
#include "rtl837x_regs.h"
|
#include "rtl837x_regs.h"
|
||||||
#include "rtl837x_sfr.h"
|
#include "rtl837x_sfr.h"
|
||||||
#include "rtl837x_stp.h"
|
#include "rtl837x_stp.h"
|
||||||
|
#include "rtl837x_lacp.h"
|
||||||
#include "rtl837x_igmp.h"
|
#include "rtl837x_igmp.h"
|
||||||
#include "rtl837x_bandwidth.h"
|
#include "rtl837x_bandwidth.h"
|
||||||
#include "rtl837x_lldp.h"
|
#include "rtl837x_lldp.h"
|
||||||
#include "rtl837x_storm.h"
|
#include "rtl837x_storm.h"
|
||||||
|
#include "rtl837x_trap.h"
|
||||||
#include "sfp.h"
|
#include "sfp.h"
|
||||||
#include "dhcp.h"
|
#include "dhcp.h"
|
||||||
#include "syslog.h"
|
#include "syslog.h"
|
||||||
|
#include "dns.h"
|
||||||
|
#include "ntp.h"
|
||||||
#include "uip/uip.h"
|
#include "uip/uip.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
@@ -531,11 +535,21 @@ void parse_lag(void)
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (cmd_compare(2, "d")) {
|
if (cmd_compare(2, "d")) {
|
||||||
|
lacp_lag_set(group, 0);
|
||||||
port_lag_members_set(group, 0);
|
port_lag_members_set(group, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t w = 2;
|
uint8_t w = 2;
|
||||||
|
__xdata uint8_t lacp_mode = 0;
|
||||||
|
if (cmd_words_len > 2 && cmd_compare(2, "lacp")) {
|
||||||
|
lacp_mode = 1;
|
||||||
|
w = 3;
|
||||||
|
if (cmd_words_len > 3 && cmd_compare(3, "off")) {
|
||||||
|
lacp_lag_set(group, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
while (w < cmd_words_len) {
|
while (w < cmd_words_len) {
|
||||||
// Parse port.
|
// Parse port.
|
||||||
if (cmd_parse_port_separator(cmd_words_b[w++]) == 0)
|
if (cmd_parse_port_separator(cmd_words_b[w++]) == 0)
|
||||||
@@ -543,10 +557,15 @@ void parse_lag(void)
|
|||||||
|
|
||||||
members |= ((uint16_t)1) << atoi_results_u8;
|
members |= ((uint16_t)1) << atoi_results_u8;
|
||||||
}
|
}
|
||||||
|
if (lacp_mode) {
|
||||||
|
lacp_lag_set(group, members);
|
||||||
|
} else {
|
||||||
|
lacp_lag_set(group, 0);
|
||||||
port_lag_members_set(group, members);
|
port_lag_members_set(group, members);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
err:
|
err:
|
||||||
cmd_error("lag (show | <1-4> (d | <port>...))\n");
|
cmd_error("lag (show | <1-4> (d | [lacp] <port>...))\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -844,9 +863,14 @@ void parse_mirror(void)
|
|||||||
if (cmd_words_len < 2)
|
if (cmd_words_len < 2)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
// The first argument is the mirroring (monitor) port
|
||||||
|
uint8_t ret = cmd_parse_port(cmd_words_b[1]);
|
||||||
|
if (ret == 0)
|
||||||
|
goto err;
|
||||||
|
mirroring_port = atoi_results_u8;
|
||||||
|
|
||||||
uint8_t w = 2;
|
uint8_t w = 2;
|
||||||
uint8_t port;
|
uint8_t port;
|
||||||
uint8_t ret;
|
|
||||||
while (w < cmd_words_len) {
|
while (w < cmd_words_len) {
|
||||||
uint8_t idx = cmd_words_b[w++];
|
uint8_t idx = cmd_words_b[w++];
|
||||||
ret = cmd_parse_port(idx);
|
ret = cmd_parse_port(idx);
|
||||||
@@ -856,10 +880,6 @@ void parse_mirror(void)
|
|||||||
idx += ret;
|
idx += ret;
|
||||||
port = atoi_results_u8;
|
port = atoi_results_u8;
|
||||||
|
|
||||||
// Use the first port argument as mirroring_port
|
|
||||||
if (w == 2)
|
|
||||||
mirroring_port = port;
|
|
||||||
|
|
||||||
ret = cmd_buffer[idx];
|
ret = cmd_buffer[idx];
|
||||||
uint16_t pmask = ((uint16_t)1) << port;
|
uint16_t pmask = ((uint16_t)1) << port;
|
||||||
if (ret != 't')
|
if (ret != 't')
|
||||||
@@ -1866,6 +1886,10 @@ void cmd_parser(void) __banked
|
|||||||
parse_mtu();
|
parse_mtu();
|
||||||
} else if (cmd_compare(0, "syslog")) {
|
} else if (cmd_compare(0, "syslog")) {
|
||||||
parse_syslog();
|
parse_syslog();
|
||||||
|
} else if (cmd_compare(0, "dns")) {
|
||||||
|
dns_parse();
|
||||||
|
} else if (cmd_compare(0, "ntp") || cmd_compare(0, "time")) {
|
||||||
|
ntp_parse();
|
||||||
} else if (cmd_compare(0, "ip")) {
|
} else if (cmd_compare(0, "ip")) {
|
||||||
if (cmd_compare(1, "dhcp")) {
|
if (cmd_compare(1, "dhcp")) {
|
||||||
dhcp_start();
|
dhcp_start();
|
||||||
@@ -1966,6 +1990,13 @@ void cmd_parser(void) __banked
|
|||||||
} else if (cmd_compare(0, "health")) {
|
} else if (cmd_compare(0, "health")) {
|
||||||
health_show();
|
health_show();
|
||||||
#endif
|
#endif
|
||||||
|
} else if (cmd_compare(0, "lacp")) {
|
||||||
|
if (cmd_compare(1, "show"))
|
||||||
|
lacp_show();
|
||||||
|
else if (cmd_compare(1, "off"))
|
||||||
|
lacp_off();
|
||||||
|
else
|
||||||
|
cmd_error("lacp (show | off); a group starts LACP with: lag <1-4> lacp <port>...\n");
|
||||||
} 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)
|
||||||
@@ -2016,11 +2047,6 @@ void cmd_parser(void) __banked
|
|||||||
parse_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")) {
|
|
||||||
print_string(" Tick counter: "); print_long(ticks); print_string(" Sec Counter: ");
|
|
||||||
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
|
||||||
print_sfr_data();
|
|
||||||
write_char('\n');
|
|
||||||
} else if (cmd_compare(0, "history")) {
|
} else if (cmd_compare(0, "history")) {
|
||||||
__xdata uint16_t p = (cmd_history_ptr + 1) & CMD_HISTORY_MASK;
|
__xdata uint16_t p = (cmd_history_ptr + 1) & CMD_HISTORY_MASK;
|
||||||
__xdata uint8_t found_begin = 0;
|
__xdata uint8_t found_begin = 0;
|
||||||
@@ -2042,9 +2068,11 @@ void cmd_parser(void) __banked
|
|||||||
if (cmd_compare(1, "on")) {
|
if (cmd_compare(1, "on")) {
|
||||||
print_string("LLDP enabled\n");
|
print_string("LLDP enabled\n");
|
||||||
lldp_enabled = 1;
|
lldp_enabled = 1;
|
||||||
|
trap_rma_set(RTL837X_RMA0E_CONF, RTL837X_RMA_ACT_TRAP);
|
||||||
} else {
|
} else {
|
||||||
print_string("LLDP disabled\n");
|
print_string("LLDP disabled\n");
|
||||||
lldp_enabled = 0;
|
lldp_enabled = 0;
|
||||||
|
trap_rma_set(RTL837X_RMA0E_CONF, RTL837X_RMA_ACT_FORWARD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -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,103 @@
|
|||||||
|
#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;
|
||||||
|
|
||||||
|
#ifdef CHACHA20_TEST
|
||||||
|
__xdata uint8_t plaintext[256];
|
||||||
|
__xdata uint8_t cyphertext[256];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
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(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CHACHA20_TEST
|
||||||
|
// 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(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,238 @@
|
|||||||
|
/*
|
||||||
|
* DNS resolver for the RTL837x platform
|
||||||
|
* This code is in the Public Domain
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "rtl837x_common.h"
|
||||||
|
#include "cmd_parser.h"
|
||||||
|
#include "uip/uip.h"
|
||||||
|
#include "dhcp.h"
|
||||||
|
#include "dns.h"
|
||||||
|
|
||||||
|
#pragma codeseg BANK3
|
||||||
|
#pragma constseg BANK3
|
||||||
|
|
||||||
|
#define DNS_PORT 53
|
||||||
|
#define DNS_TRIES 6
|
||||||
|
#define DNS_TIMEOUT (2 * SYS_TICK_HZ)
|
||||||
|
|
||||||
|
extern __xdata struct dhcp_state dhcp_state;
|
||||||
|
extern volatile __xdata uint32_t ticks;
|
||||||
|
|
||||||
|
__xdata struct dns_state dns_state;
|
||||||
|
__xdata uip_ipaddr_t dns_ip;
|
||||||
|
uint8_t * __xdata dns_cand[3];
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t dns_used(__xdata uint8_t *a) __reentrant
|
||||||
|
{
|
||||||
|
return a[0] | a[1] | a[2] | a[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t dns_name_is_ip(void) __reentrant
|
||||||
|
{
|
||||||
|
__xdata char *s = dns_state.name;
|
||||||
|
uint8_t i, n;
|
||||||
|
uint16_t v;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
v = 0;
|
||||||
|
n = 0;
|
||||||
|
while (*s >= '0' && *s <= '9') {
|
||||||
|
v = v * 10 + (*s++ - '0');
|
||||||
|
if (++n > 3 || v > 255)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!n)
|
||||||
|
return 0;
|
||||||
|
dns_state.addr[i] = v;
|
||||||
|
if (i < 3 && *s++ != '.')
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return !*s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void dns_next(void) __reentrant
|
||||||
|
{
|
||||||
|
uint8_t k = 0;
|
||||||
|
|
||||||
|
if (dns_state.conn) {
|
||||||
|
uip_udp_remove(dns_state.conn);
|
||||||
|
dns_state.conn = 0;
|
||||||
|
}
|
||||||
|
if (dns_used(dns_state.server[0]))
|
||||||
|
dns_cand[k++] = dns_state.server[0];
|
||||||
|
if (dns_used(dns_state.server[1]))
|
||||||
|
dns_cand[k++] = dns_state.server[1];
|
||||||
|
if (dns_used(dhcp_state.dns))
|
||||||
|
dns_cand[k++] = dhcp_state.dns;
|
||||||
|
if (!k || dns_state.tries >= DNS_TRIES) {
|
||||||
|
dns_state.status = DNS_FAILED;
|
||||||
|
if (dns_state.verbose)
|
||||||
|
print_string(k ? "DNS: no answer\n" : "DNS: no server\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
k = dns_state.tries % k;
|
||||||
|
uip_ipaddr(dns_ip, dns_cand[k][0], dns_cand[k][1], dns_cand[k][2], dns_cand[k][3]);
|
||||||
|
dns_state.conn = uip_udp_new(&dns_ip, HTONS(DNS_PORT));
|
||||||
|
if (!dns_state.conn) {
|
||||||
|
dns_state.status = DNS_FAILED;
|
||||||
|
print_string("DNS: no free UDP connection\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dns_state.send = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void dns_query(void) __reentrant
|
||||||
|
{
|
||||||
|
__xdata uint8_t *p = (__xdata uint8_t *)uip_appdata;
|
||||||
|
__xdata char *n = dns_state.name;
|
||||||
|
__xdata uint8_t *label;
|
||||||
|
uint16_t len = 12;
|
||||||
|
|
||||||
|
dns_state.id++;
|
||||||
|
p[0] = dns_state.id >> 8;
|
||||||
|
p[1] = dns_state.id;
|
||||||
|
p[2] = 0x01;
|
||||||
|
p[3] = 0x00;
|
||||||
|
p[4] = 0;
|
||||||
|
p[5] = 1;
|
||||||
|
p[6] = p[7] = p[8] = p[9] = p[10] = p[11] = 0;
|
||||||
|
while (*n) {
|
||||||
|
label = p + len++;
|
||||||
|
*label = 0;
|
||||||
|
while (*n && *n != '.') {
|
||||||
|
p[len++] = *n++;
|
||||||
|
(*label)++;
|
||||||
|
}
|
||||||
|
if (*n)
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
p[len++] = 0;
|
||||||
|
p[len++] = 0;
|
||||||
|
p[len++] = 1;
|
||||||
|
p[len++] = 0;
|
||||||
|
p[len++] = 1;
|
||||||
|
uip_udp_send(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint16_t dns_skip_name(__xdata uint8_t *p, uint16_t i, uint16_t len) __reentrant
|
||||||
|
{
|
||||||
|
while (i < len) {
|
||||||
|
if (!p[i])
|
||||||
|
return i + 1;
|
||||||
|
if ((p[i] & 0xc0) == 0xc0)
|
||||||
|
return i + 2;
|
||||||
|
i += p[i] + 1;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void dns_answer(void) __reentrant
|
||||||
|
{
|
||||||
|
__xdata uint8_t *p = (__xdata uint8_t *)uip_appdata;
|
||||||
|
uint16_t len = uip_datalen();
|
||||||
|
uint16_t i, an;
|
||||||
|
|
||||||
|
if (dns_state.status != DNS_PENDING || len < 12 || !(p[2] & 0x80)
|
||||||
|
|| p[0] != (uint8_t)(dns_state.id >> 8) || p[1] != (uint8_t)dns_state.id)
|
||||||
|
return;
|
||||||
|
an = ((uint16_t)p[6] << 8) | p[7];
|
||||||
|
i = dns_skip_name(p, 12, len) + 4;
|
||||||
|
while (!(p[3] & 0x0f) && an-- && i + 10 <= len) {
|
||||||
|
i = dns_skip_name(p, i, len);
|
||||||
|
if (i + 10 > len)
|
||||||
|
break;
|
||||||
|
if (!p[i] && p[i + 1] == 1 && !p[i + 8] && p[i + 9] == 4 && i + 14 <= len) {
|
||||||
|
memcpy(dns_state.addr, p + i + 10, 4);
|
||||||
|
dns_state.status = DNS_DONE;
|
||||||
|
uip_udp_remove(dns_state.conn);
|
||||||
|
dns_state.conn = 0;
|
||||||
|
if (dns_state.verbose) {
|
||||||
|
print_string("DNS: ");
|
||||||
|
print_string_x(dns_state.name);
|
||||||
|
print_string(" is ");
|
||||||
|
print_ip(dns_state.addr);
|
||||||
|
write_char('\n');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i += 10 + (((uint16_t)p[i + 8] << 8) | p[i + 9]);
|
||||||
|
}
|
||||||
|
dns_state.tries = DNS_TRIES;
|
||||||
|
dns_next();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dns_init(void) __banked
|
||||||
|
{
|
||||||
|
memset(dns_state.server, 0, sizeof(dns_state.server));
|
||||||
|
dns_state.name[0] = 0;
|
||||||
|
dns_state.status = DNS_IDLE;
|
||||||
|
dns_state.conn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dns_lookup(void) __banked
|
||||||
|
{
|
||||||
|
if (dns_name_is_ip()) {
|
||||||
|
dns_state.status = DNS_DONE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dns_state.tries = 0;
|
||||||
|
dns_state.status = DNS_PENDING;
|
||||||
|
dns_next();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dns_show(void) __banked
|
||||||
|
{
|
||||||
|
print_string("DNS servers ");
|
||||||
|
print_ip(dns_state.server[0]);
|
||||||
|
write_char(' ');
|
||||||
|
print_ip(dns_state.server[1]);
|
||||||
|
print_string(", from DHCP ");
|
||||||
|
print_ip(dhcp_state.dns);
|
||||||
|
write_char('\n');
|
||||||
|
if (!dns_state.name[0])
|
||||||
|
return;
|
||||||
|
print_string("Last lookup ");
|
||||||
|
print_string_x(dns_state.name);
|
||||||
|
print_string(": ");
|
||||||
|
if (dns_state.status == DNS_DONE)
|
||||||
|
print_ip(dns_state.addr);
|
||||||
|
else if (dns_state.status == DNS_PENDING)
|
||||||
|
print_string("pending");
|
||||||
|
else
|
||||||
|
print_string("failed");
|
||||||
|
write_char('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dns_callback(uint16_t lport) __banked __reentrant
|
||||||
|
{
|
||||||
|
if (!dns_state.conn || lport != dns_state.conn->lport)
|
||||||
|
return;
|
||||||
|
if (uip_newdata()) {
|
||||||
|
dns_answer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (dns_state.status != DNS_PENDING)
|
||||||
|
return;
|
||||||
|
if (dns_state.send) {
|
||||||
|
dns_state.send = 0;
|
||||||
|
dns_state.sent = ticks;
|
||||||
|
dns_query();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ticks - dns_state.sent >= DNS_TIMEOUT) {
|
||||||
|
dns_state.tries++;
|
||||||
|
dns_next();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef _DNS_H_
|
||||||
|
#define _DNS_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define DNS_NAME_LEN 48
|
||||||
|
|
||||||
|
#define DNS_IDLE 0
|
||||||
|
#define DNS_PENDING 1
|
||||||
|
#define DNS_DONE 2
|
||||||
|
#define DNS_FAILED 3
|
||||||
|
|
||||||
|
struct uip_udp_conn;
|
||||||
|
|
||||||
|
struct dns_state {
|
||||||
|
uint8_t server[2][4]; /* configured servers, 0.0.0.0 = unused */
|
||||||
|
char name[DNS_NAME_LEN]; /* name of the current or last lookup */
|
||||||
|
uint8_t addr[4]; /* address found by the last lookup */
|
||||||
|
uint8_t status; /* DNS_* */
|
||||||
|
uint8_t verbose; /* print the result of the lookup */
|
||||||
|
uint8_t tries; /* queries sent for the current lookup */
|
||||||
|
uint8_t send; /* a query is due on the connection */
|
||||||
|
uint16_t id;
|
||||||
|
uint32_t sent; /* ticks when the last query went out */
|
||||||
|
struct uip_udp_conn *conn;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern __xdata struct dns_state dns_state;
|
||||||
|
|
||||||
|
void dns_init(void) __banked;
|
||||||
|
void dns_lookup(void) __banked;
|
||||||
|
void dns_show(void) __banked;
|
||||||
|
void dns_callback(uint16_t lport) __banked __reentrant;
|
||||||
|
void dns_parse(void) __banked __reentrant;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Command line interface of the DNS resolver for the RTL837x platform
|
||||||
|
* This code is in the Public Domain
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "rtl837x_common.h"
|
||||||
|
#include "cmd_parser.h"
|
||||||
|
#include "dns.h"
|
||||||
|
|
||||||
|
#pragma codeseg BANK2
|
||||||
|
#pragma constseg BANK2
|
||||||
|
|
||||||
|
extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
||||||
|
extern __xdata uint8_t cmd_words_len;
|
||||||
|
extern __xdata uint8_t cmd_words_b[15];
|
||||||
|
extern __xdata uint8_t ip[4];
|
||||||
|
uint8_t cmd_compare(uint8_t start, __code const uint8_t * cmd);
|
||||||
|
uint8_t parse_ip(uint8_t idx);
|
||||||
|
|
||||||
|
|
||||||
|
void dns_parse(void) __banked __reentrant
|
||||||
|
{
|
||||||
|
__xdata uint8_t *s;
|
||||||
|
uint8_t n;
|
||||||
|
|
||||||
|
if (cmd_words_len < 2) {
|
||||||
|
dns_show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cmd_compare(1, "server") && cmd_words_len >= 3 && parse_ip(cmd_words_b[2])) {
|
||||||
|
memcpy(dns_state.server[0], ip, 4);
|
||||||
|
memset(dns_state.server[1], 0, 4);
|
||||||
|
if (cmd_words_len >= 4) {
|
||||||
|
if (!parse_ip(cmd_words_b[3]))
|
||||||
|
goto err;
|
||||||
|
memcpy(dns_state.server[1], ip, 4);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cmd_compare(1, "lookup") && cmd_words_len >= 3) {
|
||||||
|
if (dns_state.status == DNS_PENDING) {
|
||||||
|
print_string("DNS: a lookup is already running\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s = &cmd_buffer[cmd_words_b[2]];
|
||||||
|
for (n = 0; s[n] && s[n] != ' '; n++) {
|
||||||
|
if (n == DNS_NAME_LEN - 1)
|
||||||
|
goto err;
|
||||||
|
dns_state.name[n] = s[n];
|
||||||
|
}
|
||||||
|
dns_state.name[n] = 0;
|
||||||
|
dns_state.verbose = 1;
|
||||||
|
dns_lookup();
|
||||||
|
if (dns_state.status == DNS_DONE) {
|
||||||
|
print_ip(dns_state.addr);
|
||||||
|
write_char('\n');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
err:
|
||||||
|
print_string("Error: dns [server <ip> [<ip>]|lookup <name>]\n");
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
# DNS
|
||||||
|
|
||||||
|
The switch can resolve host names to IPv4 addresses, for the NTP client and
|
||||||
|
for anything else that is given a name instead of an address.
|
||||||
|
|
||||||
|
```
|
||||||
|
dns server <ip> [<ip>] # one or two servers, 0.0.0.0 removes them
|
||||||
|
dns lookup <name> # resolve a name and print the address
|
||||||
|
dns # show the servers and the last lookup
|
||||||
|
```
|
||||||
|
|
||||||
|
The answer to a lookup arrives after the command has returned, so it is
|
||||||
|
printed on the serial console and in the syslog. In the console of the web
|
||||||
|
interface, run `dns` afterwards to see it.
|
||||||
|
|
||||||
|
Without a configured server the resolver uses the one handed out by DHCP.
|
||||||
|
Only address records are looked up; a query goes to the servers in turn,
|
||||||
|
every two seconds, and gives up after six tries. A name that already is a
|
||||||
|
dotted address is taken as it is, without a query.
|
||||||
|
|
||||||
|
The DNS servers are set in the Network card of the System page as well.
|
||||||
|
Settings made there or on the console are kept only once the configuration is
|
||||||
|
saved.
|
||||||
@@ -1,572 +0,0 @@
|
|||||||
# LEDs HOWTO using firmware function tracing
|
|
||||||
|
|
||||||
This is a tutorial to show how to figure out the LED configuration for
|
|
||||||
unmanaged switches (on managed ones one can just print out the registers
|
|
||||||
from the command line) without using an I2C port on the device together
|
|
||||||
an I2C-capable microcontroller. You will only need to have a SOIC clamp
|
|
||||||
and will have to run ghidra to do a bit of reversing.
|
|
||||||
|
|
||||||
The additional advantage of this method is that it not only gives the LED
|
|
||||||
configuration but also the full PHY configuration and SDS configuration e.g.
|
|
||||||
in case of additional PHYs being used on the device.
|
|
||||||
|
|
||||||
We will use the ZoeRax HG0402XG V1.1 as an example device.
|
|
||||||
|
|
||||||
The first step is to read out the flash with a SOIC clamp.
|
|
||||||
Save the image as
|
|
||||||
`zoerax_hg0402xg.bin`
|
|
||||||
|
|
||||||
The next step is to use a decompiler such as ghidra to identify the
|
|
||||||
functions used to write or read registers, SDS or to the PHY.
|
|
||||||
|
|
||||||
<img src="images/ghidra_open.png" width="300" />
|
|
||||||
|
|
||||||
First, load the code in BANK0 into ghidra. The type of code is
|
|
||||||
8051 default big-endian. The code starts at offset 0x0002 in the file
|
|
||||||
and has length 0x3ffd
|
|
||||||
|
|
||||||
<img src="images/ghidra_add_block.png" width="300" />
|
|
||||||
Add BANK1 into ghidra by using File->Add to program...
|
|
||||||
and add the code starting at 0x4000 in `zoerax_hg0402xg.bin` with length
|
|
||||||
0xc000. Repeat for BANK2 (starts at 0x10000) and BANK3 (starts at 0x1c0000).
|
|
||||||
They both have length 0xc000.
|
|
||||||
|
|
||||||
<img src="images/ghidra_search_read_reg.png" width="300" />
|
|
||||||
|
|
||||||
Now, find the read_reg function. An example of the read-register function
|
|
||||||
is given below. Note the critical bit, namely the execution of the
|
|
||||||
read-function of an ASIC register via an SFR:
|
|
||||||
```
|
|
||||||
CODE1::4dc9 75 a0 01 MOV SFR_EXEC_GO,#0x1
|
|
||||||
```
|
|
||||||
|
|
||||||
This sequence of bytes is very specific. Replace 0x01 with 0x03 and you have
|
|
||||||
the regster write SFR, 0x05 reads the SerDes, 0x07 writes it. 0x09 reads
|
|
||||||
from the PHY and 0x0b writes to it.
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
**************************************************************
|
|
||||||
* FUNCTION *
|
|
||||||
**************************************************************
|
|
||||||
undefined reg_read()
|
|
||||||
undefined <UNASSIGNED> <RETURN>
|
|
||||||
reg_read
|
|
||||||
CODE1::4da9 ab 07 MOV R3,BANK0_R7 = ??
|
|
||||||
CODE1::4dab aa 06 MOV R2,BANK0_R6 = ??
|
|
||||||
CODE1::4dad e4 CLR A
|
|
||||||
CODE1::4dae ff MOV R7,A
|
|
||||||
CODE1::4daf fe MOV R6,A
|
|
||||||
CODE1::4db0 fd MOV R5,A
|
|
||||||
CODE1::4db1 fc MOV R4,A
|
|
||||||
CODE1::4db2 90 00 c9 MOV DPTR,#0xc9
|
|
||||||
CODE1::4db5 12 06 15 LCALL FUN_CODE_0615 undefined FUN_CODE_0615()
|
|
||||||
CODE1::4db8 e4 CLR A
|
|
||||||
CODE1::4db9 ff MOV R7,A
|
|
||||||
CODE1::4dba fe MOV R6,A
|
|
||||||
CODE1::4dbb fd MOV R5,A
|
|
||||||
CODE1::4dbc fc MOV R4,A
|
|
||||||
CODE1::4dbd 90 00 c5 MOV DPTR,#0xc5
|
|
||||||
CODE1::4dc0 12 06 15 LCALL FUN_CODE_0615 undefined FUN_CODE_0615()
|
|
||||||
CODE1::4dc3 ea MOV A,R2
|
|
||||||
CODE1::4dc4 f5 a2 MOV SFR_A_ADDRH,A = ??
|
|
||||||
CODE1::4dc6 eb MOV A,R3
|
|
||||||
CODE1::4dc7 f5 a3 MOV SFR_A_ADDRL,A = ??
|
|
||||||
CODE1::4dc9 75 a0 01 MOV SFR_EXEC_GO,#0x1 <<<<<<<< Executes READ REG
|
|
||||||
LAB_CODE1__4dcc XREF[1]: CODE1::4dcf(j)
|
|
||||||
CODE1::4dcc af a1 MOV R7,SFR_EXEC_STATUS = ??
|
|
||||||
CODE1::4dce ef MOV A,R7
|
|
||||||
CODE1::4dcf 70 fb JNZ LAB_CODE1__4dcc
|
|
||||||
CODE1::4dd1 af a4 MOV R7,DAT_SFR_a4 = ??
|
|
||||||
CODE1::4dd3 fc MOV R4,A
|
|
||||||
CODE1::4dd4 fd MOV R5,A
|
|
||||||
CODE1::4dd5 fe MOV R6,A
|
|
||||||
CODE1::4dd6 90 00 c9 MOV DPTR,#0xc9
|
|
||||||
CODE1::4dd9 12 06 15 LCALL FUN_CODE_0615 undefined FUN_CODE_0615()
|
|
||||||
CODE1::4ddc 90 00 c5 MOV DPTR,#0xc5
|
|
||||||
CODE1::4ddf 12 05 f9 LCALL FUN_CODE_05f9 undefined FUN_CODE_05f9()
|
|
||||||
CODE1::4de2 c0 00 PUSH BANK0_R0
|
|
||||||
CODE1::4de4 90 00 c9 MOV DPTR,#0xc9
|
|
||||||
CODE1::4de7 12 05 dd LCALL read_xmem_32_b undefined read_xmem_32_b()
|
|
||||||
CODE1::4dea 78 18 MOV R0,#0x18
|
|
||||||
CODE1::4dec 12 05 86 LCALL FUN_CODE_0586 undefined FUN_CODE_0586()
|
|
||||||
CODE1::4def d0 00 POP BANK0_R0
|
|
||||||
CODE1::4df1 12 05 48 LCALL FUN_CODE_0548 undefined FUN_CODE_0548()
|
|
||||||
CODE1::4df4 90 00 c5 MOV DPTR,#0xc5
|
|
||||||
CODE1::4df7 12 06 15 LCALL FUN_CODE_0615 undefined FUN_CODE_0615()
|
|
||||||
CODE1::4dfa af a5 MOV R7,DAT_SFR_a5 = ??
|
|
||||||
CODE1::4dfc e4 CLR A
|
|
||||||
CODE1::4dfd fc MOV R4,A
|
|
||||||
CODE1::4dfe fd MOV R5,A
|
|
||||||
CODE1::4dff fe MOV R6,A
|
|
||||||
CODE1::4e00 90 00 c9 MOV DPTR,#0xc9
|
|
||||||
CODE1::4e03 12 06 15 LCALL FUN_CODE_0615 undefined FUN_CODE_0615()
|
|
||||||
CODE1::4e06 90 00 c5 MOV DPTR,#0xc5
|
|
||||||
CODE1::4e09 12 05 f9 LCALL FUN_CODE_05f9 undefined FUN_CODE_05f9()
|
|
||||||
CODE1::4e0c c0 00 PUSH BANK0_R0
|
|
||||||
CODE1::4e0e 90 00 c9 MOV DPTR,#0xc9
|
|
||||||
CODE1::4e11 12 05 dd LCALL read_xmem_32_b undefined read_xmem_32_b()
|
|
||||||
CODE1::4e14 78 10 MOV R0,#0x10
|
|
||||||
CODE1::4e16 12 05 86 LCALL FUN_CODE_0586 undefined FUN_CODE_0586()
|
|
||||||
CODE1::4e19 d0 00 POP BANK0_R0
|
|
||||||
CODE1::4e1b 12 05 48 LCALL FUN_CODE_0548 undefined FUN_CODE_0548()
|
|
||||||
CODE1::4e1e 90 00 c5 MOV DPTR,#0xc5
|
|
||||||
CODE1::4e21 12 06 15 LCALL FUN_CODE_0615 undefined FUN_CODE_0615()
|
|
||||||
CODE1::4e24 af a6 MOV R7,DAT_SFR_a6 = ??
|
|
||||||
CODE1::4e26 e4 CLR A
|
|
||||||
CODE1::4e27 fc MOV R4,A
|
|
||||||
CODE1::4e28 fd MOV R5,A
|
|
||||||
CODE1::4e29 fe MOV R6,A
|
|
||||||
CODE1::4e2a 90 00 c9 MOV DPTR,#0xc9
|
|
||||||
CODE1::4e2d 12 06 15 LCALL FUN_CODE_0615 undefined FUN_CODE_0615()
|
|
||||||
CODE1::4e30 90 00 c5 MOV DPTR,#0xc5
|
|
||||||
CODE1::4e33 12 05 f9 LCALL FUN_CODE_05f9 undefined FUN_CODE_05f9()
|
|
||||||
CODE1::4e36 c0 00 PUSH BANK0_R0
|
|
||||||
CODE1::4e38 90 00 c9 MOV DPTR,#0xc9
|
|
||||||
CODE1::4e3b 12 05 dd LCALL read_xmem_32_b undefined read_xmem_32_b()
|
|
||||||
CODE1::4e3e 78 08 MOV R0,#0x8
|
|
||||||
CODE1::4e40 12 05 86 LCALL FUN_CODE_0586 undefined FUN_CODE_0586()
|
|
||||||
CODE1::4e43 d0 00 POP BANK0_R0
|
|
||||||
CODE1::4e45 12 05 48 LCALL FUN_CODE_0548 undefined FUN_CODE_0548()
|
|
||||||
CODE1::4e48 90 00 c5 MOV DPTR,#0xc5
|
|
||||||
CODE1::4e4b 12 06 15 LCALL FUN_CODE_0615 undefined FUN_CODE_0615()
|
|
||||||
CODE1::4e4e af a7 MOV R7,DAT_SFR_a7 = ??
|
|
||||||
CODE1::4e50 e4 CLR A
|
|
||||||
CODE1::4e51 fc MOV R4,A
|
|
||||||
CODE1::4e52 fd MOV R5,A
|
|
||||||
CODE1::4e53 fe MOV R6,A
|
|
||||||
CODE1::4e54 90 00 c9 MOV DPTR,#0xc9
|
|
||||||
CODE1::4e57 12 06 15 LCALL FUN_CODE_0615 undefined FUN_CODE_0615()
|
|
||||||
CODE1::4e5a 90 00 c5 MOV DPTR,#0xc5
|
|
||||||
CODE1::4e5d 12 05 dd LCALL read_xmem_32_b undefined read_xmem_32_b()
|
|
||||||
CODE1::4e60 90 00 c9 MOV DPTR,#0xc9
|
|
||||||
CODE1::4e63 12 05 f9 LCALL FUN_CODE_05f9 undefined FUN_CODE_05f9()
|
|
||||||
CODE1::4e66 12 05 48 LCALL FUN_CODE_0548 undefined FUN_CODE_0548()
|
|
||||||
CODE1::4e69 90 00 c5 MOV DPTR,#0xc5
|
|
||||||
CODE1::4e6c 12 06 15 LCALL FUN_CODE_0615 undefined FUN_CODE_0615()
|
|
||||||
CODE1::4e6f 90 00 c5 MOV DPTR,#0xc5
|
|
||||||
CODE1::4e72 02 05 dd LJMP read_xmem_32_b undefined read_xmem_32_b()
|
|
||||||
-- Flow Override: CALL_RETURN (CALL_TERMINATOR)
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
INSERT ghidra_search_read_reg.png
|
|
||||||
|
|
||||||
Identify all the read and write function to the HW of the SoC using the find
|
|
||||||
in memory function.
|
|
||||||
|
|
||||||
The next task is to adapt the intercept routines in a special assembler
|
|
||||||
file. Don't worry, you do not need to understand assembler to do this.
|
|
||||||
|
|
||||||
```
|
|
||||||
; Assembler file to intercept register writes/reads and PHY writes/reads
|
|
||||||
; assemble with as31
|
|
||||||
; Compile with
|
|
||||||
; as31 -Fbyte -Orwintercept_zoerax_hg0402xg.hex rwintercept_zoerax_hg0402xg.asm
|
|
||||||
; ./injector zoerax_hg0402xg.bin RTLPlayground/rwintercept_zoerax_hg0402xg.hex zoerax_hg0402xg_patched.bin
|
|
||||||
; Start at 0x3b00, where there is always some space in BANK 0
|
|
||||||
.equ valptr, 0x199
|
|
||||||
|
|
||||||
|
|
||||||
.equ SFR_DATA_0, 0xa7
|
|
||||||
.equ SFR_DATA_8, 0xa6
|
|
||||||
.equ SFR_DATA_16, 0xa5
|
|
||||||
.equ SFR_DATA_24, 0xa4
|
|
||||||
|
|
||||||
; Intercept Register Write
|
|
||||||
.org 0x4d62
|
|
||||||
lcall reg_write
|
|
||||||
nop
|
|
||||||
|
|
||||||
; Intercept Register Read
|
|
||||||
.org 0x4dad
|
|
||||||
lcall reg_read_head
|
|
||||||
.org 0x4e6f
|
|
||||||
lcall reg_read_tail
|
|
||||||
|
|
||||||
; Intercept PHY write
|
|
||||||
.org 0x522c
|
|
||||||
lcall phy_write
|
|
||||||
|
|
||||||
; Intercept PHY read
|
|
||||||
.org 0x526f
|
|
||||||
lcall phy_read_head
|
|
||||||
.org 0x5295
|
|
||||||
ljmp phy_read_tail
|
|
||||||
|
|
||||||
; Intercept SDS write
|
|
||||||
.org 0x503c
|
|
||||||
lcall sds_write
|
|
||||||
nop
|
|
||||||
|
|
||||||
; Intercept SDS read
|
|
||||||
.org 0x5061
|
|
||||||
lcall sds_read_head
|
|
||||||
nop
|
|
||||||
.org 0x507b
|
|
||||||
ljmp sds_read_tail
|
|
||||||
|
|
||||||
;
|
|
||||||
; BEGIN actual code at unused end of BANK0
|
|
||||||
;
|
|
||||||
.org 0x3b00
|
|
||||||
|
|
||||||
;
|
|
||||||
; print the address of a register write. The address is in R6/R7. A and r4 can be scratched
|
|
||||||
;
|
|
||||||
reg_write:
|
|
||||||
mov a, #'R'
|
|
||||||
acall putc
|
|
||||||
|
|
||||||
mov a, r6
|
|
||||||
acall wbyte
|
|
||||||
|
|
||||||
mov a, r7
|
|
||||||
acall wbyte
|
|
||||||
|
|
||||||
mov a, #'-'
|
|
||||||
acall putc
|
|
||||||
|
|
||||||
mov dptr, #valptr
|
|
||||||
movx a, @dptr
|
|
||||||
acall wbyte
|
|
||||||
mov dptr, #valptr + 1
|
|
||||||
movx a, @dptr
|
|
||||||
acall wbyte
|
|
||||||
mov dptr, #valptr + 2
|
|
||||||
movx a, @dptr
|
|
||||||
acall wbyte
|
|
||||||
mov dptr, #valptr + 3
|
|
||||||
movx a, @dptr
|
|
||||||
acall wbyte
|
|
||||||
|
|
||||||
mov a, #' '
|
|
||||||
acall putc
|
|
||||||
|
|
||||||
mov a, r7
|
|
||||||
mov r5, a
|
|
||||||
mov a, r6
|
|
||||||
mov r4, a
|
|
||||||
ret
|
|
||||||
[...]
|
|
||||||
```
|
|
||||||
|
|
||||||
The full assembler file can be found here: XXXXXXXXXX
|
|
||||||
|
|
||||||
|
|
||||||
Once you have assembled the code, inject the bytes into the existing image,
|
|
||||||
creating a patched version:
|
|
||||||
```
|
|
||||||
$ as31 -Fbyte -Orwintercept_zoerax_hg0402xg.hex rwintercept_zoerax_hg0402xg.asm
|
|
||||||
Begin Pass #1
|
|
||||||
Begin Pass #2
|
|
||||||
./injector zoerax_hg0402xg.bin rwintercept_zoerax_hg0402xg.hex zoerax_hg0402xg_patched.bin
|
|
||||||
Input file size: 1048576
|
|
||||||
Bytes read:: 1048576
|
|
||||||
Patched 417 bytes.
|
|
||||||
```
|
|
||||||
|
|
||||||
Now flash `zoerax_hg0402xg_patched.bin` onto device.
|
|
||||||
|
|
||||||
Connect a serial adapter and plug in power. You will see:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ picocom -b 9600 /dev/ttyUSB0
|
|
||||||
picocom v3.1
|
|
||||||
|
|
||||||
port is : /dev/ttyUSB0
|
|
||||||
flowcontrol : none
|
|
||||||
baudrate is : 9600
|
|
||||||
parity is : none
|
|
||||||
databits are : 8
|
|
||||||
stopbits are : 1
|
|
||||||
escape is : C-a
|
|
||||||
local echo is : no
|
|
||||||
noinit is : no
|
|
||||||
noreset is : no
|
|
||||||
hangup is : no
|
|
||||||
nolock is : no
|
|
||||||
send_cmd is : sz -vv
|
|
||||||
receive_cmd is : rz -vv -E
|
|
||||||
imap is :
|
|
||||||
omap is :
|
|
||||||
emap is : crcrlf,delbs,
|
|
||||||
logfile is : none
|
|
||||||
initstring : none
|
|
||||||
exit_after is : not set
|
|
||||||
exit is : no
|
|
||||||
|
|
||||||
Type [C-a] [C-h] to see available commands
|
|
||||||
Terminal ready
|
|
||||||
[The printout only starts once the serial peripherial has been set up. Initially its timing is off:]
|
|
||||||
�.Ӛ�҂���������30-00005555 r6330:00005555 R6330-00005515 [RTL837X_REG_SMI_MAC_TYPE]
|
|
||||||
[RTL837X_REG_SMI_PORT_POLLING: ]
|
|
||||||
r6334:00000000 R6334-000000f0
|
|
||||||
r6454:00000000 R6454-00007000
|
|
||||||
|
|
||||||
[Read SoC-Revision]
|
|
||||||
r000c:00200000 R000c-002a0000 r000c:202a6818 r000c:202a6818 R000c-20206818
|
|
||||||
p001e.000d:ffff R02f8-0000ffff R02f4-0000fffa P000001.1e00000d:fffa p001e.000d:ffff p001e.000d:ffff
|
|
||||||
R02f8-0000ffff R02f4-0000fff0 P000001.1e00000d:fff0
|
|
||||||
|
|
||||||
[RTL837X_REG_LED_MODE being configured:]
|
|
||||||
r6520:0021fdb0 R6520-0021e7b0 r6520:0021e7b0 R6520-0021e6b0
|
|
||||||
|
|
||||||
[RLDP Leds configured via RTL837X_REG_LED_RLDP_X:]
|
|
||||||
r65f8:00000018 R65f8-0000001b R65fc-fffff000 r6600:00000000 R6600-0000000f
|
|
||||||
|
|
||||||
[RTL837X_REG_LED_GLB_IO_EN: ]
|
|
||||||
r65dc:5fffff00 R65dc-7fffff00 r65dc:7fffff00 R65dc-77ffff00
|
|
||||||
|
|
||||||
[RTL837X_PIN_MUX_0, makes serial go out of sync:]
|
|
||||||
r7f8c:30000000 R7f8c-30000000 r7f8c:300��.Ӛ�҂���������30-00005555
|
|
||||||
|
|
||||||
r6330:00005555 R6330-00005515 r6334:00000000 R6334-000000f0
|
|
||||||
|
|
||||||
r6454:00000000 R6454-00007000
|
|
||||||
|
|
||||||
[Read SoC-Revision (again)]
|
|
||||||
r000c:00200000 R000c-002a0000 r000c:202a6818 r000c:202a6818 R000c-20206818
|
|
||||||
p001e.000d:ffff R02f8-0000ffff R02f4-0000fffa P000001.1e00000d:fffa p001e.000d:ffff p001e.000d:ffff
|
|
||||||
R02f8-0000ffff R02f4-0000fff0
|
|
||||||
P000001.1e00000d:fff0
|
|
||||||
|
|
||||||
#### LED configuration ########
|
|
||||||
[RTL837X_REG_LED_MODE being configured (final):]
|
|
||||||
r6520:0021fdb0 R6520-0021e7b0 r6520:0021e7b0 R6520-0021e6b0
|
|
||||||
|
|
||||||
[More RTL837X_REG_LED_RLDP]
|
|
||||||
r65f8:00000018 R65f8-0000001b R65fc-fffff000 r6600:00000000 R6600-0000000f
|
|
||||||
|
|
||||||
[RTL837X_REG_LED_GLB_IO_EN]
|
|
||||||
r65dc:5fffff00 R65dc-7fffff00 r65dc:7fffff00 R65dc-77ffff00
|
|
||||||
|
|
||||||
[RTL837X_PIN_MUX_0
|
|
||||||
r7f8c:30000000 R7f8c-30000000 r7f8c:30000000 R7f8c-38000000
|
|
||||||
|
|
||||||
[RTL837X_LED_PORT_SET_SEL]
|
|
||||||
r654c:00000000 R654c-00010000
|
|
||||||
|
|
||||||
[RTL837X_REG_LED1_0_SET0]
|
|
||||||
R6548-00000141
|
|
||||||
|
|
||||||
[RTL837X_REG_LED3_2_SET0]
|
|
||||||
r6544:01411000 R6544-01410174
|
|
||||||
|
|
||||||
[RTL837X_REG_LED1_0_SET1]
|
|
||||||
r6540:00440070 R6540-0044017f
|
|
||||||
|
|
||||||
[RTL837X_REG_LED3_0_SET1]
|
|
||||||
r6528:00000000 R6528-000f0000
|
|
||||||
|
|
||||||
[SDS 0 being configure:]
|
|
||||||
r7b20:00000bff R7b20-000003ff r7b20:000003ff R7b20-000003fa r7b20:000003fa R7b20-000003fa
|
|
||||||
Q002110:4480 Q002113:0400 Q002118:6d02 Q00211b:424e Q00211d:0002 Q00361c:1390
|
|
||||||
Q003614:003f Q003610:0200 Q002e04:0080 Q002e06:0408 Q002e07:020d Q002e09:0601
|
|
||||||
Q002e0b:222c Q002e0c:a217 Q002e0d:fe40 Q002e15:f5c1 Q002e16:0443 Q002e1d:abb0
|
|
||||||
Q000612:5078 Q000706:9401 Q000708:9401 Q00070a:9401 Q00070c:9401 Q001f0b:0003
|
|
||||||
Q000603:c45c Q00061f:2100 q001f0b:0003 Q001f0b:000f q002000:0000 Q002000:0030
|
|
||||||
q002000:0030 Q002000:0010 q002000:0010 Q002000:0050 q002000:0050 Q002000:00d0
|
|
||||||
q002000:00d0 Q002000:0cd0 q002000:0cd0 Q002000:04d0 q002000:04d0 Q002000:04d0
|
|
||||||
q002000:04d0 Q002000:0cd0 q002000:0cd0 Q002000:00d0 q002000:00d0 Q002000:00d0
|
|
||||||
q002000:00d0 Q002000:0050 q002000:0050 Q002000:0010 q002000:0010 Q002000:0010
|
|
||||||
q002000:0010 Q002000:0030 q002000:0030 Q002000:0000 q001f00:0000 Q001f00:000b
|
|
||||||
q001f00:000b Q001f00:0000
|
|
||||||
|
|
||||||
[SDS 1 being configured]
|
|
||||||
r7b20:000003fa R7b20-000003fa r7b20:000003fa R7b20-0000035a r7b20:0000035a R7b20-0000035a
|
|
||||||
Q012110:4480 Q012113:0400 Q012118:6d02 Q01211b:424e Q01211d:0002 Q01361c:1390
|
|
||||||
Q013614:003f Q013610:0200 Q012e04:0080 Q012e06:0408 Q012e07:020d Q012e09:0601
|
|
||||||
Q012e0b:222c Q012e0c:a217 Q012e0d:fe40 Q012e15:f5c1 Q012e16:0443 Q012e1d:abb0
|
|
||||||
Q010612:5078 Q010706:9401 Q010708:9401 Q01070a:9401 Q01070c:9401 Q011f0b:0003
|
|
||||||
Q010603:c45c Q01061f:2100 q011f0b:0003 Q011f0b:000f q012000:0000 Q012000:0030
|
|
||||||
q012000:0030 Q012000:0010 q012000:0010 Q012000:0050 q012000:0050 Q012000:00d0
|
|
||||||
q012000:00d0 Q012000:0cd0 q012000:0cd0 Q012000:04d0 q012000:04d0 Q012000:04d0
|
|
||||||
q012000:04d0 Q012000:0cd0 q012000:0cd0 Q012000:00d0 q012000:00d0 Q012000:00d0
|
|
||||||
q012000:00d0 Q012000:0050 q012000:0050 Q012000:0010 q012000:0010 Q012000:0010
|
|
||||||
q012000:0010 Q012000:0030 q012000:0030 Q012000:0000 q011f00:0000 Q011f00:000b
|
|
||||||
q011f00:000b Q011f00:0000 q012100:4902 Q012100:4906 q013605:0000 Q013605:4000
|
|
||||||
Q011f02:001f q011f15:0096 q002100:4902 Q002100:4906 q003605:0000 Q003605:4000
|
|
||||||
Q001f02:001f q001f15:00a6
|
|
||||||
|
|
||||||
r0a90:000000f3 R0a90-000000fc P0000f0.1f00a610:2858 r5fd4:0002914a
|
|
||||||
R5fd4-001a914a r1538:00000e33 R1538-00000e37 r1538:00000e37 R1538-00000e37
|
|
||||||
r1538:00000e37 R1538-00000f37 r1638:00000e33 R1638-00000e37 r1638:00000e37
|
|
||||||
R1638-00000e37 r1638:00000e37 R1638-00000f37 r1738:00000e33 R1738-00000e37
|
|
||||||
r1738:00000e37 R1738-00000e37 r1738:00000e37 R1738-00000f37 r1838:00000e33
|
|
||||||
R1838-00000e37 r1838:00000e37 R1838-00000e37 r1838:00000e37 R1838-00000f37
|
|
||||||
r1938:00000e33 R1938-00000e37 r1938:00000e37 R1938-00000e37 r1938:00000e37
|
|
||||||
R1938-00000f37 r1a38:00000e33 R1a38-00000e37 r1a38:00000e37 R1a38-00000e37
|
|
||||||
r1a38:00000e37 R1a38-00000f37 r0b7c:000000d8 R0b7c-000000f8 R7124-00001050
|
|
||||||
R7128-00001050 R712c-00001050 R7130-00001050 R7134-00001050 R7138-00001050
|
|
||||||
R713c-00001050 R7140-00001050 R7144-00001050 R7148-00001050 r6040:00000030
|
|
||||||
R6040-00000031 p041f.a436:8195 P000010.1f00a436:0005 p041f.a438:02d4
|
|
||||||
P000010.1f00a436:801e p041f.a438:0000 p041f.b820:0000 P000010.1f00b820:0010
|
|
||||||
p041f.b800:00c0 p041f.a436:801e P000010.1f00a436:8023 p041f.a438:0000
|
|
||||||
P000010.1f00a438:1802 p041f.a436:8025
|
|
||||||
|
|
||||||
[PHY with ID 5 being patched] P000010.1f00a436:b82e p041f.a438:0000
|
|
||||||
P000010.1f00a438:0001 p041f.b820:0010 P000010.1f00b820:0090
|
|
||||||
P000010.1f00a436:a016 P000010.1f00a438:0000 P000010.1f00a436:a012
|
|
||||||
P000010.1f00a438:0000 P000010.1f00a436:a014 P000010.1f00a438:1800
|
|
||||||
P000010.1f00a438:8010 P000010.1f00a438:1800 P000010.1f00a438:8013
|
|
||||||
P000010.1f00a438:1800 P000010.1f00a438:8026 P000010.1f00a438:1800
|
|
||||||
P000010.1f00a438:802a P000010.1f00a438:1800 P000010.1f00a438:802e
|
|
||||||
P000010.1f00a438:1800 P000010.1f00a438:802e P000010.1f00a438:1800
|
|
||||||
P000010.1f00a438:802e P000010.1f00a438:1800 P000010.1f00a438:802e
|
|
||||||
...
|
|
||||||
```
|
|
||||||
Where:
|
|
||||||
```
|
|
||||||
r: read-reg
|
|
||||||
R: write-reg
|
|
||||||
q: read SDS
|
|
||||||
Q: write SDS
|
|
||||||
p: read PHY
|
|
||||||
P: write SDS
|
|
||||||
```
|
|
||||||
|
|
||||||
The LED configuration has been marked above. We now write exactly those registers
|
|
||||||
into the registers of `rtlplayground.c` on startup:
|
|
||||||
|
|
||||||
```
|
|
||||||
[...]
|
|
||||||
set_sys_led_state(SYS_LED_ON);
|
|
||||||
|
|
||||||
// [RTL837X_REG_LED_MODE being configured (final):]
|
|
||||||
// r6520:0021fdb0 R6520-0021e7b0 r6520:0021e7b0 R6520-0021e6b0
|
|
||||||
REG_SET(RTL837X_REG_LED_MODE, 0x0021e6b0);
|
|
||||||
|
|
||||||
// [More RTL837X_REG_LED_RLDP]
|
|
||||||
// r65f8:00000018 R65f8-0000001b R65fc-fffff000 r6600:00000000 R6600-0000000f
|
|
||||||
REG_SET(0x65f8, 0x0000001b);
|
|
||||||
REG_SET(0x65fc, 0xfffff000);
|
|
||||||
REG_SET(0x6600, 0x0000000f);
|
|
||||||
|
|
||||||
// [RTL837X_REG_LED_GLB_IO_EN]
|
|
||||||
// r65dc:5fffff00 R65dc-7fffff00 r65dc:7fffff00 R65dc-77ffff00
|
|
||||||
REG_SET(0x65dc, 0x77ffff00);
|
|
||||||
|
|
||||||
// [RTL837X_PIN_MUX_0
|
|
||||||
// r7f8c:30000000 R7f8c-30000000 r7f8c:30000000 R7f8c-38000000
|
|
||||||
REG_SET(0x7f8c, 0x38000000);
|
|
||||||
|
|
||||||
// [RTL837X_LED_PORT_SET_SEL]
|
|
||||||
// r654c:00000000 R654c-00010000
|
|
||||||
REG_SET(0x654c, 0x00010040);
|
|
||||||
|
|
||||||
// [RTL837X_REG_LED1_0_SET0]
|
|
||||||
// R6548-00000141
|
|
||||||
REG_SET(0x6548, 0x00000141);
|
|
||||||
|
|
||||||
// [RTL837X_REG_LED3_2_SET0]
|
|
||||||
// r6544:01411000 R6544-01410174
|
|
||||||
REG_SET(0x6544, 0x01410174);
|
|
||||||
|
|
||||||
// [RTL837X_REG_LED1_0_SET1]
|
|
||||||
// r6540:00440070 R6540-0044017f
|
|
||||||
REG_SET(0x6540, 0x0044017f);
|
|
||||||
|
|
||||||
// [RTL837X_REG_LED3_0_SET1]
|
|
||||||
// r6528:00000000 R6528-000f0000
|
|
||||||
REG_SET(0x6528, 0x000f0000);
|
|
||||||
|
|
||||||
cmd_editor_init();
|
|
||||||
[...]
|
|
||||||
```
|
|
||||||
|
|
||||||
Create an initial configuraiton for your device by copying over an existing one
|
|
||||||
for the same device type, i.e. same port-configuraiton and same SoC,
|
|
||||||
give it a new name. Make sure that the led_mux_custom and led_mux fields are not
|
|
||||||
used, because our device does not customize the LED muxes.
|
|
||||||
|
|
||||||
Compile and flash onto your device.
|
|
||||||
|
|
||||||
Now, boot the switch and issue the `leds`command, which will print out:
|
|
||||||
```
|
|
||||||
RTL837X_PIN_MUX_0: 0x38000000
|
|
||||||
RTL837X_REG_LED_GLB_IO_EN: 0x77ffff00
|
|
||||||
RTL837X_REG_LED1_0_SET0: 0x00000141
|
|
||||||
RTL837X_REG_LED3_2_SET0: 0x01410174
|
|
||||||
RTL837X_REG_LED1_0_SET1: 0x0044017f
|
|
||||||
RTL837X_REG_LED3_2_SET1: 0x18000040
|
|
||||||
RTL837X_REG_LED1_0_SET2: 0x00000000
|
|
||||||
RTL837X_REG_LED3_2_SET2: 0x00000000
|
|
||||||
RTL837X_REG_LED1_0_SET3: 0x00000000
|
|
||||||
RTL837X_REG_LED3_2_SET3: 0x00000000
|
|
||||||
RTL837X_REG_LED3_0_SET1: 0x000f0000
|
|
||||||
RTL837X_REG_LED3_0_SET3: 0x00000000
|
|
||||||
RTL837X_LED_PORT_SET_SEL: 0x00010040
|
|
||||||
RTL837X_REG_LED_GLB_MUX_1: 0x3fffffff
|
|
||||||
RTL837X_REG_LED_GLB_MUX_2: 0x0c3fffff
|
|
||||||
RTL837X_REG_LED_GLB_MUX_3: 0x1245038d
|
|
||||||
RTL837X_REG_LED_GLB_MUX_4: 0x19616554
|
|
||||||
RTL837X_REG_LED_GLB_MUX_5: 0x2079d71a
|
|
||||||
RTL837X_REG_LED_GLB_MUX_6: 0x000238a1
|
|
||||||
RTL837X_REG_LED_GLB_ACTIVE: 0x3ffbedff
|
|
||||||
RTL837X_REG_LED_MODE: 0x0021e6b0
|
|
||||||
LED pad Configuration:
|
|
||||||
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b
|
|
||||||
3f 3f 3f 3f 3f 3f 3f 3f 0f 0c 0d 0e 10 11 12 14 15 16 18 19 1a 1c 1d 1e 20 21 22 23
|
|
||||||
LED-set Configuration:
|
|
||||||
LED-ID 0 1 2 3
|
|
||||||
SET 0: 000141 000000 000174 000141
|
|
||||||
SET 1: 0f017f 000044 000040 001800
|
|
||||||
SET 2: 000000 000000 000000 000000
|
|
||||||
SET 3: 000000 000000 000000 000000
|
|
||||||
Port 3: SET 1: ( 2G5 TWO_1G 1G 500M 100M 10M LINK ACT 10G TWO_5G 5G TWO_2G5), ( 1G LINK), ( LINK), ( COL DUPLEX),
|
|
||||||
Port 4: SET 0: ( 2G5 LINK ACT), (), ( 1G 100M 10M LINK ACT), ( 2G5 LINK ACT),
|
|
||||||
Port 5: SET 0: ( 2G5 LINK ACT), (), ( 1G 100M 10M LINK ACT), ( 2G5 LINK ACT),
|
|
||||||
Port 6: SET 0: ( 2G5 LINK ACT), (), ( 1G 100M 10M LINK ACT), ( 2G5 LINK ACT),
|
|
||||||
Port 7: SET 0: ( 2G5 LINK ACT), (), ( 1G 100M 10M LINK ACT), ( 2G5 LINK ACT),
|
|
||||||
Port 8: SET 1: ( 2G5 TWO_1G 1G 500M 100M 10M LINK ACT 10G TWO_5G 5G TWO_2G5), ( 1G LINK), ( LINK), ( COL DUPLEX),
|
|
||||||
|
|
||||||
```
|
|
||||||
Together with the GPIO information, this will give you the following machine configuration:
|
|
||||||
```
|
|
||||||
_code const struct machine machine = {
|
|
||||||
.machine_name = "ZOERAX HG0402XG",
|
|
||||||
.isRTL8373 = 0,
|
|
||||||
.min_port = 3,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 2,
|
|
||||||
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
|
||||||
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
|
||||||
.is_sfp = {0, 0, 0, 1, 0, 0, 0, 0, 2},
|
|
||||||
// Left SFP port (5)
|
|
||||||
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
|
||||||
.sfp_port[0].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
|
||||||
// Right SFP port (6)
|
|
||||||
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
|
||||||
.sfp_port[1].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[1].sds = 0,
|
|
||||||
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
|
|
||||||
.reset_pin = GPIO_NA,
|
|
||||||
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
|
||||||
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
|
||||||
/* On Ethernet: Left led is orange, right green
|
|
||||||
* 100M and 1G give right led green with activity
|
|
||||||
* 2.5GBit adds solid left orange LED
|
|
||||||
* LEDs for the SFP-ports are the same as for the Ethernet ports
|
|
||||||
*/
|
|
||||||
.led_sets = { { LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
LEDS_2G5 | LEDS_LINK | LEDS_ACT
|
|
||||||
},
|
|
||||||
{ LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M |
|
|
||||||
LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
|
||||||
LEDS_1G | LEDS_LINK,
|
|
||||||
LEDS_LINK,
|
|
||||||
LEDS_COL | LEDS_DUPLEX
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
+5
-1
@@ -73,7 +73,8 @@ 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
|
||||||
default, as otherwise no IP-MC would be possible in the network.
|
default, as otherwise no IP-MC would be possible in the network. `igmp off` calls it as
|
||||||
|
well; groups learned while IGMP was on stay in the table, but are no longer looked up.
|
||||||
|
|
||||||
`igmp_enable()`starts IGMP which cause IGMP packets to be handled by the CPU and forwarding
|
`igmp_enable()`starts IGMP which cause IGMP packets to be handled by the CPU and forwarding
|
||||||
of IP-MC packets to be limited to only subscribed ports.
|
of IP-MC packets to be limited to only subscribed ports.
|
||||||
@@ -85,6 +86,9 @@ for frames to 01:00:5e:xx:xx:xx and returns 0 when the frame is not a trapped IG
|
|||||||
so that it is passed on to the IP stack. IGMPv1/v2 reports (0x12, 0x16) join the group given
|
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
|
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.
|
(type 4 joins, type 3 leaves). Trapped IGMP frames arrive without a VLAN tag.
|
||||||
|
Reports for groups in 224.0.0.0/24 are ignored: the switch floods that block
|
||||||
|
even with IGMP on, and an entry for a group such as 224.0.0.251 (mDNS) would
|
||||||
|
otherwise limit it to the ports that reported it, as RFC 4541 warns against.
|
||||||
|
|
||||||
`igmp_show()` prints out the IGMP configuration on the CLI.
|
`igmp_show()` prints out the IGMP configuration on the CLI.
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 75 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 72 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 100 KiB |
@@ -73,13 +73,14 @@ without being flooded to the other ports. No bridge relays these frames:
|
|||||||
their addresses are in the set that 802.1D-2004 clause 7.12.6 forbids a
|
their addresses are in the set that 802.1D-2004 clause 7.12.6 forbids a
|
||||||
bridge to forward, and what travels the network is the information, with
|
bridge to forward, and what travels the network is the information, with
|
||||||
every bridge regenerating BPDUs of its own on its designated ports. The reserved-multicast *trap* action
|
every bridge regenerating BPDUs of its own on its designated ports. The reserved-multicast *trap* action
|
||||||
cannot do that on this hardware, because its destination is an external CPU
|
does that: it delivers to the port named in `EXT_CPU_CTRL` (0x6724), which
|
||||||
attached to a physical port, which these boards do not populate. The protocol
|
`trap_init()` sets to 9, the CPU port, at startup; with the reset value 0xf it
|
||||||
modules therefore leave the reserved-multicast action at *forward* and constrain
|
names no port and the trapped frame is dropped. STP traps its address while it
|
||||||
the egress with a static L2 multicast entry instead: the lookup hits the entry's
|
runs (see stp.md). Where the action is left at *forward*, the egress can be
|
||||||
own port mask rather than the VLAN flood mask. Verified on a SWTGW218AS both
|
constrained with a static L2 multicast entry instead: the lookup hits the
|
||||||
ways, with the CPU bit cleared, where delivery stops, and with the CPU bit alone,
|
entry's own port mask rather than the VLAN flood mask. Verified on a SWTGW218AS
|
||||||
where nothing egresses.
|
both ways, with the CPU bit cleared, where delivery stops, and with the CPU bit
|
||||||
|
alone, where nothing egresses.
|
||||||
|
|
||||||
`port_l2mc_set()` writes one such entry. The SMI layout is the L2 multicast
|
`port_l2mc_set()` writes one such entry. The SMI layout is the L2 multicast
|
||||||
variant of the table entry:
|
variant of the table entry:
|
||||||
|
|||||||
+155
@@ -0,0 +1,155 @@
|
|||||||
|
# LACP (Link Aggregation Control Protocol, IEEE 802.3ad)
|
||||||
|
|
||||||
|
A static link aggregation group works only if both ends are configured for the
|
||||||
|
same links, and nothing checks that they are. LACP lets the two ends agree on
|
||||||
|
which links reach the same partner, aggregates only those, and takes a link out
|
||||||
|
of the group when the partner stops answering.
|
||||||
|
|
||||||
|
The switch runs LACP in software on the 8051. LACP frames belong to the Slow
|
||||||
|
Protocols, with destination `01:80:C2:00:00:02` and ethertype `0x8809`; the
|
||||||
|
subtype of LACP frames is 1. The implementation has the Receive, Selection and
|
||||||
|
Mux machines of 802.3ad clause 43 and does not aggregate links whose partners
|
||||||
|
differ. Up to `LACP_NUM_LAGS` (4) groups can run LACP; the others stay static.
|
||||||
|
|
||||||
|
## Getting the frames to the CPU
|
||||||
|
|
||||||
|
While LACP runs, the reserved multicast action for `01:80:C2:00:00:02` is
|
||||||
|
*trap*, the same mechanism STP uses for its BPDUs, see [stp.md](stp.md). A
|
||||||
|
trapped LACPDU has no VLAN tag after the RTL tag, and `TRAP_RX_BODY()` gives the
|
||||||
|
offset of the LACPDU in the received frame. When the last group leaves LACP,
|
||||||
|
the action goes back to *drop*.
|
||||||
|
|
||||||
|
## What has to match across the members
|
||||||
|
|
||||||
|
802.3ad requires that every link in an aggregate be full duplex and run at the
|
||||||
|
same speed. Beyond the standard, anything that changes how a frame is treated
|
||||||
|
has to be identical across members, because the hash picks the member per frame
|
||||||
|
and a difference would make the behaviour depend on that choice:
|
||||||
|
|
||||||
|
* must match: speed and duplex, VLAN membership and pvid, ingress filtering,
|
||||||
|
port isolation
|
||||||
|
* may differ: EEE, LED configuration, counters, cable diagnostics
|
||||||
|
|
||||||
|
None of this is enforced yet — `port_lag_members_set()` writes a member mask and
|
||||||
|
a hash setting and validates nothing. See #377 for the discussion of whether a
|
||||||
|
mismatch should be rejected or applied to the whole group.
|
||||||
|
|
||||||
|
## Protocol timing
|
||||||
|
|
||||||
|
The timer values are in units of the LACP timer, which steps every four ticks
|
||||||
|
of the system clock, 50 times per second:
|
||||||
|
|
||||||
|
| Constant | Value | Time |
|
||||||
|
|----------------------|-------|------|
|
||||||
|
| `LACP_FAST_PERIODIC` | 50 | 1 s |
|
||||||
|
| `LACP_SLOW_PERIODIC` | 1500 | 30 s |
|
||||||
|
| `LACP_SHORT_TIMEOUT` | 200 | 4 s |
|
||||||
|
|
||||||
|
802.3ad specifies a fast periodic time of 1 s with a short timeout of 3 s, and a
|
||||||
|
slow periodic time of 30 s with a long timeout of 90 s. The switch transmits at
|
||||||
|
the rate the partner asks for with its TIMEOUT bit. Its own timeout is always
|
||||||
|
the short one, one second above the standard, so a partner that stops sending
|
||||||
|
while its link stays up leaves the trunk after 4 s.
|
||||||
|
|
||||||
|
The Partner block of a transmitted LACPDU repeats the partner's actor
|
||||||
|
information as it was last received: system priority, system, key, port
|
||||||
|
priority, port and state. A Linux partner sets our SYNC only when this block
|
||||||
|
matches what it sent.
|
||||||
|
|
||||||
|
## LACP API
|
||||||
|
|
||||||
|
```
|
||||||
|
void lacp_init(void) __banked;
|
||||||
|
void lacp_off(void) __banked;
|
||||||
|
void lacp_lag_set(uint8_t lag, __xdata uint16_t ports) __banked;
|
||||||
|
void lacp_in(void) __banked;
|
||||||
|
void lacp_timers(void) __banked;
|
||||||
|
void lacp_show(void) __banked;
|
||||||
|
```
|
||||||
|
|
||||||
|
`lacp_init()` has to run before the startup configuration replays, because xdata
|
||||||
|
is not zeroed and the port-to-LAG map uses `0xff` as "no LAG"; a stray zero would
|
||||||
|
make a port look like it belongs to LAG 0.
|
||||||
|
|
||||||
|
## LACP configuration on the serial console
|
||||||
|
|
||||||
|
A group is put under LACP by adding `lacp` to the `lag` command:
|
||||||
|
|
||||||
|
```
|
||||||
|
lag 1 lacp 7 8 # ports 7 and 8 become LACP candidates of group 1
|
||||||
|
lag 1 lacp off # group 1 leaves LACP, its trunk is cleared (so does "lag 1 lacp")
|
||||||
|
lag 1 d # group 1 disabled, whether it ran LACP or not
|
||||||
|
lag 1 7 8 # plain static aggregation, no protocol
|
||||||
|
```
|
||||||
|
|
||||||
|
A group put under LACP gives up the static trunk it had: the hardware trunk is
|
||||||
|
cleared and rebuilt from the ports that converge. The other way round, `lag 1 d`
|
||||||
|
and a static member list take the group out of LACP before they touch the
|
||||||
|
trunk. A port named in another LACP group moves to the new one. The protocol
|
||||||
|
starts with the first group put under LACP and stops when the last one is taken
|
||||||
|
out; there is no separate switch for it. Two commands act on the whole engine:
|
||||||
|
|
||||||
|
```
|
||||||
|
lacp off # every group leaves LACP, protocol stopped
|
||||||
|
lacp show
|
||||||
|
```
|
||||||
|
|
||||||
|
`lacp show` prints the engine state, then one line per group with its candidate
|
||||||
|
ports, the elected aggregator and the trunk members actually programmed into the
|
||||||
|
hardware, then one line per port with the actor and partner state bytes and the
|
||||||
|
receive-machine state.
|
||||||
|
|
||||||
|
## LACP configuration via the Web Interface
|
||||||
|
|
||||||
|
Each group on the LAG page has a Static/LACP mode next to its member ports;
|
||||||
|
for an LACP group it shows the elected aggregator and the active members. Below
|
||||||
|
the groups a table has one row per LACP port with its group, actor and partner
|
||||||
|
state, receive state, LACPDU count and partner system. The page reads
|
||||||
|
`/lacp.json` every three seconds while it is open. The member checkboxes of a
|
||||||
|
static group come from the hardware registers in `/lag.json`.
|
||||||
|
|
||||||
|
## A test with a Linux 802.3ad bond
|
||||||
|
|
||||||
|
Two ports of the switch to two interfaces of one host:
|
||||||
|
|
||||||
|
```
|
||||||
|
ip link add bond0 type bond mode 802.3ad
|
||||||
|
ip link set enp1s0 down && ip link set enp1s0 master bond0
|
||||||
|
ip link set enp2s0 down && ip link set enp2s0 master bond0
|
||||||
|
ip link set bond0 up
|
||||||
|
```
|
||||||
|
|
||||||
|
On the switch, with those two ports as the group:
|
||||||
|
|
||||||
|
```
|
||||||
|
lag 1 lacp 7 8
|
||||||
|
```
|
||||||
|
|
||||||
|
`lacp show` should then give both ports an actor state of `0x3f` (ACTIVITY,
|
||||||
|
TIMEOUT, AGGREGATION, SYNC, COLLECTING and DISTRIBUTING), a partner state with
|
||||||
|
SYNC set, and the partner's system MAC. `lag show` lists the trunk members as
|
||||||
|
programmed in the hardware and should show both ports.
|
||||||
|
|
||||||
|
On the host, `/proc/net/bonding/bond0` should show the same `Aggregator ID` for
|
||||||
|
both slaves; different IDs mean that each link is in a group of its own. Both
|
||||||
|
churn states should read `none`.
|
||||||
|
|
||||||
|
Further checks:
|
||||||
|
|
||||||
|
* `tcpdump -i enp1s0 ether proto 0x8809` on each slave shows the LACPDUs of the
|
||||||
|
switch and of that slave, never those of the other slave.
|
||||||
|
* The host log has no `illegal loopback`.
|
||||||
|
* The three reserved bytes after the actor state in a LACPDU from the switch
|
||||||
|
are zero.
|
||||||
|
|
||||||
|
When one slave goes down, the group narrows to the remaining member, and the
|
||||||
|
slave rejoins after it comes back.
|
||||||
|
|
||||||
|
## Known limits
|
||||||
|
|
||||||
|
* No Churn Detection machines and no Marker protocol.
|
||||||
|
* Coupled Mux: collecting and distributing are enabled together.
|
||||||
|
* One aggregator per group.
|
||||||
|
* Selection compares the partner's system only, not its key: two aggregates
|
||||||
|
that one partner system offers on the same group land in one trunk here.
|
||||||
|
* Member compatibility is not validated; see #377.
|
||||||
@@ -227,3 +227,7 @@ iperf Done.
|
|||||||
```
|
```
|
||||||
As you can see, the total throughput was 4.71 GBit/sec which is close to the
|
As you can see, the total throughput was 4.71 GBit/sec which is close to the
|
||||||
maximum possible with a single 5GBit link.
|
maximum possible with a single 5GBit link.
|
||||||
|
|
||||||
|
## LACP
|
||||||
|
|
||||||
|
Dynamic aggregation with LACP is described in [lacp.md](lacp.md).
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
# Time
|
||||||
|
|
||||||
|
The switch has no battery backed clock. It counts seconds from power on, and
|
||||||
|
it can take the date and time from an NTP server once the network is up. The
|
||||||
|
time is lost at every restart and set again at the first synchronisation.
|
||||||
|
|
||||||
|
```
|
||||||
|
ntp server <name|ip> # default pool.ntp.org
|
||||||
|
ntp interval <1-1440> # minutes between two synchronisations, default 60
|
||||||
|
ntp timezone <+hh:mm> # offset from UTC, -12:00 to +14:00
|
||||||
|
ntp dst off|eu|us # daylight saving rule
|
||||||
|
ntp on
|
||||||
|
ntp off
|
||||||
|
ntp # settings and time
|
||||||
|
time # local date and time
|
||||||
|
```
|
||||||
|
|
||||||
|
The client speaks SNTP version 4 and synchronises at once when turned on,
|
||||||
|
then after every interval. A server given by name is resolved through the DNS
|
||||||
|
resolver before every synchronisation. An answer from an unsynchronised
|
||||||
|
server is ignored, and a failed attempt is repeated after 30 seconds.
|
||||||
|
|
||||||
|
The local time is UTC plus the time zone offset, plus one hour while daylight
|
||||||
|
saving time applies:
|
||||||
|
|
||||||
|
* `eu`: from 01:00 UTC on the last Sunday of March to 01:00 UTC on the last
|
||||||
|
Sunday of October;
|
||||||
|
* `us`: from 02:00 local time on the second Sunday of March to 02:00 local
|
||||||
|
time on the first Sunday of November.
|
||||||
|
|
||||||
|
The same settings, with the current local time and the last synchronisation,
|
||||||
|
are in the Time card of the System page. Settings made there or on the
|
||||||
|
console are kept only once the configuration is saved.
|
||||||
+25
-19
@@ -35,28 +35,34 @@ BPDUs are addressed to `01:80:C2:00:00:00`, a reserved link-local group. The
|
|||||||
ASIC's Reserved-Multicast action for that address decides what happens to the
|
ASIC's Reserved-Multicast action for that address decides what happens to the
|
||||||
frame.
|
frame.
|
||||||
|
|
||||||
Forwarding to the CPU port works normally: the 8051 sits behind an ordinary
|
While STP runs, the action is *trap*. A trap delivers to the port named in
|
||||||
port of the internal switch and is an ordinary member of a forwarding mask.
|
`EXT_CPU_CTRL` (0x6724), whose reset value 0xf names no port, and with that
|
||||||
The *trap* action does not deliver to it. Its destination is an external CPU
|
value the trapped frame is dropped at ingress. `trap_init()` sets it to 9, the
|
||||||
attached to a physical port (`cpuTag_externalCpuPort_set`, `EXT_CPU_CTRL` in
|
port the 8051 sits behind, once at startup. The trap needs no per-VLAN L2
|
||||||
the vendor SDK), which these boards do not populate. The ACL trap and
|
entries, so it does not depend on which VLANs exist or on the PVIDs, and turning
|
||||||
redirect actions do not deliver to the 8051 either.
|
STP on no longer walks the whole VLAN table. BPDUs reach the CPU on a port that
|
||||||
|
STP holds in blocking with either action: measured on a SWTGW218AS by sending
|
||||||
|
BPDUs into a blocked port with forward and with trap, both ports stopped being
|
||||||
|
edge and waited out the forward delay. The chip exempts this address from the
|
||||||
|
ingress state check; the slow-protocols address used by LACP is not exempt.
|
||||||
|
|
||||||
Delivery therefore uses the *forward* action, constrained to the CPU port
|
A trapped frame reaches the CPU in the format it came in with: unlike a
|
||||||
by a static L2 multicast entry (`port_l2mc_set()`), one per VLAN in use:
|
forwarded one it has no VLAN tag inserted after the RTL tag, and the RTL tag
|
||||||
|
carries the trap reason. `stp_in()` reads the BPDU from the offset
|
||||||
|
`TRAP_RX_BODY()` returns, which works for both.
|
||||||
|
|
||||||
* while STP runs, the entry's member mask is the CPU port only — BPDUs reach
|
With STP off, the action goes back to *forward* and a static L2 multicast
|
||||||
the CPU and are not flooded to other ports, as a participating bridge
|
entry per VLAN in use (`port_l2mc_set()`) targets all ports, restoring the
|
||||||
requires;
|
transparency an unmanaged switch is expected to have, so a surrounding
|
||||||
* with STP off, the same entries are retargeted to all ports, restoring the
|
spanning tree can span *through* this device.
|
||||||
transparency an unmanaged switch is expected to have, so a surrounding
|
|
||||||
spanning tree can span *through* this device.
|
|
||||||
|
|
||||||
A BPDU delivered this way is an ordinary frame to the port's ingress logic
|
The port's acceptable-frame-type filter treats the two actions differently.
|
||||||
and passes through its acceptable-frame-type filter. BPDUs are untagged, so a
|
BPDUs are untagged, so a port set to admit tagged frames only
|
||||||
port set to admit tagged frames only (`ingress <port>t`) never delivers one
|
(`ingress <port>t`) drops a forwarded BPDU before it reaches the CPU, while a
|
||||||
to the CPU. `stp_setup()` prints a warning for every STP-enabled port in that
|
trapped one passes. Both were measured on a SWTGW218AS with `ingress 3t`:
|
||||||
state.
|
LACPDUs, delivered by forward, stopped arriving on port 3, and BPDUs sent into
|
||||||
|
the same port, delivered by trap, kept arriving. A port that admits tagged
|
||||||
|
frames only therefore takes part in STP.
|
||||||
|
|
||||||
## Link aggregation
|
## Link aggregation
|
||||||
|
|
||||||
|
|||||||
+151
-17
@@ -67,6 +67,9 @@ iso_title:"Port isolation",iso_from:"From port",iso_to:"To port",iso_all:"Allow
|
|||||||
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_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.",
|
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.",
|
||||||
|
lacp_heading:"LACP (802.3ad)",lag_mode:"Mode",lag_static:"Static",lacp_neg:"negotiating",lacp_agg:"aggregator",
|
||||||
|
lacp_members:"active members",lacp_hint:"LACP: select candidate ports and press Apply to start negotiation",
|
||||||
|
lacp_actor:"Actor",lacp_partner:"Partner",lacp_rxstate:"RX state",lacp_rx:"LACPDUs received",lacp_psys:"Partner system",
|
||||||
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",
|
||||||
e_note:"Advertised and link-partner flags per speed: 100M, 1G, 2.5G. SFP ports do not support EEE.",
|
e_note:"Advertised and link-partner flags per speed: 100M, 1G, 2.5G. SFP ports do not support EEE.",
|
||||||
@@ -90,7 +93,14 @@ sy_ip_err:"Invalid IP / netmask / gateway",sy_host_err:"Hostname: 1-23 printable
|
|||||||
sy_net_q:"Apply network settings?",sy_net_d:"The management IP changes to {ip}: this page will need to be reopened there.",
|
sy_net_q:"Apply network settings?",sy_net_d:"The management IP changes to {ip}: this page will need to be reopened there.",
|
||||||
sy_ip_changed:"IP changed, reconnect at http://{ip}/",sy_dhcp_q:"Switch to DHCP?",
|
sy_ip_changed:"IP changed, reconnect at http://{ip}/",sy_dhcp_q:"Switch to DHCP?",
|
||||||
sy_dhcp_d:"The switch requests an address via DHCP. You must find its new IP to reconnect.",
|
sy_dhcp_d:"The switch requests an address via DHCP. You must find its new IP to reconnect.",
|
||||||
sy_sysip_err:"Invalid syslog server IP",sy_sysport_err:"Syslog port must be 1-65535",
|
sy_sysip_err:"Invalid syslog server IP",sy_dns1:"DNS server",sy_dns2:"Second DNS",sy_dns_err:"Invalid DNS server IP",sy_dns_dhcp:"from DHCP: {ip}",
|
||||||
|
sy_time:"Time",sy_ntp:"NTP",sy_ntpsrv:"NTP server",sy_ntpsrv_p:"host name or IPv4 address",sy_ntpint:"Poll interval [min]",
|
||||||
|
sy_tz:"Time zone",sy_dst:"Daylight saving",sy_dst_eu:"Europe",
|
||||||
|
sy_dst_us:"United States",sy_now:"Local time",
|
||||||
|
sy_sync:"Last synchronisation",sy_ntpaddr:"Server address",sy_nosync:"not synchronised",sy_waiting:"waiting for the server",
|
||||||
|
sy_ago:"{n} min ago",sy_ntp_err:"Enter the host name or IPv4 address of the NTP server",sy_ntpint_err:"Poll interval must be 1-1440",
|
||||||
|
sy_time_note:"The switch has no battery backed clock: the time is lost at every restart and set again from the NTP server once the network is up. Save to flash to keep the settings.",
|
||||||
|
sy_sysport_err:"Syslog port must be 1-65535",
|
||||||
sy_pw_len:"Password: 1-20 characters",sy_pw_space:"Password cannot contain spaces",sy_pw_match:"Passwords do not match",
|
sy_pw_len:"Password: 1-20 characters",sy_pw_space:"Password cannot contain spaces",sy_pw_match:"Passwords do not match",
|
||||||
sy_pw_q:"Change admin password?",sy_pw_d:"Takes effect immediately for new logins. Save to flash to persist.",
|
sy_pw_q:"Change admin password?",sy_pw_d:"Takes effect immediately for new logins. Save to flash to persist.",
|
||||||
sy_reboot_q:"Reboot the switch?",sy_reboot_d:"There are UNSAVED changes and they will be lost. Save to flash first if you want to keep them.",
|
sy_reboot_q:"Reboot the switch?",sy_reboot_d:"There are UNSAVED changes and they will be lost. Save to flash first if you want to keep them.",
|
||||||
@@ -109,6 +119,7 @@ fw_intro:"Upload an RTLPlayground image (512 KiB .bin). The image is staged to f
|
|||||||
fw_upload:"Upload",fw_checking:"{f}: {n} bytes. Checking...",fw_size_err:"size is {n}, expected 524288 (512 KiB)",
|
fw_upload:"Upload",fw_checking:"{f}: {n} bytes. Checking...",fw_size_err:"size is {n}, expected 524288 (512 KiB)",
|
||||||
fw_magic_err:"missing bank header / LJMP magic: not a firmware image",fw_crc_err:"CRC16 check failed: corrupt image",
|
fw_magic_err:"missing bank header / LJMP magic: not a firmware image",fw_crc_err:"CRC16 check failed: corrupt image",
|
||||||
fw_valid:"valid RTLPlayground image (size, magic and CRC16 OK)",fw_q:"Upload firmware?",
|
fw_valid:"valid RTLPlayground image (size, magic and CRC16 OK)",fw_q:"Upload firmware?",
|
||||||
|
fw_other:"This image was not built for this switch ({m}): its SFP, LED and button pins may differ. Upload it only if you are sure.",
|
||||||
fw_d:"On a good checksum the switch resets itself and applies the image during boot (the startup config is preserved). Do not power it off until it comes back.",
|
fw_d:"On a good checksum the switch resets itself and applies the image during boot (the startup config is preserved). Do not power it off until it comes back.",
|
||||||
fw_finishing:"finishing flash write... {s} s",fw_uploading:"uploading... {p}% / {s} s",
|
fw_finishing:"finishing flash write... {s} s",fw_uploading:"uploading... {p}% / {s} s",
|
||||||
fw_verified:"checksum verified, the switch is rebooting...",
|
fw_verified:"checksum verified, the switch is rebooting...",
|
||||||
@@ -520,6 +531,9 @@ l2_learned:"appris",l2_loading:"chargement...",l2_failed:"chargement non réussi
|
|||||||
l2_del_t:"Supprimer l'entrée",l2_flush_q:"Effacer toutes les entrées MAC apprises?",
|
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_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",
|
m_note:"RX&TX = duplique RX et TX du port vers le port de supervision.",m_none:"Selectionnez au moins un port à dupliquer",
|
||||||
|
iso_title:"Isolation des ports",iso_from:"Du port",iso_to:"Au port",iso_all:"Tout autoriser",
|
||||||
|
iso_intro:"Une trame réseau accédant à un port ne peut repartir que par le port selectionné dans cette ligne. L'isolement est prioritaire sur la retransmission, un port non non coché n'est pas accessible directement, quoi que dit la table d'adresses.",
|
||||||
|
iso_legend:"La cellule du port lui-même est toujours autorisée. Une port de couleur rouge indique que celui-ci n'est que partiellement ouvert.",
|
||||||
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_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.",
|
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_title:"Gestion énergétique des ports",e_adv:"Capacités",e_lp:"Capacité du partenaire",e_active:"Actif",e_enable:"Basse consommation",
|
||||||
@@ -560,6 +574,7 @@ fw_intro:"Charge une image RTLPlayground (512 KiB .bin). L'image est envoée en
|
|||||||
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_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_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_valid:"Image RTLPlayground valide (taille, LJMP et somme de contrôle OK)",fw_q:"Chargement du firmware?",
|
||||||
|
fw_other:"Cette image n'a pas été prévue pour ce commutateur({m}): La puce, les LED et les boouton peuvent être différents. Poursuivez seulement si vous êtes sûrs de vous.",
|
||||||
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_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_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_verified:"Somme de contrôle vérifiée, le commutateur redémarre...",
|
||||||
@@ -676,6 +691,7 @@ fw_intro:"Ein RTLPlayground-Image hochladen (.bin, 512 KiB). Das Image wird im F
|
|||||||
fw_upload:"Hochladen",fw_checking:"{f}: {n} Bytes. Wird geprüft...",fw_size_err:"Grösse ist {n}, erwartet 524288 (512 KiB)",
|
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_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_valid:"gültiges RTLPlayground-Image (Grösse, Kennung und CRC16 in Ordnung)",fw_q:"Firmware hochladen?",
|
||||||
|
fw_other:"Dieses Image wurde nicht für diesen Switch ({m}) gebaut: SFP-, LED- und Tasten-Pins können abweichen. Nur hochladen, wenn du sicher bist.",
|
||||||
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_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_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_verified:"Prüfsumme bestätigt, der Switch startet neu...",
|
||||||
@@ -782,6 +798,9 @@ var CONF_CMDS=[
|
|||||||
/^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}$/,
|
/^session\s+\d{1,5}$/,
|
||||||
|
/^dns\s+server\s+(\d{1,3}\.){3}\d{1,3}(\s+(\d{1,3}\.){3}\d{1,3})?$/,
|
||||||
|
/^ntp\s+(on|off)$/,/^ntp\s+server\s+[A-Za-z0-9.-]{1,47}$/,/^ntp\s+interval\s+\d{1,4}$/,
|
||||||
|
/^ntp\s+timezone\s+[+-]?\d{1,2}(:\d{2})?$/,/^ntp\s+dst\s+(off|eu|us)$/,
|
||||||
/^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?)+$/,
|
||||||
@@ -792,7 +811,7 @@ var CONF_CMDS=[
|
|||||||
/^port\s+\d{1,2}\s+lldp\s+(permit|block)+$/,
|
/^port\s+\d{1,2}\s+lldp\s+(permit|block)+$/,
|
||||||
/^eee\s+(on|off)(\s+\d{1,2})?(\s+(100m|1g|2g5))?$/,
|
/^eee\s+(on|off)(\s+\d{1,2})?(\s+(100m|1g|2g5))?$/,
|
||||||
/^mirror(\s+\d{1,2})(\s+\d{1,2}[tr]?)+$/,/^mirror\s+off$/,
|
/^mirror(\s+\d{1,2})(\s+\d{1,2}[tr]?)+$/,/^mirror\s+off$/,
|
||||||
/^lag\s+[1-4](\s+\d{1,2})+$/,/^lag\s+[1-4]\s+d$/,/^laghash\s+[1-4](\s+\w+)+$/,
|
/^lag\s+[1-4](\s+\d{1,2})+$/,/^lag\s+[1-4]\s+d$/,/^lag\s+[1-4]\s+lacp(\s+\d{1,2})+$/,/^lag\s+[1-4]\s+lacp\s+off$/,/^laghash\s+[1-4](\s+\w+)+$/,
|
||||||
/^isolate\s+\d{1,2}(\s+(off|\d{1,2}))+$/,
|
/^isolate\s+\d{1,2}(\s+(off|\d{1,2}))+$/,
|
||||||
/^stp\s+(on|off)$/,/^stp\s+(prio|hello|maxage|fwd|txhold)\s+\d{1,2}$/,
|
/^stp\s+(on|off)$/,/^stp\s+(prio|hello|maxage|fwd|txhold)\s+\d{1,2}$/,
|
||||||
/^stp\s+version\s+(rstp|stp)$/,
|
/^stp\s+version\s+(rstp|stp)$/,
|
||||||
@@ -1051,7 +1070,11 @@ function renderInfo(){
|
|||||||
if(v==null||v==="")return;
|
if(v==null||v==="")return;
|
||||||
tb.appendChild(h("tr",null,[h("td",{class:"mut",text:t(r[0])}),h("td",{class:"mono",text:String(v)})]));
|
tb.appendChild(h("tr",null,[h("td",{class:"mut",text:t(r[0])}),h("td",{class:"mono",text:String(v)})]));
|
||||||
});
|
});
|
||||||
if(S.info.hostname)$("brandname").textContent=$("brandname").title=S.info.hostname;
|
if(S.info.hostname){
|
||||||
|
$("brandname").textContent=$("brandname").title=document.title=S.info.hostname;
|
||||||
|
// Remembered per switch (each has its own origin) for the login page tab
|
||||||
|
try{localStorage.setItem("rtl_host",S.info.hostname);}catch(e){}
|
||||||
|
}
|
||||||
if(S.info.sw_ver)$("fver").textContent="RTLPlayground "+S.info.sw_ver;
|
if(S.info.sw_ver)$("fver").textContent="RTLPlayground "+S.info.sw_ver;
|
||||||
}
|
}
|
||||||
function pollInfo(){
|
function pollInfo(){
|
||||||
@@ -1794,6 +1817,15 @@ function buildLag(){
|
|||||||
for(var g=1;g<=4;g++)(function(g){
|
for(var g=1;g<=4;g++)(function(g){
|
||||||
var card=h("div",{class:"card"});
|
var card=h("div",{class:"card"});
|
||||||
card.appendChild(h("h2",{text:"LAG "+g}));
|
card.appendChild(h("h2",{text:"LAG "+g}));
|
||||||
|
var mr=h("div",{style:"display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-bottom:10px",class:"small"});
|
||||||
|
mr.appendChild(h("span",{class:"mut",text:t("lag_mode")}));
|
||||||
|
var ms=h("select",{class:"in",id:"lgm"+g});
|
||||||
|
ms.appendChild(h("option",{value:"static",text:t("lag_static")}));
|
||||||
|
ms.appendChild(h("option",{value:"lacp",text:"LACP"}));
|
||||||
|
ms.addEventListener("change",function(){$("lgs"+g).textContent=ms.value==="lacp"?t("lacp_hint"):""});
|
||||||
|
mr.appendChild(ms);
|
||||||
|
card.appendChild(mr);
|
||||||
|
card.appendChild(h("p",{class:"small mono",id:"lgs"+g,style:"margin-bottom:10px"}));
|
||||||
var pr=h("div",{style:"display:flex;gap:10px;flex-wrap:wrap;margin-bottom:10px"});
|
var pr=h("div",{style:"display:flex;gap:10px;flex-wrap:wrap;margin-bottom:10px"});
|
||||||
for(var p=1;p<=S.n;p++)pr.appendChild(h("label",null,[
|
for(var p=1;p<=S.n;p++)pr.appendChild(h("label",null,[
|
||||||
h("input",{type:"checkbox",id:"lg"+g+"p"+p}),document.createTextNode(" "+p+" "),
|
h("input",{type:"checkbox",id:"lg"+g+"p"+p}),document.createTextNode(" "+p+" "),
|
||||||
@@ -1806,14 +1838,34 @@ function buildLag(){
|
|||||||
});
|
});
|
||||||
card.appendChild(hr);
|
card.appendChild(hr);
|
||||||
card.appendChild(h("button",{class:"ctl pri",text:t("c_apply"),onclick:function(){lagApply(g)}}));
|
card.appendChild(h("button",{class:"ctl pri",text:t("c_apply"),onclick:function(){lagApply(g)}}));
|
||||||
|
card.addEventListener("change",function(){card.dataset.dirty="1"});
|
||||||
w.appendChild(card);
|
w.appendChild(card);
|
||||||
})(g);
|
})(g);
|
||||||
}
|
}
|
||||||
|
var lacpCfg=[0,0,0,0,0];
|
||||||
|
function maskPorts(m){var r=[];for(var p=1;p<=S.n;p++)if((m>>S.physToLog[p-1])&1)r.push(p);return r.length?r.join(" "):"-"}
|
||||||
function lagLoad(){
|
function lagLoad(){
|
||||||
return getJSON("/lag.json").then(function(s){
|
return getJSON("/lacp.json").then(function(c){
|
||||||
|
var tb=$("lacptbl").tBodies[0];
|
||||||
|
tb.innerHTML="";
|
||||||
|
c.lags.forEach(function(lg,i){
|
||||||
|
var g=i+1;
|
||||||
|
lacpCfg[g]=parseInt(lg.cfg,16);
|
||||||
|
if($("lgm"+g).closest(".card").dataset.dirty)return;
|
||||||
|
$("lgm"+g).value=lacpCfg[g]?"lacp":"static";
|
||||||
|
$("lgs"+g).textContent=lacpCfg[g]?"LACP: "+t("lacp_agg")+" "+(lg.aggValid?lg.agg:"("+t("lacp_neg")+")")+", "+t("lacp_members")+" "+maskPorts(parseInt(lg.members,16)):"";
|
||||||
|
});
|
||||||
|
if(c.on)c.ports.forEach(function(p){
|
||||||
|
if(p.lag===255)return;
|
||||||
|
var tr=tb.insertRow();
|
||||||
|
[p.p,p.lag+1,p.a,p.pt,p.rs,parseInt(p.rx,16),p.psys].forEach(function(v){tr.insertCell().textContent=v});
|
||||||
|
});
|
||||||
|
return getJSON("/lag.json");
|
||||||
|
}).then(function(s){
|
||||||
s.forEach(function(l){
|
s.forEach(function(l){
|
||||||
var g=l.lagNum+1;
|
var g=l.lagNum+1;
|
||||||
var members=parseInt(l.members,2);
|
if($("lgm"+g).closest(".card").dataset.dirty)return;
|
||||||
|
var members=lacpCfg[g]||parseInt(l.members,2);
|
||||||
for(var p=1;p<=S.n;p++)
|
for(var p=1;p<=S.n;p++)
|
||||||
$("lg"+g+"p"+p).checked=!!((members>>S.physToLog[p-1])&1);
|
$("lg"+g+"p"+p).checked=!!((members>>S.physToLog[p-1])&1);
|
||||||
var hash=parseInt(l.hash,16);
|
var hash=parseInt(l.hash,16);
|
||||||
@@ -1822,21 +1874,25 @@ function lagLoad(){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
function lagApply(g){
|
function lagApply(g){
|
||||||
var cmd="lag "+g,n=0;
|
var lacp=$("lgm"+g).value==="lacp",cmd="lag "+g+(lacp?" lacp":""),n=0,pre=[];
|
||||||
|
delete $("lgm"+g).closest(".card").dataset.dirty;
|
||||||
for(var p=1;p<=S.n;p++)if($("lg"+g+"p"+p).checked){cmd+=" "+p;n++;}
|
for(var p=1;p<=S.n;p++)if($("lg"+g+"p"+p).checked){cmd+=" "+p;n++;}
|
||||||
if(!n){
|
if(!lacp&&lacpCfg[g])pre.push("lag "+g+" lacp off");
|
||||||
|
if(lacp&&!n)cmd="lag "+g+" lacp off";
|
||||||
|
if(!n&&!lacp){
|
||||||
confirmModal(t("lag_clear_q",{n:g}),t("lag_clear_d"),function(){
|
confirmModal(t("lag_clear_q",{n:g}),t("lag_clear_d"),function(){
|
||||||
postCmd("lag "+g+" d").then(lagLoad).catch(function(){});
|
postCmds(pre.concat(["lag "+g+" d"])).then(lagLoad).catch(function(){});
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var hcmd="laghash "+g,nh=0;
|
var hcmd="laghash "+g,nh=0;
|
||||||
HASHF.forEach(function(f){if($("lg"+g+"h"+f).checked){hcmd+=" "+f;nh++;}});
|
HASHF.forEach(function(f){if($("lg"+g+"h"+f).checked){hcmd+=" "+f;nh++;}});
|
||||||
var cmds=[cmd];
|
var cmds=pre.concat([cmd]);
|
||||||
if(nh)cmds.push(hcmd);
|
if(nh)cmds.push(hcmd);
|
||||||
postCmds(cmds).then(lagLoad).catch(function(){});
|
postCmds(cmds).then(lagLoad).catch(function(){});
|
||||||
}
|
}
|
||||||
tabHooks.lag={enter:function(){needPorts(function(){buildLag();lagLoad().catch(function(){})})}};
|
var lagPoller=new Poller(function(){return lagLoad().catch(function(){})},3000);
|
||||||
|
tabHooks.lag={enter:function(){needPorts(function(){buildLag();lagPoller.start()})},leave:function(){lagPoller.stop()}};
|
||||||
|
|
||||||
|
|
||||||
function lldpLoad(){
|
function lldpLoad(){
|
||||||
@@ -2022,6 +2078,16 @@ function sysLoad(){
|
|||||||
if(S.info.session_timeout)$("sy-sesstmo").value=S.info.session_timeout;
|
if(S.info.session_timeout)$("sy-sesstmo").value=S.info.session_timeout;
|
||||||
}).catch(function(){});
|
}).catch(function(){});
|
||||||
cfgReload();
|
cfgReload();
|
||||||
|
dnsLoad();
|
||||||
|
}
|
||||||
|
function dnsLoad(){
|
||||||
|
return api("/cmd",{method:"POST",body:"dns"}).then(function(r){
|
||||||
|
var m=r.body.match(/DNS servers ([\d.]+) ([\d.]+), from DHCP ([\d.]+)/);
|
||||||
|
if(!m)return;
|
||||||
|
function v(x){return x==="0.0.0.0"?"":x}
|
||||||
|
$("sy-dns1").value=v(m[1]);$("sy-dns2").value=v(m[2]);
|
||||||
|
$("sy-dnsdhcp").textContent=m[3]==="0.0.0.0"?"":t("sy_dns_dhcp",{ip:m[3]});
|
||||||
|
}).catch(function(){});
|
||||||
}
|
}
|
||||||
function cfgParseKnown(txt){
|
function cfgParseKnown(txt){
|
||||||
var igmp=false,syslog=false;
|
var igmp=false,syslog=false;
|
||||||
@@ -2038,13 +2104,15 @@ function cfgParseKnown(txt){
|
|||||||
$("sy-apply").addEventListener("click",function(){
|
$("sy-apply").addEventListener("click",function(){
|
||||||
var ip=$("sy-ip").value.trim(),mask=$("sy-mask").value.trim(),gw=$("sy-gw").value.trim();
|
var ip=$("sy-ip").value.trim(),mask=$("sy-mask").value.trim(),gw=$("sy-gw").value.trim();
|
||||||
if(!okIp(ip)||!okIp(mask)||!okIp(gw)){toast(t("sy_ip_err"),"err");return;}
|
if(!okIp(ip)||!okIp(mask)||!okIp(gw)){toast(t("sy_ip_err"),"err");return;}
|
||||||
|
var d1=$("sy-dns1").value.trim(),d2=$("sy-dns2").value.trim();
|
||||||
|
if((d1&&!okIp(d1))||(d2&&!okIp(d2))){toast(t("sy_dns_err"),"err");return;}
|
||||||
var cmds=[];
|
var cmds=[];
|
||||||
var hn=$("sy-host").value.trim();
|
var hn=$("sy-host").value.trim();
|
||||||
if(hn&&hn!==S.info.hostname){
|
if(hn&&hn!==S.info.hostname){
|
||||||
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+"\nnetmask "+mask+"\ngw "+gw);
|
cmds.push("ip "+ip+"\nnetmask "+mask+"\ngw "+gw+"\ndns server "+(d1||"0.0.0.0")+(d2?" "+d2:""));
|
||||||
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(){
|
||||||
@@ -2136,11 +2204,58 @@ $("cfgreload").addEventListener("click",cfgReload);
|
|||||||
$("cfgwrite").addEventListener("click",function(){
|
$("cfgwrite").addEventListener("click",function(){
|
||||||
writeConfig($("cfgedit").value,t("cw_title"));
|
writeConfig($("cfgedit").value,t("cw_title"));
|
||||||
});
|
});
|
||||||
tabHooks.system={enter:sysLoad};
|
var ntpBase=null,ntpTimer=null;
|
||||||
|
function tzText(m){var a=Math.abs(m);return(m<0?"-":"+")+String(Math.floor(a/60)).padStart(2,"0")+":"+String(a%60).padStart(2,"0")}
|
||||||
|
function ntpTick(){
|
||||||
|
if(!ntpBase)return;
|
||||||
|
var d=new Date(ntpBase.ms+(Date.now()-ntpBase.at));
|
||||||
|
function p(n){return String(n).padStart(2,"0")}
|
||||||
|
$("sy-sync").textContent=t("sy_ago",{n:ntpBase.sync+Math.floor((Date.now()-ntpBase.at)/60000)});
|
||||||
|
$("sy-now").textContent=d.getUTCFullYear()+"-"+p(d.getUTCMonth()+1)+"-"+p(d.getUTCDate())+" "
|
||||||
|
+p(d.getUTCHours())+":"+p(d.getUTCMinutes())+":"+p(d.getUTCSeconds())+" UTC"+ntpBase.tz;
|
||||||
|
}
|
||||||
|
function ntpLoad(){
|
||||||
|
return api("/cmd",{method:"POST",body:"ntp"}).then(function(r){
|
||||||
|
var m=r.body.match(/NTP (on|off), server (\S*), address ([\d.]+), interval (\d+) min, timezone ([+-]\d\d:\d\d), dst (\w+)/);
|
||||||
|
if(!m)return;
|
||||||
|
var x=r.body.match(/Time (\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d) UTC([+-]\d\d:\d\d)( DST)?, synchronised (\d+) min ago/);
|
||||||
|
$("sy-ntpaddr").textContent=m[3]==="0.0.0.0"?"-":m[3];
|
||||||
|
if(x){
|
||||||
|
ntpBase={at:Date.now(),ms:Date.UTC(+x[1],+x[2]-1,+x[3],+x[4],+x[5],+x[6]),tz:x[7]+(x[8]?" DST":""),sync:+x[9]};
|
||||||
|
ntpTick();
|
||||||
|
}else{
|
||||||
|
ntpBase=null;
|
||||||
|
$("sy-now").textContent=t("sy_nosync");
|
||||||
|
$("sy-sync").textContent=m[1]==="on"?t("sy_waiting"):"-";
|
||||||
|
}
|
||||||
|
if($("sy-ntpcard").dataset.dirty)return;
|
||||||
|
$("sy-ntp").checked=m[1]==="on";$("sy-ntpsrv").value=m[2];$("sy-ntpint").value=m[4];
|
||||||
|
$("sy-tz").value=m[5];$("sy-dst").value=m[6];
|
||||||
|
}).catch(function(){});
|
||||||
|
}
|
||||||
|
[-720,-660,-600,-570,-540,-480,-420,-360,-300,-240,-210,-180,-120,-60,0,60,120,180,210,240,270,300,330,345,
|
||||||
|
360,390,420,480,525,540,570,600,630,660,720,765,780,840].forEach(function(z){
|
||||||
|
$("sy-tz").appendChild(h("option",{value:tzText(z),text:"UTC"+tzText(z)}));
|
||||||
|
});
|
||||||
|
["change","input"].forEach(function(ev){$("sy-ntpcard").addEventListener(ev,function(){this.dataset.dirty="1"})});
|
||||||
|
$("sy-ntpapply").addEventListener("click",function(){
|
||||||
|
var srv=$("sy-ntpsrv").value.trim(),iv=$("sy-ntpint").value.trim();
|
||||||
|
if(!/^[A-Za-z0-9.-]{1,47}$/.test(srv)){toast(t("sy_ntp_err"),"err");return;}
|
||||||
|
if(!(+iv>=1&&+iv<=1440)){toast(t("sy_ntpint_err"),"err");return;}
|
||||||
|
delete $("sy-ntpcard").dataset.dirty;
|
||||||
|
postCmds(["ntp server "+srv,"ntp interval "+iv,"ntp timezone "+$("sy-tz").value,"ntp dst "+$("sy-dst").value,
|
||||||
|
"ntp "+($("sy-ntp").checked?"on":"off")]).then(ntpLoad).catch(function(){});
|
||||||
|
});
|
||||||
|
$("sy-ntprefresh").addEventListener("click",ntpLoad);
|
||||||
|
tabHooks.system={
|
||||||
|
enter:function(){sysLoad();ntpLoad();clearInterval(ntpTimer);ntpTimer=setInterval(ntpTick,1000)},
|
||||||
|
leave:function(){clearInterval(ntpTimer)},
|
||||||
|
};
|
||||||
|
|
||||||
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/,/^session\b/,
|
/^syslog\s+ip\b/,/^syslog\s+port\b/,/^dns\s+server\b/,/^passwd\b/,/^session\b/,
|
||||||
|
/^ntp\s+server\b/,/^ntp\s+interval\b/,/^ntp\s+timezone\b/,/^ntp\s+dst\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/,
|
/^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/,
|
||||||
@@ -2150,7 +2265,7 @@ var CONF_OVERWRITE=[
|
|||||||
/^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/,/^storm\s+\d{1,2}\s+(bcast|mcast|ucast|umcast)\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)$/,/^(ntp)\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){
|
||||||
var conf=base.slice();
|
var conf=base.slice();
|
||||||
function drop(rx){conf=conf.filter(function(c){return!rx.test(c)})}
|
function drop(rx){conf=conf.filter(function(c){return!rx.test(c)})}
|
||||||
@@ -2166,6 +2281,7 @@ function mergeConf(base,texts){
|
|||||||
else drop(/^eee /);
|
else drop(/^eee /);
|
||||||
conf.push(line);return;
|
conf.push(line);return;
|
||||||
}
|
}
|
||||||
|
if((m=line.match(/^lag (\d) lacp off$/))){drop(new RegExp("^lag "+m[1]+" lacp( |$)"));return;}
|
||||||
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((m=line.match(/^ingress (.+)$/))){
|
||||||
@@ -2260,10 +2376,26 @@ $("saveBtn").addEventListener("click",function(){
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var fwBuf=null;
|
var fwBuf=null,fwOther=false;
|
||||||
|
// Every image carries its machine name as a NUL-terminated string, the same
|
||||||
|
// one the running switch reports as hw_ver: an image without it was built
|
||||||
|
// for another board (SFP, LED and button pins differ between machines).
|
||||||
|
function fwForThisSwitch(u){
|
||||||
|
var name=S.info.hw_ver;
|
||||||
|
if(!name)return true;
|
||||||
|
var n=[];
|
||||||
|
for(var i=0;i<name.length;i++)n.push(name.charCodeAt(i)&0xff);
|
||||||
|
n.push(0);
|
||||||
|
outer:for(var p=0;p<=u.length-n.length;p++){
|
||||||
|
for(var k=0;k<n.length;k++)if(u[p+k]!==n[k])continue outer;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$("fwfile").addEventListener("change",function(){
|
$("fwfile").addEventListener("change",function(){
|
||||||
var f=this.files[0];
|
var f=this.files[0];
|
||||||
fwBuf=null;
|
fwBuf=null;
|
||||||
|
fwOther=false;
|
||||||
$("fwup").disabled=true;
|
$("fwup").disabled=true;
|
||||||
$("fwinfo").textContent="";
|
$("fwinfo").textContent="";
|
||||||
if(!f)return;
|
if(!f)return;
|
||||||
@@ -2286,13 +2418,15 @@ $("fwfile").addEventListener("change",function(){
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fwBuf=f;
|
fwBuf=f;
|
||||||
info.innerHTML='<span style="color:var(--ok)">\u2713 '+esc(t("fw_valid"))+"</span>";
|
fwOther=!fwForThisSwitch(u);
|
||||||
|
info.innerHTML='<span style="color:var(--ok)">\u2713 '+esc(t("fw_valid"))+"</span>"+
|
||||||
|
(fwOther?'<br><span style="color:var(--warn)">\u26a0 '+esc(t("fw_other",{m:S.info.hw_ver}))+"</span>":"");
|
||||||
$("fwup").disabled=false;
|
$("fwup").disabled=false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$("fwup").addEventListener("click",function(){
|
$("fwup").addEventListener("click",function(){
|
||||||
if(!fwBuf)return;
|
if(!fwBuf)return;
|
||||||
confirmModal(t("fw_q"),t("fw_d"),function(){
|
confirmModal(t("fw_q"),(fwOther?t("fw_other",{m:S.info.hw_ver})+" ":"")+t("fw_d"),function(){
|
||||||
var form=new FormData();
|
var form=new FormData();
|
||||||
form.append("uploadedfile",fwBuf,fwBuf.name);
|
form.append("uploadedfile",fwBuf,fwBuf.name);
|
||||||
var xhr=new XMLHttpRequest();
|
var xhr=new XMLHttpRequest();
|
||||||
|
|||||||
@@ -356,6 +356,11 @@ button.danger{background:var(--bad);color:#fff;border-color:transparent}
|
|||||||
|
|
||||||
<section class="tab" id="tab-lag">
|
<section class="tab" id="tab-lag">
|
||||||
<div id="lagwrap" class="grid2"></div>
|
<div id="lagwrap" class="grid2"></div>
|
||||||
|
<div class="card" style="margin-top:14px"><h2 data-i18n="lacp_heading">LACP (802.3ad)</h2>
|
||||||
|
<div class="scrollx"><table class="t" id="lacptbl">
|
||||||
|
<thead><tr><th data-i18n="c_port">Port</th><th>LAG</th><th data-i18n="lacp_actor">Actor</th><th data-i18n="lacp_partner">Partner</th><th data-i18n="lacp_rxstate">RX state</th><th data-i18n="lacp_rx">LACPDUs received</th><th data-i18n="lacp_psys">Partner system</th></tr></thead>
|
||||||
|
<tbody></tbody></table></div>
|
||||||
|
</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>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -389,6 +394,9 @@ button.danger{background:var(--bad);color:#fff;border-color:transparent}
|
|||||||
<label class="row"><span class="lb" data-i18n="i_ip">IP address</span><input class="in" id="sy-ip" size="15"></label>
|
<label class="row"><span class="lb" data-i18n="i_ip">IP address</span><input class="in" id="sy-ip" size="15"></label>
|
||||||
<label class="row"><span class="lb" data-i18n="i_mask">Netmask</span><input class="in" id="sy-mask" size="15"></label>
|
<label class="row"><span class="lb" data-i18n="i_mask">Netmask</span><input class="in" id="sy-mask" size="15"></label>
|
||||||
<label class="row"><span class="lb" data-i18n="i_gw">Gateway</span><input class="in" id="sy-gw" size="15"></label>
|
<label class="row"><span class="lb" data-i18n="i_gw">Gateway</span><input class="in" id="sy-gw" size="15"></label>
|
||||||
|
<label class="row"><span class="lb" data-i18n="sy_dns1">DNS server</span><input class="in" id="sy-dns1" size="15"></label>
|
||||||
|
<label class="row"><span class="lb" data-i18n="sy_dns2">Second DNS</span><input class="in" id="sy-dns2" size="15"></label>
|
||||||
|
<p class="small mut" id="sy-dnsdhcp"></p>
|
||||||
<div style="display:flex;gap:10px;margin-top:12px">
|
<div style="display:flex;gap:10px;margin-top:12px">
|
||||||
<button class="ctl pri" id="sy-apply" data-i18n="c_apply">Apply</button>
|
<button class="ctl pri" id="sy-apply" data-i18n="c_apply">Apply</button>
|
||||||
<button class="ctl" id="sy-dhcp" data-i18n="sy_dhcp" data-i18n-t="sy_dhcp_t">Use DHCP</button>
|
<button class="ctl" id="sy-dhcp" data-i18n="sy_dhcp" data-i18n-t="sy_dhcp_t">Use DHCP</button>
|
||||||
@@ -408,6 +416,22 @@ button.danger{background:var(--bad);color:#fff;border-color:transparent}
|
|||||||
<input class="in" id="sy-sesstmo" style="width:80px" type="number" min="1" max="65535"></label>
|
<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" id="sy-ntpcard"><h2 data-i18n="sy_time">Time</h2>
|
||||||
|
<label class="row" style="justify-content:space-between"><span data-i18n="sy_ntp">NTP</span>
|
||||||
|
<span class="switch"><input type="checkbox" id="sy-ntp"><i></i></span></label>
|
||||||
|
<label class="row"><span class="lb" data-i18n="sy_ntpsrv">NTP server</span><input class="in" id="sy-ntpsrv" maxlength="47" data-i18n-p="sy_ntpsrv_p"></label>
|
||||||
|
<label class="row"><span class="lb" data-i18n="sy_ntpint">Poll interval [min]</span><input class="in sm" id="sy-ntpint" type="number" min="1" max="1440"></label>
|
||||||
|
<label class="row"><span class="lb" data-i18n="sy_tz">Time zone</span><select class="in" id="sy-tz"></select></label>
|
||||||
|
<label class="row"><span class="lb" data-i18n="sy_dst">Daylight saving</span><select class="in" id="sy-dst"><option value="off" data-i18n="c_offc">Off</option><option value="eu" data-i18n="sy_dst_eu">Europe</option><option value="us" data-i18n="sy_dst_us">United States</option></select></label>
|
||||||
|
<div style="display:flex;gap:10px;margin-top:8px">
|
||||||
|
<button class="ctl pri" id="sy-ntpapply" data-i18n="c_apply">Apply</button>
|
||||||
|
<button class="ctl" id="sy-ntprefresh" data-i18n="c_refresh">Refresh</button>
|
||||||
|
</div>
|
||||||
|
<label class="row" style="margin-top:10px"><span class="lb" data-i18n="sy_now">Local time</span><span class="mono" id="sy-now">-</span></label>
|
||||||
|
<label class="row"><span class="lb" data-i18n="sy_sync">Last synchronisation</span><span id="sy-sync">-</span></label>
|
||||||
|
<label class="row"><span class="lb" data-i18n="sy_ntpaddr">Server address</span><span class="mono" id="sy-ntpaddr">-</span></label>
|
||||||
|
<p class="small mut" style="margin-top:8px" data-i18n="sy_time_note">The switch has no battery backed clock.</p>
|
||||||
|
</div>
|
||||||
<div class="card"><h2 data-i18n="sy_password">Admin password</h2>
|
<div class="card"><h2 data-i18n="sy_password">Admin password</h2>
|
||||||
<label class="row"><span class="lb" data-i18n="sy_newpw">New password</span><input class="in" id="sy-pw1" type="password" maxlength="20"></label>
|
<label class="row"><span class="lb" data-i18n="sy_newpw">New password</span><input class="in" id="sy-pw1" type="password" maxlength="20"></label>
|
||||||
<label class="row"><span class="lb" data-i18n="sy_repeat">Repeat</span><input class="in" id="sy-pw2" type="password" maxlength="20"></label>
|
<label class="row"><span class="lb" data-i18n="sy_repeat">Repeat</span><input class="in" id="sy-pw2" type="password" maxlength="20"></label>
|
||||||
|
|||||||
+6
-2
@@ -92,8 +92,12 @@ button:hover{filter:brightness(1.1)}
|
|||||||
try{l=localStorage.getItem("rtl_lang");}catch(e){}
|
try{l=localStorage.getItem("rtl_lang");}catch(e){}
|
||||||
if(!L[l])l=(navigator.language||"en").slice(0,2);
|
if(!L[l])l=(navigator.language||"en").slice(0,2);
|
||||||
var s=L[l]||L.en;
|
var s=L[l]||L.en;
|
||||||
document.title=s[0];
|
// Name the tab after the switch: the hostname seen at the last login here,
|
||||||
document.getElementById("hn").textContent=s[0];
|
// otherwise the address, so several open switches can be told apart
|
||||||
|
var host=null;
|
||||||
|
try{host=localStorage.getItem("rtl_host");}catch(e){}
|
||||||
|
document.title=(host||location.hostname)+" – "+s[0];
|
||||||
|
document.getElementById("hn").textContent=host||s[0];
|
||||||
document.getElementById("sub").textContent=s[1];
|
document.getElementById("sub").textContent=s[1];
|
||||||
document.getElementById("lp").textContent=s[2];
|
document.getElementById("lp").textContent=s[2];
|
||||||
document.getElementById("lb").textContent=s[3];
|
document.getElementById("lb").textContent=s[3];
|
||||||
|
|||||||
@@ -1036,6 +1036,8 @@ void httpd_appcall(void)
|
|||||||
send_stp();
|
send_stp();
|
||||||
} else if (is_word(q, "/lldp.json")) {
|
} else if (is_word(q, "/lldp.json")) {
|
||||||
send_lldp();
|
send_lldp();
|
||||||
|
} else if (is_word(q, "/lacp.json")) {
|
||||||
|
send_lacp();
|
||||||
} else if (is_word(q, "/vlanlist")) {
|
} else if (is_word(q, "/vlanlist")) {
|
||||||
send_vlanlist();
|
send_vlanlist();
|
||||||
} else if (is_word(q, "/config")) {
|
} else if (is_word(q, "/config")) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "rtl837x_stp.h"
|
#include "rtl837x_stp.h"
|
||||||
|
#include "rtl837x_lacp.h"
|
||||||
#include "page_impl.h"
|
#include "page_impl.h"
|
||||||
#include "syslog.h"
|
#include "syslog.h"
|
||||||
|
|
||||||
@@ -736,6 +737,53 @@ void send_stp(void)
|
|||||||
slen += strtox(outbuf + slen, "]}");
|
slen += strtox(outbuf + slen, "]}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void send_lacp(void)
|
||||||
|
{
|
||||||
|
dbg_string("send_lacp called\n");
|
||||||
|
slen = strtox(outbuf, HTTP_RESPONCE_JSON);
|
||||||
|
|
||||||
|
slen += strtox(outbuf + slen, "{\"on\":");
|
||||||
|
bool_to_html(lacpEnabled);
|
||||||
|
slen += strtox(outbuf + slen, ",\"lags\":[");
|
||||||
|
for (uint8_t l = 0; l < LACP_NUM_LAGS; l++) {
|
||||||
|
slen += strtox(outbuf + slen, "{\"cfg\":\"");
|
||||||
|
byte_to_html(lacp_lag_ports[l] >> 8);
|
||||||
|
byte_to_html(lacp_lag_ports[l]);
|
||||||
|
slen += strtox(outbuf + slen, "\",\"aggValid\":");
|
||||||
|
bool_to_html(lacp_agg_valid[l]);
|
||||||
|
slen += strtox(outbuf + slen, ",\"agg\":\"");
|
||||||
|
for (uint8_t j = 0; j < MAC_ADDR_LEN; j++)
|
||||||
|
byte_to_html(lacp_agg_sys[l][j]);
|
||||||
|
slen += strtox(outbuf + slen, "\",\"members\":\"");
|
||||||
|
byte_to_html(lacp_members_last[l] >> 8);
|
||||||
|
byte_to_html(lacp_members_last[l]);
|
||||||
|
slen += strtox(outbuf + slen, "\"},");
|
||||||
|
}
|
||||||
|
slen -= 1; // remove comma
|
||||||
|
slen += strtox(outbuf + slen, "],\"ports\":[");
|
||||||
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
|
slen += strtox(outbuf + slen, "{\"p\":");
|
||||||
|
itoa_html(machine.log_to_phys_port[i]);
|
||||||
|
slen += strtox(outbuf + slen, ",\"lag\":");
|
||||||
|
itoa_html(lacp_port_lag[i]);
|
||||||
|
slen += strtox(outbuf + slen, ",\"a\":\"");
|
||||||
|
byte_to_html(lacp_actor_state[i]);
|
||||||
|
slen += strtox(outbuf + slen, "\",\"pt\":\"");
|
||||||
|
byte_to_html(lacp_partner_state[i]);
|
||||||
|
slen += strtox(outbuf + slen, "\",\"rs\":");
|
||||||
|
itoa_html(lacp_rx_state[i]);
|
||||||
|
slen += strtox(outbuf + slen, ",\"rx\":\"");
|
||||||
|
byte_to_html(lacp_rx_count[i] >> 8);
|
||||||
|
byte_to_html(lacp_rx_count[i]);
|
||||||
|
slen += strtox(outbuf + slen, "\",\"psys\":\"");
|
||||||
|
for (uint8_t j = 0; j < MAC_ADDR_LEN; j++)
|
||||||
|
byte_to_html(lacp_partner_sys[i][j]);
|
||||||
|
slen += strtox(outbuf + slen, "\"},");
|
||||||
|
}
|
||||||
|
slen -= 1; // remove comma
|
||||||
|
slen += strtox(outbuf + slen, "]}");
|
||||||
|
}
|
||||||
|
|
||||||
void send_lldp(void)
|
void send_lldp(void)
|
||||||
{
|
{
|
||||||
dbg_string("send_lldp called\n");
|
dbg_string("send_lldp called\n");
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ void send_cmd_log(void);
|
|||||||
void send_lag(void);
|
void send_lag(void);
|
||||||
void send_stp(void);
|
void send_stp(void);
|
||||||
void send_lldp(void);
|
void send_lldp(void);
|
||||||
|
void send_lacp(void);
|
||||||
void send_vlanlist(void);
|
void send_vlanlist(void);
|
||||||
|
|
||||||
/* Convert only the lower nibble to ascii HEX char.
|
/* Convert only the lower nibble to ascii HEX char.
|
||||||
|
|||||||
@@ -3,55 +3,19 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/*
|
#define MACHINE_STR_HELPER(x) #x
|
||||||
* Select your machine type below
|
#define MACHINE_STR(x) MACHINE_STR_HELPER(x)
|
||||||
*/
|
|
||||||
// Legacy KP-9000 4+2 targets. Prefer the PCB-revision-specific targets below.
|
|
||||||
// #define MACHINE_KP_9000_6XHML_X2
|
|
||||||
// #define MACHINE_KP_9000_6XH_X2
|
|
||||||
|
|
||||||
// KP-9000 4+2 targets by PCB silkscreen revision.
|
|
||||||
// #define MACHINE_KP_9000_6XH_X2_V1_1
|
|
||||||
// #define MACHINE_KP_9000_6XHML_X2_V1_1
|
|
||||||
// #define MACHINE_KP_9000_6XH_X2_V1_2
|
|
||||||
// #define MACHINE_KP_9000_6XHML_X2_V1_2
|
|
||||||
// #define MACHINE_KP_9000_6XH_X2_V2_1
|
|
||||||
// #define MACHINE_KP_9000_6XHML_X2_V2_1
|
|
||||||
|
|
||||||
// #define MACHINE_KP_9000_6XH_X
|
#define MACHINE_DEF_DIR machine
|
||||||
// #define MACHINE_KP_9000_9XH_X_EU
|
|
||||||
// #define MACHINE_KP_9000_9XHML_X_V2_2
|
#ifndef MACHINE_NAME
|
||||||
// #define MACHINE_KP_9000_9XHML_X_V3_1
|
#define MACHINE_NAME default_machine
|
||||||
// #define MACHINE_KP_9000_9XHML_X_V3_2
|
#endif
|
||||||
// #define MACHINE_SWGT024_V2_0_MANAGED
|
|
||||||
// #define MACHINE_SWGT024_V2_0_UNMANAGED
|
#define MACHINE_INC(dir,file) MACHINE_STR(dir/file)
|
||||||
// #define MACHINE_TRENDNET_TEG_S562
|
|
||||||
// #define MACHINE_HG0402XG_V1_1
|
#include MACHINE_INC(MACHINE_DEF_DIR,MACHINE_NAME.h)
|
||||||
// #define MACHINE_SWTG018AS_A_V_2_0
|
|
||||||
// #define MACHINE_SWTGW218AS
|
|
||||||
// #define MACHINE_PCB_SWTG018AS_V2_1_0
|
|
||||||
// #define MACHINE_PCB_K0402WS_V3
|
|
||||||
// #define MACHINE_PCB_K0402WS_V2
|
|
||||||
// #define MACHINE_K0501W_V2_0
|
|
||||||
// #define MACHINE_LIANGUO_ZX_SWTGW215AS
|
|
||||||
// #define MACHINE_ZX310S_4T2XH
|
|
||||||
// #define MACHINE_ZX310S_4T2XT
|
|
||||||
// #define MACHINE_STEAMEMO_IG204_V1
|
|
||||||
// #define MACHINE_DEFAULT_8C_1SFP
|
|
||||||
// #define MACHINE_HI_K0801WS
|
|
||||||
// #define MACHINE_FNS1200P
|
|
||||||
// #define MACHINE_PCB_SWTG024AS_A_2_0_1
|
|
||||||
// #define MACHINE_ONT_S207CW_62TS_SE
|
|
||||||
// #define MACHINE_SWTG024AS_A_2_0_1_5C_1SFP
|
|
||||||
// #define MACHINE_SWTG024AS_V2_0
|
|
||||||
// #define MACHINE_FG_4GT_2SX_V2_0
|
|
||||||
// #define MACHINE_FG_8GT_1SX
|
|
||||||
// #define MACHINE_LIANGUO_HYWS_SGT0108S
|
|
||||||
// #define MACHINE_POE_2G080110GS
|
|
||||||
// #define MACHINE_PB_2132
|
|
||||||
// #define MACHINE_HASIVO_S600W_4GT_2XGT_SE
|
|
||||||
// #define MACHINE_HASIVO_S1100WP_8GT_1SX_SE
|
|
||||||
// #define MACHINE_F7008_2_5
|
|
||||||
|
|
||||||
#define LED_27 1
|
#define LED_27 1
|
||||||
// SYSTEM LED
|
// SYSTEM LED
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
.led_sets = { { LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
||||||
|
LEDS_2G5 | LEDS_LINK,
|
||||||
|
LEDS_1G | LEDS_LINK,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT },
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_DEFAULT_8C_1SFP_H_
|
||||||
|
#define _MACHINE_DEFAULT_8C_1SFP_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "8+1 SFP Port Switch"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.led_sets = {
|
||||||
|
{ /* SET0 */
|
||||||
|
LEDS_2G5 | LEDS_LINK, /* LEDID0 - green: 2.5G link */
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, /* LEDID1 - yellow: traffic */
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
{ /* SET1 - SFP+ */
|
||||||
|
LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_LINK,
|
||||||
|
LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_1G | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = {
|
||||||
|
0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0c, 0x02,
|
||||||
|
0x0d, 0x10, 0x11, 0x02, 0x14, 0x02, 0x02, 0x15,
|
||||||
|
0x02, 0x02, 0x18, 0x02, 0x02, 0x19, 0x02, 0x02,
|
||||||
|
0x1c, 0x1d, 0x02, 0x02,
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_F7008_2_5_H_
|
||||||
|
#define _MACHINE_F7008_2_5_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "F7008-2.5 8+1 SFP Port Switch"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
|
// Left SFP port
|
||||||
|
.sfp_port[0].pin_detect = GPIO38,
|
||||||
|
.sfp_port[0].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
// Right SFP port
|
||||||
|
.sfp_port[1].pin_detect = GPIO37,
|
||||||
|
.sfp_port[1].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 0,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
|
/* Ports 1-4 RJ45 use set 0, port 5-6 SFP uses set 1
|
||||||
|
* Ports 1-4: Green: 2.5GBit, Amber: 10/100/1000MBit
|
||||||
|
* Ports 5-6: Green: 100MBit-10GBit
|
||||||
|
*/
|
||||||
|
.led_sets = {
|
||||||
|
{
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_10G | LEDS_LINK,
|
||||||
|
0,
|
||||||
|
LEDS_COL | LEDS_DUPLEX
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_LINK,
|
||||||
|
LEDS_5G | LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_10G | LEDS_LINK | LEDS_ACT
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LEDS_TX,
|
||||||
|
LEDS_RX,
|
||||||
|
LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5 |
|
||||||
|
LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_ACT,
|
||||||
|
LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5 |
|
||||||
|
LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = {
|
||||||
|
0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x3f, 0x15, 0x16,
|
||||||
|
0x18, 0x0e, 0x19, 0x11, 0x12, 0x1a, 0x15, 0x16, 0x1c, 0x19,
|
||||||
|
0x1a, 0x1d, 0x1d, 0x1e, 0x1e, 0x20, 0x21, 0x22
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_FG_4GT_2SX_V2_0_H_
|
||||||
|
#define _MACHINE_FG_4GT_2SX_V2_0_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "FG-4GT-2SX_V2.0"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = GPIO38,
|
||||||
|
.sfp_port[0].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
.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 = {
|
||||||
|
/*
|
||||||
|
Ports 1-8: Left Amber 10/100/1000MBit (Vendor no 10M, but we add it)
|
||||||
|
Right Green 2.5GBit
|
||||||
|
SFP-port: Any speed
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = {
|
||||||
|
0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0c, 0x09, 0x0d, 0x10,
|
||||||
|
0x11, 0x0e, 0x14, 0x11, 0x12, 0x15, 0x15, 0x16, 0x18, 0x19,
|
||||||
|
0x1a, 0x19, 0x1d, 0x1e, 0x1c, 0x1d, 0x20, 0x21,
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_FG_8GT_1SX_H_
|
||||||
|
#define _MACHINE_FG_8GT_1SX_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "FG-8GT-1SX"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
|
/* Left SFP (logical 8, SDS1): GPIO30=ModAbs, GPIO37=RX_LOS */
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
/* Right SFP (logical 3, SDS0): GPIO50=ModAbs, GPIO51=RX_LOS */
|
||||||
|
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
||||||
|
.sfp_port[1].pin_los = GPIO51_I2C_SDA2_UART1_RX,
|
||||||
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 0,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
|
||||||
|
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
|
||||||
|
/* Copper ports use SET0; SFP ports use SET1 */
|
||||||
|
.port_led_set = {0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
|
.led_sets = {
|
||||||
|
{ /* SET0: copper — LED0=amber (2.5G), LED2=green (1G/100M/10M) */
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{ /* SET1: SFP — all speeds link/act */
|
||||||
|
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0, 0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = {
|
||||||
|
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, /* GPIO0-7: unused */
|
||||||
|
0x0f, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12, /* GPIO8-14 */
|
||||||
|
0x14, 0x15, 0x16, 0x18, 0x19, 0x1a, /* GPIO15-20 */
|
||||||
|
0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x23 /* GPIO21-27 */
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_FNS1200P_H_
|
||||||
|
#define _MACHINE_FNS1200P_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "FNS-1200P"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.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
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_HASIVO_S1100WP_8GT_1SX_SE_H_
|
||||||
|
#define _MACHINE_HASIVO_S1100WP_8GT_1SX_SE_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "Hasivo S1100WP-8GT-1SX-SE"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 0,
|
||||||
|
.n_10g = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
.reset_pin = GPIO54_ACL_BIT2_EN,
|
||||||
|
.high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1 },
|
||||||
|
/* Ports 1-4: Green: 2.5GBit, Orange: 10/100/1000MBit
|
||||||
|
* Ports 5-6: Green: 10GBit, Orange: 5/2.5GBit, None: 10/100/1000MBit
|
||||||
|
*/
|
||||||
|
.led_sets = {
|
||||||
|
{
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // Yellow
|
||||||
|
LEDS_2G5 | LEDS_LINK, // Green
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK, // Orange
|
||||||
|
0, // Unused
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // Yellow
|
||||||
|
LEDS_10G | LEDS_LINK, // Green
|
||||||
|
LEDS_5G | LEDS_2G5 | LEDS_LINK, // Orange
|
||||||
|
0, // Unused
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = {
|
||||||
|
0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
||||||
|
0x3f, 0x3f, 0x3f, 0x0f, 0x20,
|
||||||
|
0x21, 0x22, 0x10, 0x11, 0x12,
|
||||||
|
0x14, 0x15, 0x16, 0x18, 0x19,
|
||||||
|
0x1a, 0x1c, 0x1d, 0x1e, 0x0c,
|
||||||
|
0x0d, 0x0e, 0x23
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_HASIVO_S600W_4GT_2XGT_SE_H_
|
||||||
|
#define _MACHINE_HASIVO_S600W_4GT_2XGT_SE_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "Hasivo S600W-4GT-2XGT-SE"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = 50,
|
||||||
|
.sfp_port[0].pin_los = 10,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.sfp_port[1].pin_detect = 30,
|
||||||
|
.sfp_port[1].pin_los = 51,
|
||||||
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 0,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
.high_leds = { .mux = LED_27 , .enable = LED_27 | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
|
/* The Ethernet ports have 1 amber LED (left) and 1 green LED (right)
|
||||||
|
* The SFP ports have also 1 amber LED and 1 green LED
|
||||||
|
* Ethernet ports use LED-set 0, SFP ports use LED-set 1
|
||||||
|
*/
|
||||||
|
.led_sets = { { LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
0 },
|
||||||
|
{ LEDS_100M | LEDS_10M | LEDS_LINK,
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
LEDS_10G | LEDS_LINK,
|
||||||
|
0 },
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_HG0402XG_V1_1_H_
|
||||||
|
#define _MACHINE_HG0402XG_V1_1_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "HG0402XG V1.1"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
|
// Left SFP port
|
||||||
|
.sfp_port[0].pin_detect = GPIO38,
|
||||||
|
.sfp_port[0].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
// Right SFP port
|
||||||
|
.sfp_port[1].pin_detect = GPIO37,
|
||||||
|
.sfp_port[1].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 0,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
.high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
|
.led_sets = {
|
||||||
|
{
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_10M | LEDS_ACT,
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
LEDS_1G | LEDS_LINK,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK,
|
||||||
|
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = {
|
||||||
|
0x00,0x01,0x04,0x05,0x08,0x09,0x0c,0x3f,0x0d,0x10,0x11,0x0e,0x14,0x11,0x12,0x15,0x15,0x16,0x18,0x19,0x1a,0x19,0x1d,0x1e,0x1c,0x1d,0x20,0x21
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_HI_K0402WS_H_
|
||||||
|
#define _MACHINE_HI_K0402WS_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "PCB-K0402WS-V3.0"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
|
||||||
|
.high_leds = {
|
||||||
|
.mux = LED_27 | LED_29,
|
||||||
|
.enable = LED_28_SYS | LED_29
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Ports 1-8 use set 0, port 9 SFP uses set 1 */
|
||||||
|
.port_led_set = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
|
.led_sets = {
|
||||||
|
{ /* Set 0: RJ45 copper ports
|
||||||
|
* Amber = 2.5G
|
||||||
|
* Green = 1G/100M/10M with activity
|
||||||
|
*/
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT, /* Amber */
|
||||||
|
0,
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, /* Green */
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{ /* Set 1: SFP port, single green LED for all valid speeds */
|
||||||
|
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_HI_K0801WS_H_
|
||||||
|
#define _MACHINE_HI_K0801WS_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "Hi-Source HI-k0801WS"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.led_sets = {
|
||||||
|
{
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_K0501W_V2_0_H_
|
||||||
|
#define _MACHINE_K0501W_V2_0_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "K0501W V2.0"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 1, 0, 0, 0, 0, 2},
|
||||||
|
// Left SFP port (5)
|
||||||
|
.sfp_port[0].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
||||||
|
.sfp_port[0].pin_los = GPIO10_LED10,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 0,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
// Right SFP port (6)
|
||||||
|
.sfp_port[1].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[1].pin_los = GPIO37,
|
||||||
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 1,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO54_ACL_BIT2_EN,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
/* Conditions for LED on:
|
||||||
|
* dual led orange: ledset_0 & ledset_2
|
||||||
|
* dual led green: ledset_2 & !ledset_0
|
||||||
|
* single right led green: ledset_0 & !ledset_1
|
||||||
|
*/
|
||||||
|
.led_sets = { { LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_10G,
|
||||||
|
LEDS_1G | LEDS_LINK,
|
||||||
|
0 },
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_KP_9000_6XHML_X2_H_
|
||||||
|
#define _MACHINE_KP_9000_6XHML_X2_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "keepLink KP-9000-6XHML-X2"
|
||||||
|
|
||||||
|
#endif
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
KP_9000_6XHML_X2.c
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_KP_9000_6XHML_X2_V1_1_H_
|
||||||
|
#define _MACHINE_KP_9000_6XHML_X2_V1_1_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "keepLink KP-9000-6XHML V1.1"
|
||||||
|
|
||||||
|
#endif
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
KP_9000_6XHML_X2.c
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_KP_9000_6XHML_X2_V1_2_H_
|
||||||
|
#define _MACHINE_KP_9000_6XHML_X2_V1_2_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "keepLink KP-9000-6XHML V1.2"
|
||||||
|
|
||||||
|
#endif
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
KP_9000_6XH_X2.c
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_KP_9000_6XHML_X2_V2_1_H_
|
||||||
|
#define _MACHINE_KP_9000_6XHML_X2_V2_1_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "keepLink KP-9000-6XHML V2.1"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
/* Conditions for LED on:
|
||||||
|
* dual led orange: ledset_0 & ledset_2
|
||||||
|
* dual led green: ledset_2 & !ledset_0
|
||||||
|
* single right led green: ledset_0 & !ledset_1
|
||||||
|
*/
|
||||||
|
.led_sets = { { LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_10G,
|
||||||
|
LEDS_1G | LEDS_LINK,
|
||||||
|
0 },
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_KP_9000_6XH_X_H_
|
||||||
|
#define _MACHINE_KP_9000_6XH_X_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "keepLink KP-9000-6XH-X"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
|
// Left SFP port
|
||||||
|
.sfp_port[0].pin_detect = GPIO38,
|
||||||
|
.sfp_port[0].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
// Right SFP port
|
||||||
|
.sfp_port[1].pin_detect = GPIO37,
|
||||||
|
.sfp_port[1].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 0,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
.reset_pin = GPIO48_I2C_SCL1, // Button-Switch is unpopulated on PCB, but can be added manually (hole in case is already there)
|
||||||
|
.high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
|
.led_sets = {
|
||||||
|
{
|
||||||
|
LEDS_2G5 | LEDS_LINK, // Left LED (Amber)
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // Right LED (Green)
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = {
|
||||||
|
0x00,0x01,0x04,0x05,0x08,0x09,0x0c,0x3f,0x0d,0x10,
|
||||||
|
0x11,0x0e,0x14,0x11,0x12,0x15,0x15,0x16,0x18,0x19,
|
||||||
|
0x1a,0x19,0x1d,0x1e,0x1c,0x1d,0x20,0x21
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_KP_9000_6XH_X2_H_
|
||||||
|
#define _MACHINE_KP_9000_6XH_X2_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "keepLink KP-9000-6XH-X2"
|
||||||
|
|
||||||
|
#endif
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
KP_9000_6XHML_X2.c
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_KP_9000_6XH_X2_V1_1_H_
|
||||||
|
#define _MACHINE_KP_9000_6XH_X2_V1_1_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "keepLink KP-9000-6XH V1.1"
|
||||||
|
|
||||||
|
#endif
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
KP_9000_6XHML_X2.c
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_KP_9000_6XH_X2_V1_2_H_
|
||||||
|
#define _MACHINE_KP_9000_6XH_X2_V1_2_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "keepLink KP-9000-6XH V1.2"
|
||||||
|
|
||||||
|
#endif
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
KP_9000_6XH_X2.c
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_KP_9000_6XH_X2_V2_1_H_
|
||||||
|
#define _MACHINE_KP_9000_6XH_X2_V2_1_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "keepLink KP-9000-6XH-X2 V2.1"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
|
||||||
|
.phys_to_log_port = { 0, 1, 2, 3, 4, 5, 6, 7, 8 },
|
||||||
|
.is_sfp = { 0, 0, 0, 0, 0, 0, 0, 0, 1 },
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO54_ACL_BIT2_EN,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1 },
|
||||||
|
.led_sets = {
|
||||||
|
{ /* Set 0 for RJ45 connectors */
|
||||||
|
/* LED0: Right Green */
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
/* LED1: Left Orange */
|
||||||
|
LEDS_2G5 | LEDS_LINK,
|
||||||
|
/* LED2: Left Green */
|
||||||
|
LEDS_1G | LEDS_LINK,
|
||||||
|
/* LED3: None */
|
||||||
|
0,
|
||||||
|
}, { /* Set 1 for SFP port */
|
||||||
|
/* LED0: Single Green "9" LED */
|
||||||
|
LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
||||||
|
/* LED1: D23 LED on PCB */
|
||||||
|
LEDS_1G | LEDS_LINK,
|
||||||
|
/* LED2: D22 LED on PCB */
|
||||||
|
LEDS_2G5 | LEDS_LINK,
|
||||||
|
/* LED3: Unused */
|
||||||
|
LEDS_COL | LEDS_DUPLEX,
|
||||||
|
}, { /* Set 2: Unused, but set to same things as stock firmware for consistency */
|
||||||
|
LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_1G | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT | LEDS_5G,
|
||||||
|
LEDS_10G | LEDS_ACT | LEDS_LINK,
|
||||||
|
}, { /* Set 3: Unused, but set to same things as stock firmware for consistency */
|
||||||
|
LEDS_TX,
|
||||||
|
LEDS_RX,
|
||||||
|
LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
||||||
|
LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_KP_9000_9XHML_X_V2_2_H_
|
||||||
|
#define _MACHINE_KP_9000_9XHML_X_V2_2_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "keepLink KP-9000-9XHML-X V2.2"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
// 2M-PCB23-V3.2 is wired like V3.1 (SFP detection, LEDs, factory MAC location)
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = GPIO38,
|
||||||
|
.sfp_port[0].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO48_I2C_SCL1,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.led_sets = {
|
||||||
|
{ /* RJ45: First LED, yellow, second LED: green */
|
||||||
|
LEDS_2G5 | LEDS_LINK,
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
}, { /* SFP PORT, SINGLE GREEN LED */
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
}},
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = {0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0c, 0x09, 0x0d, 0x10,
|
||||||
|
0x11, 0x0e, 0x14, 0x11, 0x12, 0x15, 0x15, 0x16, 0x18, 0x19,
|
||||||
|
0x1a, 0x19, 0x1d, 0x1e, 0x1c, 0x1d, 0x20, 0x21},
|
||||||
|
.mac_flash_offset = 0x1FC000,
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_KP_9000_9XHML_X_V3_1_H_
|
||||||
|
#define _MACHINE_KP_9000_9XHML_X_V3_1_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "keepLink KP-9000-9XHML-X V3.1"
|
||||||
|
|
||||||
|
#endif
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
KP_9000_9XHML_X_V3_1.c
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_KP_9000_9XHML_X_V3_2_H_
|
||||||
|
#define _MACHINE_KP_9000_9XHML_X_V3_2_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "keepLink KP-9000-9XHML-X V3.2"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
.led_sets = { { LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
||||||
|
LEDS_2G5 | LEDS_LINK,
|
||||||
|
LEDS_1G | LEDS_LINK,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT },
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_KP_9000_9XH_X_EU_H_
|
||||||
|
#define _MACHINE_KP_9000_9XH_X_EU_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "keepLink KP-9000-9XH-X-EU"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {2, 1, 4, 3, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {1, 0, 3, 2, 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 = GPIO_NA,
|
||||||
|
.high_leds = { .mux = 0, .enable = 0 },
|
||||||
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1 },
|
||||||
|
.led_sets = {
|
||||||
|
{
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // RJ45 Blue LEDs
|
||||||
|
LEDS_2G5 | LEDS_LINK, // RJ45 White LEDs
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // SFP blue LED?
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_LIANGUO_HYWS_SGT0108S_H_
|
||||||
|
#define _MACHINE_LIANGUO_HYWS_SGT0108S_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "Lianguo HYWS-SGT0108S"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.mac_flash_offset = 0x1FC000,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = 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, // unused
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // Amber LED (left)
|
||||||
|
0
|
||||||
|
}, // unused
|
||||||
|
{ LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT, // SFP LED
|
||||||
|
0, // unused
|
||||||
|
0, // unused
|
||||||
|
0
|
||||||
|
}, // unused },
|
||||||
|
},
|
||||||
|
.led_mux_custom = 0,
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_LIANGUO_ZX_SWTGW215AS_H_
|
||||||
|
#define _MACHINE_LIANGUO_ZX_SWTGW215AS_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "Lianguo ZX-SWTGW215AS"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 5, 4, 3, 2, 1, 6},
|
||||||
|
.phys_to_log_port = {7, 6, 5, 4, 3, 8, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 1, 0, 0, 0, 0, 2},
|
||||||
|
|
||||||
|
// SFP port on SDS0 / logical port 3
|
||||||
|
.sfp_port[0].pin_detect = GPIO37,
|
||||||
|
.sfp_port[0].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 0,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
// SFP port on SDS1 / logical port 8
|
||||||
|
.sfp_port[1].pin_detect = GPIO38,
|
||||||
|
.sfp_port[1].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 1,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
.high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 3, 0, 0, 2, 2, 3},
|
||||||
|
.mac_flash_offset = 0x1FC000,
|
||||||
|
.led_sets = {
|
||||||
|
{ // RJ45 Ports 3-4 (normal wiring)
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{ // Unused
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{ // RJ45 Ports 1-2 (reversed wiring)
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{ // SFP Ports 5-6
|
||||||
|
LEDS_10G | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = {
|
||||||
|
0x00,0x01,0x04,0x05,0x08,0x09,0x0c,0x3f,0x0d,0x10,0x11,0x0e,0x14,0x11,0x12,0x15,0x15,0x16,0x18,0x19,0x1a,0x19,0x1d,0x1e,0x1c,0x1d,0x20,0x21
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_ONT_S207CW_62TS_SE_H_
|
||||||
|
#define _MACHINE_ONT_S207CW_62TS_SE_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "ONT-S207CW-62TS-SE / Binardat 2G06-04210GSM / Binardat 2G06-04210GS"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
|
||||||
|
.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 = {
|
||||||
|
{
|
||||||
|
/* LED0 = RJ45: Amber LED: 2.5G */
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
/* LED1 = RJ45: Green LED: 10M / 100M / 1000M */
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* SFP+ single Green LED. */
|
||||||
|
LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_PB_2132_H_
|
||||||
|
#define _MACHINE_PB_2132_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "PB-2132"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
|
/* Left SFP (logical 8, SDS1): GPIO30=ModAbs, GPIO37=RX_LOS */
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
/* Right SFP (logical 3, SDS0): GPIO50=ModAbs, GPIO51=RX_LOS */
|
||||||
|
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
||||||
|
.sfp_port[1].pin_los = GPIO51_I2C_SDA2_UART1_RX,
|
||||||
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 0,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
|
||||||
|
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
|
||||||
|
/* Copper ports use SET0; SFP ports use SET1 */
|
||||||
|
.port_led_set = {0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
|
.led_sets = {
|
||||||
|
{ /* SET0: copper — LED0=amber (2.5G), LED2=green (1G/100M/10M) */
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{ /* SET1: SFP — all speeds link/act */
|
||||||
|
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0, 0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = {
|
||||||
|
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, /* GPIO0-7: unused */
|
||||||
|
0x0f, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12, /* GPIO8-14 */
|
||||||
|
0x14, 0x15, 0x16, 0x18, 0x19, 0x1a, /* GPIO15-20 */
|
||||||
|
0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x23 /* GPIO21-27 */
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_PCB_K0402WS_V2_H_
|
||||||
|
#define _MACHINE_PCB_K0402WS_V2_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "PCB-K0402WS-V2.0"
|
||||||
|
|
||||||
|
#endif
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
HI_K0402WS.c
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_PCB_K0402WS_V3_H_
|
||||||
|
#define _MACHINE_PCB_K0402WS_V3_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "PCB-K0402WS-V3.0"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.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 = GPIO38, // pulled low on module insert
|
||||||
|
.sfp_port[0].pin_los = GPIO_NA, // no LOS pin wired
|
||||||
|
.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 wiring matches the SWTG018AS-A V2.0 (same PCB family)
|
||||||
|
.led_sets = {
|
||||||
|
{ /* RJ45: First LED, yellow, second LED: green */
|
||||||
|
LEDS_2G5 | LEDS_LINK,
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
}, { /* SFP set (superseded by the raw register override in machine_custom_init) */
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
}},
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = { 0x00, 0x01, 0x04, 0x05, 0x08, // 65e0
|
||||||
|
0x09, 0x0c, 0x09, 0x0d, 0x10, // 65e4
|
||||||
|
0x11, 0x0e, 0x14, 0x11, 0x12, // 65e8
|
||||||
|
0x15, 0x15, 0x16, 0x18, 0x19, // 65ec
|
||||||
|
0x1a, 0x19, 0x1d, 0x1e, 0x1c, // 65f0
|
||||||
|
0x1d, 0x20, 0x21 },
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_PCB_SWTG018AS_V2_1_0_H_
|
||||||
|
#define _MACHINE_PCB_SWTG018AS_V2_1_0_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "SWTGW218AS (SWTG018AS-V2.1.0)"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 1, 0, 0, 0, 0, 2},
|
||||||
|
|
||||||
|
// SFP port on SDS0 / logical port 3
|
||||||
|
.sfp_port[0].pin_detect = GPIO37,
|
||||||
|
.sfp_port[0].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 0,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
// SFP port on SDS1 / logical port 8
|
||||||
|
.sfp_port[1].pin_detect = GPIO38,
|
||||||
|
.sfp_port[1].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 1,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
.high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
|
.led_sets = {
|
||||||
|
{
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_DUPLEX,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_10G | LEDS_LINK | LEDS_ACT,
|
||||||
|
LEDS_2G5 | LEDS_LINK,
|
||||||
|
LEDS_COL | LEDS_DUPLEX
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = {
|
||||||
|
0x00,0x01,0x04,0x05,0x08,0x09,0x0c,0x3f,0x0d,0x10,0x11,0x0e,0x14,0x11,0x12,0x15,0x15,0x16,0x18,0x19,0x1a,0x19,0x1d,0x1e,0x1c,0x1d,0x20,0x21
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_PCB_SWTG024AS_A_2_0_1_H_
|
||||||
|
#define _MACHINE_PCB_SWTG024AS_A_2_0_1_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "PCB-SWTG024AS-A-2.0.1"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.led_sets = {
|
||||||
|
{
|
||||||
|
/* SET0: RJ45 2.5G = amber, 1G/100M/10M = green */
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT, /* amber */
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, /* green */
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* SET1: SFP+ port = green */
|
||||||
|
LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M |
|
||||||
|
LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = { 0x00, 0x01, 0x04, 0x05, 0x08,
|
||||||
|
0x09, 0x0c, 0x09, 0x0d, 0x10,
|
||||||
|
0x11, 0x0e, 0x14, 0x11, 0x12,
|
||||||
|
0x15, 0x15, 0x16, 0x18, 0x19,
|
||||||
|
0x1a, 0x19, 0x1d, 0x1e, 0x1c,
|
||||||
|
0x1d, 0x20, 0x21 },
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_POE_2G080110GS_H_
|
||||||
|
#define _MACHINE_POE_2G080110GS_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "MokerLink POE-2G080110GS"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
|
// Left SFP port (5)
|
||||||
|
// LED pin 9
|
||||||
|
.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 ),
|
||||||
|
// Right SFP port (6)
|
||||||
|
// LED pin 24
|
||||||
|
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
||||||
|
.sfp_port[1].pin_los = GPIO51_I2C_SDA2_UART1_RX,
|
||||||
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 0,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
|
.led_sets = {
|
||||||
|
{
|
||||||
|
// RJ45 Amber LED (left)
|
||||||
|
LEDS_2G5 | LEDS_LINK,
|
||||||
|
// RJ45 Green LED (Right)
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// SFP LED
|
||||||
|
LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0, // unused
|
||||||
|
0, // unused
|
||||||
|
0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = {
|
||||||
|
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x0f, 0x20, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x15, 0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x0c, 0x21, 0x22, 0x23
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_STEAMEMO_IG204_V1_H_
|
||||||
|
#define _MACHINE_STEAMEMO_IG204_V1_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "Steamemo IG204 V1"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
||||||
|
.is_sfp= {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
|
// Left SFP port (J4)
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), /* GPIO 39 */
|
||||||
|
// Right SFP port (J2)
|
||||||
|
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
||||||
|
.sfp_port[1].pin_los = GPIO_NA,
|
||||||
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 0,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), /* GPIO 40 */
|
||||||
|
.reset_pin = GPIO54_ACL_BIT2_EN,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
|
.led_sets = {
|
||||||
|
{ /* RJ45: Green LED */
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
0,
|
||||||
|
/* Amber LED */
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
0
|
||||||
|
}, { /* SFP PORT: SINGLE GREEN LED */
|
||||||
|
LEDS_10M | LEDS_100M | LEDS_1G | LEDS_2G5 | LEDS_10G | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_SWGT024_V2_0_MANAGED_H_
|
||||||
|
#define _MACHINE_SWGT024_V2_0_MANAGED_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "SWGT024 V2.0 Managed"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
||||||
|
.is_sfp= {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
|
// Left SFP port (J4)
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = 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 ), /* GPIO 39 */
|
||||||
|
// Right SFP port (J2)
|
||||||
|
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
||||||
|
.sfp_port[1].pin_los = GPIO51_I2C_SDA2_UART1_RX,
|
||||||
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 0,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), /* GPIO 40 */
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
|
.led_sets = {
|
||||||
|
{ /* RJ45: Green LED */
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
0,
|
||||||
|
/* Amber LED */
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
0
|
||||||
|
}, { /* SFP PORT: SINGLE GREEN LED */
|
||||||
|
LEDS_10M | LEDS_100M | LEDS_1G | LEDS_2G5 | LEDS_10G | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
Loaded 100 of 140 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user