Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
347950ff72 | ||
|
|
0bccfbd11f | ||
|
|
360bc1e86d | ||
|
|
5b385385de | ||
|
|
ea23dfedc5 | ||
|
|
34a32fa7e8 | ||
|
|
06930df7c6 | ||
|
|
df058dfe33 | ||
|
|
45213b4eac |
@@ -18,4 +18,4 @@ jobs:
|
|||||||
apt update
|
apt update
|
||||||
apt install make gcc sdcc xxd python-is-python3 libjson-c-dev -y
|
apt install make gcc sdcc xxd python-is-python3 libjson-c-dev -y
|
||||||
- name: Make project
|
- name: Make project
|
||||||
run: make MACHINE="KP_9000_6XHML_X2"
|
run: make
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
|
BOOTLOADER_ADDRESS=0x100
|
||||||
|
|
||||||
VERSION=0.1.0
|
VERSION=0.1.0
|
||||||
IMAGESIZE = 524288
|
IMAGESIZE = 524288
|
||||||
DEFAULT_CONFIG_LOCATION = 454656
|
|
||||||
CONFIG_LOCATION = 458752
|
CONFIG_LOCATION = 458752
|
||||||
HTML_LOCATION = 262144
|
HTML_LOCATION = 262144
|
||||||
|
|
||||||
@@ -15,20 +16,14 @@ SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS))
|
|||||||
BUILDDIR = output/
|
BUILDDIR = output/
|
||||||
VERSION_HEADER := version.h
|
VERSION_HEADER := version.h
|
||||||
|
|
||||||
ifeq ($(MACHINE),)
|
|
||||||
else
|
|
||||||
CC_FLAGS += -DMACHINE_$(MACHINE)
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: create_build_dir $(VERSION_HEADER) $(SUBDIRS) $(BUILDDIR)rtlplayground.bin
|
all: create_build_dir $(VERSION_HEADER) $(SUBDIRS) $(BUILDDIR)rtlplayground.bin
|
||||||
|
|
||||||
create_build_dir:
|
create_build_dir:
|
||||||
mkdir -p $(BUILDDIR)
|
mkdir -p $(BUILDDIR)
|
||||||
|
|
||||||
SRCS = rtlplayground.c rtl837x_flash.c rtl837x_leds.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c \
|
SRCS = rtlplayground.c rtl837x_flash.c rtl837x_leds.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c
|
||||||
rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c cmd_editor.c rtl837x_bandwidth.c
|
|
||||||
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel}
|
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel}
|
||||||
OBJS += uip/$(BUILDDIR)/timer.rel uip/$(BUILDDIR)/uip-fw.rel uip/$(BUILDDIR)/uip-split.rel uip/$(BUILDDIR)/uip.rel uip/$(BUILDDIR)/uip_arp.rel uip/$(BUILDDIR)/uiplib.rel httpd/$(BUILDDIR)/httpd.rel httpd/$(BUILDDIR)/page_impl.rel
|
OBJS += uip/$(BUILDDIR)/timer.rel uip/$(BUILDDIR)/uip-fw.rel uip/$(BUILDDIR)/uip-neighbor.rel uip/$(BUILDDIR)/uip-split.rel uip/$(BUILDDIR)/uip.rel uip/$(BUILDDIR)/uip_arp.rel uip/$(BUILDDIR)/uiplib.rel httpd/$(BUILDDIR)/httpd.rel httpd/$(BUILDDIR)/page_impl.rel
|
||||||
|
|
||||||
html_data.c html_data.h: html tools
|
html_data.c html_data.h: html tools
|
||||||
tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -d html -p html_data
|
tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -d html -p html_data
|
||||||
@@ -37,7 +32,6 @@ $(VERSION_HEADER):
|
|||||||
@echo "#ifndef VERSION_H" > $(VERSION_HEADER)
|
@echo "#ifndef VERSION_H" > $(VERSION_HEADER)
|
||||||
@echo "#define VERSION_H" >> $(VERSION_HEADER)
|
@echo "#define VERSION_H" >> $(VERSION_HEADER)
|
||||||
@echo "#define VERSION_SW \"v$(VERSION)-g$(shell git rev-parse --short HEAD)\"" >> $(VERSION_HEADER)
|
@echo "#define VERSION_SW \"v$(VERSION)-g$(shell git rev-parse --short HEAD)\"" >> $(VERSION_HEADER)
|
||||||
@echo "#define BUILD_DATE \"$(shell date +"%Y-%m-%d %H:%M:%S")\"" >> $(VERSION_HEADER)
|
|
||||||
@echo "#endif" >> $(VERSION_HEADER)
|
@echo "#endif" >> $(VERSION_HEADER)
|
||||||
|
|
||||||
httpd: html_data.h
|
httpd: html_data.h
|
||||||
@@ -64,8 +58,8 @@ $(BUILDDIR)%.rel: $(BUILDDIR)%.asm
|
|||||||
${ASM} ${AFLAGS} -o $@ $<
|
${ASM} ${AFLAGS} -o $@ $<
|
||||||
# mv -f $(addprefix $(basename $^), .lst .rel .sym) .
|
# mv -f $(addprefix $(basename $^), .lst .rel .sym) .
|
||||||
|
|
||||||
$(BUILDDIR)rtlplayground.ihx: $(OBJS) $(BUILDDIR)crtstart.rel $(BUILDDIR)crc16.rel
|
$(BUILDDIR)rtlplayground.ihx: $(BUILDDIR)crtstart.rel $(OBJS) $(BUILDDIR)crc16.rel
|
||||||
$(CC) $(CC_FLAGS) -Wl-bHOME=0x00000 -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-r -o $@ $^
|
$(CC) $(CC_FLAGS) -Wl-bHOME=${BOOTLOADER_ADDRESS} -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-r -o $@ $^
|
||||||
|
|
||||||
$(BUILDDIR)rtlplayground.img: $(BUILDDIR)rtlplayground.ihx
|
$(BUILDDIR)rtlplayground.img: $(BUILDDIR)rtlplayground.ihx
|
||||||
objcopy --input-target=ihex -O binary $< $@
|
objcopy --input-target=ihex -O binary $< $@
|
||||||
@@ -73,7 +67,6 @@ $(BUILDDIR)rtlplayground.img: $(BUILDDIR)rtlplayground.ihx
|
|||||||
$(BUILDDIR)rtlplayground.bin: $(BUILDDIR)rtlplayground.img
|
$(BUILDDIR)rtlplayground.bin: $(BUILDDIR)rtlplayground.img
|
||||||
if [ -e $@ ]; then rm $@; fi
|
if [ -e $@ ]; then rm $@; fi
|
||||||
tools/$(BUILDDIR)imagebuilder -i $^ $@
|
tools/$(BUILDDIR)imagebuilder -i $^ $@
|
||||||
tools/$(BUILDDIR)fileadder -a $(DEFAULT_CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
|
||||||
tools/$(BUILDDIR)fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
tools/$(BUILDDIR)fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
||||||
tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data $@
|
tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data $@
|
||||||
tools/$(BUILDDIR)crc_calculator -u $@
|
tools/$(BUILDDIR)crc_calculator -u $@
|
||||||
|
|||||||
@@ -56,12 +56,20 @@ device simulator is provided, which runs entirely under Linux as a local webserv
|
|||||||
Install the following particular build requisites (Debian 12/13), note that Ubuntu 24.04
|
Install the following particular build requisites (Debian 12/13), note that Ubuntu 24.04
|
||||||
still has an older version of sdcc, but you will need sdcc version 4.5 for the code to compile:
|
still has an older version of sdcc, but you will need sdcc version 4.5 for the code to compile:
|
||||||
```
|
```
|
||||||
sudo apt install make gcc sdcc xxd python-is-python3 libjson-c-dev
|
sudo apt install sdcc xxd python-is-python3 libjson-c-dev
|
||||||
```
|
```
|
||||||
Edit machine.h with an editor like vi or nano. Select the correct machine the firmware should build for.
|
|
||||||
Now, building the firmware image should work:
|
Now, building the firmware image should work:
|
||||||
```
|
```
|
||||||
make
|
$ make
|
||||||
|
sdas8051 -plosgff crtstart.asm
|
||||||
|
sdcc -mmcs51 -c rtlplayground.c
|
||||||
|
sdcc -mmcs51 -c rtl837x_flash.c
|
||||||
|
sdcc -mmcs51 -Wl-bHOME=0x100 -o rtlplayground.ihx crtstart.rel rtlplayground.rel rtl837x_flash.rel
|
||||||
|
objcopy --input-target=ihex -O binary rtlplayground.ihx rtlplayground.img
|
||||||
|
if [ -e rtlplayground.bin ]; then rm rtlplayground.bin; fi
|
||||||
|
echo "0000000: 00 40" | xxd -r - rtlplayground.bin
|
||||||
|
cat rtlplayground.img >> rtlplayground.bin
|
||||||
```
|
```
|
||||||
Note, that the image generated ends in .bin, not .img, in order to make
|
Note, that the image generated ends in .bin, not .img, in order to make
|
||||||
IMSProg happy.
|
IMSProg happy.
|
||||||
|
|||||||
@@ -1,208 +0,0 @@
|
|||||||
#include "cmd_parser.h"
|
|
||||||
#include "machine.h"
|
|
||||||
|
|
||||||
#pragma codeseg BANK2
|
|
||||||
#pragma constseg BANK2
|
|
||||||
|
|
||||||
// Position in the serial buffer
|
|
||||||
__xdata uint8_t l;
|
|
||||||
// Properties of currently edited command line in cmd_buffer[CMD_BUF_SIZE]
|
|
||||||
__xdata uint8_t cursor;
|
|
||||||
__xdata uint8_t cmd_line_len;
|
|
||||||
__xdata uint8_t current_cmdline[CMD_BUF_SIZE];
|
|
||||||
__xdata uint16_t history_editptr;
|
|
||||||
|
|
||||||
|
|
||||||
extern __xdata uint8_t cmd_history[CMD_HISTORY_SIZE];
|
|
||||||
extern __xdata uint16_t cmd_history_ptr;
|
|
||||||
|
|
||||||
void cmd_editor_init(void) __banked
|
|
||||||
{
|
|
||||||
l = sbuf_ptr; // We have printed out entered characters until l
|
|
||||||
cursor = 0;
|
|
||||||
cmd_line_len = 0;
|
|
||||||
cmd_available = 0;
|
|
||||||
history_editptr = 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allows editing the current command line held in cmd_buffer[CMD_BUF_SIZE] by
|
|
||||||
* identifying new characters typed or up to 4-byte escape sequences in the
|
|
||||||
* serial buffer ring sbuf[SBUF_SIZE].
|
|
||||||
* Upon detecting new characters or escape sequences, the cmd_buffer and the
|
|
||||||
* representation of the command line in the terminal are updated.
|
|
||||||
* To debug, the easist is to interpose a tty-interceptor between the physical
|
|
||||||
* serial device and a logical one created by interceptty:
|
|
||||||
* sudo interceptty -s 'ispeed 115200 ospeed 115200' /dev/ttyUSB0 /dev/tmpS
|
|
||||||
* picocom -b 115200 /dev/tmpS
|
|
||||||
*/
|
|
||||||
void cmd_edit(void) __banked
|
|
||||||
{
|
|
||||||
while (l != sbuf_ptr) {
|
|
||||||
if (sbuf[l] >= ' ' && sbuf[l] < 127) { // A printable character, copy to command line
|
|
||||||
if (cmd_line_len >= CMD_BUF_SIZE)
|
|
||||||
continue;
|
|
||||||
write_char(sbuf[l]);
|
|
||||||
// Shift buffer to right
|
|
||||||
for (uint8_t i = cmd_line_len; i > cursor; i--)
|
|
||||||
cmd_buffer[i] = cmd_buffer[i-1];
|
|
||||||
// Insert char in comand buffer
|
|
||||||
cmd_buffer[cursor++] = sbuf[l];
|
|
||||||
cmd_line_len++;
|
|
||||||
// Print rest of line
|
|
||||||
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
|
||||||
write_char(cmd_buffer[i]);
|
|
||||||
// Move backwards
|
|
||||||
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
|
||||||
write_char('\010'); // BS works like cursor-left
|
|
||||||
} else if (sbuf[l] == '\033') { // ESC-Sequence
|
|
||||||
// Wait until we have at least 3 characters including the ESC character in the serial buffer
|
|
||||||
if (((sbuf_ptr + SBUF_SIZE - l) & SBUF_MASK) < 3)
|
|
||||||
continue;
|
|
||||||
if (((sbuf_ptr > l ? sbuf_ptr - l : SBUF_SIZE + sbuf_ptr - l) >= 4)
|
|
||||||
&& sbuf[l] == '\033' && sbuf[(l + 1) & SBUF_MASK] == '[' && sbuf[(l + 2) & SBUF_MASK] == '3' && sbuf[(l + 3) & SBUF_MASK] == '~') { // DEL
|
|
||||||
if (cursor < cmd_line_len) {
|
|
||||||
write_char('\033'); write_char('['); write_char('1'); write_char('P'); // Delete to end of line
|
|
||||||
cmd_line_len--;
|
|
||||||
for (uint8_t i = cursor; i < cmd_line_len; i++) {
|
|
||||||
cmd_buffer[i] = cmd_buffer[i+1];
|
|
||||||
write_char(cmd_buffer[i]);
|
|
||||||
}
|
|
||||||
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
|
||||||
write_char('\010');
|
|
||||||
}
|
|
||||||
l += 4;
|
|
||||||
l &= SBUF_MASK;
|
|
||||||
continue;
|
|
||||||
} else if (sbuf[l] == '\033' && sbuf[(l + 1) & SBUF_MASK] == '[' && sbuf[(l + 2) & SBUF_MASK] == 'D') { // <CURSOR-LEFT>
|
|
||||||
if (cursor) {
|
|
||||||
write_char('\010'); // BS works like cursor-left
|
|
||||||
cursor--;
|
|
||||||
}
|
|
||||||
l += 3;
|
|
||||||
l &= SBUF_MASK;
|
|
||||||
continue;
|
|
||||||
} else if (sbuf[l] == '\033' && sbuf[(l + 1) & SBUF_MASK] == '[' && sbuf[(l + 2) & SBUF_MASK] == 'C') { // <CURSOR-RIGHT>
|
|
||||||
if (cursor < cmd_line_len) {
|
|
||||||
write_char('\033'); write_char('['); write_char('C');
|
|
||||||
cursor++;
|
|
||||||
}
|
|
||||||
l += 3;
|
|
||||||
l &= SBUF_MASK;
|
|
||||||
continue;
|
|
||||||
} else if (sbuf[l] == '\033' && sbuf[(l + 1) & SBUF_MASK] == '[' && sbuf[(l + 2) & SBUF_MASK] == 'A') { // <CURSOR-UP>
|
|
||||||
for (uint8_t i = 0; i < cmd_line_len; i++)
|
|
||||||
current_cmdline[i] = cmd_buffer[i];
|
|
||||||
current_cmdline[cmd_line_len] = 0;
|
|
||||||
__xdata uint16_t p;
|
|
||||||
if (history_editptr == 0xffff)
|
|
||||||
p = (cmd_history_ptr - 2) & CMD_HISTORY_MASK;
|
|
||||||
else
|
|
||||||
p = history_editptr;
|
|
||||||
// Move cursor to beginning of line
|
|
||||||
write_char('\033'); write_char('['); itoa(cursor + 2); write_char('D');
|
|
||||||
cursor = 0;
|
|
||||||
while (cmd_history[p] && cmd_history[p] != '\n') {
|
|
||||||
cursor++;
|
|
||||||
p--;
|
|
||||||
p &= CMD_HISTORY_MASK;
|
|
||||||
}
|
|
||||||
history_editptr = (p - 1) & CMD_HISTORY_MASK;
|
|
||||||
p = (p + 1) & CMD_HISTORY_MASK;
|
|
||||||
if (cursor) {
|
|
||||||
print_string("\033[2K> "); // Clear entire line: ^[[2K and print new prompt
|
|
||||||
for (uint8_t i = 0; i < cursor; i++) {
|
|
||||||
cmd_buffer[i] = cmd_history[p];
|
|
||||||
write_char(cmd_buffer[i]);
|
|
||||||
p = (p+1) & CMD_HISTORY_MASK;
|
|
||||||
}
|
|
||||||
cmd_line_len = cursor;
|
|
||||||
} else {
|
|
||||||
print_string("\033[2C"); // Move 2 right to start of editing space
|
|
||||||
}
|
|
||||||
l += 3;
|
|
||||||
l &= SBUF_MASK;
|
|
||||||
continue;
|
|
||||||
} else if (sbuf[l] == '\033' && sbuf[(l + 1) & SBUF_MASK] == '[' && sbuf[(l + 2) & SBUF_MASK] == 'B') { // <CURSOR-DOWN>
|
|
||||||
if (history_editptr != 0xffff) {
|
|
||||||
__xdata uint16_t p = (history_editptr + 2) & CMD_HISTORY_MASK;
|
|
||||||
// Move cursor to beginning of line
|
|
||||||
write_char('\033'); write_char('['); itoa(cursor + 2); write_char('D');
|
|
||||||
print_string("\033[2K> "); // Clear entire line: ^[[2K and print new prompt
|
|
||||||
uint8_t i = 0;
|
|
||||||
while (cmd_history[p] && cmd_history[p] != '\n') {
|
|
||||||
p = (p + 1) & CMD_HISTORY_MASK;
|
|
||||||
}
|
|
||||||
p = (p + 1) & CMD_HISTORY_MASK;
|
|
||||||
while (cmd_history[p] && cmd_history[p] != '\n') {
|
|
||||||
cmd_buffer[i] = cmd_history[p];
|
|
||||||
write_char(cmd_buffer[i++]);
|
|
||||||
p = (p + 1) & CMD_HISTORY_MASK;
|
|
||||||
}
|
|
||||||
history_editptr = (p - 1) & CMD_HISTORY_MASK;
|
|
||||||
if (!i) {
|
|
||||||
if (current_cmdline[i]) {
|
|
||||||
while (current_cmdline[i]) {
|
|
||||||
cmd_buffer[i] = current_cmdline[i];
|
|
||||||
write_char(cmd_buffer[i++]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
write_char('\033'); write_char('['); write_char('C');
|
|
||||||
}
|
|
||||||
history_editptr = 0xffff;
|
|
||||||
// Move cursor right
|
|
||||||
}
|
|
||||||
cmd_line_len = i;
|
|
||||||
cursor = 0;
|
|
||||||
// Move cursor again to beginning of line
|
|
||||||
write_char('\033'); write_char('['); itoa(i); write_char('D');
|
|
||||||
} else {
|
|
||||||
// If we are at the last entry of the history, just move the cursor to the end of the line
|
|
||||||
if (cursor < cmd_line_len) {
|
|
||||||
write_char('\033'); write_char('['); itoa(cmd_line_len - cursor); write_char('C');
|
|
||||||
}
|
|
||||||
cursor = cmd_line_len;
|
|
||||||
}
|
|
||||||
l += 3;
|
|
||||||
l &= SBUF_MASK;
|
|
||||||
continue;
|
|
||||||
} else { // An unknown or not yet complete Escape sequence: wait
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else if (sbuf[l] == 127) { // Backspace
|
|
||||||
if (cursor > 0) {
|
|
||||||
write_char('\010');
|
|
||||||
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
|
||||||
write_char(cmd_buffer[i]);
|
|
||||||
write_char(' '); // Overwrite end of line
|
|
||||||
// Move backwards n steps:
|
|
||||||
for (uint8_t i = cursor; i <= cmd_line_len; i++)
|
|
||||||
write_char('\010');
|
|
||||||
cursor--;
|
|
||||||
for (uint8_t i = cursor; i <= cmd_line_len; i++)
|
|
||||||
cmd_buffer[i] = cmd_buffer[i+1];
|
|
||||||
cmd_line_len--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If the command buffer is currently in use, we cannot copy to it
|
|
||||||
if (cmd_available)
|
|
||||||
break;
|
|
||||||
// Check whether return was pressed:
|
|
||||||
if (sbuf[l] == '\n' || sbuf[l] == '\r') {
|
|
||||||
write_char('\n');
|
|
||||||
cmd_buffer[cmd_line_len] = '\0';
|
|
||||||
// write_char('>'); print_string_x(cmd_buffer); write_char('<');
|
|
||||||
// If there is a command we print the prompt after execution
|
|
||||||
// otherwise immediately because there is nothing to execute
|
|
||||||
if (cmd_line_len)
|
|
||||||
cmd_available = 1;
|
|
||||||
else
|
|
||||||
print_string("\n> ");
|
|
||||||
cursor = 0;
|
|
||||||
cmd_line_len = 0;
|
|
||||||
history_editptr = 0xffff;
|
|
||||||
}
|
|
||||||
l++;
|
|
||||||
l &= SBUF_MASK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#ifndef _CMD_EDITOR_H_
|
|
||||||
#define _CMD_EDITOR_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void cmd_editor_init(void) __banked;
|
|
||||||
void cmd_edit(void) __banked;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
#include "rtl837x_sfr.h"
|
#include "rtl837x_sfr.h"
|
||||||
#include "rtl837x_stp.h"
|
#include "rtl837x_stp.h"
|
||||||
#include "rtl837x_igmp.h"
|
#include "rtl837x_igmp.h"
|
||||||
#include "rtl837x_bandwidth.h"
|
|
||||||
#include "dhcp.h"
|
#include "dhcp.h"
|
||||||
#include "uip/uip.h"
|
#include "uip/uip.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
@@ -34,7 +33,7 @@ extern volatile __xdata uint8_t sfr_data[4];
|
|||||||
extern __code uint8_t * __code greeting;
|
extern __code uint8_t * __code greeting;
|
||||||
extern __code uint8_t * __code hex;
|
extern __code uint8_t * __code hex;
|
||||||
|
|
||||||
extern __xdata uint8_t flash_buf[FLASH_BUF_SIZE];
|
extern __xdata uint8_t flash_buf[512];
|
||||||
extern __xdata struct flash_region_t flash_region;
|
extern __xdata struct flash_region_t flash_region;
|
||||||
|
|
||||||
extern __xdata char passwd[21];
|
extern __xdata char passwd[21];
|
||||||
@@ -44,7 +43,6 @@ extern __xdata struct dhcp_state dhcp_state;
|
|||||||
__xdata uint8_t vlan_names[VLAN_NAMES_SIZE];
|
__xdata uint8_t vlan_names[VLAN_NAMES_SIZE];
|
||||||
__xdata uint16_t vlan_ptr;
|
__xdata uint16_t vlan_ptr;
|
||||||
extern __xdata uint16_t management_vlan;
|
extern __xdata uint16_t management_vlan;
|
||||||
extern __xdata uint16_t dhcpd_vlan;
|
|
||||||
__xdata uint8_t gpio_last_value[8] = { 0 };
|
__xdata uint8_t gpio_last_value[8] = { 0 };
|
||||||
|
|
||||||
// Temporatly for str to hex convertion value.
|
// Temporatly for str to hex convertion value.
|
||||||
@@ -53,16 +51,17 @@ __xdata uint8_t hexvalue[4] = { 0 };
|
|||||||
|
|
||||||
|
|
||||||
// Buffer for writing to flash 0x1fd000, copy to 0x1fe000
|
// Buffer for writing to flash 0x1fd000, copy to 0x1fe000
|
||||||
__xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
__xdata uint8_t cmd_buffer[SBUF_SIZE];
|
||||||
__xdata uint8_t cmd_available;
|
__xdata uint8_t cmd_available;
|
||||||
|
|
||||||
|
__xdata uint8_t l;
|
||||||
__xdata uint8_t line_ptr;
|
__xdata uint8_t line_ptr;
|
||||||
__xdata char is_white;
|
__xdata char is_white;
|
||||||
__xdata char save_cmd;
|
__xdata char save_cmd;
|
||||||
|
|
||||||
__xdata uint8_t ip[4];
|
__xdata uint8_t ip[4];
|
||||||
|
|
||||||
#define N_WORDS CMD_BUF_SIZE
|
#define N_WORDS SBUF_SIZE
|
||||||
__xdata signed char cmd_words_b[N_WORDS];
|
__xdata signed char cmd_words_b[N_WORDS];
|
||||||
|
|
||||||
__xdata uint8_t cmd_history[CMD_HISTORY_SIZE];
|
__xdata uint8_t cmd_history[CMD_HISTORY_SIZE];
|
||||||
@@ -94,7 +93,7 @@ uint8_t cmd_compare(uint8_t start, uint8_t * __code cmd)
|
|||||||
signed char j = 0;
|
signed char j = 0;
|
||||||
|
|
||||||
for (i = cmd_words_b[start]; i != cmd_words_b[start + 1] && cmd_buffer[i] != ' '; i++) {
|
for (i = cmd_words_b[start]; i != cmd_words_b[start + 1] && cmd_buffer[i] != ' '; i++) {
|
||||||
i &= CMD_BUF_SIZE - 1;
|
i &= SBUF_SIZE - 1;
|
||||||
// print_byte(i); write_char(':'); print_byte(j); write_char('#'); print_string("\n");
|
// print_byte(i); write_char(':'); print_byte(j); write_char('#'); print_string("\n");
|
||||||
// write_char('>'); write_char(cmd[j]); write_char('-'); write_char(cmd_buffer[i]); print_string("\n");
|
// write_char('>'); write_char(cmd[j]); write_char('-'); write_char(cmd_buffer[i]); print_string("\n");
|
||||||
if (!cmd[j] && !isletter(cmd_buffer[i]))
|
if (!cmd[j] && !isletter(cmd_buffer[i]))
|
||||||
@@ -151,14 +150,6 @@ uint8_t atoi_hex(uint8_t idx)
|
|||||||
h_idx++;
|
h_idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h_idx & 1) {
|
|
||||||
hexvalue[h_idx >> 1] <<= 4;
|
|
||||||
hexvalue[3] = hexvalue[3] >> 4 | (hexvalue[2] << 4);
|
|
||||||
hexvalue[2] = hexvalue[2] >> 4 | (hexvalue[1] << 4);
|
|
||||||
hexvalue[1] = hexvalue[1] >> 4 | (hexvalue[0] << 4);
|
|
||||||
hexvalue[0] >>= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((h_idx + 1) >> 1);
|
return ((h_idx + 1) >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,17 +282,17 @@ void parse_lag_hash(void)
|
|||||||
|
|
||||||
void parse_vlan(void)
|
void parse_vlan(void)
|
||||||
{
|
{
|
||||||
vlan_settings.vlan = 0;
|
__xdata uint16_t vlan;
|
||||||
vlan_settings.members = 0;
|
__xdata uint16_t members = 0;
|
||||||
vlan_settings.tagged = 0;
|
__xdata uint16_t tagged = 0;
|
||||||
if (!atoi_short(&vlan_settings.vlan, cmd_words_b[1])) {
|
if (!atoi_short(&vlan, cmd_words_b[1])) {
|
||||||
if (cmd_words_b[2] > 0 && cmd_buffer[cmd_words_b[2]] == 'd' && cmd_words_b[3] < 0) {
|
if (cmd_words_b[2] > 0 && cmd_buffer[cmd_words_b[2]] == 'd' && cmd_words_b[3] < 0) {
|
||||||
vlan_delete(vlan_settings.vlan);
|
vlan_delete(vlan);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cmd_words_b[2] > 0 && cmd_compare(2, "mgmt")) {
|
if (cmd_words_b[2] > 0 && cmd_compare(2, "mgmt")) {
|
||||||
management_vlan = vlan_settings.vlan;
|
management_vlan = vlan;
|
||||||
if (!vlan_settings.vlan)
|
if (!vlan)
|
||||||
print_string("Management VLAN disabled\n");
|
print_string("Management VLAN disabled\n");
|
||||||
else
|
else
|
||||||
print_string("Management VLAN set to "); print_short(management_vlan); write_char('\n');
|
print_string("Management VLAN set to "); print_short(management_vlan); write_char('\n');
|
||||||
@@ -310,9 +301,9 @@ void parse_vlan(void)
|
|||||||
uint8_t w = 2;
|
uint8_t w = 2;
|
||||||
if (cmd_words_b[w] > 0 && isletter(cmd_buffer[cmd_words_b[w]])) {
|
if (cmd_words_b[w] > 0 && isletter(cmd_buffer[cmd_words_b[w]])) {
|
||||||
register uint8_t i = 0;
|
register uint8_t i = 0;
|
||||||
vlan_names[vlan_ptr++] = hex[(vlan_settings.vlan >> 8) & 0xf];
|
vlan_names[vlan_ptr++] = hex[(vlan >> 8) & 0xf];
|
||||||
vlan_names[vlan_ptr++] = hex[(vlan_settings.vlan >> 4) & 0xf] ;
|
vlan_names[vlan_ptr++] = hex[(vlan >> 4) & 0xf] ;
|
||||||
vlan_names[vlan_ptr++] = hex[vlan_settings.vlan & 0xf];
|
vlan_names[vlan_ptr++] = hex[vlan & 0xf];
|
||||||
while(cmd_buffer[cmd_words_b[w] + i] != ' ') {
|
while(cmd_buffer[cmd_words_b[w] + i] != ' ') {
|
||||||
write_char(cmd_buffer[cmd_words_b[w] + i]);
|
write_char(cmd_buffer[cmd_words_b[w] + i]);
|
||||||
vlan_names[vlan_ptr++] = cmd_buffer[cmd_words_b[w] + i++];
|
vlan_names[vlan_ptr++] = cmd_buffer[cmd_words_b[w] + i++];
|
||||||
@@ -322,25 +313,25 @@ void parse_vlan(void)
|
|||||||
print_string("<\n");
|
print_string("<\n");
|
||||||
}
|
}
|
||||||
while (cmd_words_b[w] > 0) {
|
while (cmd_words_b[w] > 0) {
|
||||||
__xdata uint8_t port;
|
uint8_t port;
|
||||||
if (isnumber(cmd_buffer[cmd_words_b[w]])) {
|
if (isnumber(cmd_buffer[cmd_words_b[w]])) {
|
||||||
port = cmd_buffer[cmd_words_b[w]] - '1';
|
port = cmd_buffer[cmd_words_b[w]] - '1';
|
||||||
if (isnumber(cmd_buffer[cmd_words_b[w] + 1])) {
|
if (isnumber(cmd_buffer[cmd_words_b[w] + 1])) {
|
||||||
port = (port + 1) * 10 + cmd_buffer[cmd_words_b[w] + 1] - '1';
|
port = (port + 1) * 10 + cmd_buffer[cmd_words_b[w] + 1] - '1';
|
||||||
if (cmd_buffer[cmd_words_b[w] + 2] == 't')
|
if (cmd_buffer[cmd_words_b[w] + 2] == 't')
|
||||||
vlan_settings.tagged |= ((uint16_t)1) << port;
|
tagged |= ((uint16_t)1) << port;
|
||||||
} else {
|
} else {
|
||||||
port = machine.phys_to_log_port[port];
|
port = machine.phys_to_log_port[port];
|
||||||
if (cmd_buffer[cmd_words_b[w] + 1] == 't')
|
if (cmd_buffer[cmd_words_b[w] + 1] == 't')
|
||||||
vlan_settings.tagged |= ((uint16_t)1) << port;
|
tagged |= ((uint16_t)1) << port;
|
||||||
}
|
}
|
||||||
if (port > machine.max_port)
|
if (port > machine.max_port)
|
||||||
goto err;
|
goto err;
|
||||||
vlan_settings.members |= ((uint16_t)1) << port;
|
members |= ((uint16_t)1) << port;
|
||||||
}
|
}
|
||||||
w++;
|
w++;
|
||||||
}
|
}
|
||||||
vlan_create();
|
vlan_create(vlan, members, tagged);
|
||||||
}
|
}
|
||||||
if (cmd_words_b[2] > 0 && isletter(cmd_buffer[cmd_words_b[2]])) {
|
if (cmd_words_b[2] > 0 && isletter(cmd_buffer[cmd_words_b[2]])) {
|
||||||
print_string("vlan_ptr "); print_short(vlan_ptr); write_char(':');
|
print_string("vlan_ptr "); print_short(vlan_ptr); write_char(':');
|
||||||
@@ -431,10 +422,10 @@ void parse_mirror(void)
|
|||||||
void parse_port(void)
|
void parse_port(void)
|
||||||
{
|
{
|
||||||
print_string("\nPORT ");
|
print_string("\nPORT ");
|
||||||
phy_settings.port = cmd_buffer[cmd_words_b[1]] - '1';
|
uint8_t p = cmd_buffer[cmd_words_b[1]] - '1';
|
||||||
phy_settings.port = machine.phys_to_log_port[phy_settings.port];
|
p = machine.phys_to_log_port[p];
|
||||||
print_byte(phy_settings.port);
|
print_byte(p);
|
||||||
if (machine.is_sfp[phy_settings.port]) {
|
if (machine.is_sfp[p]) {
|
||||||
print_string(" is SFP no PHY information available.\n");
|
print_string(" is SFP no PHY information available.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -442,53 +433,46 @@ void parse_port(void)
|
|||||||
print_string("\nport <port> [show|on|off|10m|100m|1g|2g5] [half|full]");
|
print_string("\nport <port> [show|on|off|10m|100m|1g|2g5] [half|full]");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
phy_settings.duplex = PHY_DUPLEX_BOTH;
|
|
||||||
if (cmd_compare(2, "10m")) {
|
if (cmd_compare(2, "10m")) {
|
||||||
print_string(" 10M\n");
|
print_string(" 10M\n");
|
||||||
phy_settings.speed = PHY_SPEED_10M;
|
|
||||||
if (cmd_words_b[3] > 0 && cmd_compare(3, "half"))
|
if (cmd_words_b[3] > 0 && cmd_compare(3, "half"))
|
||||||
phy_settings.duplex = PHY_DUPLEX_HALF;
|
phy_set_speed(p, PHY_SPEED_10M, PHY_DUPLEX_HALF);
|
||||||
else if (cmd_words_b[3] > 0 && cmd_compare(3, "full"))
|
else if (cmd_words_b[3] > 0 && cmd_compare(3, "full"))
|
||||||
phy_settings.duplex = PHY_DUPLEX_FULL;
|
phy_set_speed(p, PHY_SPEED_10M, PHY_DUPLEX_FULL);
|
||||||
phy_set_speed();
|
else
|
||||||
|
phy_set_speed(p, PHY_SPEED_10M, PHY_DUPLEX_BOTH);
|
||||||
} else if (cmd_compare(2, "100m")) {
|
} else if (cmd_compare(2, "100m")) {
|
||||||
print_string(" 100M\n");
|
print_string(" 100M\n");
|
||||||
phy_settings.speed = PHY_SPEED_100M;
|
|
||||||
if (cmd_words_b[3] > 0 && cmd_compare(3, "half"))
|
if (cmd_words_b[3] > 0 && cmd_compare(3, "half"))
|
||||||
phy_settings.duplex = PHY_DUPLEX_HALF;
|
phy_set_speed(p, PHY_SPEED_100M, PHY_DUPLEX_HALF);
|
||||||
else if (cmd_words_b[3] > 0 && cmd_compare(3, "full"))
|
else if (cmd_words_b[3] > 0 && cmd_compare(3, "full"))
|
||||||
phy_settings.duplex = PHY_DUPLEX_FULL;
|
phy_set_speed(p, PHY_SPEED_100M, PHY_DUPLEX_FULL);
|
||||||
phy_set_speed();
|
else
|
||||||
|
phy_set_speed(p, PHY_SPEED_100M, PHY_DUPLEX_BOTH);
|
||||||
} else if (cmd_compare(2, "2g5")) {
|
} else if (cmd_compare(2, "2g5")) {
|
||||||
print_string(" 2.5G\n");
|
print_string(" 2.5G\n");
|
||||||
phy_settings.speed = PHY_SPEED_2G5;
|
phy_set_speed(p, PHY_SPEED_2G5, PHY_DUPLEX_BOTH);
|
||||||
phy_set_speed();
|
|
||||||
} else if (cmd_compare(2, "1g")) {
|
} else if (cmd_compare(2, "1g")) {
|
||||||
print_string(" 1G\n");
|
print_string(" 1G\n");
|
||||||
phy_settings.speed = PHY_SPEED_1G;
|
phy_set_speed(p, PHY_SPEED_1G, PHY_DUPLEX_BOTH);
|
||||||
phy_set_speed();
|
|
||||||
} else if (cmd_compare(2, "auto")) {
|
} else if (cmd_compare(2, "auto")) {
|
||||||
print_string(" AUTO\n");
|
print_string(" AUTO\n");
|
||||||
phy_settings.speed = PHY_SPEED_AUTO;
|
phy_set_speed(p, PHY_SPEED_AUTO, PHY_DUPLEX_BOTH);
|
||||||
phy_set_speed();
|
|
||||||
} else if (cmd_compare(2, "off")) {
|
} else if (cmd_compare(2, "off")) {
|
||||||
print_string(" OFF\n");
|
print_string(" OFF\n");
|
||||||
phy_settings.speed = PHY_OFF;
|
phy_set_speed(p, PHY_OFF, PHY_DUPLEX_BOTH);
|
||||||
phy_set_speed();
|
|
||||||
} else if (cmd_compare(2, "on")) {
|
} else if (cmd_compare(2, "on")) {
|
||||||
print_string(" ON\n");
|
print_string(" ON\n");
|
||||||
phy_settings.speed = PHY_SPEED_AUTO;
|
phy_set_speed(p, PHY_SPEED_AUTO, PHY_DUPLEX_BOTH);
|
||||||
phy_set_speed();
|
|
||||||
} else if (cmd_compare(2, "duplex")) {
|
} else if (cmd_compare(2, "duplex")) {
|
||||||
print_string(" DUPLEX\n");
|
print_string(" DUPLEX\n");
|
||||||
if (cmd_words_b[3] > 0 && cmd_compare(3, "full"))
|
if (cmd_words_b[3] > 0 && cmd_compare(3, "full"))
|
||||||
phy_settings.speed = PHY_DUPLEX_FULL;
|
phy_set_duplex(p, PHY_DUPLEX_FULL);
|
||||||
else
|
else
|
||||||
phy_settings.speed = PHY_DUPLEX_HALF;
|
phy_set_duplex(p, PHY_DUPLEX_HALF);
|
||||||
phy_set_duplex();
|
|
||||||
}
|
}
|
||||||
if (cmd_words_b[2] > 0 && cmd_compare(2, "show")) {
|
if (cmd_words_b[2] > 0 && cmd_compare(2, "show")) {
|
||||||
phy_show(phy_settings.port);
|
phy_show(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,137 +633,6 @@ void parse_passwd(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void parse_eee(void)
|
|
||||||
{
|
|
||||||
__xdata int8_t port = -1;
|
|
||||||
__xdata uint8_t speed = EEE_2G5;
|
|
||||||
__xdata uint8_t speed_word = 0;
|
|
||||||
// Check if word 2 is a speed (contains 'g' or 'm') or a port number
|
|
||||||
if (cmd_words_b[3] > 0) {
|
|
||||||
uint8_t idx = cmd_words_b[2];
|
|
||||||
// Skip digits to check if there's a letter after
|
|
||||||
while (isnumber(cmd_buffer[idx]))
|
|
||||||
idx++;
|
|
||||||
if (cmd_buffer[idx] == 'g' || cmd_buffer[idx] == 'm') {
|
|
||||||
// Word 2 is a speed (e.g., "2g5", "100m", "1g")
|
|
||||||
speed_word = 2;
|
|
||||||
} else if (cmd_buffer[idx] == ' ' || cmd_buffer[idx] == '\0') {
|
|
||||||
// Word 2 is a port number
|
|
||||||
port = cmd_buffer[cmd_words_b[2]] - '1';
|
|
||||||
port = machine.phys_to_log_port[port];
|
|
||||||
// Check if word 3 is a speed
|
|
||||||
if (cmd_words_b[4] > 0)
|
|
||||||
speed_word = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Parse speed if found
|
|
||||||
if (speed_word > 0) {
|
|
||||||
if (cmd_compare(speed_word, "100m"))
|
|
||||||
speed = EEE_100;
|
|
||||||
else if (cmd_compare(speed_word, "1g"))
|
|
||||||
speed = EEE_1000;
|
|
||||||
else if (cmd_compare(speed_word, "2g5"))
|
|
||||||
speed = EEE_2G5;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
print_string("Speed word invalid, use: [100m|1g|2g5]\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cmd_words_b[1] > 0 && cmd_compare(1, "on")) {
|
|
||||||
if (port >= 0)
|
|
||||||
port_eee_enable(port, speed);
|
|
||||||
else
|
|
||||||
port_eee_enable_all(speed);
|
|
||||||
} else if (cmd_words_b[1] > 0 && cmd_compare(1, "off")) {
|
|
||||||
if (port >= 0)
|
|
||||||
port_eee_disable(port);
|
|
||||||
else
|
|
||||||
port_eee_disable_all();
|
|
||||||
} else if (cmd_words_b[1] > 0 && cmd_compare(1, "status")) {
|
|
||||||
if (port >= 0)
|
|
||||||
port_eee_status(port);
|
|
||||||
else
|
|
||||||
port_eee_status_all();
|
|
||||||
} else {
|
|
||||||
print_string("eee [on|off|status] [port] [100m|1g|2g5]\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void parse_bw(void)
|
|
||||||
{
|
|
||||||
__xdata uint8_t port;
|
|
||||||
__xdata uint32_t bw = 0;
|
|
||||||
|
|
||||||
if (cmd_words_b[3] < 0) // Check for at least 2 arguments
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
port = cmd_buffer[cmd_words_b[2]] - '1';
|
|
||||||
if (port > 9)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
port = machine.phys_to_log_port[port];
|
|
||||||
|
|
||||||
if (cmd_compare(1, "status")) {
|
|
||||||
bandwidth_status(port);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd_words_b[4] < 0) // Check for at least 3 arguments
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (cmd_compare(3, "drop")) {
|
|
||||||
if (cmd_compare(1, "in")) {
|
|
||||||
bandwidth_ingress_drop(port);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd_compare(3, "fc")) {
|
|
||||||
if (cmd_compare(1, "in")) {
|
|
||||||
bandwidth_ingress_fc(port);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd_compare(3, "off")) {
|
|
||||||
if (cmd_compare(1, "in")) {
|
|
||||||
bandwidth_ingress_disable(port);
|
|
||||||
return;
|
|
||||||
} else if (cmd_compare(1, "out")) {
|
|
||||||
bandwidth_egress_disable(port);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t hex_size = atoi_hex(cmd_words_b[3]);
|
|
||||||
if (hex_size == 0 || hex_size > 4) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
uint8_t i = 0;
|
|
||||||
while (hex_size) {
|
|
||||||
hex_size--;
|
|
||||||
*(((uint8_t *) &bw) + hex_size) = hexvalue[i++];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd_compare(1, "in")) {
|
|
||||||
bandwidth_ingress_set(port, bw);
|
|
||||||
} else if (cmd_compare(1, "out")) {
|
|
||||||
bandwidth_egress_set(port, bw);
|
|
||||||
} else {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
err:
|
|
||||||
print_string("usage: bw [in|out|status] <port> [<hexvalue>|off|drop|fc]\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse command into words
|
// Parse command into words
|
||||||
uint8_t cmd_tokenize(void) __banked
|
uint8_t cmd_tokenize(void) __banked
|
||||||
{
|
{
|
||||||
@@ -792,7 +645,7 @@ uint8_t cmd_tokenize(void) __banked
|
|||||||
is_white = 1;
|
is_white = 1;
|
||||||
uint8_t word = 0;
|
uint8_t word = 0;
|
||||||
cmd_words_b[0] = -1;
|
cmd_words_b[0] = -1;
|
||||||
while (cmd_buffer[line_ptr] && line_ptr < CMD_BUF_SIZE - 1) {
|
while (cmd_buffer[line_ptr] && line_ptr < SBUF_SIZE - 1) {
|
||||||
if (is_white && cmd_buffer[line_ptr] != ' ') {
|
if (is_white && cmd_buffer[line_ptr] != ' ') {
|
||||||
is_white = 0;
|
is_white = 0;
|
||||||
cmd_words_b[word++] = line_ptr;
|
cmd_words_b[word++] = line_ptr;
|
||||||
@@ -805,7 +658,7 @@ uint8_t cmd_tokenize(void) __banked
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (line_ptr == CMD_BUF_SIZE - 1)
|
if (line_ptr == SBUF_SIZE - 1)
|
||||||
return 1;
|
return 1;
|
||||||
cmd_words_b[word++] = line_ptr;
|
cmd_words_b[word++] = line_ptr;
|
||||||
cmd_words_b[word++] = -1;
|
cmd_words_b[word++] = -1;
|
||||||
@@ -842,8 +695,9 @@ void print_gpio_status(void) {
|
|||||||
|
|
||||||
// Show software version
|
// Show software version
|
||||||
void print_sw_version(void) __banked {
|
void print_sw_version(void) __banked {
|
||||||
print_string("Software version: " VERSION_SW);
|
print_string("Software version: ");
|
||||||
print_string("\nBuild date: " BUILD_DATE);
|
print_string(VERSION_SW);
|
||||||
|
print_string("\nBuild: " __DATE__ " " __TIME__);
|
||||||
print_string("\nHardware: ");
|
print_string("\nHardware: ");
|
||||||
print_string(machine.machine_name);
|
print_string(machine.machine_name);
|
||||||
write_char('\n');
|
write_char('\n');
|
||||||
@@ -886,27 +740,47 @@ void cmd_parser(void) __banked
|
|||||||
}
|
}
|
||||||
} else if (cmd_compare(0, "stat")) {
|
} else if (cmd_compare(0, "stat")) {
|
||||||
port_stats_print();
|
port_stats_print();
|
||||||
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 's') {
|
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'r') {
|
||||||
print_string("\nSECURITY REGISTERS\n");
|
print_string("\nPRINT SECURITY REGISTERS\n");
|
||||||
// The following will only show something else than 0xff if it was programmed for a managed switch
|
// The following will only show something else than 0xff if it was programmed for a managed switch
|
||||||
print_string("Region 1: ");
|
|
||||||
flash_region.addr = 0x0001000;
|
flash_region.addr = 0x0001000;
|
||||||
flash_region.len = 40;
|
flash_region.len = 40;
|
||||||
flash_read_security();
|
flash_read_security();
|
||||||
print_string("\nRegion 2: ");
|
|
||||||
flash_region.addr = 0x0002000;
|
flash_region.addr = 0x0002000;
|
||||||
flash_region.len = 40;
|
flash_region.len = 40;
|
||||||
flash_read_security();
|
flash_read_security();
|
||||||
print_string("\nRegion 3: ");
|
|
||||||
flash_region.addr = 0x0003000;
|
flash_region.addr = 0x0003000;
|
||||||
flash_region.len = 40;
|
flash_region.len = 40;
|
||||||
flash_read_security();
|
flash_read_security();
|
||||||
|
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'd') {
|
||||||
|
print_string("\nDUMPING FLASH\n");
|
||||||
|
flash_region.addr = 0;
|
||||||
|
flash_region.len = 255;
|
||||||
|
flash_dump(255);
|
||||||
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'j') {
|
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'j') {
|
||||||
print_string("\nJEDEC ID\n");
|
print_string("\nJEDEC ID\n");
|
||||||
flash_read_jedecid();
|
flash_read_jedecid();
|
||||||
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'u') {
|
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'u') {
|
||||||
print_string("\nUNIQUE ID (note: only 4 bytes are likely correct here!)\n");
|
print_string("\nUNIQUE ID\n");
|
||||||
flash_read_uid();
|
flash_read_uid();
|
||||||
|
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 's') {
|
||||||
|
print_string("\nFLASH FAST MODE\n"); // Switch to flash 62.5 MHz mode
|
||||||
|
flash_init(1);
|
||||||
|
print_string("\nNow dumping flash\n");
|
||||||
|
flash_region.addr = 0;
|
||||||
|
flash_region.len = 255;
|
||||||
|
flash_dump(255);
|
||||||
|
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'e') {
|
||||||
|
print_string("\nFLASH erase\n");
|
||||||
|
flash_region.addr = 0x20000;
|
||||||
|
flash_sector_erase();
|
||||||
|
} else if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'w') {
|
||||||
|
print_string("\nFLASH write\n");
|
||||||
|
for (uint8_t i = 0; i < 20; i++)
|
||||||
|
flash_buf[i] = greeting[i];
|
||||||
|
flash_region.addr = 0x200000;
|
||||||
|
flash_region.len = 20;
|
||||||
|
flash_write_bytes(flash_buf);
|
||||||
} else if (cmd_compare(0, "port") && cmd_words_b[1] > 0) {
|
} else if (cmd_compare(0, "port") && cmd_words_b[1] > 0) {
|
||||||
parse_port();
|
parse_port();
|
||||||
} else if (cmd_compare(0, "mtu") && cmd_words_b[1] > 0) {
|
} else if (cmd_compare(0, "mtu") && cmd_words_b[1] > 0) {
|
||||||
@@ -993,24 +867,6 @@ void cmd_parser(void) __banked
|
|||||||
stp_off();
|
stp_off();
|
||||||
stpEnabled = 0;
|
stpEnabled = 0;
|
||||||
}
|
}
|
||||||
} else if (cmd_compare(0, "dhcp")) {
|
|
||||||
if (cmd_words_b[1] > 0 && cmd_compare(1, "on")) {
|
|
||||||
dhcp_start();
|
|
||||||
} else {
|
|
||||||
print_string("DHCP disabled\n");
|
|
||||||
dhcp_stop();
|
|
||||||
}
|
|
||||||
} else if (cmd_compare(0, "dhcpd")) {
|
|
||||||
if (cmd_words_b[1] > 0 && cmd_compare(1, "on")) {
|
|
||||||
if (cmd_words_b[2] > 0)
|
|
||||||
atoi_short(&dhcpd_vlan, cmd_words_b[2]);
|
|
||||||
else
|
|
||||||
dhcpd_vlan = 0;
|
|
||||||
dhcpd_start();
|
|
||||||
} else {
|
|
||||||
print_string("DHCP Server disabled\n");
|
|
||||||
dhcpd_stop();
|
|
||||||
}
|
|
||||||
} else if (cmd_compare(0, "pvid") && cmd_words_b[1] > 0 && cmd_words_b[2] > 0) {
|
} else if (cmd_compare(0, "pvid") && cmd_words_b[1] > 0 && cmd_words_b[2] > 0) {
|
||||||
__xdata uint16_t pvid;
|
__xdata uint16_t pvid;
|
||||||
uint8_t port;
|
uint8_t port;
|
||||||
@@ -1039,9 +895,27 @@ void cmd_parser(void) __banked
|
|||||||
} else if (cmd_compare(0, "passwd")) {
|
} else if (cmd_compare(0, "passwd")) {
|
||||||
parse_passwd();
|
parse_passwd();
|
||||||
} else if (cmd_compare(0, "eee")) {
|
} else if (cmd_compare(0, "eee")) {
|
||||||
parse_eee();
|
int8_t port = -1;
|
||||||
} else if (cmd_compare(0, "bw")) {
|
if (cmd_words_b[3] > 0) {
|
||||||
parse_bw();
|
port = cmd_buffer[cmd_words_b[2]] - '1';
|
||||||
|
port = machine.phys_to_log_port[port];
|
||||||
|
}
|
||||||
|
if (cmd_words_b[1] > 0 && cmd_compare(1, "on")) {
|
||||||
|
if (port >= 0)
|
||||||
|
port_eee_enable(port);
|
||||||
|
else
|
||||||
|
port_eee_enable_all();
|
||||||
|
} else if (cmd_words_b[1] > 0 && cmd_compare(1, "off")) {
|
||||||
|
if (port >= 0)
|
||||||
|
port_eee_disable(port);
|
||||||
|
else
|
||||||
|
port_eee_disable_all();
|
||||||
|
} else if (cmd_words_b[1] > 0 && cmd_compare(1, "status")) {
|
||||||
|
if (port >= 0)
|
||||||
|
port_eee_status(port);
|
||||||
|
else
|
||||||
|
port_eee_status_all();
|
||||||
|
}
|
||||||
} else if (cmd_compare(0, "version")) {
|
} else if (cmd_compare(0, "version")) {
|
||||||
print_sw_version();
|
print_sw_version();
|
||||||
} else if (cmd_compare(0, "time")) {
|
} else if (cmd_compare(0, "time")) {
|
||||||
@@ -1083,16 +957,6 @@ void cmd_parser(void) __banked
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void clear_command_history(void) __banked
|
|
||||||
{
|
|
||||||
for (cmd_history_ptr = 0; cmd_history_ptr < CMD_HISTORY_SIZE; cmd_history_ptr++)
|
|
||||||
cmd_history[cmd_history_ptr] = 0;
|
|
||||||
cmd_history_ptr = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define FLASH_READ_BURST_SIZE 0x100
|
#define FLASH_READ_BURST_SIZE 0x100
|
||||||
#define PASSWORD "1234"
|
#define PASSWORD "1234"
|
||||||
void execute_config(void) __banked
|
void execute_config(void) __banked
|
||||||
@@ -1112,7 +976,7 @@ void execute_config(void) __banked
|
|||||||
__xdata uint8_t cfg_idx = 0;
|
__xdata uint8_t cfg_idx = 0;
|
||||||
uint8_t c = 0;
|
uint8_t c = 0;
|
||||||
do {
|
do {
|
||||||
for (uint8_t cmd_idx = 0; cmd_idx < (CMD_BUF_SIZE - 1); cmd_idx++) {
|
for (uint8_t cmd_idx = 0; cmd_idx < (SBUF_SIZE - 1); cmd_idx++) {
|
||||||
c = flash_buf[cfg_idx++];
|
c = flash_buf[cfg_idx++];
|
||||||
if (c == 0 || c == '\n') {
|
if (c == 0 || c == '\n') {
|
||||||
cmd_buffer[cmd_idx] = '\0';
|
cmd_buffer[cmd_idx] = '\0';
|
||||||
@@ -1133,6 +997,8 @@ void execute_config(void) __banked
|
|||||||
|
|
||||||
config_done:
|
config_done:
|
||||||
// Start saving commands to cmd_history
|
// Start saving commands to cmd_history
|
||||||
clear_command_history();
|
|
||||||
save_cmd = 1;
|
save_cmd = 1;
|
||||||
|
for (cmd_history_ptr = 0; cmd_history_ptr < CMD_HISTORY_SIZE; cmd_history_ptr++)
|
||||||
|
cmd_history[cmd_history_ptr] = 0;
|
||||||
|
cmd_history_ptr = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,11 @@
|
|||||||
|
|
||||||
#include "rtl837x_common.h"
|
#include "rtl837x_common.h"
|
||||||
|
|
||||||
extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
extern __xdata uint8_t cmd_buffer[SBUF_SIZE];
|
||||||
extern __xdata uint8_t cmd_available;
|
extern __xdata uint8_t cmd_available;
|
||||||
|
|
||||||
uint8_t cmd_tokenize(void) __banked;
|
uint8_t cmd_tokenize(void) __banked;
|
||||||
void cmd_parser(void) __banked;
|
void cmd_parser(void) __banked;
|
||||||
void execute_config(void) __banked;
|
void execute_config(void) __banked;
|
||||||
void print_sw_version(void) __banked;
|
void print_sw_version(void) __banked;
|
||||||
void clear_command_history(void) __banked;
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,44 @@
|
|||||||
|
.globl __start__stack
|
||||||
|
;--------------------------------------------------------
|
||||||
|
; Stack segment in internal ram
|
||||||
|
;--------------------------------------------------------
|
||||||
|
.area SSEG (DATA)
|
||||||
|
__start__stack:
|
||||||
|
.ds 1
|
||||||
|
|
||||||
|
.area VECTOR (CODE)
|
||||||
|
.globl __interrupt_vect
|
||||||
|
__interrupt_vect:
|
||||||
|
ljmp __sdcc_gsinit_startup
|
||||||
|
ljmp _isr_ext0 ; 0x03
|
||||||
|
.ds 5
|
||||||
|
ljmp _isr_timer0 ; 0x0b
|
||||||
|
.ds 5
|
||||||
|
ljmp _isr_ext1 ; 0x13
|
||||||
|
.ds 5
|
||||||
|
reti ; 0x1b TIMER 1 IRQ
|
||||||
|
.ds 7
|
||||||
|
ljmp _isr_serial ; 0x23
|
||||||
|
.ds 5
|
||||||
|
ljmp _isr_timer2 ; 0x2b TIMER 2 IRQ
|
||||||
|
.ds 5
|
||||||
|
reti ; 0x33 NOT used by DW8051
|
||||||
|
.ds 7
|
||||||
|
reti ; 0x3b Serial port 1 RX/TX IRQ
|
||||||
|
.ds 7
|
||||||
|
ljmp _isr_ext2 ; 0x43
|
||||||
|
.ds 5
|
||||||
|
ljmp _isr_ext3 ; 0x4b
|
||||||
|
|
||||||
|
.globl __start__stack
|
||||||
|
|
||||||
|
.area GSINIT0 (CODE)
|
||||||
|
|
||||||
|
__sdcc_gsinit_startup::
|
||||||
|
mov sp,#__start__stack - 1
|
||||||
|
|
||||||
.area GSFINAL (CODE)
|
.area GSFINAL (CODE)
|
||||||
|
ljmp _bootloader
|
||||||
|
|
||||||
__sdcc_banked_call::
|
__sdcc_banked_call::
|
||||||
push _PSBANK
|
push _PSBANK
|
||||||
|
|||||||
@@ -12,12 +12,10 @@
|
|||||||
#include "uip.h"
|
#include "uip.h"
|
||||||
#include "uip/uip.h"
|
#include "uip/uip.h"
|
||||||
|
|
||||||
|
extern __code struct uip_eth_addr uip_ethaddr;
|
||||||
__xdata struct dhcp_state dhcp_state;
|
__xdata struct dhcp_state dhcp_state;
|
||||||
__xdata uip_ipaddr_t server;
|
__xdata uip_ipaddr_t server;
|
||||||
|
|
||||||
#define BOOTP_REQUEST 1
|
|
||||||
#define BOOTP_REPY 2
|
|
||||||
|
|
||||||
#define DHCP_HW_TYPE_ETH 1
|
#define DHCP_HW_TYPE_ETH 1
|
||||||
|
|
||||||
#define DHCP_SUBNET_MASK 1
|
#define DHCP_SUBNET_MASK 1
|
||||||
@@ -35,7 +33,6 @@ __xdata uip_ipaddr_t server;
|
|||||||
#define DHCP_MESSAGE_DISCOVER 1
|
#define DHCP_MESSAGE_DISCOVER 1
|
||||||
#define DHCP_MESSAGE_OFFER 2
|
#define DHCP_MESSAGE_OFFER 2
|
||||||
#define DHCP_MESSAGE_REQUEST 3
|
#define DHCP_MESSAGE_REQUEST 3
|
||||||
#define DHCP_MESSAGE_NACK 4
|
|
||||||
#define DHCP_MESSAGE_ACK 5
|
#define DHCP_MESSAGE_ACK 5
|
||||||
#define DHCP_LEASE 51
|
#define DHCP_LEASE 51
|
||||||
#define DHCP_LEASE_LEN 4
|
#define DHCP_LEASE_LEN 4
|
||||||
@@ -47,23 +44,15 @@ __xdata uip_ipaddr_t server;
|
|||||||
#define DHCP_CLIENT_ID_LEN 7
|
#define DHCP_CLIENT_ID_LEN 7
|
||||||
#define DHCP_REQUEST_IP 50
|
#define DHCP_REQUEST_IP 50
|
||||||
#define DHCP_REQUEST_IP_LEN 4
|
#define DHCP_REQUEST_IP_LEN 4
|
||||||
#define DHCP_CLIENT_NAME 12
|
|
||||||
#define DHCP_PARAMS 55
|
#define DHCP_PARAMS 55
|
||||||
#define DHCP_VENDOR_ID 60
|
|
||||||
#define DHCP_CLIENT_ID 61
|
|
||||||
#define DHCP_PARAM_SUBNET 1
|
#define DHCP_PARAM_SUBNET 1
|
||||||
#define DHCP_PARAM_ROUTER 3
|
#define DHCP_PARAM_ROUTER 3
|
||||||
#define DHCP_PARAM_DNS 6
|
#define DHCP_PARAM_DNS 6
|
||||||
#define DHCP_END 255
|
#define DHCP_END 255
|
||||||
|
|
||||||
#define LEASE_TIME 43200
|
|
||||||
#define RENEWAL_TIME 21600
|
|
||||||
#define REBIND_TIME 21600
|
|
||||||
|
|
||||||
#pragma codeseg BANK2
|
#pragma codeseg BANK2
|
||||||
#pragma constseg BANK2
|
#pragma constseg BANK2
|
||||||
|
|
||||||
|
|
||||||
struct dhcp_pkt {
|
struct dhcp_pkt {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint8_t hw;
|
uint8_t hw;
|
||||||
@@ -83,13 +72,16 @@ struct dhcp_pkt {
|
|||||||
uint8_t cookie[4];
|
uint8_t cookie[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define DHCP_P ((__xdata struct dhcp_pkt *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE])
|
||||||
|
#define DHCP_OPT ((__xdata uint8_t *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE + sizeof (struct dhcp_pkt)])
|
||||||
|
*/
|
||||||
|
|
||||||
#define DHCP_P ((__xdata struct dhcp_pkt *)uip_appdata)
|
#define DHCP_P ((__xdata struct dhcp_pkt *)uip_appdata)
|
||||||
#define DHCP_OPT ((__xdata uint8_t *)(uip_appdata) + sizeof (struct dhcp_pkt))
|
#define DHCP_OPT ((__xdata uint8_t *)(uip_appdata) + sizeof (struct dhcp_pkt))
|
||||||
|
|
||||||
__xdata uint32_t long_value;
|
__xdata uint32_t long_value;
|
||||||
__xdata struct dhcpd_cstate cstates[DHCPD_MAX_CLIENTS];
|
|
||||||
__xdata uint8_t client_idx;
|
|
||||||
__xdata uint16_t dhcpd_vlan;
|
|
||||||
|
|
||||||
void dhcp_print_ip(uint8_t *a)
|
void dhcp_print_ip(uint8_t *a)
|
||||||
{
|
{
|
||||||
@@ -100,19 +92,19 @@ void dhcp_print_ip(uint8_t *a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dhcp_prepare_msg(void)
|
void dhcp_prepare_request(void)
|
||||||
{
|
{
|
||||||
DHCP_P->type = BOOTP_REQUEST;
|
DHCP_P->type = 1;
|
||||||
DHCP_P->hw = DHCP_HW_TYPE_ETH;
|
DHCP_P->hw = DHCP_HW_TYPE_ETH;
|
||||||
DHCP_P->hw_len = 6;
|
DHCP_P->hw_len = 6;
|
||||||
DHCP_P->hops = 0;
|
DHCP_P->hops = 0;
|
||||||
|
|
||||||
DHCP_P->tid = dhcp_state.transaction_id; // In network byte order
|
DHCP_P->tid = HTONS(dhcp_state.transaction_id);
|
||||||
DHCP_P->delay = HTONS(0);
|
DHCP_P->delay = HTONS(0);
|
||||||
DHCP_P->flags = 0;
|
DHCP_P->flags = 0;
|
||||||
// Clear fields client_ip to bootp_file
|
// Clear fields client_ip to bootp_file
|
||||||
memset(DHCP_P->client_ip, 0, 224);
|
memset(DHCP_P->client_ip, 0, 224);
|
||||||
memcpy(DHCP_P->client_addr, uip_ethaddr.addr, 6);
|
memcpyc(DHCP_P->client_addr, uip_ethaddr.addr, 6);
|
||||||
DHCP_P->cookie[0] = 0x63;
|
DHCP_P->cookie[0] = 0x63;
|
||||||
DHCP_P->cookie[1] = 0x82;
|
DHCP_P->cookie[1] = 0x82;
|
||||||
DHCP_P->cookie[2] = 0x53;
|
DHCP_P->cookie[2] = 0x53;
|
||||||
@@ -125,7 +117,7 @@ void dhcp_addopt_client_id(void)
|
|||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_CLIENT_ID;
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_CLIENT_ID;
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_CLIENT_ID_LEN;
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_CLIENT_ID_LEN;
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_HW_TYPE_ETH;
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_HW_TYPE_ETH;
|
||||||
memcpy(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 6);
|
memcpyc(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 6);
|
||||||
dhcp_state.opt_ptr += 6;
|
dhcp_state.opt_ptr += 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +130,7 @@ void dhcp_addopt_request_ip(void)
|
|||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[1];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[1];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[2];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[2];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[3];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[3];
|
||||||
|
memcpyc(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -149,68 +142,14 @@ void dhcp_addopt_server_id(void)
|
|||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[1];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[1];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[2];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[2];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[3];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[3];
|
||||||
}
|
memcpyc(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
|
||||||
|
|
||||||
|
|
||||||
void dhcp_addopt_subnet(void)
|
|
||||||
{
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_SUBNET_MASK;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_SUBNET_MASK_LEN;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.subnet[0];
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.subnet[1];
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.subnet[2];
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.subnet[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dhcp_addopt_router(void)
|
|
||||||
{
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_ROUTER;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_ROUTER_LEN;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.router[0];
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.router[1];
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.router[2];
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.router[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dhcp_addopt_lease(void)
|
|
||||||
{
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_LEASE;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_LEASE_LEN;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = LEASE_TIME >> 8;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = LEASE_TIME & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dhcp_addopt_renewal(void)
|
|
||||||
{
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_RENEWAL;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_RENEWAL_LEN;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = RENEWAL_TIME >> 8;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = RENEWAL_TIME & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dhcp_addopt_rebind(void)
|
|
||||||
{
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_REBIND;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_REBIND_LEN;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = REBIND_TIME >> 8;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = REBIND_TIME & 0xff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dhcp_send_discover(void)
|
void dhcp_send_discover(void)
|
||||||
{
|
{
|
||||||
print_string("dhcp_send_discover called\n");
|
print_string("dhcp_send_discover called\n");
|
||||||
dhcp_prepare_msg();
|
dhcp_prepare_request();
|
||||||
|
|
||||||
dhcp_state.opt_ptr = 0;
|
dhcp_state.opt_ptr = 0;
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE;
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE;
|
||||||
@@ -245,7 +184,7 @@ void dhcp_send_discover(void)
|
|||||||
void dhcp_send_request(void)
|
void dhcp_send_request(void)
|
||||||
{
|
{
|
||||||
print_string("dhcp_send_request called\n");
|
print_string("dhcp_send_request called\n");
|
||||||
dhcp_prepare_msg();
|
dhcp_prepare_request();
|
||||||
|
|
||||||
dhcp_state.opt_ptr = 0;
|
dhcp_state.opt_ptr = 0;
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE;
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE;
|
||||||
@@ -278,41 +217,6 @@ void dhcp_send_request(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dhcp_send_reply(uint8_t rtype)
|
|
||||||
{
|
|
||||||
print_string("dhcp_send_reply called\n");
|
|
||||||
dhcp_prepare_msg();
|
|
||||||
DHCP_P->type = BOOTP_REPY;
|
|
||||||
DHCP_P->client_addr[0] = cstates[client_idx].mac[0]; DHCP_P->client_addr[1] = cstates[client_idx].mac[1];
|
|
||||||
DHCP_P->client_addr[2] = cstates[client_idx].mac[2]; DHCP_P->client_addr[3] = cstates[client_idx].mac[3];
|
|
||||||
DHCP_P->client_addr[4] = cstates[client_idx].mac[4]; DHCP_P->client_addr[5] = cstates[client_idx].mac[5];
|
|
||||||
|
|
||||||
if (rtype != DHCP_MESSAGE_NACK) {
|
|
||||||
DHCP_P->your_ip[0] = dhcp_state.server[0];
|
|
||||||
DHCP_P->your_ip[1] = dhcp_state.server[1];
|
|
||||||
DHCP_P->your_ip[2] = dhcp_state.server[2];
|
|
||||||
DHCP_P->your_ip[3] = DHCPD_START_IP + client_idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
dhcp_state.opt_ptr = 0;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE_LEN;
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = rtype;
|
|
||||||
|
|
||||||
if (rtype != DHCP_MESSAGE_NACK) {
|
|
||||||
dhcp_addopt_subnet();
|
|
||||||
dhcp_addopt_router();
|
|
||||||
dhcp_addopt_server_id();
|
|
||||||
dhcp_addopt_rebind();
|
|
||||||
dhcp_addopt_lease();
|
|
||||||
dhcp_addopt_renewal();
|
|
||||||
}
|
|
||||||
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_END;
|
|
||||||
uip_udp_send(sizeof(struct dhcp_pkt) + dhcp_state.opt_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ip_opt(uint8_t * __xdata ip)
|
void ip_opt(uint8_t * __xdata ip)
|
||||||
{
|
{
|
||||||
dhcp_state.opt_ptr++;
|
dhcp_state.opt_ptr++;
|
||||||
@@ -340,22 +244,6 @@ void long_opt(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void print_txt_opt(void)
|
|
||||||
{
|
|
||||||
dhcp_state.opt_ptr++;
|
|
||||||
for (uint8_t l = DHCP_OPT[dhcp_state.opt_ptr++]; l ; l--)
|
|
||||||
write_char(DHCP_OPT[dhcp_state.opt_ptr++]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void print_eth_opt(void)
|
|
||||||
{
|
|
||||||
dhcp_state.opt_ptr++;
|
|
||||||
for (uint8_t l = DHCP_OPT[dhcp_state.opt_ptr++]; l ; l--)
|
|
||||||
print_byte(DHCP_OPT[dhcp_state.opt_ptr++]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void parse_opts(void)
|
void parse_opts(void)
|
||||||
{
|
{
|
||||||
while (DHCP_OPT[dhcp_state.opt_ptr] && DHCP_OPT[dhcp_state.opt_ptr] != DHCP_END) {
|
while (DHCP_OPT[dhcp_state.opt_ptr] && DHCP_OPT[dhcp_state.opt_ptr] != DHCP_END) {
|
||||||
@@ -375,9 +263,6 @@ void parse_opts(void)
|
|||||||
case DHCP_BROADCAST:
|
case DHCP_BROADCAST:
|
||||||
ip_opt(&dhcp_state.broadcast[0]);
|
ip_opt(&dhcp_state.broadcast[0]);
|
||||||
break;
|
break;
|
||||||
case DHCP_REQUEST_IP:
|
|
||||||
ip_opt(&dhcp_state.current_ip[0]);
|
|
||||||
break;
|
|
||||||
case DHCP_LEASE:
|
case DHCP_LEASE:
|
||||||
long_opt();
|
long_opt();
|
||||||
dhcp_state.lease = long_value;
|
dhcp_state.lease = long_value;
|
||||||
@@ -390,27 +275,6 @@ void parse_opts(void)
|
|||||||
long_opt();
|
long_opt();
|
||||||
dhcp_state.renewal = long_value;
|
dhcp_state.renewal = long_value;
|
||||||
break;
|
break;
|
||||||
case DHCP_CLIENT_NAME:
|
|
||||||
print_string("Client name: ");
|
|
||||||
print_txt_opt();
|
|
||||||
write_char('\n');
|
|
||||||
break;
|
|
||||||
case DHCP_VENDOR_ID:
|
|
||||||
print_string("Vendor ID: ");
|
|
||||||
print_txt_opt();
|
|
||||||
write_char('\n');
|
|
||||||
break;
|
|
||||||
case DHCP_CLIENT_ID:
|
|
||||||
print_string("Client ID: ");
|
|
||||||
print_eth_opt();
|
|
||||||
write_char('\n');
|
|
||||||
break;
|
|
||||||
case DHCP_PARAMS:
|
|
||||||
print_string("PARAMS request (ignored)\n");
|
|
||||||
dhcp_state.opt_ptr++;
|
|
||||||
dhcp_state.opt_ptr += DHCP_OPT[dhcp_state.opt_ptr];
|
|
||||||
dhcp_state.opt_ptr++;
|
|
||||||
break;
|
|
||||||
case DHCP_END:
|
case DHCP_END:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -423,39 +287,9 @@ void parse_opts(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void find_client(void)
|
void parse_dhcp(void)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
if (!DHCP_P->tid == HTONS(dhcp_state.transaction_id))
|
||||||
for (i = 0; i < DHCPD_MAX_CLIENTS; i++) {
|
|
||||||
if (cstates[i].mac[0] == DHCP_P->client_addr[0] && cstates[i].mac[1] == DHCP_P->client_addr[1]
|
|
||||||
&& cstates[i].mac[2] == DHCP_P->client_addr[2] && cstates[i].mac[3] == DHCP_P->client_addr[3]
|
|
||||||
&& cstates[i].mac[4] == DHCP_P->client_addr[4] && cstates[i].mac[5] == DHCP_P->client_addr[5]
|
|
||||||
)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i < DHCPD_MAX_CLIENTS) {
|
|
||||||
client_idx = i;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
client_idx = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void find_slot(void)
|
|
||||||
{
|
|
||||||
for (client_idx = 0; client_idx < DHCPD_MAX_CLIENTS; client_idx++) {
|
|
||||||
if (!cstates[client_idx].cstate)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
client_idx = 255;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void parse_dhcp_response(void)
|
|
||||||
{
|
|
||||||
if (!DHCP_P->tid == dhcp_state.transaction_id)
|
|
||||||
return;
|
return;
|
||||||
if (DHCP_P->cookie[0] != 0x63 || DHCP_P->cookie[1] != 0x82 || DHCP_P->cookie[2] != 0x53 || DHCP_P->cookie[3] != 0x63)
|
if (DHCP_P->cookie[0] != 0x63 || DHCP_P->cookie[1] != 0x82 || DHCP_P->cookie[2] != 0x53 || DHCP_P->cookie[3] != 0x63)
|
||||||
return;
|
return;
|
||||||
@@ -494,50 +328,13 @@ void parse_dhcp_response(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void parse_dhcp_request(void)
|
|
||||||
{
|
|
||||||
print_string("parse_dhcp_request called\n");
|
|
||||||
if (DHCP_P->cookie[0] != 0x63 || DHCP_P->cookie[1] != 0x82 || DHCP_P->cookie[2] != 0x53 || DHCP_P->cookie[3] != 0x63)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dhcp_state.opt_ptr = 0;
|
|
||||||
if (DHCP_OPT[dhcp_state.opt_ptr++] != DHCP_MESSAGE_TYPE || DHCP_OPT[dhcp_state.opt_ptr++] != DHCP_MESSAGE_TYPE_LEN)
|
|
||||||
return;
|
|
||||||
if (DHCP_OPT[dhcp_state.opt_ptr] == DHCP_MESSAGE_DISCOVER) {
|
|
||||||
dhcp_state.opt_ptr++;
|
|
||||||
find_client();
|
|
||||||
if (client_idx == 255)
|
|
||||||
find_slot();
|
|
||||||
// If there is no empty slot, we play possum and do not answer to the request
|
|
||||||
if (client_idx == 255)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cstates[client_idx].cstate = CSTATE_OFFERED;
|
|
||||||
cstates[client_idx].mac[0] = DHCP_P->client_addr[0]; cstates[client_idx].mac[1] = DHCP_P->client_addr[1];
|
|
||||||
cstates[client_idx].mac[2] = DHCP_P->client_addr[2]; cstates[client_idx].mac[3] = DHCP_P->client_addr[3];
|
|
||||||
cstates[client_idx].mac[4] = DHCP_P->client_addr[4]; cstates[client_idx].mac[5] = DHCP_P->client_addr[5];
|
|
||||||
dhcp_state.transaction_id = DHCP_P->tid;
|
|
||||||
parse_opts();
|
|
||||||
dhcp_send_reply(DHCP_MESSAGE_OFFER);
|
|
||||||
} else if (DHCP_OPT[dhcp_state.opt_ptr++] == DHCP_MESSAGE_REQUEST) {
|
|
||||||
find_client();
|
|
||||||
if (client_idx == 255) {
|
|
||||||
dhcp_send_reply(DHCP_MESSAGE_NACK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
parse_opts();
|
|
||||||
dhcp_send_reply(DHCP_MESSAGE_ACK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dhcp_start(void) __banked
|
void dhcp_start(void) __banked
|
||||||
{
|
{
|
||||||
uip_ipaddr(server, 255,255,255,255);
|
uip_ipaddr(server, 255,255,255,255);
|
||||||
dhcp_state.conn = uip_udp_new(&server, HTONS(DHCP_SERVER_PORT));
|
dhcp_state.conn = uip_udp_new(&server, HTONS(DHCPC_SERVER_PORT));
|
||||||
dhcp_state.current_ip[0] = dhcp_state.current_ip[1] = dhcp_state.current_ip[2] = dhcp_state.current_ip[3] = 0;
|
dhcp_state.current_ip[0] = dhcp_state.current_ip[1] = dhcp_state.current_ip[2] = dhcp_state.current_ip[3] = 0;
|
||||||
if(dhcp_state.conn) {
|
if(dhcp_state.conn) {
|
||||||
uip_udp_bind(dhcp_state.conn, HTONS(DHCP_CLIENT_PORT));
|
uip_udp_bind(dhcp_state.conn, HTONS(DHCPC_CLIENT_PORT));
|
||||||
} else {
|
} else {
|
||||||
print_string("dhcp_start failed to set up socket\n");
|
print_string("dhcp_start failed to set up socket\n");
|
||||||
return;
|
return;
|
||||||
@@ -549,43 +346,6 @@ void dhcp_start(void) __banked
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dhcpd_start(void) __banked
|
|
||||||
{
|
|
||||||
memset(&cstates[0], 0, sizeof (struct dhcpd_cstate) * DHCPD_MAX_CLIENTS);
|
|
||||||
dhcp_state.conn = uip_udp_new(0, 0);
|
|
||||||
if(dhcp_state.conn) {
|
|
||||||
uip_udp_bind(dhcp_state.conn, HTONS(DHCP_SERVER_PORT));
|
|
||||||
} else {
|
|
||||||
print_string("dhcpd_start failed to set up socket\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!dhcpd_vlan)
|
|
||||||
print_string("dhcpd: enabling for all VLANs\n");
|
|
||||||
else
|
|
||||||
print_string("dhcpd: enabling for VLAN "); print_short(dhcpd_vlan); write_char('\n');
|
|
||||||
dhcp_state.state = DHCP_SERVER;
|
|
||||||
|
|
||||||
dhcp_state.server[1] = uip_hostaddr[0] >> 8; dhcp_state.server[0] = uip_hostaddr[0] & 0xff;
|
|
||||||
dhcp_state.server[3] = uip_hostaddr[1] >> 8; dhcp_state.server[2] = uip_hostaddr[1] & 0xff;
|
|
||||||
|
|
||||||
dhcp_state.router[1] = uip_draddr[0] >> 8; dhcp_state.router[0] = uip_draddr[0] & 0xff;
|
|
||||||
dhcp_state.router[3] = uip_draddr[1] >> 8; dhcp_state.router[2] = uip_draddr[1] & 0xff;
|
|
||||||
|
|
||||||
dhcp_state.subnet[1] = uip_netmask[0] >> 8; dhcp_state.subnet[0] = uip_netmask[0] & 0xff;
|
|
||||||
dhcp_state.subnet[3] = uip_netmask[1] >> 8; dhcp_state.subnet[2] = uip_netmask[1] & 0xff;
|
|
||||||
|
|
||||||
dhcp_state.broadcast[0] = dhcp_state.router[0]; dhcp_state.broadcast[1] = dhcp_state.router[1];
|
|
||||||
dhcp_state.broadcast[2] = dhcp_state.router[2]; dhcp_state.broadcast[3] = 0xff;
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < DHCPD_MAX_CLIENTS; i++) {
|
|
||||||
cstates[i].cstate = CSTATE_NONE;
|
|
||||||
}
|
|
||||||
// TODO: DNS, correct broadcast address
|
|
||||||
|
|
||||||
print_string("dhcpd_start done\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dhcp_stop(void) __banked
|
void dhcp_stop(void) __banked
|
||||||
{
|
{
|
||||||
print_string("dhcp_stop called\n");
|
print_string("dhcp_stop called\n");
|
||||||
@@ -593,13 +353,6 @@ void dhcp_stop(void) __banked
|
|||||||
dhcp_state.state = DHCP_OFF;
|
dhcp_state.state = DHCP_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dhcpd_stop(void) __banked
|
|
||||||
{
|
|
||||||
print_string("dhcpd_stop called\n");
|
|
||||||
uip_udp_remove(dhcp_state.conn);
|
|
||||||
dhcp_state.state = DHCP_OFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dhcp_callback(void) __banked
|
void dhcp_callback(void) __banked
|
||||||
{
|
{
|
||||||
@@ -608,10 +361,8 @@ void dhcp_callback(void) __banked
|
|||||||
if (uip_closed()) {
|
if (uip_closed()) {
|
||||||
print_string("Closed\n");
|
print_string("Closed\n");
|
||||||
return;
|
return;
|
||||||
} else if (dhcp_state.state == DHCP_SERVER && uip_newdata()) {
|
|
||||||
parse_dhcp_request();
|
|
||||||
} else if (uip_newdata()) {
|
} else if (uip_newdata()) {
|
||||||
parse_dhcp_response();
|
parse_dhcp();
|
||||||
} else {
|
} else {
|
||||||
if (dhcp_state.state == DHCP_START) {
|
if (dhcp_state.state == DHCP_START) {
|
||||||
dhcp_send_discover();
|
dhcp_send_discover();
|
||||||
@@ -634,4 +385,7 @@ void dhcp_callback(void) __banked
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// By default we do not send anything out
|
||||||
|
uip_len = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,27 +3,22 @@
|
|||||||
|
|
||||||
#include "uipopt.h"
|
#include "uipopt.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#define DHCPD_MAX_CLIENTS 20
|
|
||||||
#define DHCPD_START_IP 100
|
|
||||||
|
|
||||||
#define DHCP_SERVER_PORT 67
|
#define DHCPC_SERVER_PORT 67
|
||||||
#define DHCP_CLIENT_PORT 68
|
#define DHCPC_CLIENT_PORT 68
|
||||||
|
|
||||||
#define DHCP_OFF 0
|
#define DHCP_OFF 0
|
||||||
#define DHCP_START 1
|
#define DHCP_START 1
|
||||||
#define DHCP_DISCOVER_SENT 2
|
#define DHCP_DISCOVER_SENT 2
|
||||||
#define DHCP_REQUEST_SENT 3
|
#define DHCP_REQUEST_SENT 3
|
||||||
#define DHCP_LEASING 4
|
#define DHCP_LEASING 4
|
||||||
#define DHCP_SERVER 5
|
|
||||||
|
|
||||||
#define CSTATE_NONE 0
|
|
||||||
#define CSTATE_OFFERED 1
|
|
||||||
#define CSTATE_LEASED 2
|
|
||||||
|
|
||||||
void dhcp_start(void) __banked;
|
void dhcp_start(void) __banked;
|
||||||
void dhcp_stop(void) __banked;
|
void dhcp_stop(void) __banked;
|
||||||
|
// void dhcp_periodic(void) __banked;
|
||||||
void dhcp_callback(void) __banked;
|
void dhcp_callback(void) __banked;
|
||||||
|
|
||||||
|
|
||||||
struct dhcp_state {
|
struct dhcp_state {
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
uint32_t transaction_id;
|
uint32_t transaction_id;
|
||||||
@@ -43,18 +38,6 @@ struct dhcp_state {
|
|||||||
struct uip_udp_conn *conn;
|
struct uip_udp_conn *conn;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dhcpd_cstate {
|
|
||||||
uint8_t cstate;
|
|
||||||
uint16_t timer;
|
|
||||||
uint32_t transaction_id;
|
|
||||||
uint8_t mac[6];
|
|
||||||
uint8_t ip[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void dhcpd_start(void) __banked;
|
|
||||||
void dhcpd_stop(void) __banked;
|
|
||||||
|
|
||||||
typedef struct dhcp_state uip_udp_appstate_t;
|
typedef struct dhcp_state uip_udp_appstate_t;
|
||||||
|
|
||||||
/* Finally we define the application function to be called by uIP. */
|
/* Finally we define the application function to be called by uIP. */
|
||||||
|
|||||||
@@ -1,238 +0,0 @@
|
|||||||
# Egress and Ingress Bandwidth Control
|
|
||||||
The RTL8372/3 allows to control the bandwidth of data transmitted (egress) and/or
|
|
||||||
admitted (ingress) at any given port. Once admitted, packets are internally switched
|
|
||||||
at wire-speed, since the backplane of the devices has a bandwidth of 60GBit/s.
|
|
||||||
|
|
||||||
The devices schedules transmission of packets by assigning packets to 8 queues
|
|
||||||
implemented in hardware per port, which share a total of 8Mbit of memory internal
|
|
||||||
to the switching part of the SoCs. Packets are assigned to the respective queues
|
|
||||||
based on the priority assigned to a packet, which can be based on various
|
|
||||||
properties of a packet such as IEEE 802.1P priority, DSCP value, physical port
|
|
||||||
number, destination or source MAC, Ether-Type-based, CVID, SVID, IPv4 source or
|
|
||||||
destination IP, IPv4/IPv6 TOS field, IPv6 Flow Label and even TCP/UDP
|
|
||||||
source/destination port. Once in a queue, packets are scheduled for egress
|
|
||||||
based on differnent configurable algorithms.
|
|
||||||
|
|
||||||
RTLPlayground currently allows only to control the bandwidth at ingress at a port
|
|
||||||
or just before packets leave a port. There is no control of the priority assignment
|
|
||||||
or queue scheduling mechanisms. The bandwidth can be controlled in steps of 16Kbit/s
|
|
||||||
from 16Kbit/s to 10Gbp/s.
|
|
||||||
|
|
||||||
The bandwidth control as currently implemented allows e.g. to assign a certain
|
|
||||||
share of bandwidth to an attached device (e.g. to share an uplink), or simulate
|
|
||||||
connections with low bandwidth and even bad connectivity with packet drops when
|
|
||||||
ingress is not controlled by Flow Control but by simply droping packets.
|
|
||||||
|
|
||||||
## Ingress/Egress control
|
|
||||||
The relevant registers for controlling Ingress and Egress at a port are:
|
|
||||||
```
|
|
||||||
#define RTL837X_IGBW_CTRL 0x4c10
|
|
||||||
#define IGBW_INC_BYPASS_PKT 0x100
|
|
||||||
#define IGBW_INC_IFG 0x80
|
|
||||||
#define IGBW_ADM_DHCP 0x20
|
|
||||||
#define IGBW_ADM_ARPREQ 0x10
|
|
||||||
#define IGBW_ADM_RMA 0x08
|
|
||||||
#define IGBW_ADM_BPDU 0x04
|
|
||||||
#define IGBW_ADM_RTKPKT 0x02
|
|
||||||
#define IGBW_ADM_IGMP 0x01
|
|
||||||
#define RTL837X_IGBW_PORT_CTRL 0x4C18
|
|
||||||
#define RTL837X_IGBW_PORT_FC_CTRL 0x4C8C
|
|
||||||
#define RTL837X_EGBW_PORT_CTRL 0x1c34
|
|
||||||
#define RTL837X_EGBW_CTRL 0x447c
|
|
||||||
#define EGBW_INC_IFG 0x02
|
|
||||||
#define EGBW_CPUMODE 0x01
|
|
||||||
```
|
|
||||||
`RTL837X_IGBW_CTRL/RTL837X_EGBW_CTRL` control the behaviour of the bandwidth control
|
|
||||||
at ingress and egress. The flags such as `IGBW_ADM_DHCP`control whether certain types
|
|
||||||
of packets such as DHCP are exempt from being ingress controlled. The
|
|
||||||
`IGBW_INC_IFG/EGBW_INC_IFG` flags control whether the Inter Frame Gaps are part of
|
|
||||||
the bandwidth being controlled. `EGBW_CPUMODE` controls whether packets generated
|
|
||||||
by the internal CPU are subject to egress control.
|
|
||||||
|
|
||||||
`RTL837X_IGBW_PORT_CTRL/RTL837X_EGBW_PORT_CTRL` configure the bandwidth for ingress
|
|
||||||
and egress at a port.
|
|
||||||
|
|
||||||
`RTL837X_IGBW_PORT_FC_CTRL` configures whether packets are bandwidth-controlled using
|
|
||||||
Flow Control (port-bit set), or simply dropped (port-bit clear).
|
|
||||||
|
|
||||||
## Ingress/Egress bandwidth API
|
|
||||||
The code currently provides the following functions:
|
|
||||||
```
|
|
||||||
void bandwidth_setup(void) __banked;
|
|
||||||
void bandwidth_ingress_set(uint8_t port, __xdata uint32_t bw) __banked;
|
|
||||||
void bandwidth_ingress_disable(uint8_t port) __banked;
|
|
||||||
void bandwidth_ingress_drop(uint8_t port) __banked;
|
|
||||||
void bandwidth_egress_set(uint8_t port, __xdata uint32_t bw) __banked;
|
|
||||||
void bandwidth_egress_disable(uint8_t port) __banked;
|
|
||||||
void bandwidth_status(uint8_t port) __banked;
|
|
||||||
```c
|
|
||||||
|
|
||||||
`bandwidth_setup()` is called at boot-time and configures excluding all special packets
|
|
||||||
that may be for the CPU and packets outgoing from the CPU to be excluded from bandwidth
|
|
||||||
control. IFG is not part of the bandwidth calculation.
|
|
||||||
|
|
||||||
`bandwidth_ingress_set()` enables ingress bandwidth control for a particular port given
|
|
||||||
the specified bandwidth. This also enabled Flow Control at a port.
|
|
||||||
|
|
||||||
`bandwidth_ingress_set()` enables egress bandwidth control for a particular port given
|
|
||||||
the specified bandwidth
|
|
||||||
|
|
||||||
`bandwidth_ingress_disable() / bandwidth_egress_disable()` disable ingress and egress
|
|
||||||
bandwidth control at a given port
|
|
||||||
|
|
||||||
`bandwidth_ingress_drop(port)` configures packets exceeding bandwidth limitations to
|
|
||||||
simply be dropped
|
|
||||||
|
|
||||||
`bandwidth_status(port)` shows the current bandwidth control status for a given port
|
|
||||||
|
|
||||||
## Bandwidth control configuration on the Serial Console
|
|
||||||
The following commands are provided on the serial console:
|
|
||||||
```
|
|
||||||
> bw [in|out|status] <port> [<hexvalue>|off|drop]
|
|
||||||
Configures or shows the status of bandwidth control
|
|
||||||
```
|
|
||||||
The bandwidth is given as the `<hexvalue>` in Kbit/s. Note that the control is only
|
|
||||||
possible at a granularity of 16 Kbit/s and the minimum value is also 16 Kbit/s. The
|
|
||||||
hexadecimal numbers must be given in full bytes, i.e. have an even number of digits.
|
|
||||||
|
|
||||||
To enable bandwidth control of ingress for physical port 2 to be set to 256 Kbit/s
|
|
||||||
do:
|
|
||||||
```
|
|
||||||
> bw in 2 0100
|
|
||||||
```
|
|
||||||
|
|
||||||
To drop packets when the bandwidth is exceeeded at port 2 do:
|
|
||||||
```
|
|
||||||
> bw in 2 drop
|
|
||||||
```
|
|
||||||
|
|
||||||
To disable bandwidth control for incoming packets on port 2 do:
|
|
||||||
```
|
|
||||||
> bw in 2 off
|
|
||||||
```
|
|
||||||
|
|
||||||
## Bandwidth configuration via the Web Interface
|
|
||||||
Not implemented, yet!
|
|
||||||
|
|
||||||
## A Test using iperf3
|
|
||||||
The following is and example how to test bandwidth control with a signle Linux device using
|
|
||||||
network namespaces to route packets between a client and a server on the same Linux device
|
|
||||||
through an external switch.
|
|
||||||
|
|
||||||
You will need 2 network intefaces on the linux device, say, 2 USB-Ethernet controllers called
|
|
||||||
eth0 and eth1:
|
|
||||||
```
|
|
||||||
$ sudo ip netns add client
|
|
||||||
$ sudo ip netns add server
|
|
||||||
|
|
||||||
$ sudo ip link set dev eth0 netns client
|
|
||||||
$ sudo ip link set dev eth1 netns server
|
|
||||||
|
|
||||||
$ sudo ip netns exec client ip link set dev eth0 up
|
|
||||||
$ sudo ip netns exec server ip link set dev eth1 up
|
|
||||||
|
|
||||||
$ sudo ip netns exec client ip addr add dev eth0 192.168.99.1/24
|
|
||||||
$ sudo ip netns exec server ip addr add dev eth1 192.168.99.2/24
|
|
||||||
|
|
||||||
$ sudo ip netns exec server iperf3 -s
|
|
||||||
```
|
|
||||||
This will start an iper3 server in the above shell.
|
|
||||||
|
|
||||||
In a different shell you can now run the iperf3 client against your server:
|
|
||||||
```
|
|
||||||
$ sudo ip netns exec client iperf -c 192.168.99.2
|
|
||||||
```
|
|
||||||
The LEDs on your switch where your network adapters are connected should start to flicker.
|
|
||||||
On a 1GBit connection, you should see:
|
|
||||||
```
|
|
||||||
$ sudo ip netns exec client iperf3 -c 192.168.99.2
|
|
||||||
Connecting to host 192.168.99.2, port 5201
|
|
||||||
[ 5] local 192.168.99.1 port 46776 connected to 192.168.99.2 port 5201
|
|
||||||
[ ID] Interval Transfer Bitrate Retr Cwnd
|
|
||||||
[ 5] 0.00-1.00 sec 114 MBytes 952 Mbits/sec 0 339 KBytes
|
|
||||||
[ 5] 1.00-2.00 sec 113 MBytes 946 Mbits/sec 0 356 KBytes
|
|
||||||
[ 5] 2.00-3.00 sec 112 MBytes 937 Mbits/sec 0 390 KBytes
|
|
||||||
[ 5] 3.00-4.00 sec 112 MBytes 942 Mbits/sec 0 390 KBytes
|
|
||||||
[ 5] 4.00-5.00 sec 112 MBytes 943 Mbits/sec 0 390 KBytes
|
|
||||||
[ 5] 5.00-6.00 sec 112 MBytes 944 Mbits/sec 0 390 KBytes
|
|
||||||
[ 5] 6.00-7.00 sec 112 MBytes 938 Mbits/sec 0 390 KBytes
|
|
||||||
[ 5] 7.00-8.00 sec 112 MBytes 942 Mbits/sec 0 410 KBytes
|
|
||||||
[ 5] 8.00-9.00 sec 113 MBytes 947 Mbits/sec 0 410 KBytes
|
|
||||||
[ 5] 9.00-10.00 sec 112 MBytes 940 Mbits/sec 0 410 KBytes
|
|
||||||
- - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
[ ID] Interval Transfer Bitrate Retr
|
|
||||||
[ 5] 0.00-10.00 sec 1.10 GBytes 943 Mbits/sec 0 sender
|
|
||||||
[ 5] 0.00-10.00 sec 1.10 GBytes 941 Mbits/sec receiver
|
|
||||||
```
|
|
||||||
|
|
||||||
Now, we limit ingress on port 1 (connected to eth0) to 4 MBit/s:
|
|
||||||
```> bw in 1 1000
|
|
||||||
bandwidth_ingress_set called, port 04
|
|
||||||
RTL837X_IGBW_PORT_CTRL:0x00100100
|
|
||||||
RTL837X_IGBW_PORT_FC_CTRL:0x00000010
|
|
||||||
```
|
|
||||||
|
|
||||||
We now get:
|
|
||||||
```
|
|
||||||
$ sudo ip netns exec client iperf3 -c 192.168.99.2
|
|
||||||
[ 5] local 192.168.99.1 port 43324 connected to 192.168.99.2 port 5201
|
|
||||||
[ ID] Interval Transfer Bitrate Retr Cwnd
|
|
||||||
[ 5] 0.00-1.00 sec 1.12 MBytes 9.43 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 1.00-2.00 sec 640 KBytes 5.24 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 2.00-3.00 sec 384 KBytes 3.15 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 3.00-4.00 sec 384 KBytes 3.15 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 4.00-5.00 sec 640 KBytes 5.24 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 5.00-6.00 sec 256 KBytes 2.10 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 6.00-7.00 sec 640 KBytes 5.24 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 7.00-8.00 sec 384 KBytes 3.15 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 8.00-9.00 sec 640 KBytes 5.24 Mbits/sec 0 160 KBytes
|
|
||||||
[ 5] 9.00-10.00 sec 256 KBytes 2.10 Mbits/sec 0 160 KBytes
|
|
||||||
- - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
[ ID] Interval Transfer Bitrate Retr
|
|
||||||
[ 5] 0.00-10.00 sec 5.25 MBytes 4.40 Mbits/sec 0 sender
|
|
||||||
[ 5] 0.00-10.16 sec 4.75 MBytes 3.92 Mbits/sec receiver
|
|
||||||
|
|
||||||
iperf Done.
|
|
||||||
```
|
|
||||||
Which is the 4Mbit/s we configured. There are no packet drops (retries) because
|
|
||||||
Flow Control is used to signal the Ethernet adapter on the incoming interface
|
|
||||||
(port 1 of the router) to slow down.
|
|
||||||
|
|
||||||
We can also configure a mere 256KBit/s and packet drop to simulate a bad connection:
|
|
||||||
```
|
|
||||||
> bw in 1 0100
|
|
||||||
bandwidth_ingress_set called, port 04
|
|
||||||
RTL837X_IGBW_PORT_CTRL:0x00100010
|
|
||||||
RTL837X_IGBW_PORT_FC_CTRL:0x00000010
|
|
||||||
|
|
||||||
> bw in 1 drop
|
|
||||||
RTL837X_IGBW_PORT_FC_CTRL:0x00000000
|
|
||||||
```
|
|
||||||
|
|
||||||
We now get:
|
|
||||||
```
|
|
||||||
$ sudo ip netns exec client iperf3 -c 192.168.99.2
|
|
||||||
Connecting to host 192.168.99.2, port 5201
|
|
||||||
[ 5] local 192.168.99.1 port 46060 connected to 192.168.99.2 port 5201
|
|
||||||
[ ID] Interval Transfer Bitrate Retr Cwnd
|
|
||||||
[ 5] 0.00-1.00 sec 384 KBytes 3.14 Mbits/sec 2 1.41 KBytes
|
|
||||||
[ 5] 1.00-2.00 sec 0.00 Bytes 0.00 bits/sec 54 1.41 KBytes
|
|
||||||
[ 5] 2.00-3.00 sec 0.00 Bytes 0.00 bits/sec 31 29.7 KBytes
|
|
||||||
[ 5] 3.00-4.00 sec 0.00 Bytes 0.00 bits/sec 2 1.41 KBytes
|
|
||||||
[ 5] 4.00-5.00 sec 0.00 Bytes 0.00 bits/sec 23 1.41 KBytes
|
|
||||||
[ 5] 5.00-6.00 sec 128 KBytes 1.05 Mbits/sec 16 14.1 KBytes
|
|
||||||
[ 5] 6.00-7.00 sec 0.00 Bytes 0.00 bits/sec 2 1.41 KBytes
|
|
||||||
[ 5] 7.00-8.00 sec 0.00 Bytes 0.00 bits/sec 11 1.41 KBytes
|
|
||||||
[ 5] 8.00-9.00 sec 128 KBytes 1.05 Mbits/sec 9 8.48 KBytes
|
|
||||||
[ 5] 9.00-10.00 sec 0.00 Bytes 0.00 bits/sec 2 1.41 KBytes
|
|
||||||
- - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
[ ID] Interval Transfer Bitrate Retr
|
|
||||||
[ 5] 0.00-10.00 sec 640 KBytes 524 Kbits/sec 152 sender
|
|
||||||
[ 5] 0.00-10.00 sec 256 KBytes 210 Kbits/sec receiver
|
|
||||||
|
|
||||||
iperf Done.
|
|
||||||
```
|
|
||||||
Which shows a large number of retries due to dropped packets and an average number
|
|
||||||
of received packets (the client sends the packets to the server, and they are sent
|
|
||||||
back to the client by the server) of 210 KBit/s, the number is higher for the transmitted
|
|
||||||
packets, because they may include dropped packets.
|
|
||||||
@@ -5,30 +5,13 @@
|
|||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| keepLINK | KP-9000-9XHML-X | Yes| 2M-PCB23-V3.1 | 2M| 8273N + 8224N |
|
| keepLINK | KP-9000-9XHML-X | Yes| 2M-PCB23-V3.1 | 2M| 8273N + 8224N |
|
||||||
|
|
||||||
## PCB
|
|
||||||
|
|
||||||
<img src="photos/2M-PCB23-V3.1-managed/2M-PCB23-V3.1-top.jpeg" width="300" />
|
|
||||||
|
|
||||||
## Port overview
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ ┌──────────┐ │
|
|
||||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ SFP (J4) │ │
|
|
||||||
│ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ PORT 9 │ │
|
|
||||||
│ │ PORT 1 │ │ PORT 2 │ │ PORT 3 │ │ PORT 4 │ │ PORT 5 │ │ PORT 6 │ │ PORT 7 │ │ PORT 8 │ │ MAC 8 │ O (PWR) │
|
|
||||||
│ O │ MAC 0 │ │ MAC 1 │ │ MAC 2 │ │ MAC 3 │ │ MAC 4 │ │ MAC 5 │ │ MAC 6 │ │ MAC 7 │ │ SerDes 1 │ O (SFP) │
|
|
||||||
│ RST └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘ │
|
|
||||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
# Connectors
|
# Connectors
|
||||||
|`J4` SFP PINs | Signal | Component | GPIO | Notes |
|
|`J4` SFP PINs | Signal | Component | GPIO | Notes |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
|2| TX_FAULT | | --- | |
|
|2| TX_FAULT | | --- | |
|
||||||
|3| TX_DISABLE | | --- | Pull down - 0R |
|
|3| TX_DISABLE | | --- | Pull down - 0R |
|
||||||
|4| MODDEF2 – SDA | b-r273 | GPIO39-SDA4 | |
|
|4| MODDEF2 – SDA | b-r273 | GPIO39 | |
|
||||||
|5| MODDEF1 – SCL | b-r274 | GPIO40-SCL3 | |
|
|5| MODDEF1 – SCL | b-r274 | GPIO40 | |
|
||||||
|6| MODDEF0 – PRESENT | B-R275 | GPIO38 | |
|
|6| MODDEF0 – PRESENT | B-R275 | GPIO38 | |
|
||||||
|7| RATE SEL | | --- | |
|
|7| RATE SEL | | --- | |
|
||||||
|8| LOS | B-R276 | GPIO38 | |
|
|8| LOS | B-R276 | GPIO38 | |
|
||||||
@@ -48,26 +31,15 @@ Note: component numbering `<L>-<REFDES>-<SIDE>`
|
|||||||
| 3 | GPIO32 | U0RXD (Input) |
|
| 3 | GPIO32 | U0RXD (Input) |
|
||||||
| 4 | 3V3 | PWR |
|
| 4 | 3V3 | PWR |
|
||||||
|
|
||||||
### T7, Slave Interface
|
### T7
|
||||||
|`T7` pin|what|Signal|Components|
|
|`T7` pin|what|Signal|
|
||||||
|---|---|---|---|
|
|---|---|---|
|
||||||
| 1 | Slave Interface | Slave SCK/SCL/MDC/EE_SCL | U7-6 |
|
| 1 | GPIO | |
|
||||||
| 2 | GND | | |
|
| 2 | GND | |
|
||||||
| 3 | Slave Interface | Slave SDI/SDA/MDIO/EE_SDA | U7-5 |
|
| 3 | GPIO | |
|
||||||
| 4 | 3V3 | | |
|
| 4 | 3V3 | |
|
||||||
| 5 | GPIO? | | |
|
| 5 | GPIO | |
|
||||||
| 6 | GPIO? | | |
|
| 6 | GPIO | |
|
||||||
|
|
||||||
`U7` can be a standard I2C eeprom memory, like `24LC32`.
|
|
||||||
|
|
||||||
The Slave Interface allows an extenal host to controll the SOC even if the internal MCU is used.
|
|
||||||
Depending on the `IF_SEL` bootstrap resistors, this can me `I2C`, `SPI` or `SMI`.
|
|
||||||
On this device it is `I2C` on address `0b1011100` or `0x5c` (7-bit notation).
|
|
||||||
|
|
||||||
* I2c Read: must be a write_read opperation `<Dev-ADDR><RegAddr15:8><RegAddr7:0>` `<DevAddr><Data7:0><Data15:8><Data23:16><Data31:24>`.
|
|
||||||
* I2c Write: `<Dev-ADDR><RegAddr15:8><RegAddr7:0><DevAddr><Data7:0><Data15:8><Data23:16><Data31:24>`.
|
|
||||||
|
|
||||||
Example register `0x0004` return chip id `0x00, 0x00, 0x72, 0x83` = `0x83720000`.
|
|
||||||
|
|
||||||
### T9
|
### T9
|
||||||
|`T9` SMI | Signal | Component | GPIO | Notes |
|
|`T9` SMI | Signal | Component | GPIO | Notes |
|
||||||
@@ -96,22 +68,22 @@ Reset-line found at `T-D6-L`, `T-R83`, `T-R97`, `T-R94`, `T-R93` active-low.
|
|||||||
| -------- | ------ | ---- | ---- | ---- | ---- | ---- | ---- |
|
| -------- | ------ | ---- | ---- | ---- | ---- | ---- | ---- |
|
||||||
| 00000001 | GPIO00 | T-R34-R, P1-LED-YL |? | | GPIO32 | B-r126-r | U0RXD |
|
| 00000001 | GPIO00 | T-R34-R, P1-LED-YL |? | | GPIO32 | B-r126-r | U0RXD |
|
||||||
| 00000002 | GPIO01 | T-R99-R, P1-LED-GR |? | | GPIO33 | | |
|
| 00000002 | GPIO01 | T-R99-R, P1-LED-GR |? | | GPIO33 | | |
|
||||||
| 00000004 | GPIO02 | |? | | GPIO34 | B-R172, To RTL8224 | SMI-MDC0 |
|
| 00000004 | GPIO02 | |? | | GPIO34 | B-R172, To RTL8225 | Already driver HIGH INT? |
|
||||||
| 00000008 | GPIO03 | T-R113-R, P2-LED-GR |? | | GPIO35 | B-R173, To RTL8224 | SMI-MDIO0 |
|
| 00000008 | GPIO03 | T-R113-R, P2-LED-GR |? | | GPIO35 | B-R173, To RTL8225 | Easy to pulldown Reset? |
|
||||||
| 00000010 | GPIO04 | T-R115-R, P3-LED-YL |? | | GPIO36 | | | |
|
| 00000010 | GPIO04 | T-R115-R, P3-LED-YL |? | | GPIO36 || | |
|
||||||
| 00000020 | GPIO05 | T-R117-R, P3-LED-GR |? | | GPIO37 | To RTL8224 ?? | Already driver low | |
|
| 00000020 | GPIO05 | T-R117-R, P3-LED-GR |? | | GPIO37 | To RTL8225 | Already driver low I2C-SCL? | |
|
||||||
| 00000040 | GPIO06 | |? | | GPIO38 | sfp-6 via B-R275, sfp-8 via B-R276 | SFP-PRESENT |
|
| 00000040 | GPIO06 | |? | | GPIO38 | sfp-6 via B-R275, sfp-8 via B-R276 | |
|
||||||
| 00000080 | GPIO07 | |? | | GPIO39 | sfp-4, b-r273, B-r143 | I2C4-SDA |
|
| 00000080 | GPIO07 | |? | | GPIO39 | sfp-4, b-r273, B-r143 | |
|
||||||
| 00000100 | GPIO08 | | | | GPIO40 | T9-2, sfp-5 b-r274, B-r146 | I2C3-SCL |
|
| 00000100 | GPIO08 | | | | GPIO40 | T9-2, sfp-5 b-r274, B-r146 | SMI-MDC |
|
||||||
| 00000200 | GPIO09 | |LEDx[^1] | | GPIO41 | T9-1, B-r143 | | I2C3-SDA (Unused) |
|
| 00000200 | GPIO09 | |LEDx[^1] | | GPIO41 | T9-1, | SMI-MDO , B-r143 |
|
||||||
| 00000400 | GPIO10 | | | | GPIO42 | U6?8?-P6, T-R | SPI-MEMORY, CLK |
|
| 00000400 | GPIO10 | | | | GPIO42 | U6?8?-P6, T-R | SPI-MEMORY, CLK |
|
||||||
| 00000800 | GPIO11 | |LEDx[^1] | | GPIO43 | U6?8?-P5, T-R | SPI-MEMORY, DI,IO0 |
|
| 00000800 | GPIO11 | |LEDx[^1] | | GPIO43 | U6?8?-P5, T-R | SPI-MEMORY, DI,IO0 |
|
||||||
| 00001000 | GPIO12 | |LEDx[^1] | | GPIO44 | U6?8?-P2, T-R | SPI-MEMORY, DO,IO1 |
|
| 00001000 | GPIO12 | |LEDx[^1] | | GPIO44 | U6?8?-P2, T-R | SPI-MEMORY, DO,IO1 |
|
||||||
| 00002000 | GPIO13 | |LEDx[^1] | | GPIO45 | U6?8?-P1, T-R | SPI-MEMORY, CS |
|
| 00002000 | GPIO13 | |LEDx[^1] | | GPIO45 | U6?8?-P1, T-R | SPI-MEMORY, CS |
|
||||||
| 00004000 | GPIO14 | |LEDx[^1] | | GPIO46 | T10-6 | SPI0-SCK |
|
| 00004000 | GPIO14 | |LEDx[^1] | | GPIO46 | T10-6 | |
|
||||||
| 00008000 | GPIO15 | |LEDx[^1] | | GPIO47 | T10-2 | SPI0-SDA |
|
| 00008000 | GPIO15 | |LEDx[^1] | | GPIO47 | T10-2 | |
|
||||||
| 00010000 | GPIO16 | |LEDx[^1] | | GPIO48 | T10-4, J6 (BUTTON RESET) | SPI1-SCK |
|
| 00010000 | GPIO16 | |LEDx[^1] | | GPIO48 | T10-4, J6 (BUTTON RESET) | |
|
||||||
| 00020000 | GPIO17 | |LEDx[^1] | | GPIO49 | T10-1 | SPI1-SDA |
|
| 00020000 | GPIO17 | |LEDx[^1] | | GPIO49 | T10-1 | |
|
||||||
| 00040000 | GPIO18 | |LEDx[^1] | | GPIO50 | | |
|
| 00040000 | GPIO18 | |LEDx[^1] | | GPIO50 | | |
|
||||||
| 00080000 | GPIO19 | |LEDx[^1] | | GPIO51 | | |
|
| 00080000 | GPIO19 | |LEDx[^1] | | GPIO51 | | |
|
||||||
| 00100000 | GPIO20 | |LEDx[^1] | | GPIO52 | | |
|
| 00100000 | GPIO20 | |LEDx[^1] | | GPIO52 | | |
|
||||||
@@ -124,7 +96,7 @@ Reset-line found at `T-D6-L`, `T-R83`, `T-R97`, `T-R94`, `T-R93` active-low.
|
|||||||
| 08000000 | GPIO27 | |? | | GPIO59 | | |
|
| 08000000 | GPIO27 | |? | | GPIO59 | | |
|
||||||
| 10000000 | GPIO28 | | | | GPIO60 | | |
|
| 10000000 | GPIO28 | | | | GPIO60 | | |
|
||||||
| 20000000 | GPIO29 | | | | GPIO61 | | |
|
| 20000000 | GPIO29 | | | | GPIO61 | | |
|
||||||
| 40000000 | GPIO30 | RTL8224N Reset |RTL8224 | | GPIO62 | To RTL8224 | Already driver | |
|
| 40000000 | GPIO30 | |SFP-DETE | | GPIO62 | To RTL8225 | Already driver INT? | |
|
||||||
| 80000000 | GPIO31 | B-r129-r? |U0TXD | | GPIO63 | | |
|
| 80000000 | GPIO31 | B-r129-r? |U0TXD | | GPIO63 | | |
|
||||||
|
|
||||||
## GPIO Register Input value
|
## GPIO Register Input value
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
# Hisource Hi-K0402WS
|
|
||||||
|
|
||||||
Following is documentation for unmanaged switch marked as `Hi-K0402WS`.
|
|
||||||
|
|
||||||
Original software is running UART on 9600 baud rate.
|
|
||||||
|
|
||||||
Using SPI clamp in-board is the only method for initial installation.
|
|
||||||
|
|
||||||
The board has two flash chips `BY25Q16BS` with 16M-bit size. The front switch, switches between the two flash chips.
|
|
||||||
These can be programed independently by using said switch - so it is e.g. possible to run the original and new firmware in parallel.
|
|
||||||
|
|
||||||
### Label specifications
|
|
||||||
|
|
||||||
- **Name**: 2.5G Ethernet Switch
|
|
||||||
- **Model**: Hi-K0402WS
|
|
||||||
- **Ports**:
|
|
||||||
- 4 × RJ45: 10/100/1000/2500 Mbps
|
|
||||||
- 2 × SFP: 1000 / 2500 / 10000 Mbps
|
|
||||||
|
|
||||||
### What works (expected from label + similar devices)
|
|
||||||
|
|
||||||
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
|
||||||
- Both SFP ports supporting 1G, 2.5G and 10G modules
|
|
||||||
- LEDs
|
|
||||||
|
|
||||||
### PCB overview
|
|
||||||
|
|
||||||
**Board markings**
|
|
||||||
- Top silkscreen: PCB-KO4022W-V3.0 / DIP-KO4022WS-V3.0
|
|
||||||
|
|
||||||
Top side
|
|
||||||
|
|
||||||
<img src="photos/K0402W-V3.0-unmanaged\PCB-top.jpg" width="300" />
|
|
||||||
|
|
||||||
Bottom
|
|
||||||
|
|
||||||
<img src="photos/K0402W-V3.0-unmanaged\PCB-bottom.jpg" width="300" />
|
|
||||||
|
|
||||||
### T2, serial console
|
|
||||||
|
|
||||||
| `J2` pin | Signal |
|
|
||||||
| -------- | ----------- |
|
|
||||||
| 1 | 3V3 |
|
|
||||||
| 2 | RX (Input) |
|
|
||||||
| 3 | TX (Output) |
|
|
||||||
| 4 | GND |
|
|
||||||
|
|
||||||
|
|
||||||
## Power supply
|
|
||||||
|
|
||||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
|
||||||
Board has two supply rails. `0.95` and `3.3` volt.
|
|
||||||
|
|
||||||
### `0.95` Core Voltage
|
|
||||||
|
|
||||||
Voltage is made by a `Techcode TD1720` .
|
|
||||||
|
|
||||||
### `3.3` Voltage
|
|
||||||
|
|
||||||
Voltage is created by chip marked as `Techcode TD1720`.
|
|
||||||
|
|
||||||
**There seems to have been a miscalculation when choosing the inductor and the device is ~25% more efficient with an 5V power supply.**
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
# SWTG018AS-A V2.0
|
|
||||||
|
|
||||||
The following is a documentation for the unmanaged switch marked as `SWTG018AS-A V2.0`.
|
|
||||||
It is e.g. sold under the Ampcom brand, but no branh-markings are found on the device.
|
|
||||||
|
|
||||||
The original software is running UART on 9600 baud rate.
|
|
||||||
|
|
||||||
Using a SOIC clamp in-board is the only method for initial installation.
|
|
||||||
|
|
||||||
The board has a single flash chips `BS` with 4M-bit size. The front switch, switches between the two flash chips.
|
|
||||||
These can be programed independently by using said switch - so it is e.g. possible to run the original and new firmware in parallel.
|
|
||||||
|
|
||||||
### Label specifications
|
|
||||||
|
|
||||||
- **Name**: 9-Ports 2.5G Ethernet Switch
|
|
||||||
- **Ports**:
|
|
||||||
- 8 × RJ45: 10/100/1000/2500 Mbps
|
|
||||||
- 1 × SFP+: 1000 / 2500 / 10000 Mbps
|
|
||||||
- **Power**: 12V DC, 1A barrel connector
|
|
||||||
|
|
||||||
<img src="photos/SWTG018AS_A_V_2_0/label.jpg" width="300" />
|
|
||||||
|
|
||||||
### What works
|
|
||||||
The device is fully supported:
|
|
||||||
- All 8 2.5GBASE-T RJ45 ports work at 10/100/1000/2500 Mbps
|
|
||||||
- The SFP+ port supports 1G, 2.5G and 10G modules
|
|
||||||
- LEDs work with the same indiciations as the OEM firmware
|
|
||||||
|
|
||||||
### PCB overview
|
|
||||||
|
|
||||||
**Board markings**
|
|
||||||
- Top silkscreen: SWTG018AS-A-V2.0.1_19649
|
|
||||||
|
|
||||||
Top side
|
|
||||||
|
|
||||||
<img src="photos/SWTG018AS_A_V_2_0/pcb_top.jpg" width="300" />
|
|
||||||
|
|
||||||
Bottom
|
|
||||||
|
|
||||||
<img src="photos/SWTG018AS_A_V_2_0/pcb_bottom.jpg" width="300" />
|
|
||||||
|
|
||||||
### J1, serial console
|
|
||||||
|
|
||||||
| `J1` pin | Signal |
|
|
||||||
| -------- | ----------- |
|
|
||||||
| 1 | 3V3 |
|
|
||||||
| 2 | GND |
|
|
||||||
| 3 | RX (Input) |
|
|
||||||
| 4 | TX (Output) |
|
|
||||||
|
|
||||||
|
|
||||||
## Power supply
|
|
||||||
|
|
||||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
### ZX-SWTGW218AS
|
|
||||||
|
|
||||||
## Brands
|
|
||||||
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
|
||||||
|---|---|---|---|---|---|
|
|
||||||
| Mokerlink | ZX-SWTGW218AS | Yes| SWTG118AS-V2.0-16029 | 2MB (FM25Q16A)| 8273N + 8224N |
|
|
||||||
| Sodola | | | | | |
|
|
||||||
| Horaco | | | | | |
|
|
||||||
|
|
||||||
|
|
||||||
## Photos
|
|
||||||
|
|
||||||
<img src="photos/SWTGW218AS-managed/front.png" width="800" />
|
|
||||||
|
|
||||||
<img src="photos/SWTGW218AS-managed/label.jpg" width="800" />
|
|
||||||
|
|
||||||
## PCB
|
|
||||||
|
|
||||||
See up'n'atom's Repo:
|
|
||||||
|
|
||||||
https://github.com/up-n-atom/SWTG118AS/blob/main/photos/SWTG118AS-v2.0/SWTG118AS-v2.0-pcb-top.JPG
|
|
||||||
|
|
||||||
https://github.com/up-n-atom/SWTG118AS/blob/main/photos/SWTG118AS-v2.0/SWTG118AS-v2.0-pcb-bottom.JPG
|
|
||||||
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
# TrendNet TEG-S562
|
|
||||||
|
|
||||||
Following is documentation for unmanaged switch marked as `TEG-S563/EU H/W: V1.0R`.
|
|
||||||
|
|
||||||
Original software is running UART on 57600 baud rate. The software does not allow to
|
|
||||||
do anything fancy via serial. There is `IP` configuration which can be printed as well.
|
|
||||||
There might be also some flash upload procedure, but using SPI clamp in-board seems to
|
|
||||||
be easier method.
|
|
||||||
|
|
||||||
The memory chip is `Winbond W25Q16JV` with 16M-bit size.
|
|
||||||
|
|
||||||
## What does work
|
|
||||||
|
|
||||||
1. 2.5G ports on all advertised speeds.
|
|
||||||
2. SFP+ communication.
|
|
||||||
3. Serial, Web UI.
|
|
||||||
|
|
||||||
## Known issues
|
|
||||||
|
|
||||||
1. LEDs are not initialized properly.
|
|
||||||
|
|
||||||
## PCB
|
|
||||||
|
|
||||||
Manufacturer information be found [on the product page](https://www.trendnet.com/support/support-detail.asp?prod=105_TEG-S562).
|
|
||||||
|
|
||||||
Top side
|
|
||||||
|
|
||||||
<img src="photos/TEG-S562/TEG-S562-v1.0R-top.jpg" width="300" />
|
|
||||||
|
|
||||||
Bottom
|
|
||||||
|
|
||||||
<img src="photos/TEG-S562/TEG-S562-v1.0R-bottom.jpg" width="300" />
|
|
||||||
|
|
||||||
## Connectors
|
|
||||||
|
|
||||||
### Port overview
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ ┌──────────┐ ┌──────────┐ │
|
|
||||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ SFP │ │ SFP │ │
|
|
||||||
│ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ PORT 5 │ │ PORT 6 │ │
|
|
||||||
│ │ PORT 1 │ │ PORT 2 │ │ PORT 3 │ │ PORT 4 │ │ MAC ? │ │ MAC ? │ │
|
|
||||||
│ │ MAC 4 │ │ MAC 5 │ │ MAC 6 │ │ MAC 7 │ │ SerDes ? │ │ SerDes ? │ │
|
|
||||||
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘ └──────────┘ │
|
|
||||||
└─────────────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### J2, serial console
|
|
||||||
|
|
||||||
| `J2` pin | Signal |
|
|
||||||
| -------- | ----------- |
|
|
||||||
| 1 | 3V3 |
|
|
||||||
| 2 | TX (Output) |
|
|
||||||
| 3 | RX (Input) |
|
|
||||||
| 4 | GND |
|
|
||||||
|
|
||||||
Note: 1 pin is square shaped, towards the power input.
|
|
||||||
|
|
||||||
### J5, power pass-thru
|
|
||||||
|
|
||||||
| `J5` pin | Signal |
|
|
||||||
| -------- | ------ |
|
|
||||||
| 1 | 12V |
|
|
||||||
| 2 | 12V |
|
|
||||||
| 3 | GND |
|
|
||||||
| 4 | GND |
|
|
||||||
|
|
||||||
Note: 1 pin is square shaped.
|
|
||||||
|
|
||||||
### U5, I2C eeprom placeholder
|
|
||||||
|
|
||||||
| `J5` pin | Signal |
|
|
||||||
| -------- | ------------- |
|
|
||||||
| 1 | GND |
|
|
||||||
| 2 | GND |
|
|
||||||
| 3 | GND |
|
|
||||||
| 4 | GND |
|
|
||||||
| 5 | 3V3 |
|
|
||||||
| 6 | ??? Logic Low |
|
|
||||||
| 7 | SCL |
|
|
||||||
| 8 | SDA |
|
|
||||||
|
|
||||||
SOC I2C address is 0x5c.
|
|
||||||
|
|
||||||
### SW1 GPIO switch?
|
|
||||||
|
|
||||||
Not populated but looks like a switch for selecting
|
|
||||||
GPIO level. Missing resistors in place.
|
|
||||||
|
|
||||||
GPIO mapping unknown.
|
|
||||||
|
|
||||||
### S2 Reset ciruit
|
|
||||||
|
|
||||||
Not populated but looks like a button can be added on `S2` connector,
|
|
||||||
requires additional `R571` resistor which will pull signal to ground.
|
|
||||||
|
|
||||||
GPIO mapping unknown.
|
|
||||||
|
|
||||||
### GPIO
|
|
||||||
|
|
||||||
| HEX VAL. | GPIO | When | GPIO | When |
|
|
||||||
| -------- | ------ | ----------------| ------ | -----------------------|
|
|
||||||
| 00000001 | GPIO00 | | GPIO32 | |
|
|
||||||
| 00000002 | GPIO01 | | GPIO33 | |
|
|
||||||
| 00000004 | GPIO02 | | GPIO34 | Random changes |
|
|
||||||
| 00000008 | GPIO03 | | GPIO35 | |
|
|
||||||
| 00000010 | GPIO04 | | GPIO36 | SFP1 Present |
|
|
||||||
| 00000020 | GPIO05 | | GPIO37 | SFP1 RX Los |
|
|
||||||
| 00000040 | GPIO06 | | GPIO38 | SFP2 Present |
|
|
||||||
| 00000080 | GPIO07 | | GPIO39 | |
|
|
||||||
| 00000100 | GPIO08 | | GPIO40 | |
|
|
||||||
| 00000200 | GPIO09 | | GPIO41 | |
|
|
||||||
| 00000400 | GPIO10 | | GPIO42 | Random changes |
|
|
||||||
| 00000800 | GPIO11 | | GPIO43 | |
|
|
||||||
| 00001000 | GPIO12 | PORT1 Link | GPIO44 | |
|
|
||||||
| 00002000 | GPIO13 | PORT1-LED-GREEN | GPIO45 | |
|
|
||||||
| 00004000 | GPIO14 | PORT1-LED-AMBER | GPIO46 | SFP1 I2C CLK |
|
|
||||||
| 00008000 | GPIO15 | PORT2 Link | GPIO47 | SFP1 I2C SDA |
|
|
||||||
| 00010000 | GPIO16 | PORT2-LED-GREEN | GPIO48 | SFP2 I2C CLK |
|
|
||||||
| 00020000 | GPIO17 | PORT2-LED-AMBER | GPIO49 | SFP2 I2C SDA |
|
|
||||||
| 00040000 | GPIO18 | PORT3 Link | GPIO50 | SFP2 Rx LOS |
|
|
||||||
| 00080000 | GPIO19 | PORT3-LED-GREEN | GPIO51 | SFP1 TX Disable |
|
|
||||||
| 00100000 | GPIO20 | PORT4-LED-AMBER | GPIO52 | |
|
|
||||||
| 00200000 | GPIO21 | PORT4 Link | GPIO53 | |
|
|
||||||
| 00400000 | GPIO22 | PORT4-LED-GREEN | GPIO54 | SFP2 TX Disable |
|
|
||||||
| 00800000 | GPIO23 | PORT4-LED-AMBER | GPIO55 | |
|
|
||||||
| 01000000 | GPIO24 | | GPIO56 | |
|
|
||||||
| 02000000 | GPIO25 | | GPIO57 | |
|
|
||||||
| 04000000 | GPIO26 | | GPIO58 | |
|
|
||||||
| 08000000 | GPIO27 | | GPIO59 | |
|
|
||||||
| 10000000 | GPIO28 | | GPIO60 | |
|
|
||||||
| 20000000 | GPIO29 | | GPIO61 | |
|
|
||||||
| 40000000 | GPIO30 | | GPIO62 | |
|
|
||||||
| 80000000 | GPIO31 | | GPIO63 | |
|
|
||||||
|
|
||||||
## LEDs
|
|
||||||
|
|
||||||
Leds are not yet working as in stock firmware. This will be handled later.
|
|
||||||
|
|
||||||
Ports 1-4 are amber for 100M/1G links, Green for 2.5G.
|
|
||||||
Port 5-6 are green for 10G/1G link. Both should flash on activity.
|
|
||||||
|
|
||||||
| NAME | When active |
|
|
||||||
| ---------------- | ---------------|
|
|
||||||
| PWR | 3V3 |
|
|
||||||
| SFP1 | |
|
|
||||||
| SFP2 | |
|
|
||||||
| PORT1-LED-GREEN | - |
|
|
||||||
| PORT2-LED-GREEN | PORT2 2.5G |
|
|
||||||
| PORT3-LED-GREEN | PORT3 2.5G |
|
|
||||||
| PORT4-LED-GREEN | PORT4 2.5G |
|
|
||||||
| PORT1-LED-AMBER | PORT1 1GB/100M |
|
|
||||||
| PORT2-LED-AMBER | PORT2 1GB/100M |
|
|
||||||
| PORT3-LED-AMBER | PORT3 1GB/100M |
|
|
||||||
| PORT4-LED-AMBER | PORT4 1GB/100M |
|
|
||||||
|
|
||||||
## Power supply
|
|
||||||
|
|
||||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
|
||||||
Board has two supply rails. `0.95` and `3.3` volt.
|
|
||||||
|
|
||||||
### `0.95` Core Voltage
|
|
||||||
|
|
||||||
Voltage is made by a `APW8713` (U3).
|
|
||||||
|
|
||||||
### `3.3` Voltage
|
|
||||||
|
|
||||||
Voltage is crated regulated by chip marke as `GoIAT` (U2).
|
|
||||||
|
|
||||||
## SFP SPI
|
|
||||||
|
|
||||||
There is separate clock and data lines for both SFP modules. MSDA/MSCK 0 and 1 need to be enabled.
|
|
||||||
|
|
||||||
SFP1 slot is connected to SPI0. SFP2 slot is connected to SPI1.
|
|
||||||
|
Before Width: | Height: | Size: 754 KiB |
|
Before Width: | Height: | Size: 521 KiB |
|
Before Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 3.1 MiB |
|
Before Width: | Height: | Size: 2.8 MiB |
|
Before Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 1.6 MiB |
|
Before Width: | Height: | Size: 1.6 MiB |
|
Before Width: | Height: | Size: 876 KiB |
|
Before Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 1.8 MiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 558 KiB |
|
Before Width: | Height: | Size: 1.8 MiB |
|
Before Width: | Height: | Size: 2.6 MiB |
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## SPI-Flash Memory
|
## SPI-Flash Memory
|
||||||
|
|
||||||
SPI-Flash memory can be replaced with an other type. Because the chip is defect, like #69 & #70 or you have an unmanaged-switch with a small flash size, and want to convert it to a managed-variant to run `RTLPlayground` software on it. Currently `RTLPlayground`-firmware expects `8 MBit / 1 MiB`.
|
SPI-Flash memory can be replaced with an other type. Because the chip is defect, like #69 & #70 or you have an unmanaged-switch with a small flash size, and want to convert it to a managed-variant to run `RTLPlayground` software on it. Currently `RTLPlayground`-firmware expects `8 MBit / 2 MiB`.
|
||||||
|
|
||||||
### Size
|
### Size
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ Most use package are `SO8`-type may also called `SOIC8`-type. Which can also hav
|
|||||||
|
|
||||||
### Specification
|
### Specification
|
||||||
|
|
||||||
1. Size: At least `8 MBit / 1 MiB` (theoretic max. `128 MBit / 16 MiB`, but is not *tested*!)
|
1. Size: At least `16 MBit / 4 MiB` (theoretic max. `128 MBit / 32 MiB`, but is not *tested*!)
|
||||||
2. Speed: `62.5 MHz` or better.
|
2. Speed: `62.5 MHz` or better.
|
||||||
3. Support for `DUAL SPI operation`.
|
3. Support for `DUAL SPI operation`.
|
||||||
Device need support for command `BBh`, `Dual I/O Fast Read` or `Fast Read Dual I/O`.
|
Device need support for command `BBh`, `Dual I/O Fast Read` or `Fast Read Dual I/O`.
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ The following devices have been tested and are fully working:
|
|||||||
- Lianguo LG-SWTGW218AS (RTL8373 + RTL8224 PHY: 8x 2.5GBit + 1x 10GBit SFP+)
|
- Lianguo LG-SWTGW218AS (RTL8373 + RTL8224 PHY: 8x 2.5GBit + 1x 10GBit SFP+)
|
||||||
- No-Name ZX-SWTGW215AS, managed version of kp-9000-6hx-x, ordered on
|
- No-Name ZX-SWTGW215AS, managed version of kp-9000-6hx-x, ordered on
|
||||||
AliExpress as keepLINK 5+1 port managed
|
AliExpress as keepLINK 5+1 port managed
|
||||||
- TrendNet TEG-S562 (RTL8372: 4x 2.5GBit + 2x 10GBit SFP+)
|
|
||||||
|
|
||||||
Other device based on RTL8272/3 that may work are described here: [Up-N-Atoms 2.5 GBit RTL Switch hacking guide]
|
Other device based on RTL8272/3 that may work are described here: [Up-N-Atoms 2.5 GBit RTL Switch hacking guide]
|
||||||
(https://github.com/up-n-atom/SWTG118AS)
|
(https://github.com/up-n-atom/SWTG118AS)
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<script src="/main.js"></script>
|
|
||||||
<link rel="stylesheet" href="style.css">
|
|
||||||
<title>Ingress and Egress Bandwidth</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav id="sidebar"></nav>
|
|
||||||
<div style="margin-left:16%;padding:1px 16px;height:1000px;">
|
|
||||||
<div id="ports"></div>
|
|
||||||
<h1>Ingress and Egress Bandwidth</h1>
|
|
||||||
<table id="bwtable">
|
|
||||||
<tr> <th> </th> <th colspan="3"> Ingress </th> <th colspan="2">Egress</th> <th></th></tr>
|
|
||||||
<tr> <th>Port</th> <th>Limit</th> <th>Bandwidth [kBit/s]</th> <th>Flow Control</th> <th>Limit</th> <th>Bandwidth [kBit/s]</th> <th>Apply</th></tr>
|
|
||||||
</table>
|
|
||||||
<script src="/bandwidth.js"></script>
|
|
||||||
</div>
|
|
||||||
<script src="/navigation.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
const iLayout = '" type="number" maxlength="10" size="10" onfocus="inputFocus(';
|
|
||||||
function createBW() {
|
|
||||||
var tbl = document.getElementById('bwtable');
|
|
||||||
const limit = '<input type="checkbox" id="limit_port" onchange="exec();">'
|
|
||||||
if (tbl.rows.length <= 2 && numPorts) {
|
|
||||||
clearInterval(createBWInterval);
|
|
||||||
console.log("CREATING TABLE ", tbl.rows.length);
|
|
||||||
for (let i = 2; i < 2 + numPorts; i++) {
|
|
||||||
const tr = tbl.insertRow();
|
|
||||||
let td = tr.insertCell(); td.appendChild(document.createTextNode(`Port ${i-1}`));
|
|
||||||
td = tr.insertCell();
|
|
||||||
td.innerHTML = limit.replaceAll("limit_port", "ilimit_port_" + i).replace("exec()", "iClicked(" + i + ")");
|
|
||||||
td = tr.insertCell();
|
|
||||||
td.innerHTML = 'UNLIMITED';
|
|
||||||
td = tr.insertCell();
|
|
||||||
td.innerHTML = limit.replaceAll("limit_port", "fc_port_" + i).replace("exec()", "document.getElementById('bwapply_" + i + "').disabled=false;");
|
|
||||||
td = tr.insertCell();
|
|
||||||
td.innerHTML = limit.replaceAll("limit_port", "elimit_port_" + i).replace("exec()", "eClicked(" + i + ")");
|
|
||||||
td = tr.insertCell();
|
|
||||||
td.innerHTML = 'UNLIMITED';
|
|
||||||
var button = '<button type="button" id="bwapply_' + i + '" style="margin: 0 0 0 24px" onclick="applyBandwidth(' + i + ');">Apply</button>';
|
|
||||||
td = tr.insertCell();
|
|
||||||
td.innerHTML = button;
|
|
||||||
document.getElementById("bwapply_" + i).disabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function iClicked(i)
|
|
||||||
{
|
|
||||||
document.getElementById("bwapply_" + i).disabled=false;
|
|
||||||
var tbl = document.getElementById('bwtable');
|
|
||||||
var tr = tbl.rows[i];
|
|
||||||
if (!document.getElementById("ilimit_port_" + i).checked) {
|
|
||||||
tr.cells[2].innerHTML = "UNLIMITED";
|
|
||||||
document.getElementById("fc_port_" + i).disabled = true;
|
|
||||||
document.getElementById("fc_port_" + i).checked = true;
|
|
||||||
} else {
|
|
||||||
tr.cells[2].innerHTML = '<input id="ibw_' + i + iLayout + i + ')" value="0"/>';
|
|
||||||
document.getElementById("fc_port_" + i).disabled = false;
|
|
||||||
document.getElementById("fc_port_" + i).checked = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function eClicked(i)
|
|
||||||
{
|
|
||||||
document.getElementById("bwapply_" + i).disabled=false;
|
|
||||||
var tbl = document.getElementById('bwtable');
|
|
||||||
var tr = tbl.rows[i];
|
|
||||||
if (!document.getElementById("elimit_port_" + i).checked) {
|
|
||||||
tr.cells[5].innerHTML = "UNLIMITED";
|
|
||||||
} else {
|
|
||||||
tr.cells[5].innerHTML = '<input id="ebw_' + i + iLayout + i + ')" value="0"/>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function inputFocus(i)
|
|
||||||
{
|
|
||||||
document.getElementById("bwapply_" + i).disabled=false;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function doCMD(cmd)
|
|
||||||
{
|
|
||||||
console.log("Sending >" + cmd + "<");
|
|
||||||
try {
|
|
||||||
const response = await fetch('/cmd', {
|
|
||||||
method: 'POST',
|
|
||||||
body: cmd
|
|
||||||
});
|
|
||||||
console.log('Completed!', response);
|
|
||||||
} catch(err) {
|
|
||||||
console.error(`Error: ${err}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function applyBandwidth(i) {
|
|
||||||
var tbl = document.getElementById('bwtable');
|
|
||||||
var tr = tbl.rows[i];
|
|
||||||
var cmd = "bw in " + (i-1) + " off";
|
|
||||||
if (document.getElementById("ilimit_port_" + i).checked)
|
|
||||||
cmd = 'bw in ' + (i-1) + ' ' + parseInt(document.getElementById("ibw_" + i).value).toString(16).padStart(4, "0");;
|
|
||||||
doCMD(cmd);
|
|
||||||
if (document.getElementById("ilimit_port_" + i).checked) {
|
|
||||||
if (!document.getElementById("fc_port_" + i).checked)
|
|
||||||
cmd = "bw in " + (i-1) + " drop";
|
|
||||||
doCMD(cmd);
|
|
||||||
}
|
|
||||||
var cmd = "bw out " + (i-1) + " off";
|
|
||||||
if (document.getElementById("elimit_port_" + i).checked)
|
|
||||||
cmd = 'bw out ' + (i-1) + ' ' + parseInt(document.getElementById("ebw_" + i).value).toString(16).padStart(4, "0");;
|
|
||||||
doCMD(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBW() {
|
|
||||||
var xhttp = new XMLHttpRequest();
|
|
||||||
xhttp.onreadystatechange = function() {
|
|
||||||
if (this.readyState == 4 && this.status == 200) {
|
|
||||||
const s = JSON.parse(xhttp.responseText);
|
|
||||||
console.log("BW: ", JSON.stringify(s));
|
|
||||||
var tbl = document.getElementById('bwtable');
|
|
||||||
if (tbl.rows.length > 2 && numPorts) {
|
|
||||||
for (let i = 2; i < 2 + numPorts; i++) {
|
|
||||||
p = s[i-2];
|
|
||||||
let n = p.portNum;
|
|
||||||
let tr = tbl.rows[n+1];
|
|
||||||
if (!document.getElementById("bwapply_" + (n+1)).disabled)
|
|
||||||
continue;
|
|
||||||
console.log("Table Update row: " + i + " portNum is " + n + ", pState is " + pState[i-2] + ", row number is " + (n+1));
|
|
||||||
let iBW = parseInt(p.iBW,16) * 16; let eBW = parseInt(p.eBW,16) * 16;
|
|
||||||
document.getElementById("ilimit_port_" + (n+1)).checked = p.iLimited;
|
|
||||||
document.getElementById("elimit_port_" + (n+1)).checked = p.eLimited;
|
|
||||||
if (!p.iLimited) {
|
|
||||||
tr.cells[2].innerHTML = "UNLIMITED";
|
|
||||||
} else {
|
|
||||||
tr.cells[2].innerHTML = '<input id="ibw_' + (n+1) + iLayout + (n+1) + ')" value="' + iBW +'"/>';
|
|
||||||
}
|
|
||||||
if (!p.eLimited) {
|
|
||||||
tr.cells[5].innerHTML = "UNLIMITED";
|
|
||||||
} else {
|
|
||||||
tr.cells[5].innerHTML = '<input id="ebw_' + (n+1) + iLayout + (n+1) + ')" value="' + eBW +'"/>';
|
|
||||||
}
|
|
||||||
document.getElementById("fc_port_" + (n+1)).checked = p.iFC==1?true:false;
|
|
||||||
document.getElementById("fc_port_" + (n+1)).disabled = p.iLimited==1?false:true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhttp.open("GET", "/bandwidth.json", true);
|
|
||||||
xhttp.timeout = 1500; xhttp.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
|
||||||
getBW();
|
|
||||||
const iCount = setInterval(getBW, 2000);
|
|
||||||
});
|
|
||||||
const createBWInterval = setInterval(createBW, 1010);
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../config.txt
|
||||||
@@ -49,8 +49,7 @@ async function fetchCmdLog() {
|
|||||||
console.log("CMD-Log: ", response);
|
console.log("CMD-Log: ", response);
|
||||||
const t = await response.text();
|
const t = await response.text();
|
||||||
return t;
|
return t;
|
||||||
} catch(err) {
|
} catch(error) {
|
||||||
console.error("Error: ", err);
|
console.error("Error: ", err);
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ var txG = new BigInt64Array(10);
|
|||||||
var txB = new BigInt64Array(10);
|
var txB = new BigInt64Array(10);
|
||||||
var rxG = new BigInt64Array(10);
|
var rxG = new BigInt64Array(10);
|
||||||
var rxB = new BigInt64Array(10);
|
var rxB = new BigInt64Array(10);
|
||||||
const linkS = ["Disabled", "Down", "10M", "100M", "1000M", "500M", "10G", "2.5G", "5G"];
|
const linkS = ["Disabled", "No Link", "100M", "1000M", "500M", "10G", "2.5G", "5G"];
|
||||||
var pState = new Int8Array(10);
|
var pState = new Int8Array(10);
|
||||||
var pIsSFP = new Int8Array(10);
|
var pIsSFP = new Int8Array(10);
|
||||||
var pAdvertised = new Int8Array(10);
|
var pAdvertised = new Int8Array(10);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ function fetchMirror() {
|
|||||||
for (let i = 1; i <= numPorts; i++) {
|
for (let i = 1; i <= numPorts; i++) {
|
||||||
let p = i - 1;
|
let p = i - 1;
|
||||||
if (numPorts < 9)
|
if (numPorts < 9)
|
||||||
p = physToLogPort[p];
|
p = physToLogPort[p];members & (1<<p)
|
||||||
setM("mPortsTX"+i, m_tx&(1<<p)); setM("mPortsRX"+i, m_rx&(1<<p));
|
setM("mPortsTX"+i, m_tx&(1<<p)); setM("mPortsRX"+i, m_rx&(1<<p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,5 @@ document.getElementById('sidebar').innerHTML =
|
|||||||
+ "<li><a href='mirror.html'>Mirroring</a></li>"
|
+ "<li><a href='mirror.html'>Mirroring</a></li>"
|
||||||
+ "<li><a href='lag.html'>Link Aggregation</a></li>"
|
+ "<li><a href='lag.html'>Link Aggregation</a></li>"
|
||||||
+ "<li><a href='eee.html'>EEE</a></li>"
|
+ "<li><a href='eee.html'>EEE</a></li>"
|
||||||
+ "<li><a href='bandwidth.html'>Bandwidth Limits</a></li>"
|
|
||||||
+ "<li><a href='system.html'>System Settings</a></li>"
|
+ "<li><a href='system.html'>System Settings</a></li>"
|
||||||
+ "<li><a href='update.html'>Firmware Update</a></li></ul>";
|
+ "<li><a href='update.html'>Firmware Update</a></li></ul>";
|
||||||
|
|||||||
@@ -6,9 +6,8 @@ ul {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 12%;
|
width: 12%;
|
||||||
height: calc(100% - 50px);
|
height: 100%;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 50px;
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,27 +3,12 @@
|
|||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<title>System Settings</title>
|
<title>System Settings</title>
|
||||||
<style>
|
|
||||||
.tab-bar { display: flex; border-bottom: 2px solid #226; margin-bottom: 0; margin-left: 16%; padding: 1px 16px; padding-bottom: 0; }
|
|
||||||
.tab-btn { padding: 10px 20px; background-color: #ddf; border: none; cursor: pointer; font-size: 1em; border-radius: 8px 8px 0 0; margin-right: 4px; }
|
|
||||||
.tab-btn:hover { background-color: #aaf; }
|
|
||||||
.tab-btn.active { background-color: #aaf; font-weight: bold; border-bottom: 2px solid #aaf; margin-bottom: -2px; }
|
|
||||||
.tab-content { display: none; }
|
|
||||||
.tab-content.active { display: block; }
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="tab-bar">
|
|
||||||
<button class="tab-btn active" onclick="openTab(event, 'system-tab')">System</button>
|
|
||||||
<button class="tab-btn" onclick="openTab(event, 'advanced-tab')">Advanced</button>
|
|
||||||
</div>
|
|
||||||
<nav id="sidebar"></nav>
|
<nav id="sidebar"></nav>
|
||||||
<div style="margin-left:16%;padding:1px 16px;height:1000px;">
|
<div style="margin-left:16%;padding:1px 16px;height:1000px;">
|
||||||
<div id="ports"></div>
|
<div id="ports"></div>
|
||||||
|
|
||||||
<div id="system-tab" class="tab-content active">
|
|
||||||
<h1>System Settings</h1>
|
<h1>System Settings</h1>
|
||||||
<label class="dhcpon">DHCP client endabled: <input id="dhcp" type="checkbox" onchange="dhcpClicked(this)"></label><br/><br/>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="lcol"> <label for="ip">IP address:</label></div>
|
<div class="lcol"> <label for="ip">IP address:</label></div>
|
||||||
<div class="rcol"> <input id="ip" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
<div class="rcol"> <input id="ip" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
||||||
@@ -36,36 +21,10 @@
|
|||||||
<div class="lcol"> <label for="gw">Gateway:</label></div>
|
<div class="lcol"> <label for="gw">Gateway:</label></div>
|
||||||
<div class="rcol"><input id="gw" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
<div class="rcol"><input id="gw" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
|
||||||
When updating the above settings, remember to point your browser to the new IP afterwards:<br/>
|
|
||||||
<input style="width:40%;" class="action" id="ip_sub" onclick="ipSub();" type="button" value="Update Settings"><br/>
|
|
||||||
<br/>
|
|
||||||
Save all current settings to Flash:<br/>
|
|
||||||
<input style="width:40%;" class="action" id="flash_sub" onclick="flashSave();" type="button" value="Save Settings to Flash">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="advanced-tab" class="tab-content">
|
|
||||||
<h1>Advanced Settings</h1>
|
|
||||||
<div class="lcol"> <label for="config_display">Startup configuration:</label></div>
|
|
||||||
<textarea id="config_display" rows="8" cols="60"></textarea>
|
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
Be careful when saving the directly edited startup configuration, you can lock yourself out:<br/>
|
|
||||||
<input style="width:40%;" class="action" id="clear_config" onclick="clearConfig();" type="button" value="Clear Startup Config">
|
|
||||||
<br/>
|
|
||||||
<input style="width:40%;" class="action" id="flash_startup_sub" onclick="flashStartupSave();" type="button" value="Save Startup Settings to Flash">
|
|
||||||
<br/>
|
|
||||||
<input style="width:40%;" class="action" id="switch_reset" onclick="resetSwitch();" type="button" value="Reset Switch">
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="lcol"> <label for="gw">Gateway:</label></div>
|
|
||||||
<div class="rcol"><input id="gw" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
|
|
||||||
</div><br/>
|
|
||||||
When updating the above settings, remember to point your browser to the new IP afterwards:<br/>
|
When updating the above settings, remember to point your browser to the new IP afterwards:<br/>
|
||||||
<input style="width:40%;" class="action" id="ip_sub" onclick="ipSub();" type="button" value="Update Settings"><br/>
|
<input style="width:40%;" class="action" id="ip_sub" onclick="ipSub();" type="button" value="Update Settings"><br/>
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
<label class="dhcpdon">Enable DHCP Server: <input id="dhcpd" type="checkbox"></label><br/><br/>
|
|
||||||
<label class="dhcpdvlan">Limit DHCP Server to VLAN (0: serve all VLANs): <input type="number" min="0" max="2047" value="0" id="dhcpd_vid" name="dhcpd_vid"></label><br/>
|
|
||||||
<input style="width:40%;" class="action" id="dhcpd_sub" onclick="dhcpdSub();" type="button" value="Change DHCPD State"><br/><br/><br/>
|
|
||||||
Save all current settings to Flash:<br/>
|
Save all current settings to Flash:<br/>
|
||||||
<input style="width:40%;" class="action" id="flash_sub" onclick="flashSave();" type="button" value="Save Settings to Flash">
|
<input style="width:40%;" class="action" id="flash_sub" onclick="flashSave();" type="button" value="Save Settings to Flash">
|
||||||
|
|
||||||
@@ -73,13 +32,5 @@
|
|||||||
<script src="/config.js"></script>
|
<script src="/config.js"></script>
|
||||||
<script src="/system.js"></script>
|
<script src="/system.js"></script>
|
||||||
<script src="/navigation.js"></script>
|
<script src="/navigation.js"></script>
|
||||||
<script>
|
|
||||||
function openTab(evt, tabId) {
|
|
||||||
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
|
|
||||||
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
|
|
||||||
document.getElementById(tabId).classList.add('active');
|
|
||||||
evt.currentTarget.classList.add('active');
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -8,20 +8,6 @@ function checkIp(ip) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function ipSub() {
|
async function ipSub() {
|
||||||
if (document.getElementById('dhcp').checked) {
|
|
||||||
var cmd = "ip dhcp";
|
|
||||||
try {
|
|
||||||
const response = await fetch('/cmd', {
|
|
||||||
method: 'POST',
|
|
||||||
body: cmd
|
|
||||||
});
|
|
||||||
console.log('Completed!', response);
|
|
||||||
systemInterval = setInterval(fetchIP, 10000);
|
|
||||||
} catch(err) {
|
|
||||||
console.error(`Error: ${err}`);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (let i=0;i<3;i++) {
|
for (let i=0;i<3;i++) {
|
||||||
if (!checkIp(document.getElementById(ips[i]).value))
|
if (!checkIp(document.getElementById(ips[i]).value))
|
||||||
return;
|
return;
|
||||||
@@ -40,39 +26,7 @@ async function ipSub() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function dhcpdSub() {
|
|
||||||
var dhcpd_cmd = "dhcpd off";
|
|
||||||
if (document.getElementById('dhcpd').checked) {
|
|
||||||
dhcpd_cmd = "dhcpd on";
|
|
||||||
var v=document.getElementById('dhcpd_vid').value
|
|
||||||
if (v && v!= 0)
|
|
||||||
dhcpd_cmd = dhcpd_cmd + " " + v;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
console.log("Sending: ", dhcpd_cmd);
|
|
||||||
const response = await fetch('/cmd', {
|
|
||||||
method: 'POST',
|
|
||||||
body: dhcpd_cmd
|
|
||||||
});
|
|
||||||
console.log('Completed!', response);
|
|
||||||
} catch(err) {
|
|
||||||
console.error(`Error: ${err}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function dhcpClicked(e)
|
|
||||||
{
|
|
||||||
console.log("dhcpClicked called");
|
|
||||||
if (e.checked) {
|
|
||||||
for (let i=0; i<3;i++)
|
|
||||||
document.getElementById(ips[i]).disabled = true;
|
|
||||||
document.getElementById('dhcpd').disabled = true;
|
|
||||||
} else {
|
|
||||||
console.log("dhcpClicked off");
|
|
||||||
for (let i=0; i<3;i++)
|
|
||||||
document.getElementById(ips[i]).disabled = false;
|
|
||||||
document.getElementById('dhcpd').disabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async function sendConfig(c) {
|
async function sendConfig(c) {
|
||||||
const form = new FormData();
|
const form = new FormData();
|
||||||
form.append("MAX_FILE_SIZE", "4096");
|
form.append("MAX_FILE_SIZE", "4096");
|
||||||
@@ -88,7 +42,6 @@ async function sendConfig(c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function flashSave() {
|
async function flashSave() {
|
||||||
fetchConfig().then((s) => {
|
fetchConfig().then((s) => {
|
||||||
parseConf(s);
|
parseConf(s);
|
||||||
@@ -100,39 +53,6 @@ async function flashSave() {
|
|||||||
sendConfig(body);
|
sendConfig(body);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
setTimeout(() => {
|
|
||||||
fetchIP();
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function flashStartupSave() {
|
|
||||||
var configContent = document.getElementById("config_display").value;
|
|
||||||
console.log("CONFIGURATION to save: ", configContent);
|
|
||||||
sendConfig(configContent);
|
|
||||||
// Clear the command log 1 second after initiating the config save
|
|
||||||
setTimeout(() => {
|
|
||||||
fetch('/cmd_log_clear', { method: 'GET' })
|
|
||||||
.then(response => console.log('Command log cleared', response))
|
|
||||||
.catch(err => console.error('Error clearing command log:', err));
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearConfig() {
|
|
||||||
document.getElementById("config_display").value = "";
|
|
||||||
|
|
||||||
// Validate and populate with current IP settings
|
|
||||||
for (let i=0; i<3; i++) {
|
|
||||||
if (!checkIp(document.getElementById(ips[i]).value))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var configLines = "";
|
|
||||||
for (let i=0; i<3; i++){
|
|
||||||
var cmd = ips[i]+' '+document.getElementById(ips[i]).value;
|
|
||||||
configLines += cmd + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("config_display").value = configLines;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchIP() {
|
function fetchIP() {
|
||||||
@@ -144,35 +64,13 @@ function fetchIP() {
|
|||||||
document.getElementById("ip").value=s.ip_address;
|
document.getElementById("ip").value=s.ip_address;
|
||||||
document.getElementById("netmask").value=s.ip_netmask;
|
document.getElementById("netmask").value=s.ip_netmask;
|
||||||
document.getElementById("gw").value=s.ip_gateway;
|
document.getElementById("gw").value=s.ip_gateway;
|
||||||
document.getElementById('dhcp').checked = s.dhcp_client;
|
|
||||||
document.getElementById('dhcpd').checked = s.dhcp_server;
|
|
||||||
clearInterval(systemInterval);
|
clearInterval(systemInterval);
|
||||||
// Fetch and populate the config textbox
|
}
|
||||||
fetchConfig().then((configText) => {
|
|
||||||
let fullConfig = configText;
|
|
||||||
// Fetch and append cmd_log
|
|
||||||
//return fetchCmdLog().then((cmdLogText) => {
|
|
||||||
// if (cmdLogText) {
|
|
||||||
// fullConfig = fullConfig + cmdLogText;
|
|
||||||
// }
|
|
||||||
document.getElementById("config_display").value = fullConfig;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
xhttp.open("GET", `/information.json`, true);
|
xhttp.open("GET", `/information.json`, true);
|
||||||
xhttp.send();
|
xhttp.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetSwitch() {
|
|
||||||
if (!confirm('Are you sure you want to reset the switch?')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fetch('/reset', { method: 'GET' }).catch(() => {});
|
|
||||||
setTimeout(() => {
|
|
||||||
alert('Switch is resetting. Please wait and refresh the page.');
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
window.addEventListener("load", function() {
|
||||||
systemInterval = setInterval(fetchIP, 1000);
|
systemInterval = setInterval(fetchIP, 1000);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
#define SESSION_ID_LENGTH 12
|
#define SESSION_ID_LENGTH 12
|
||||||
#define SESSION_TIMEOUT 200
|
#define SESSION_TIMEOUT 200
|
||||||
|
|
||||||
|
// Upload Firmware to 1M
|
||||||
|
#define FIRMWARE_UPLOAD_START 0x100000
|
||||||
|
|
||||||
// SPI FLASH MEMORY PAGE SIZE.
|
// SPI FLASH MEMORY PAGE SIZE.
|
||||||
#define FLASHMEM_PAGE_SIZE 0x100
|
#define FLASHMEM_PAGE_SIZE 0x100
|
||||||
|
|
||||||
@@ -27,10 +30,9 @@ extern __code uint8_t * __code hex;
|
|||||||
extern __code struct f_data f_data[];
|
extern __code struct f_data f_data[];
|
||||||
extern __code char * __code mime_strings[];
|
extern __code char * __code mime_strings[];
|
||||||
extern __xdata struct flash_region_t flash_region;
|
extern __xdata struct flash_region_t flash_region;
|
||||||
extern __xdata uint32_t flash_size;
|
|
||||||
|
|
||||||
// Flash buffer to optimize flash writing speed, write_len is the current filling position
|
// Flash buffer to optimize flash writing speed, write_len is the current filling position
|
||||||
extern __xdata uint8_t flash_buf[FLASH_BUF_SIZE];
|
extern __xdata uint8_t flash_buf[512];
|
||||||
__xdata uint32_t uptr; // Current flash write position
|
__xdata uint32_t uptr; // Current flash write position
|
||||||
__xdata uint16_t write_len;
|
__xdata uint16_t write_len;
|
||||||
|
|
||||||
@@ -299,8 +301,6 @@ uint8_t stream_upload(uint16_t bptr)
|
|||||||
print_string("Checksum incorrect!");
|
print_string("Checksum incorrect!");
|
||||||
}
|
}
|
||||||
print_string("\nUpload to flash done, will reset!\n");
|
print_string("\nUpload to flash done, will reset!\n");
|
||||||
// close connection to avoid retries by browser
|
|
||||||
uip_close();
|
|
||||||
reset_chip();
|
reset_chip();
|
||||||
}
|
}
|
||||||
// Make sure there is a 0 at the end of the uploaded data
|
// Make sure there is a 0 at the end of the uploaded data
|
||||||
@@ -310,9 +310,6 @@ uint8_t stream_upload(uint16_t bptr)
|
|||||||
flash_write_bytes(flash_buf);
|
flash_write_bytes(flash_buf);
|
||||||
if (bptr >= uip_len)
|
if (bptr >= uip_len)
|
||||||
return 0;
|
return 0;
|
||||||
if(!verify_crc)
|
|
||||||
//ugly hack to signal connection finished after config upload.
|
|
||||||
uip_close();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (p[bptr] == boundary[bindex]) {
|
if (p[bptr] == boundary[bindex]) {
|
||||||
@@ -427,12 +424,6 @@ void handle_post(void)
|
|||||||
p += 4; // Skip \r\n\r\n sequence at end of preamble of part
|
p += 4; // Skip \r\n\r\n sequence at end of preamble of part
|
||||||
|
|
||||||
if (is_word(request_path, "upload")) {
|
if (is_word(request_path, "upload")) {
|
||||||
if (flash_size < FIRMWARE_UPLOAD_START*2)
|
|
||||||
{
|
|
||||||
print_string("Flash too small for firmware upload!\n");
|
|
||||||
send_bad_request();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
print_string("Firmware upload started.");
|
print_string("Firmware upload started.");
|
||||||
uptr = FIRMWARE_UPLOAD_START;
|
uptr = FIRMWARE_UPLOAD_START;
|
||||||
verify_crc = 1;
|
verify_crc = 1;
|
||||||
@@ -586,8 +577,6 @@ void httpd_appcall(void)
|
|||||||
send_counters(q[20]-'0');
|
send_counters(q[20]-'0');
|
||||||
} else if (is_word(q, "/eee.json")) {
|
} else if (is_word(q, "/eee.json")) {
|
||||||
send_eee();
|
send_eee();
|
||||||
} else if (is_word(q, "/bandwidth.json")) {
|
|
||||||
send_bandwidth();
|
|
||||||
} else if (is_word(q, "/l2.json")) {
|
} else if (is_word(q, "/l2.json")) {
|
||||||
parse_short(q + 13); // e.g.: /l2.json?idx=10
|
parse_short(q + 13); // e.g.: /l2.json?idx=10
|
||||||
send_l2(short_parsed);
|
send_l2(short_parsed);
|
||||||
@@ -604,13 +593,6 @@ void httpd_appcall(void)
|
|||||||
send_config();
|
send_config();
|
||||||
} else if (is_word(q, "/cmd_log")) {
|
} else if (is_word(q, "/cmd_log")) {
|
||||||
send_cmd_log();
|
send_cmd_log();
|
||||||
} else if (is_word(q, "/cmd_log_clear")) {
|
|
||||||
clear_command_history();
|
|
||||||
send_mtu(); // dummy response
|
|
||||||
} else if (is_word(q, "/reset")) {
|
|
||||||
uip_close();
|
|
||||||
delay(1000); //wait for the close packet to be sent, otherwise the browser will retry
|
|
||||||
reset_chip();
|
|
||||||
} else {
|
} else {
|
||||||
send_not_found();
|
send_not_found();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
#include "uip.h"
|
#include "uip.h"
|
||||||
#include "html_data.h"
|
#include "html_data.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "dhcp.h"
|
|
||||||
#include "phy.h"
|
#include "phy.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
@@ -18,7 +17,6 @@
|
|||||||
// #define DEBUG
|
// #define DEBUG
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
#define L2_MAX_TRANSFER 30
|
#define L2_MAX_TRANSFER 30
|
||||||
|
|
||||||
#pragma codeseg BANK1
|
#pragma codeseg BANK1
|
||||||
@@ -31,6 +29,7 @@ extern __xdata uint16_t cont_len;
|
|||||||
extern __xdata uint32_t cont_addr;
|
extern __xdata uint32_t cont_addr;
|
||||||
extern __code uint8_t * __code hex;
|
extern __code uint8_t * __code hex;
|
||||||
extern __xdata uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
|
extern __xdata uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
|
||||||
|
extern __code struct uip_eth_addr uip_ethaddr;
|
||||||
|
|
||||||
extern __xdata uint8_t sfr_data[4];
|
extern __xdata uint8_t sfr_data[4];
|
||||||
extern __xdata uint8_t sfp_pins_last;
|
extern __xdata uint8_t sfp_pins_last;
|
||||||
@@ -46,8 +45,6 @@ extern __xdata char sfp_module_model[2][17];
|
|||||||
extern __xdata char sfp_module_serial[2][17];
|
extern __xdata char sfp_module_serial[2][17];
|
||||||
extern __xdata uint8_t sfp_options[2];
|
extern __xdata uint8_t sfp_options[2];
|
||||||
|
|
||||||
extern __xdata struct dhcp_state dhcp_state;
|
|
||||||
|
|
||||||
__code uint8_t * __code HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n";
|
__code uint8_t * __code HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n";
|
||||||
__code uint8_t * __code HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
|
__code uint8_t * __code HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
|
||||||
|
|
||||||
@@ -100,10 +97,6 @@ void itoa_html(uint8_t v)
|
|||||||
char_to_html('0' + (v % 10));
|
char_to_html('0' + (v % 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
void string_to_html(register char *s)
|
|
||||||
{
|
|
||||||
while (*s) char_to_html(*s++);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t stat_content(void)
|
uint16_t stat_content(void)
|
||||||
{
|
{
|
||||||
@@ -238,13 +231,8 @@ void send_basic_info(void)
|
|||||||
byte_to_html(uip_ethaddr.addr[5]);
|
byte_to_html(uip_ethaddr.addr[5]);
|
||||||
slen += strtox(outbuf + slen, "\",\"sw_ver\":\"");
|
slen += strtox(outbuf + slen, "\",\"sw_ver\":\"");
|
||||||
slen += strtox(outbuf + slen, VERSION_SW);
|
slen += strtox(outbuf + slen, VERSION_SW);
|
||||||
slen += strtox(outbuf + slen, "\",\"build_date\":\"");
|
|
||||||
slen += strtox(outbuf + slen, BUILD_DATE);
|
|
||||||
slen += strtox(outbuf + slen, "\",\"hw_ver\":\"");
|
slen += strtox(outbuf + slen, "\",\"hw_ver\":\"");
|
||||||
slen += strtox(outbuf + slen, machine.machine_name);
|
slen += strtox(outbuf + slen, machine.machine_name);
|
||||||
slen += strtox(outbuf + slen, "\",\"flash_size\":\"");
|
|
||||||
string_to_html(get_flash_size_str());
|
|
||||||
|
|
||||||
slen += strtox(outbuf + slen, "\",\"sfp_slot_0\":\"");
|
slen += strtox(outbuf + slen, "\",\"sfp_slot_0\":\"");
|
||||||
send_sfp_info(0);
|
send_sfp_info(0);
|
||||||
char_to_html('"');
|
char_to_html('"');
|
||||||
@@ -253,12 +241,6 @@ void send_basic_info(void)
|
|||||||
send_sfp_info(1);
|
send_sfp_info(1);
|
||||||
char_to_html('"');
|
char_to_html('"');
|
||||||
}
|
}
|
||||||
if (dhcp_state.state != DHCP_OFF && dhcp_state.state != DHCP_SERVER)
|
|
||||||
slen += strtox(outbuf + slen, ",\"dhcp_client\":1,\"dhcp_server\":0");
|
|
||||||
else if (dhcp_state.state == DHCP_SERVER)
|
|
||||||
slen += strtox(outbuf + slen, ",\"dhcp_client\":0,\"dhcp_server\":1");
|
|
||||||
else
|
|
||||||
slen += strtox(outbuf + slen, ",\"dhcp_client\":0,\"dhcp_server\":0");
|
|
||||||
char_to_html('}');
|
char_to_html('}');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -555,50 +537,6 @@ void send_eee(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void send_bandwidth(void)
|
|
||||||
{
|
|
||||||
dbg_string("send_bandwidth called\n");
|
|
||||||
slen = strtox(outbuf, HTTP_RESPONCE_JSON);
|
|
||||||
char_to_html('[');
|
|
||||||
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
|
||||||
slen += strtox(outbuf + slen, "{\"portNum\":");
|
|
||||||
itoa_html(machine.log_to_phys_port[i]);
|
|
||||||
slen += strtox(outbuf + slen, ",\"iLimited\":");
|
|
||||||
reg_read_m(RTL837X_IGBW_PORT_CTRL + i * 4);
|
|
||||||
if (sfr_data[1] & 0x10)
|
|
||||||
char_to_html('1');
|
|
||||||
else
|
|
||||||
char_to_html('0');
|
|
||||||
slen += strtox(outbuf + slen, ",\"iBW\":\"");
|
|
||||||
byte_to_html(sfr_data[1] & 0x0f);
|
|
||||||
byte_to_html(sfr_data[2]);
|
|
||||||
byte_to_html(sfr_data[3]);
|
|
||||||
slen += strtox(outbuf + slen, "\",\"iFC\":");
|
|
||||||
if (reg_bit_test(RTL837X_IGBW_PORT_FC_CTRL, i))
|
|
||||||
char_to_html('1');
|
|
||||||
else
|
|
||||||
char_to_html('0');
|
|
||||||
reg_read_m(RTL837X_EGBW_PORT_CTRL + i * 1024);
|
|
||||||
slen += strtox(outbuf + slen, ",\"eLimited\":");
|
|
||||||
if (sfr_data[1] & 0x10)
|
|
||||||
char_to_html('1');
|
|
||||||
else
|
|
||||||
char_to_html('0');
|
|
||||||
slen += strtox(outbuf + slen, ",\"eBW\":\"");
|
|
||||||
byte_to_html(sfr_data[1] & 0x0f);
|
|
||||||
byte_to_html(sfr_data[2]);
|
|
||||||
byte_to_html(sfr_data[3]);
|
|
||||||
char_to_html('"');
|
|
||||||
char_to_html('}');
|
|
||||||
if (i < machine.max_port)
|
|
||||||
char_to_html(',');
|
|
||||||
else
|
|
||||||
char_to_html(']');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void send_mtu(void)
|
void send_mtu(void)
|
||||||
{
|
{
|
||||||
dbg_string("send_mtu called\n");
|
dbg_string("send_mtu called\n");
|
||||||
@@ -690,24 +628,12 @@ void send_status(void)
|
|||||||
|
|
||||||
slen += strtox(outbuf + slen, ",\"link\":");
|
slen += strtox(outbuf + slen, ",\"link\":");
|
||||||
|
|
||||||
uint8_t b = 0;
|
|
||||||
// Determine link state
|
|
||||||
reg_read_m(RTL837X_REG_LINKS_STS);
|
|
||||||
if(!((sfr_data[(i / 8) + 1] >> (i % 8 ) & 1)))
|
|
||||||
{
|
|
||||||
b = 0; //link down
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Determine link speed
|
|
||||||
if (i < 8)
|
if (i < 8)
|
||||||
reg_read_m(RTL837X_REG_LINKS);
|
reg_read_m(RTL837X_REG_LINKS);
|
||||||
else
|
else
|
||||||
reg_read_m(RTL837X_REG_LINKS_89);
|
reg_read_m(RTL837X_REG_LINKS_89);
|
||||||
|
uint8_t b = sfr_data[3 - ((i & 7) >> 1)];
|
||||||
b = sfr_data[3 - ((i & 7) >> 1)];
|
b = (i & 1) ? b >> 4 : b & 0xf;
|
||||||
b = ((i & 1) ? b >> 4 : b & 0xf) + 1;
|
|
||||||
}
|
|
||||||
char_to_html('0' + b);
|
char_to_html('0' + b);
|
||||||
|
|
||||||
STAT_GET(STAT_COUNTER_TX_PKTS, i);
|
STAT_GET(STAT_COUNTER_TX_PKTS, i);
|
||||||
@@ -739,45 +665,26 @@ void send_status(void)
|
|||||||
void send_config(void)
|
void send_config(void)
|
||||||
{
|
{
|
||||||
dbg_string("send_config called\n");
|
dbg_string("send_config called\n");
|
||||||
__xdata uint32_t pos = CONFIG_START;
|
__xdata uint32_t pos = CONFIG_START; // 70000 , 6c000 / 0xc000 = 9
|
||||||
__xdata uint16_t valid_len = 0;
|
|
||||||
__xdata uint16_t len_left = CONFIG_LEN;
|
|
||||||
__xdata uint8_t flash_buf[256];
|
|
||||||
|
|
||||||
|
extern __xdata uint16_t len_left = CONFIG_LEN;
|
||||||
slen = strtox(outbuf, HTTP_RESPONCE_TXT);
|
slen = strtox(outbuf, HTTP_RESPONCE_TXT);
|
||||||
|
while (read_flash((CONFIG_START-CODE0_SIZE) / CODE_BANK_SIZE + 1,
|
||||||
// Scan through config to find the end of valid data (null terminator)
|
(__code uint8_t *) (((CONFIG_START + len_left - CODE0_SIZE) % CODE_BANK_SIZE) + CODE0_SIZE + len_left)) == 0xff) {
|
||||||
do {
|
dbg_short(len_left);
|
||||||
flash_region.addr = pos;
|
len_left--;
|
||||||
flash_region.len = (len_left > 256) ? 256 : len_left;
|
|
||||||
flash_read_bulk(flash_buf);
|
|
||||||
|
|
||||||
// Look for null terminator in this chunk
|
|
||||||
for (uint16_t i = 0; i < flash_region.len; i++) {
|
|
||||||
if (flash_buf[i] == 0) {
|
|
||||||
// Found end of valid data
|
|
||||||
valid_len += i;
|
|
||||||
goto found_end;
|
|
||||||
}
|
}
|
||||||
|
len_left++;
|
||||||
|
|
||||||
|
if (len_left > (TCP_OUTBUF_SIZE - slen)) {
|
||||||
|
cont_len = len_left - (TCP_OUTBUF_SIZE - slen);
|
||||||
|
len_left = TCP_OUTBUF_SIZE - slen;
|
||||||
|
cont_addr = len_left;
|
||||||
}
|
}
|
||||||
|
|
||||||
valid_len += flash_region.len;
|
|
||||||
len_left -= flash_region.len;
|
|
||||||
pos += flash_region.len;
|
|
||||||
} while (len_left > 0);
|
|
||||||
|
|
||||||
found_end:
|
|
||||||
// Now send the valid data
|
|
||||||
if (valid_len > (TCP_OUTBUF_SIZE - slen)) {
|
|
||||||
cont_len = valid_len - (TCP_OUTBUF_SIZE - slen);
|
|
||||||
valid_len = TCP_OUTBUF_SIZE - slen;
|
|
||||||
cont_addr = valid_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
flash_region.addr = CONFIG_START;
|
flash_region.addr = CONFIG_START;
|
||||||
flash_region.len = valid_len;
|
flash_region.len = len_left;
|
||||||
flash_read_bulk(outbuf + slen);
|
flash_read_bulk(outbuf + slen);
|
||||||
slen += valid_len;
|
slen += len_left;
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_cmd_log(void)
|
void send_cmd_log(void)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ void send_counters(char port);
|
|||||||
void send_status(void);
|
void send_status(void);
|
||||||
void send_vlan(uint16_t vlan);
|
void send_vlan(uint16_t vlan);
|
||||||
void send_basic_info(void);
|
void send_basic_info(void);
|
||||||
void send_bandwidth(void);
|
|
||||||
void send_eee(void);
|
void send_eee(void);
|
||||||
void send_l2(uint16_t idx);
|
void send_l2(uint16_t idx);
|
||||||
void l2_delete(uint16_t idx);
|
void l2_delete(uint16_t idx);
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "rtl837x_pins.h"
|
#include "rtl837x_pins.h"
|
||||||
#include "rtl837x_leds.h"
|
#include "rtl837x_leds.h"
|
||||||
#include "rtl837x_regs.h"
|
|
||||||
#include "rtl837x_common.h"
|
|
||||||
|
|
||||||
#ifdef MACHINE_KP_9000_6XHML_X2
|
#ifdef MACHINE_KP_9000_6XHML_X2
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
@@ -13,20 +11,18 @@ __code const struct machine machine = {
|
|||||||
.n_sfp = 2,
|
.n_sfp = 2,
|
||||||
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
||||||
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||||
.is_sfp = {0, 0, 0, 1, 0, 0, 0, 0, 2},
|
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
// Left SFP port (5)
|
|
||||||
.sfp_port[0].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
.sfp_port[0].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
||||||
.sfp_port[0].pin_los = GPIO10_LED10,
|
.sfp_port[0].pin_los = GPIO10_LED10,
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
.sfp_port[0].sds = 0,
|
.sfp_port[0].sds = 0,
|
||||||
.sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
// Right SFP port (6)
|
|
||||||
.sfp_port[1].pin_detect = GPIO30_ACL_BIT3_EN,
|
.sfp_port[1].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
.sfp_port[1].pin_los = GPIO37,
|
.sfp_port[1].pin_los = GPIO37,
|
||||||
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
.sfp_port[1].sds = 1,
|
.sfp_port[1].sds = 1,
|
||||||
.sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
.reset_pin = GPIO54_ACL_BIT2_EN,
|
.reset_pin = GPIO46_I2C_SCL0,
|
||||||
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 },
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 },
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
/* Conditions for LED on:
|
/* Conditions for LED on:
|
||||||
@@ -39,10 +35,14 @@ __code const struct machine machine = {
|
|||||||
LEDS_1G | LEDS_LINK,
|
LEDS_1G | LEDS_LINK,
|
||||||
0 },
|
0 },
|
||||||
},
|
},
|
||||||
|
.led_mux_custom = 0,
|
||||||
|
// LED0 LED1 LED2 LED3 LED4 LED5 LED6 LED7 LED8 LED9 LED10 LED11 LED12 LED13 LED14 LED15
|
||||||
|
// L-SFP R-SFP | PORT 1
|
||||||
|
// LED16 LED17 LED18 LED19 LED20 LED21 LED22 LED23 LED24 LED25 LED26 LED27
|
||||||
|
// | PORT 2 | PORT 3 | PORT 4
|
||||||
|
// .led_mux = { 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x0f, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14,
|
||||||
|
// 0x15, 0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x23 },
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_KP_9000_6XH_X
|
#elif defined MACHINE_KP_9000_6XH_X
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "keepLink KP-9000-6XH-X",
|
.machine_name = "keepLink KP-9000-6XH-X",
|
||||||
@@ -57,6 +57,7 @@ __code const struct machine machine = {
|
|||||||
.sfp_port[0].pin_los = GPIO37,
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
.sfp_port[0].sds = 1,
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c_bus = { .sda = 4, .scl = 3 },
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
.reset_pin = GPIO_NA,
|
.reset_pin = GPIO_NA,
|
||||||
/* Conditions for LED on:
|
/* Conditions for LED on:
|
||||||
@@ -70,12 +71,9 @@ __code const struct machine machine = {
|
|||||||
0 },
|
0 },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_KP_9000_9XH_X_EU
|
#elif defined MACHINE_KP_9000_9XH_X_EU
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "keepLink KP-9000-9XH-X-EU",
|
.machine_name = "keepLink KP-9000-6XH-X-EU",
|
||||||
.isRTL8373 = 1,
|
.isRTL8373 = 1,
|
||||||
.min_port = 0,
|
.min_port = 0,
|
||||||
.max_port = 8,
|
.max_port = 8,
|
||||||
@@ -98,45 +96,6 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_KP_9000_9XHML_X
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "keepLink KP-9000-9XHML-X",
|
|
||||||
.isRTL8373 = 1,
|
|
||||||
.min_port = 0,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 1,
|
|
||||||
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
|
||||||
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
|
||||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
.sfp_port[0].pin_detect = GPIO38,
|
|
||||||
.sfp_port[0].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
.reset_pin = GPIO48_I2C_SCL1,
|
|
||||||
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 },
|
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
.led_sets = {
|
|
||||||
{ /* RJ45: First LED, yellow, second LED: green */
|
|
||||||
LEDS_2G5 | LEDS_LINK,
|
|
||||||
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
}, { /* SFP PORT, SINGLE GREEN LED */
|
|
||||||
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
}},
|
|
||||||
.led_mux_custom = 1,
|
|
||||||
.led_mux = {0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0c, 0x09, 0x0d, 0x10,
|
|
||||||
0x11, 0x0e, 0x14, 0x11, 0x12, 0x15, 0x15, 0x16, 0x18, 0x19,
|
|
||||||
0x1a, 0x19, 0x1d, 0x1e, 0x1c, 0x1d, 0x20, 0x21},
|
|
||||||
};
|
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_SWGT024_V2_0
|
#elif defined MACHINE_SWGT024_V2_0
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "SWGT024 V2.0",
|
.machine_name = "SWGT024 V2.0",
|
||||||
@@ -174,49 +133,6 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_SWTG018AS_A_V_2_0
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "SWTG018AS-A V2.0",
|
|
||||||
.isRTL8373 = 1,
|
|
||||||
.min_port = 0,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 1,
|
|
||||||
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
|
||||||
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
|
||||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
.sfp_port[0].pin_detect = GPIO38,
|
|
||||||
.sfp_port[0].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
.reset_pin = GPIO_NA,
|
|
||||||
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 },
|
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
.led_sets = {
|
|
||||||
{ /* RJ45: First LED, yellow, second LED: green */
|
|
||||||
LEDS_2G5 | LEDS_LINK,
|
|
||||||
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
}, { /* SFP PORT, SINGLE GREEN LED */
|
|
||||||
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
}},
|
|
||||||
.led_mux_custom = 1,
|
|
||||||
.led_mux = { 0x00, 0x01, 0x04, 0x05, 0x08, // 65e0
|
|
||||||
0x09, 0x0c, 0x09, 0x0d, 0x10, // 65e4
|
|
||||||
0x11, 0x0e, 0x14, 0x11, 0x12, // 65e8
|
|
||||||
0x15, 0x15, 0x16, 0x18, 0x19, // 65ec
|
|
||||||
0x1a, 0x19, 0x1d, 0x1e, 0x1c, // 65f0
|
|
||||||
0x1d, 0x20, 0x21 },
|
|
||||||
};
|
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_HG0402XG_V1_1
|
#elif defined MACHINE_HG0402XG_V1_1
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "HG0402XG V1.1",
|
.machine_name = "HG0402XG V1.1",
|
||||||
@@ -254,44 +170,48 @@ __code const struct machine machine = {
|
|||||||
0 },
|
0 },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
#elif defined MACHINE_ZX_SWTGW215AS_HASIVO
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_SWTGW218AS
|
|
||||||
|
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "SWTGW218AS 8+1 Managed Switch",
|
.machine_name = "ZX-SWTGW215AS HASIVO",
|
||||||
.isRTL8373 = 1,
|
.isRTL8373 = 0,
|
||||||
.min_port = 0,
|
.min_port = 3,
|
||||||
.max_port = 8,
|
.max_port = 8,
|
||||||
.n_sfp = 1,
|
.n_sfp = 1,
|
||||||
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
||||||
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
.sfp_port[0].pin_los = GPIO37,
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
.sfp_port[0].sds = 1,
|
.sfp_port[0].sds = 1,
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
|
.sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
.reset_pin = GPIO54_ACL_BIT2_EN,
|
.reset_pin = GPIO54_ACL_BIT2_EN,
|
||||||
.high_leds = { .mux = LED_27 | LED_28 | LED_29, .enable = LED_28 | LED_29 },
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 },
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
.led_sets = { { LEDS_2G5 | LEDS_LINK | LEDS_ACT, // Green LED (right)
|
.led_sets = {
|
||||||
0, // unused
|
/* The Ethernet ports have 1 amber LED (bi-color left) and 2 green LED (left/right)
|
||||||
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // Amber LED (left)
|
* The SFP port has 1 green LED
|
||||||
0
|
* Ethernet ports use LED-set 0, SFP port uses LED-set 1
|
||||||
}, // unused
|
* Amber-LED: ledid0 & ledid1 & !ledid2
|
||||||
{ LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT, // SFP LED
|
* Left-Green: ledid-2
|
||||||
0, // unused
|
* Right-Green: ledid-0
|
||||||
0, // unused
|
* ledid3 is not used
|
||||||
0
|
*/
|
||||||
}, // unused },
|
{ LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_10G,
|
||||||
|
LEDS_1G | LEDS_LINK,
|
||||||
|
0 },
|
||||||
|
{
|
||||||
|
LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
||||||
|
LEDS_1G | LEDS_LINK,
|
||||||
|
LEDS_2G5 | LEDS_LINK,
|
||||||
|
LEDS_COL | LEDS_DUPLEX,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
.led_mux_custom = 0,
|
||||||
};
|
};
|
||||||
|
#elif defined DEFAULT_8C_1SFP
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_DEFAULT_8C_1SFP
|
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "8+1 SFP Port Switch",
|
.machine_name = "8+1 SFP Port Switch",
|
||||||
.isRTL8373 = 1,
|
.isRTL8373 = 1,
|
||||||
@@ -315,83 +235,4 @@ __code const struct machine machine = {
|
|||||||
LEDS_2G5 | LEDS_LINK | LEDS_ACT },
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_TRENDNET_TEG_S562
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "Trendnet TEG-S562",
|
|
||||||
.isRTL8373 = 0,
|
|
||||||
.min_port = 3,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 2,
|
|
||||||
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
|
||||||
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
|
||||||
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
|
||||||
.sfp_port[0].pin_detect = GPIO36_PWM_OUT,
|
|
||||||
.sfp_port[0].pin_los = GPIO37,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO51_I2C_SDA2_UART1_RX,
|
|
||||||
.sfp_port[0].sds = 0,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO47_I2C_SDA0, .scl = GPIO46_I2C_SCL0 },
|
|
||||||
.sfp_port[1].pin_detect = GPIO38,
|
|
||||||
.sfp_port[1].pin_los = GPIO50_I2C_SCL2_UART1_TX,
|
|
||||||
.sfp_port[1].pin_tx_disable = GPIO54_ACL_BIT2_EN,
|
|
||||||
.sfp_port[1].sds = 1,
|
|
||||||
.sfp_port[1].i2c = { .sda = GPIO49_I2C_SDA1, .scl = GPIO48_I2C_SCL1 },
|
|
||||||
.reset_pin = GPIO_NA,
|
|
||||||
};
|
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_HI_K0402WS
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = "HiSource HI-K0402WS",
|
|
||||||
.isRTL8373 = 0,
|
|
||||||
.min_port = 3,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 2,
|
|
||||||
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
|
||||||
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
|
||||||
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
|
||||||
|
|
||||||
// Left SFP port
|
|
||||||
.sfp_port[0].pin_detect = GPIO38,
|
|
||||||
.sfp_port[0].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
|
|
||||||
// Right SFP port
|
|
||||||
.sfp_port[1].pin_detect = GPIO37,
|
|
||||||
.sfp_port[1].pin_los = GPIO_NA,
|
|
||||||
.sfp_port[1].sds = 0,
|
|
||||||
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
|
|
||||||
|
|
||||||
.reset_pin = GPIO_NA,
|
|
||||||
.high_leds = { .mux = LED_28 | LED_29, .enable = LED_27 | LED_28 | LED_29 },
|
|
||||||
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
|
||||||
.led_sets = {
|
|
||||||
{
|
|
||||||
LEDS_2G5 | LEDS_LINK | LEDS_10M | LEDS_ACT,
|
|
||||||
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
|
||||||
LEDS_1G | LEDS_LINK,
|
|
||||||
0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK,
|
|
||||||
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.led_mux_custom = 1,
|
|
||||||
.led_mux = {
|
|
||||||
0x00,0x01,0x04,0x05,0x08,0x09,0x0c,0x3f,0x0d,0x10,0x11,0x0e,0x14,0x11,0x12,0x15,0x15,0x16,0x18,0x19,0x1a,0x19,0x1d,0x1e,0x1c,0x1d,0x20,0x21
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
void machine_custom_init(void) {
|
|
||||||
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#error "Please select a machine type in machine.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,15 +9,13 @@
|
|||||||
// #define MACHINE_KP_9000_6XHML_X2
|
// #define MACHINE_KP_9000_6XHML_X2
|
||||||
// #define MACHINE_KP_9000_6XH_X
|
// #define MACHINE_KP_9000_6XH_X
|
||||||
// #define MACHINE_KP_9000_9XH_X_EU
|
// #define MACHINE_KP_9000_9XH_X_EU
|
||||||
// #define MACHINE_KP_9000_9XHML_X
|
|
||||||
// #define MACHINE_SWGT024_V2_0
|
// #define MACHINE_SWGT024_V2_0
|
||||||
// #define MACHINE_HORACO_ZX_SG4T2
|
// #define MACHINE_HORACO_ZX_SG4T2
|
||||||
// #define MACHINE_TRENDNET_TEG_S562
|
|
||||||
// #define MACHINE_HG0402XG_V1_1
|
// #define MACHINE_HG0402XG_V1_1
|
||||||
// #define MACHINE_SWTG018AS_A_V_2_0
|
#define MACHINE_ZX_SWTGW215AS_HASIVO
|
||||||
// #define MACHINE_SWTGW218AS
|
// #define DEFAULT_8C_1SFP
|
||||||
// #define MACHINE_HI_K0402WS
|
|
||||||
// #define MACHINE_DEFAULT_8C_1SFP
|
// #define DEFAULT_5C_1SFP
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// GPIO pins for SDA/SCL
|
// GPIO pins for SDA/SCL
|
||||||
@@ -57,7 +55,7 @@ typedef struct machine {
|
|||||||
uint8_t is_sfp[9]; // 0 for non-SFP ports 1 or 2 for the I2C port number
|
uint8_t is_sfp[9]; // 0 for non-SFP ports 1 or 2 for the I2C port number
|
||||||
// sfp_port[0] is the first SFP-port from the left on the device, sfp_port[1] the next if present
|
// sfp_port[0] is the first SFP-port from the left on the device, sfp_port[1] the next if present
|
||||||
struct sfp_port sfp_port[2];
|
struct sfp_port sfp_port[2];
|
||||||
uint8_t reset_pin;
|
int8_t reset_pin;
|
||||||
struct high_leds high_leds;
|
struct high_leds high_leds;
|
||||||
uint8_t port_led_set[9];
|
uint8_t port_led_set[9];
|
||||||
uint32_t led_sets[4][4];
|
uint32_t led_sets[4][4];
|
||||||
@@ -71,6 +69,4 @@ typedef struct machine_runtime
|
|||||||
uint8_t isN : 1;
|
uint8_t isN : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,122 +0,0 @@
|
|||||||
// #define REGDBG
|
|
||||||
// #define DEBUG
|
|
||||||
|
|
||||||
#include "rtl837x_common.h"
|
|
||||||
#include "rtl837x_sfr.h"
|
|
||||||
#include "rtl837x_regs.h"
|
|
||||||
#include "rtl837x_bandwidth.h"
|
|
||||||
#include "machine.h"
|
|
||||||
|
|
||||||
#pragma codeseg BANK2
|
|
||||||
#pragma constseg BANK2
|
|
||||||
|
|
||||||
extern __xdata uint8_t sfr_data[4];
|
|
||||||
|
|
||||||
void bandwidth_setup(void) __banked
|
|
||||||
{
|
|
||||||
print_string("bandwidth_setup called\n");
|
|
||||||
// Exclude all packets possibly for the CPU port, but do not include bypassed packets or Inter-Frame-Gap into bandwidth
|
|
||||||
REG_SET(RTL837X_IGBW_CTRL, IGBW_ADM_DHCP | IGBW_ADM_ARPREQ | IGBW_ADM_RMA | IGBW_ADM_BPDU | IGBW_ADM_RTKPKT | IGBW_ADM_IGMP);
|
|
||||||
|
|
||||||
// We do not count IFG for Egress and allways allow CPU-traffic
|
|
||||||
REG_SET(RTL837X_EGBW_CTRL, EGBW_CPUMODE);
|
|
||||||
|
|
||||||
print_string("RTL837X_IGBW_CTRL: "); print_reg(RTL837X_IGBW_CTRL); write_char('\n');
|
|
||||||
print_string("RTL837X_EGBW_CTRL: "); print_reg(RTL837X_EGBW_CTRL); write_char('\n');
|
|
||||||
print_string("bandwidth_setup done\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the ingress bandwidth
|
|
||||||
* bw: Bandwidth in kb
|
|
||||||
*/
|
|
||||||
void bandwidth_ingress_set(uint8_t port, __xdata uint32_t bw) __banked
|
|
||||||
{
|
|
||||||
__xdata uint8_t * __xdata bwptr = &bw;
|
|
||||||
|
|
||||||
print_string("bandwidth_ingress_set called, port "); print_byte(port); write_char('\n');
|
|
||||||
sfr_data[0] = 0;
|
|
||||||
sfr_data[1] = 0x10 | (*(bwptr + 2) >> 4); // Set bit 20 to enable ingress bandwidth control
|
|
||||||
sfr_data[2] = (*(bwptr + 2) << 4) | (*(bwptr + 1) >> 4);
|
|
||||||
sfr_data[3] = (*(bwptr) >> 4) | (*(bwptr + 1) << 4);
|
|
||||||
reg_write_m(RTL837X_IGBW_PORT_CTRL + port * 4);
|
|
||||||
|
|
||||||
// We enable Flow Control instead of just dropping packets
|
|
||||||
reg_bit_set(RTL837X_IGBW_PORT_FC_CTRL, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void bandwidth_ingress_drop(uint8_t port) __banked
|
|
||||||
{
|
|
||||||
reg_bit_clear(RTL837X_IGBW_PORT_FC_CTRL, port);
|
|
||||||
print_string("RTL837X_IGBW_PORT_FC_CTRL:"); print_reg(RTL837X_IGBW_PORT_FC_CTRL); write_char('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void bandwidth_ingress_fc(uint8_t port) __banked
|
|
||||||
{
|
|
||||||
reg_bit_set(RTL837X_IGBW_PORT_FC_CTRL, port);
|
|
||||||
print_string("RTL837X_IGBW_PORT_FC_CTRL:"); print_reg(RTL837X_IGBW_PORT_FC_CTRL); write_char('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void bandwidth_ingress_disable(uint8_t port) __banked
|
|
||||||
{
|
|
||||||
print_string("Ingress bandwidth limit disabled, port "); print_byte(port); write_char('\n');
|
|
||||||
REG_SET(RTL837X_IGBW_PORT_CTRL + port * 4, 0x0fffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void bandwidth_egress_set(uint8_t port, __xdata uint32_t bw) __banked
|
|
||||||
{
|
|
||||||
__xdata uint8_t * __xdata bwptr = &bw;
|
|
||||||
|
|
||||||
print_string("bandwidth_egress_set called, port "); print_byte(port); write_char('\n');
|
|
||||||
sfr_data[0] = 0;
|
|
||||||
sfr_data[1] = 0x10 | (*(bwptr + 2) >> 4); // Set bit 20 to enable egress bandwidth control
|
|
||||||
sfr_data[2] = (*(bwptr + 2) << 4) | (*(bwptr + 1) >> 4);
|
|
||||||
sfr_data[3] = (*(bwptr) >> 4) | (*(bwptr + 1) << 4);
|
|
||||||
reg_write_m(RTL837X_EGBW_PORT_CTRL + port * 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void bandwidth_egress_disable(uint8_t port) __banked
|
|
||||||
{
|
|
||||||
print_string("Egress bandwidth limit disabled, port "); print_byte(port); write_char('\n');
|
|
||||||
REG_SET(RTL837X_EGBW_PORT_CTRL + port * 1024, 0x0fffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void bandwidth_status(uint8_t port) __banked
|
|
||||||
{
|
|
||||||
print_string("ingress: ");
|
|
||||||
reg_read_m(RTL837X_IGBW_PORT_CTRL + port * 4);
|
|
||||||
if (sfr_data[1] & 0x10) {
|
|
||||||
print_string("enabled: ");
|
|
||||||
sfr_data[1] &= 0xef;
|
|
||||||
print_string("0x");
|
|
||||||
print_byte(sfr_data[1]);
|
|
||||||
print_byte(sfr_data[2]);
|
|
||||||
print_byte(sfr_data[3]);
|
|
||||||
write_char('0');
|
|
||||||
write_char('\n');
|
|
||||||
} else {
|
|
||||||
print_string("disabled\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
print_string("egress: ");
|
|
||||||
reg_read_m(RTL837X_EGBW_PORT_CTRL + port * 1024);
|
|
||||||
if (sfr_data[1] & 0x10) {
|
|
||||||
print_string("enabled: ");
|
|
||||||
sfr_data[1] &= 0xef;
|
|
||||||
print_string("0x");
|
|
||||||
print_byte(sfr_data[1]);
|
|
||||||
print_byte(sfr_data[2]);
|
|
||||||
print_byte(sfr_data[3]);
|
|
||||||
write_char('0');
|
|
||||||
write_char('\n');
|
|
||||||
} else {
|
|
||||||
print_string("disabled\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#ifndef _RTL837X_BANDWIDTH_H_
|
|
||||||
#define _RTL837X_BANDWIDTH_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void bandwidth_setup(void) __banked;
|
|
||||||
void bandwidth_ingress_set(uint8_t port, __xdata uint32_t bw) __banked;
|
|
||||||
void bandwidth_ingress_disable(uint8_t port) __banked;
|
|
||||||
void bandwidth_ingress_drop(uint8_t port) __banked;
|
|
||||||
void bandwidth_ingress_fc(uint8_t port) __banked;
|
|
||||||
void bandwidth_egress_set(uint8_t port, __xdata uint32_t bw) __banked;
|
|
||||||
void bandwidth_egress_disable(uint8_t port) __banked;
|
|
||||||
void bandwidth_status(uint8_t port) __banked;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -19,19 +19,9 @@
|
|||||||
#define LOOKUP_MISS_DROP_9 0x00015555
|
#define LOOKUP_MISS_DROP_9 0x00015555
|
||||||
#define LOOKUP_MISS_FLOOD 0x00000000
|
#define LOOKUP_MISS_FLOOD 0x00000000
|
||||||
|
|
||||||
/* Buffer for serial input, SBUF_SIZE must be power of 2 < 256
|
// The serial buffer. Defines the command line size
|
||||||
* Writing to this buffer is under the sole control of the serial ISR
|
// Must be 2^x and <= 128
|
||||||
* Note that key-presses such as <cursor-left> can create multiple
|
#define SBUF_SIZE 128
|
||||||
* keys (3 to 4) being sent via the serial line, so this must be
|
|
||||||
* sufficiently large */
|
|
||||||
#define SBUF_SIZE 16
|
|
||||||
#define SBUF_MASK (SBUF_SIZE - 1)
|
|
||||||
|
|
||||||
extern __xdata volatile uint8_t sbuf_ptr;
|
|
||||||
extern __xdata uint8_t sbuf[SBUF_SIZE];
|
|
||||||
|
|
||||||
// Define the command buffer size, Must be 2^x and <= 128
|
|
||||||
#define CMD_BUF_SIZE 128
|
|
||||||
|
|
||||||
// Size of the TCP Output buffer
|
// Size of the TCP Output buffer
|
||||||
#define TCP_OUTBUF_SIZE 2500
|
#define TCP_OUTBUF_SIZE 2500
|
||||||
@@ -39,9 +29,6 @@ extern __xdata uint8_t sbuf[SBUF_SIZE];
|
|||||||
// Size of the memory area dedicated to VLAN-names
|
// Size of the memory area dedicated to VLAN-names
|
||||||
#define VLAN_NAMES_SIZE 1024
|
#define VLAN_NAMES_SIZE 1024
|
||||||
|
|
||||||
// Size of the flash buffer used for writing to flash, must be a multiple of the flash page size (0x100)
|
|
||||||
#define FLASH_BUF_SIZE 512
|
|
||||||
|
|
||||||
// For RX data, a propriatary RTL FRAME is inserted. Instead of 0x0800 for IPv4,
|
// For RX data, a propriatary RTL FRAME is inserted. Instead of 0x0800 for IPv4,
|
||||||
// the RTL_FRAME_TAG_ID is used as part of an 8-byte tag. When VLAN is activated,
|
// the RTL_FRAME_TAG_ID is used as part of an 8-byte tag. When VLAN is activated,
|
||||||
// the VLAN tag is inserted after the RTL tag
|
// the VLAN tag is inserted after the RTL tag
|
||||||
@@ -70,15 +57,11 @@ struct vlan_tag {
|
|||||||
// This is the standard size of an Ethernet frame header
|
// This is the standard size of an Ethernet frame header
|
||||||
#define ETHER_HEADER_SIZE 14
|
#define ETHER_HEADER_SIZE 14
|
||||||
|
|
||||||
#define DEFAULT_CONFIG_START 0x6f000
|
|
||||||
#define CONFIG_START 0x70000
|
#define CONFIG_START 0x70000
|
||||||
#define CONFIG_LEN 0x1000
|
#define CONFIG_LEN 0x1000
|
||||||
#define CODE0_SIZE 0x4000
|
#define CODE0_SIZE 0x4000
|
||||||
#define CODE_BANK_SIZE 0xc000
|
#define CODE_BANK_SIZE 0xc000
|
||||||
|
|
||||||
// Store update image after running image
|
|
||||||
#define FIRMWARE_UPLOAD_START 0x80000
|
|
||||||
|
|
||||||
// Constants for the circular command buffer, the size must be 2^n
|
// Constants for the circular command buffer, the size must be 2^n
|
||||||
#define CMD_HISTORY_SIZE 0x400
|
#define CMD_HISTORY_SIZE 0x400
|
||||||
#define CMD_HISTORY_MASK (CMD_HISTORY_SIZE - 1)
|
#define CMD_HISTORY_MASK (CMD_HISTORY_SIZE - 1)
|
||||||
@@ -96,14 +79,10 @@ struct flash_region_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
|
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
|
||||||
extern __xdata struct uip_eth_addr uip_ethaddr;
|
|
||||||
extern __xdata uint16_t rx_packet_vlan;
|
|
||||||
extern __xdata uint16_t dhcpd_vlan;
|
|
||||||
|
|
||||||
// Headers for calls in the common code area (HOME/BANK0)
|
// Headers for calls in the common code area (HOME/BANK0)
|
||||||
void print_string(__code char *p);
|
void print_string(__code char *p);
|
||||||
void print_string_x(__xdata char *p);
|
void print_long(__xdata uint32_t a);
|
||||||
void print_long(uint32_t a);
|
|
||||||
void print_short(uint16_t a);
|
void print_short(uint16_t a);
|
||||||
void print_byte(uint8_t a);
|
void print_byte(uint8_t a);
|
||||||
void itoa(uint8_t v);
|
void itoa(uint8_t v);
|
||||||
@@ -124,7 +103,6 @@ void print_reg(uint16_t reg);
|
|||||||
uint8_t sfp_read_reg(uint8_t slot, uint8_t reg);
|
uint8_t sfp_read_reg(uint8_t slot, uint8_t reg);
|
||||||
void reg_bit_set(uint16_t reg_addr, char bit);
|
void reg_bit_set(uint16_t reg_addr, char bit);
|
||||||
void reg_bit_clear(uint16_t reg_addr, char bit);
|
void reg_bit_clear(uint16_t reg_addr, char bit);
|
||||||
uint8_t reg_bit_test(uint16_t reg_addr, char bit);
|
|
||||||
void sfr_mask_data(uint8_t n, uint8_t mask, uint8_t set);
|
void sfr_mask_data(uint8_t n, uint8_t mask, uint8_t set);
|
||||||
void sfr_set_zero(void);
|
void sfr_set_zero(void);
|
||||||
void reset_chip(void);
|
void reset_chip(void);
|
||||||
@@ -134,8 +112,8 @@ void memset(register __xdata uint8_t *dst, register __xdata uint8_t v, register
|
|||||||
uint16_t strlen(register __code const char *s);
|
uint16_t strlen(register __code const char *s);
|
||||||
uint16_t strlen_x(register __xdata const char *s);
|
uint16_t strlen_x(register __xdata const char *s);
|
||||||
uint16_t strtox(register __xdata uint8_t *dst, register __code const char *s);
|
uint16_t strtox(register __xdata uint8_t *dst, register __code const char *s);
|
||||||
uint16_t strcpy(register __xdata uint8_t *dst, register const char *s);
|
|
||||||
void tcpip_output(void);
|
void tcpip_output(void);
|
||||||
|
void print_string_x(__xdata char *p);
|
||||||
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
|
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
|
||||||
void get_random_32(void);
|
void get_random_32(void);
|
||||||
void read_reg_timer(uint32_t * tmr);
|
void read_reg_timer(uint32_t * tmr);
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
__xdata uint8_t dio_enabled;
|
__xdata uint8_t dio_enabled;
|
||||||
__xdata struct flash_region_t flash_region;
|
__xdata struct flash_region_t flash_region;
|
||||||
|
|
||||||
__xdata uint32_t flash_size;
|
|
||||||
__xdata uint8_t flash_capacity_code;
|
|
||||||
|
|
||||||
// For the flash commands, see e.g. Windbond W25Q32JV datasheet
|
// For the flash commands, see e.g. Windbond W25Q32JV datasheet
|
||||||
#define CMD_WRITE_STATUS 0x01
|
#define CMD_WRITE_STATUS 0x01
|
||||||
@@ -19,7 +17,6 @@ __xdata uint8_t flash_capacity_code;
|
|||||||
// Don't use command `READ 0x03`, because on many device this command can't run at maximum SPI-clock speed.
|
// Don't use command `READ 0x03`, because on many device this command can't run at maximum SPI-clock speed.
|
||||||
// Use `Fast READ 0x0b` instead!
|
// Use `Fast READ 0x0b` instead!
|
||||||
//#define CMD_READ 0x03
|
//#define CMD_READ 0x03
|
||||||
#define CMD_READ_STATUS 0x05
|
|
||||||
#define CMD_WRITE_ENABLE 0x06
|
#define CMD_WRITE_ENABLE 0x06
|
||||||
#define CMD_FREAD 0x0b
|
#define CMD_FREAD 0x0b
|
||||||
#define CMD_SECTOR_ERASE 0x20
|
#define CMD_SECTOR_ERASE 0x20
|
||||||
@@ -90,7 +87,7 @@ uint8_t flash_read_status(void)
|
|||||||
|
|
||||||
// setup status read command
|
// setup status read command
|
||||||
SFR_FLASH_TCONF = 0x11;
|
SFR_FLASH_TCONF = 0x11;
|
||||||
SFR_FLASH_CMD_R = CMD_READ_STATUS;
|
SFR_FLASH_CMD_R = 5;
|
||||||
|
|
||||||
// execute and wait for controller done
|
// execute and wait for controller done
|
||||||
SFR_FLASH_EXEC_GO = 1;
|
SFR_FLASH_EXEC_GO = 1;
|
||||||
@@ -122,10 +119,9 @@ void flash_read_uid(void)
|
|||||||
print_byte(SFR_FLASH_DATA8);
|
print_byte(SFR_FLASH_DATA8);
|
||||||
print_byte(SFR_FLASH_DATA16);
|
print_byte(SFR_FLASH_DATA16);
|
||||||
print_byte(SFR_FLASH_DATA24);
|
print_byte(SFR_FLASH_DATA24);
|
||||||
write_char(' ');
|
|
||||||
|
|
||||||
SFR_FLASH_DUMMYCYCLES = 24; // Doesn't seem to work; we get the same data as for the first transfer
|
|
||||||
SFR_FLASH_EXEC_GO = 1;
|
SFR_FLASH_EXEC_GO = 1;
|
||||||
|
SFR_FLASH_DUMMYCYCLES = 24;
|
||||||
while(SFR_FLASH_EXEC_BUSY);
|
while(SFR_FLASH_EXEC_BUSY);
|
||||||
|
|
||||||
print_byte(SFR_FLASH_DATA0);
|
print_byte(SFR_FLASH_DATA0);
|
||||||
@@ -136,19 +132,6 @@ void flash_read_uid(void)
|
|||||||
flash_configure_mmio();
|
flash_configure_mmio();
|
||||||
}
|
}
|
||||||
|
|
||||||
__code char* get_flash_size_str(void)
|
|
||||||
{
|
|
||||||
switch (flash_capacity_code) {
|
|
||||||
case 0x12: return "256 KB";
|
|
||||||
case 0x13: return "512 KB";
|
|
||||||
case 0x14: return "1 MB";
|
|
||||||
case 0x15: return "2 MB";
|
|
||||||
case 0x16: return "4 MB";
|
|
||||||
case 0x17: return "8 MB";
|
|
||||||
case 0x18: return "16 MB";
|
|
||||||
default: return "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void flash_read_jedecid(void)
|
void flash_read_jedecid(void)
|
||||||
{
|
{
|
||||||
@@ -165,16 +148,15 @@ void flash_read_jedecid(void)
|
|||||||
SFR_FLASH_EXEC_GO = 1;
|
SFR_FLASH_EXEC_GO = 1;
|
||||||
while(SFR_FLASH_EXEC_BUSY);
|
while(SFR_FLASH_EXEC_BUSY);
|
||||||
|
|
||||||
print_string("Flash information:\n");
|
|
||||||
print_string(" Manufacturer ID: 0x");
|
|
||||||
print_byte(SFR_FLASH_DATA0);
|
print_byte(SFR_FLASH_DATA0);
|
||||||
print_string("\n Memory Type: 0x");
|
|
||||||
print_byte(SFR_FLASH_DATA8);
|
print_byte(SFR_FLASH_DATA8);
|
||||||
print_string("\n Capacity: 0x");
|
print_byte(SFR_FLASH_DATA16);
|
||||||
flash_capacity_code = SFR_FLASH_DATA16;
|
print_byte(SFR_FLASH_DATA24);
|
||||||
flash_size = 1UL << flash_capacity_code;
|
|
||||||
print_byte(flash_capacity_code);
|
// Reset slow read mode
|
||||||
print_string(" = "); print_string(get_flash_size_str()); write_char('\n');
|
SFR_FLASH_MODEB = 0x0;
|
||||||
|
SFR_FLASH_CMD_R = CMD_FREAD;
|
||||||
|
SFR_FLASH_DUMMYCYCLES = 8;
|
||||||
|
|
||||||
flash_configure_mmio();
|
flash_configure_mmio();
|
||||||
}
|
}
|
||||||
@@ -206,6 +188,51 @@ void flash_write_enable(void)
|
|||||||
} while (!(status & 0x2));
|
} while (!(status & 0x2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void flash_dump(uint8_t len)
|
||||||
|
{
|
||||||
|
short status;
|
||||||
|
do {
|
||||||
|
status = flash_read_status();
|
||||||
|
print_short(status);
|
||||||
|
} while (status & 0x1);
|
||||||
|
|
||||||
|
// Set fast read mode
|
||||||
|
if (dio_enabled) {
|
||||||
|
SFR_FLASH_MODEB = 0x18;
|
||||||
|
SFR_FLASH_CMD_R = CMD_FREAD_DIO;
|
||||||
|
SFR_FLASH_DUMMYCYCLES = 4;
|
||||||
|
} else {
|
||||||
|
SFR_FLASH_MODEB = 0x0;
|
||||||
|
SFR_FLASH_CMD_R = CMD_FREAD; // Fast read
|
||||||
|
SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks after read?
|
||||||
|
}
|
||||||
|
// Read 4 bytes
|
||||||
|
SFR_FLASH_TCONF = 4;
|
||||||
|
while (len) {
|
||||||
|
SFR_FLASH_ADDR16 = flash_region.addr >> 16;
|
||||||
|
SFR_FLASH_ADDR8 = flash_region.addr >> 8;
|
||||||
|
SFR_FLASH_ADDR0 = flash_region.addr;
|
||||||
|
flash_region.addr += 4;
|
||||||
|
|
||||||
|
SFR_FLASH_EXEC_GO = 1;
|
||||||
|
while(SFR_FLASH_EXEC_BUSY);
|
||||||
|
|
||||||
|
print_short(SFR_FLASH_DATA0);
|
||||||
|
if (len == 1)
|
||||||
|
return;
|
||||||
|
print_short(SFR_FLASH_DATA8);
|
||||||
|
if (len == 2)
|
||||||
|
return;
|
||||||
|
print_short(SFR_FLASH_DATA16);
|
||||||
|
if (len == 3)
|
||||||
|
return;
|
||||||
|
print_short(SFR_FLASH_DATA24);
|
||||||
|
|
||||||
|
len -= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reads bulk data of length len from the flash memory starging at address src
|
* Reads bulk data of length len from the flash memory starging at address src
|
||||||
* and writes the data into a buffer pointed to by dst in XMEM
|
* and writes the data into a buffer pointed to by dst in XMEM
|
||||||
@@ -288,7 +315,7 @@ void flash_read_security(void)
|
|||||||
if (flash_region.len == 3)
|
if (flash_region.len == 3)
|
||||||
break;
|
break;
|
||||||
print_byte(SFR_FLASH_DATA24);
|
print_byte(SFR_FLASH_DATA24);
|
||||||
write_char(' ');
|
|
||||||
flash_region.len -= 4;
|
flash_region.len -= 4;
|
||||||
} while(flash_region.len);
|
} while(flash_region.len);
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,4 @@ void flash_read_security(void);
|
|||||||
void flash_sector_erase(void);
|
void flash_sector_erase(void);
|
||||||
void flash_read_bulk(__xdata uint8_t *dst);
|
void flash_read_bulk(__xdata uint8_t *dst);
|
||||||
void flash_write_bytes(__xdata uint8_t *ptr);
|
void flash_write_bytes(__xdata uint8_t *ptr);
|
||||||
__code char* get_flash_size_str(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ extern __code uint16_t bit_mask[16];
|
|||||||
extern __code const struct machine machine;
|
extern __code const struct machine machine;
|
||||||
extern __xdata struct machine_runtime machine_detected;
|
extern __xdata struct machine_runtime machine_detected;
|
||||||
|
|
||||||
__xdata struct phy_settings phy_settings;
|
|
||||||
|
|
||||||
// SDS-settings for RTL8224 first SerDes which is connected to the RTL837x-SOC.
|
// SDS-settings for RTL8224 first SerDes which is connected to the RTL837x-SOC.
|
||||||
// Array contrains register-value, and SDS-CMD, which already encodes (sds_index, page, reg).
|
// Array contrains register-value, and SDS-CMD, which already encodes (sds_index, page, reg).
|
||||||
// This array is used in phy_config_8224().
|
// This array is used in phy_config_8224().
|
||||||
@@ -188,151 +186,106 @@ void phy_config_8224(void) __banked
|
|||||||
* See e.g. RTL8221B datasheet
|
* See e.g. RTL8221B datasheet
|
||||||
* duplex: 0: half, 1: full, 2: both
|
* duplex: 0: half, 1: full, 2: both
|
||||||
*/
|
*/
|
||||||
void phy_set_speed(void) __banked
|
void phy_set_speed(uint8_t port, uint8_t speed, uint8_t duplex) __banked
|
||||||
{
|
{
|
||||||
uint16_t v;
|
uint16_t v;
|
||||||
|
phy_read(port, PHY_MMD31, 0xa610);
|
||||||
print_string("Setting port "); write_char(machine.log_to_phys_port[phy_settings.port] + '0');
|
|
||||||
if (phy_settings.speed == PHY_OFF) {
|
|
||||||
print_string(" to disabled");
|
|
||||||
} else {
|
|
||||||
print_string(" to speed ");
|
|
||||||
switch(phy_settings.speed) {
|
|
||||||
case PHY_SPEED_AUTO:
|
|
||||||
print_string("auto");
|
|
||||||
break;
|
|
||||||
case PHY_SPEED_10M:
|
|
||||||
print_string("10M");
|
|
||||||
if (phy_settings.duplex)
|
|
||||||
print_string(" full duplex");
|
|
||||||
else
|
|
||||||
print_string(" half duplex");
|
|
||||||
break;
|
|
||||||
case PHY_SPEED_100M:
|
|
||||||
print_string("100M");
|
|
||||||
if (phy_settings.duplex)
|
|
||||||
print_string(" full duplex");
|
|
||||||
else
|
|
||||||
print_string(" half duplex");
|
|
||||||
break;
|
|
||||||
case PHY_SPEED_1G:
|
|
||||||
print_string("1G");
|
|
||||||
break;
|
|
||||||
case PHY_SPEED_2G5:
|
|
||||||
print_string("2G5");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
print_string("UNKNOWN");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write_char('\n');
|
|
||||||
|
|
||||||
phy_read(phy_settings.port, PHY_MMD31, 0xa610);
|
|
||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
if (phy_settings.speed == PHY_OFF) {
|
if (speed == PHY_OFF) {
|
||||||
phy_write(phy_settings.port, PHY_MMD31, 0xa610, v | 0x0800);
|
phy_write(port, PHY_MMD31, 0xa610, v | 0x0800);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Port is on, make sure of it:
|
// Port is on, make sure of it:
|
||||||
if (v & 0x0800)
|
if (v & 0x0800)
|
||||||
phy_write(phy_settings.port, PHY_MMD31, 0xa610, v & 0xf7ff);
|
phy_write(port, PHY_MMD31, 0xa610, v & 0xf7ff);
|
||||||
|
|
||||||
if (phy_settings.speed == PHY_SPEED_AUTO) {
|
if (speed == PHY_SPEED_AUTO) {
|
||||||
// AN Advertisement Register (MMD 7.0x0010)
|
// AN Advertisement Register (MMD 7.0x0010)
|
||||||
// bits 0-4: 0x1 (802.3 supported), Extended Next Page format used
|
// bits 0-4: 0x1 (802.3 supported), Extended Next Page format used
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x15e1);
|
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x15e1);
|
||||||
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
||||||
// bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD
|
// bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
phy_write(port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
||||||
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
||||||
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200); // Loop timing enabled
|
phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200); // Loop timing enabled
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3200); // Restart AN
|
phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x3200); // Restart AN
|
||||||
} else {
|
} else {
|
||||||
// AN Control Register (MMD 7.0x0000)
|
// AN Control Register (MMD 7.0x0000)
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x2000); // Clear bit 12: No Autoneg, Set Extended Pages (bit 13)
|
phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x2000); // Clear bit 12: No Autoneg, Set Extended Pages (bit 13)
|
||||||
if (phy_settings.speed == PHY_SPEED_10M) {
|
if (speed == PHY_SPEED_10M) {
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001);
|
phy_write(port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001);
|
||||||
if (!phy_settings.duplex)
|
if (!duplex)
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1421);
|
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1421);
|
||||||
else if (phy_settings.duplex == 1)
|
else if (duplex == 1)
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1441);
|
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1441);
|
||||||
else
|
else
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1461);
|
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1461);
|
||||||
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
||||||
} else if (phy_settings.speed == PHY_SPEED_100M) {
|
} else if (speed == PHY_SPEED_100M) {
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001);
|
phy_write(port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001);
|
||||||
if (!phy_settings.duplex)
|
if (!duplex)
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1481);
|
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1481);
|
||||||
if (phy_settings.duplex == 1)
|
if (duplex == 1)
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1501);
|
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1501);
|
||||||
else
|
else
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1581);
|
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1581);
|
||||||
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
||||||
} else {
|
} else {
|
||||||
// AN Advertisement Register (MMD 7.0x0010)
|
// AN Advertisement Register (MMD 7.0x0010)
|
||||||
// bits 0-4: 0x1 (802.3 supported), Extended Next Page format used
|
// bits 0-4: 0x1 (802.3 supported), Extended Next Page format used
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1001);
|
phy_write(port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1001);
|
||||||
if (phy_settings.speed == PHY_SPEED_1G) {
|
if (speed == PHY_SPEED_1G) {
|
||||||
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
||||||
// bit 14: SLAVE, bit 13: Multi-Port device, 1: LD Loop timin enableed
|
// bit 14: SLAVE, bit 13: Multi-Port device, 1: LD Loop timin enableed
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001);
|
phy_write(port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001);
|
||||||
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
||||||
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200);
|
phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0000, 0x0200);
|
||||||
} else if (phy_settings.speed == PHY_SPEED_2G5) {
|
} else if (speed == PHY_SPEED_2G5) {
|
||||||
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
// Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020)
|
||||||
// bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD Loop timin enableed
|
// bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD Loop timin enableed
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
phy_write(port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6081);
|
||||||
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
// GBCR (1000Base-T Control Register, MMD 31.0xA412)
|
||||||
phy_modify(phy_settings.port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
phy_modify(port, PHY_MMD31, PHY_MMD31_GBCR, 0x0200, 0x0000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3000); // Enable AN
|
phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x3000); // Enable AN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void phy_set_duplex(void) __banked
|
void phy_set_duplex(uint8_t port, uint8_t fullduplex) __banked
|
||||||
{
|
{
|
||||||
uint16_t v;
|
uint16_t v;
|
||||||
|
phy_read(port, PHY_MMD31, PHY_ANEG_CTRL);
|
||||||
print_string("Setting port "); write_char(machine.log_to_phys_port[phy_settings.port] + '0');
|
|
||||||
if (phy_settings.duplex)
|
|
||||||
print_string(" to full duplex");
|
|
||||||
else
|
|
||||||
print_string(" to half duplex");
|
|
||||||
write_char('\n');
|
|
||||||
|
|
||||||
phy_read(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL);
|
|
||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
if (!(v & 0x1000)) { // AN disabled, we are in forced mode
|
if (!(v & 0x1000)) { // AN disabled, we are in forced mode
|
||||||
phy_read(phy_settings.port, PHY_MMD31, PHY_MMD31_FEDCR);
|
phy_read(port, PHY_MMD31, PHY_MMD31_FEDCR);
|
||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
if (phy_settings.duplex)
|
if (fullduplex)
|
||||||
v |= 0x0100;
|
v |= 0x0100;
|
||||||
else
|
else
|
||||||
v &= 0xfeff;
|
v &= 0xfeff;
|
||||||
phy_write(phy_settings.port, PHY_MMD31, PHY_MMD31_FEDCR, v);
|
phy_write(port, PHY_MMD31, PHY_MMD31_FEDCR, v);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Disable AN
|
// Disable AN
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x2000);
|
phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x2000);
|
||||||
phy_read(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV);
|
phy_read(port, PHY_MMD_AN, PHY_ANEG_ADV);
|
||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
if (v & 0x0060) {
|
if (v & 0x0060) {
|
||||||
if (phy_settings.duplex)
|
if (fullduplex)
|
||||||
phy_modify(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0xffbf, 0x0040);
|
phy_modify(port, PHY_MMD_AN, PHY_ANEG_ADV, 0xffbf, 0x0040);
|
||||||
else
|
else
|
||||||
phy_modify(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0xffdf, 0x0020);
|
phy_modify(port, PHY_MMD_AN, PHY_ANEG_ADV, 0xffdf, 0x0020);
|
||||||
}
|
}
|
||||||
if (v & 0x0180) {
|
if (v & 0x0180) {
|
||||||
if (phy_settings.duplex)
|
if (fullduplex)
|
||||||
phy_modify(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0xfeff, 0x0100);
|
phy_modify(port, PHY_MMD_AN, PHY_ANEG_ADV, 0xfeff, 0x0100);
|
||||||
else
|
else
|
||||||
phy_modify(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0xff7f, 0x0080);
|
phy_modify(port, PHY_MMD_AN, PHY_ANEG_ADV, 0xff7f, 0x0080);
|
||||||
}
|
}
|
||||||
// Restart AN
|
// Restart AN
|
||||||
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_CTRL, 0x3000);
|
phy_write(port, PHY_MMD31, PHY_ANEG_CTRL, 0x3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -374,7 +327,7 @@ void phy_show(uint8_t port) __banked
|
|||||||
else
|
else
|
||||||
print_string(" half duplex");
|
print_string(" half duplex");
|
||||||
|
|
||||||
phy_read(port, PHY_MMD_AN, PHY_ANEG_CTRL);
|
phy_read(port, PHY_MMD31, PHY_ANEG_CTRL);
|
||||||
v = SFR_DATA_U16;
|
v = SFR_DATA_U16;
|
||||||
if (!(v & 0x1000)) { // AN disabled, we are in forced mode
|
if (!(v & 0x1000)) { // AN disabled, we are in forced mode
|
||||||
phy_read(port, PHY_MMD_PMAPMD, 0);
|
phy_read(port, PHY_MMD_PMAPMD, 0);
|
||||||
|
|||||||
@@ -10,19 +10,11 @@
|
|||||||
#define PHY_SPEED_AUTO 0x10
|
#define PHY_SPEED_AUTO 0x10
|
||||||
#define PHY_OFF 0xff
|
#define PHY_OFF 0xff
|
||||||
|
|
||||||
struct phy_settings {
|
|
||||||
uint8_t duplex;
|
|
||||||
uint8_t port;
|
|
||||||
uint8_t speed;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern __xdata struct phy_settings phy_settings;
|
|
||||||
|
|
||||||
void rtl8224_phy_enable(void) __banked;
|
void rtl8224_phy_enable(void) __banked;
|
||||||
void phy_config(uint8_t phy) __banked;
|
void phy_config(uint8_t phy) __banked;
|
||||||
void phy_config_8224(void) __banked;
|
void phy_config_8224(void) __banked;
|
||||||
void phy_set_speed(void) __banked;
|
void phy_set_speed(uint8_t port, uint8_t speed, uint8_t duplex) __banked;
|
||||||
void phy_set_duplex(void) __banked;
|
void phy_set_duplex(uint8_t port, uint8_t fullduplex) __banked;
|
||||||
void phy_show(uint8_t port) __banked;
|
void phy_show(uint8_t port) __banked;
|
||||||
void phy_reset(uint8_t port) __banked;
|
void phy_reset(uint8_t port) __banked;
|
||||||
void rtl8224_read_reg_u16(uint16_t reg) __banked;
|
void rtl8224_read_reg_u16(uint16_t reg) __banked;
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ extern __xdata struct machine_runtime machine_detected;
|
|||||||
|
|
||||||
__xdata uint32_t l2_head;
|
__xdata uint32_t l2_head;
|
||||||
|
|
||||||
__xdata struct vlan_settings vlan_settings;
|
|
||||||
|
|
||||||
void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked
|
void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked
|
||||||
{
|
{
|
||||||
print_string("\nport_mirror_set called \n");
|
print_string("\nport_mirror_set called \n");
|
||||||
@@ -48,7 +46,7 @@ void port_mirror_del(void) __banked
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void port_ingress_filter(__xdata uint8_t port, __xdata uint8_t type) __banked
|
void port_ingress_filter(register uint8_t port, uint8_t type) __banked
|
||||||
{
|
{
|
||||||
if (type & 0x1)
|
if (type & 0x1)
|
||||||
reg_bit_set(RTL837x_REG_INGRESS, port << 1);
|
reg_bit_set(RTL837x_REG_INGRESS, port << 1);
|
||||||
@@ -123,31 +121,27 @@ __xdata uint16_t vlan_name(register uint16_t vlan) __banked
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a VLAN
|
|
||||||
* The arguments are passed in global structure vlan_settings
|
|
||||||
* A member that is not tagged, is untagged
|
* A member that is not tagged, is untagged
|
||||||
*/
|
*/
|
||||||
void vlan_create(void) __banked
|
void vlan_create(register uint16_t vlan, register uint16_t members, register uint16_t tagged) __banked
|
||||||
{
|
{
|
||||||
// For now, the CPU-port is always a tagged member:
|
// For now, the CPU-port is always a tagged member:
|
||||||
vlan_settings.members |= 0x0200; // Set 10th bit
|
members |= 0x0200; // Set 10th bit
|
||||||
vlan_settings.tagged |= 0x0200;
|
tagged |= 0x0200;
|
||||||
|
print_string("\nvlan_create called\nvlan: "); print_short(vlan);
|
||||||
print_string("\nvlan_create called\nvlan: "); print_short(vlan_settings.vlan);
|
print_string(", members: "); print_short(members);
|
||||||
print_string(", members: "); print_short(vlan_settings.members);
|
print_string(", tagged: "); print_short(tagged); write_char('\n');
|
||||||
print_string(", tagged: "); print_short(vlan_settings.tagged); write_char('\n');
|
|
||||||
|
|
||||||
uint16_t a = (~vlan_settings.members) ^ vlan_settings.tagged ^ vlan_settings.members;
|
|
||||||
|
|
||||||
|
uint16_t a = (~members) ^ tagged ^ members;
|
||||||
// On RTL8372, port-bits 0-2 must be 0, although they are not members
|
// On RTL8372, port-bits 0-2 must be 0, although they are not members
|
||||||
if (!machine_detected.isRTL8373) {
|
if (!machine_detected.isRTL8373) {
|
||||||
a &= 0x1f8;
|
a &= 0x1f8;
|
||||||
vlan_settings.tagged &= 0x3f8;
|
tagged &= 0x3f8;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize VLAN table with VLAN 1
|
// Initialize VLAN table with VLAN 1
|
||||||
REG_WRITE(RTL837x_TBL_DATA_IN_A, 0x02, (a >> 6) & 0x0f, (a << 2) | (vlan_settings.members >> 8), vlan_settings.members);
|
REG_WRITE(RTL837x_TBL_DATA_IN_A, 0x02, (a >> 6) & 0x0f, (a << 2) | (members >> 8), members);
|
||||||
REG_WRITE(RTL837X_TBL_CTRL, vlan_settings.vlan >> 8, vlan_settings.vlan, TBL_VLAN, TBL_WRITE | TBL_EXECUTE);
|
REG_WRITE(RTL837X_TBL_CTRL, vlan >> 8, vlan, TBL_VLAN, TBL_WRITE | TBL_EXECUTE);
|
||||||
do {
|
do {
|
||||||
reg_read_m(RTL837X_TBL_CTRL);
|
reg_read_m(RTL837X_TBL_CTRL);
|
||||||
} while (sfr_data[3] & TBL_EXECUTE);
|
} while (sfr_data[3] & TBL_EXECUTE);
|
||||||
@@ -369,28 +363,15 @@ void port_stats_print(void) __banked
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t b = 0;
|
|
||||||
|
|
||||||
// Determine link state
|
|
||||||
reg_read_m(RTL837X_REG_LINKS_STS);
|
|
||||||
if(!((sfr_data[(i / 8) + 1] >> ( i % 8 ) & 1)))
|
|
||||||
{
|
|
||||||
b = 99;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (i < 8)
|
if (i < 8)
|
||||||
reg_read_m(RTL837X_REG_LINKS);
|
reg_read_m(RTL837X_REG_LINKS);
|
||||||
else
|
else
|
||||||
reg_read_m(RTL837X_REG_LINKS_89);
|
reg_read_m(RTL837X_REG_LINKS_89);
|
||||||
|
uint8_t b = sfr_data[3 - ((i & 7) >> 1)];
|
||||||
b = sfr_data[3 - ((i & 7) >> 1)];
|
|
||||||
b = (i & 1) ? b >> 4 : b & 0xf;
|
b = (i & 1) ? b >> 4 : b & 0xf;
|
||||||
}
|
|
||||||
|
|
||||||
switch (b) {
|
switch (b) {
|
||||||
case 0:
|
case 0:
|
||||||
print_string("10M\t");
|
print_string("Down\t");
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
print_string("100M\t");
|
print_string("100M\t");
|
||||||
@@ -404,9 +385,6 @@ void port_stats_print(void) __banked
|
|||||||
case 5:
|
case 5:
|
||||||
print_string("2.5G\t");
|
print_string("2.5G\t");
|
||||||
break;
|
break;
|
||||||
case 99:
|
|
||||||
print_string("Down\t");
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
print_string("Up\t");
|
print_string("Up\t");
|
||||||
break;
|
break;
|
||||||
@@ -444,49 +422,17 @@ uint16_t port_isolation_get(register uint8_t port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void port_eee_enable(__xdata uint8_t port,__xdata uint8_t speed) __banked
|
void port_eee_enable(uint8_t port) __banked
|
||||||
{
|
{
|
||||||
|
|
||||||
if (machine.is_sfp[port])
|
if (machine.is_sfp[port])
|
||||||
{
|
|
||||||
print_string("EEE can't be enabled for SFP port "); print_byte(port); print_string("\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
print_string("EEE on for "); print_byte(port); print_string(" speed ");
|
|
||||||
// Enable all speeds up to the specified speed
|
|
||||||
if ((speed & (EEE_100 | EEE_1000 | EEE_2G5)) == EEE_100) {
|
|
||||||
print_string("100m\n");
|
|
||||||
REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100);
|
|
||||||
// Enable EEE advertisement for 100BASE-T via EEE Advertisement Reg
|
|
||||||
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_100M);
|
|
||||||
if (!(speed & EEE_NORESET))
|
|
||||||
phy_reset(port);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((speed & (EEE_100 | EEE_1000 | EEE_2G5)) == EEE_1000) {
|
|
||||||
print_string("1g\n");
|
|
||||||
REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100 | EEE_1000);
|
|
||||||
// Disable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
|
||||||
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV2, 0);
|
|
||||||
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
|
||||||
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_1G | PHY_EEE_BIT_100M);
|
|
||||||
if (!(speed & EEE_NORESET))
|
|
||||||
phy_reset(port);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((speed & (EEE_100 | EEE_1000 | EEE_2G5)) == EEE_2G5) {
|
|
||||||
print_string("2g5\n");
|
|
||||||
REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100 | EEE_1000 | EEE_2G5);
|
REG_SET(RTL8373_EEE_CTRL_BASE + (port << 2), EEE_100 | EEE_1000 | EEE_2G5);
|
||||||
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
// Enable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
|
||||||
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_1G | PHY_EEE_BIT_100M);
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, PHY_EEE_BIT_1G | PHY_EEE_BIT_100M);
|
||||||
// Enable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
// Enable EEE advertisement for 2.5GBASE-T via EEE Advertisement Reg 2
|
||||||
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV2, PHY_EEE_BIT_2G5);
|
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV2, PHY_EEE_BIT_2G5);
|
||||||
if (!(speed & EEE_NORESET))
|
|
||||||
phy_reset(port);
|
phy_reset(port);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -560,10 +506,10 @@ void port_eee_status(uint8_t port) __banked
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void port_eee_enable_all(__xdata uint8_t speed) __banked
|
void port_eee_enable_all(void) __banked
|
||||||
{
|
{
|
||||||
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
port_eee_enable(i, speed);
|
port_eee_enable(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,14 +13,6 @@
|
|||||||
reg_read_m(RTL837X_STAT_GET); \
|
reg_read_m(RTL837X_STAT_GET); \
|
||||||
} while (sfr_data[3] & 0x1);
|
} while (sfr_data[3] & 0x1);
|
||||||
|
|
||||||
struct vlan_settings {
|
|
||||||
uint16_t vlan;
|
|
||||||
uint16_t members;
|
|
||||||
uint16_t tagged;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern __xdata struct vlan_settings vlan_settings;
|
|
||||||
|
|
||||||
uint8_t port_l2_forget(void) __banked;
|
uint8_t port_l2_forget(void) __banked;
|
||||||
void port_l2_learned(void) __banked;
|
void port_l2_learned(void) __banked;
|
||||||
void port_stats_print(void) __banked;
|
void port_stats_print(void) __banked;
|
||||||
@@ -28,18 +20,18 @@ int8_t vlan_get(register uint16_t vlan) __banked;
|
|||||||
__xdata uint16_t vlan_name(register uint16_t vlan) __banked;
|
__xdata uint16_t vlan_name(register uint16_t vlan) __banked;
|
||||||
void vlan_setup(void) __banked;
|
void vlan_setup(void) __banked;
|
||||||
void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked;
|
void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked;
|
||||||
void vlan_create(void) __banked;
|
void vlan_create(register uint16_t vlan, register uint16_t members, register uint16_t tagged) __banked;
|
||||||
void vlan_delete(uint16_t vlan) __banked;
|
void vlan_delete(uint16_t vlan) __banked;
|
||||||
void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked;
|
void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked;
|
||||||
void port_mirror_del(void) __banked;
|
void port_mirror_del(void) __banked;
|
||||||
void port_ingress_filter(__xdata uint8_t port, __xdata uint8_t type) __banked;
|
void port_ingress_filter(register uint8_t port, uint8_t type) __banked;
|
||||||
void port_l2_setup(void) __banked;
|
void port_l2_setup(void) __banked;
|
||||||
void port_lag_members_set(__xdata uint8_t lag, __xdata uint16_t members) __banked;
|
void port_lag_members_set(__xdata uint8_t lag, __xdata uint16_t members) __banked;
|
||||||
void port_lag_hash_set(__xdata uint8_t lag, __xdata uint8_t hash) __banked;
|
void port_lag_hash_set(__xdata uint8_t lag, __xdata uint8_t hash) __banked;
|
||||||
void port_eee_enable_all(__xdata uint8_t speed) __banked;
|
void port_eee_enable_all(void) __banked;
|
||||||
void port_eee_disable_all(void) __banked;
|
void port_eee_disable_all(void) __banked;
|
||||||
void port_eee_status_all(void) __banked;
|
void port_eee_status_all(void) __banked;
|
||||||
void port_eee_enable(__xdata uint8_t port, __xdata uint8_t speed) __banked;
|
void port_eee_enable(uint8_t port) __banked;
|
||||||
void port_eee_disable(uint8_t port) __banked;
|
void port_eee_disable(uint8_t port) __banked;
|
||||||
void port_eee_status(uint8_t port) __banked;
|
void port_eee_status(uint8_t port) __banked;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
#define RTL837X_REG_CHIP_ID 0x0004
|
#define RTL837X_REG_CHIP_ID 0x0004
|
||||||
#define RTL837X_REG_CHIP_INFO 0x000c
|
#define RTL837X_REG_CHIP_INFO 0x000c
|
||||||
#define RTL837X_REG_CHIP_UUID 0x0010
|
|
||||||
#define RTL837X_REG_CHIP_LOT_NO 0x0014
|
|
||||||
#define RTL837X_REG_RESET 0x0024
|
#define RTL837X_REG_RESET 0x0024
|
||||||
#define RESET_SOC_BIT 0
|
#define RESET_SOC_BIT 0
|
||||||
#define RESET_NIC_BIT 2
|
#define RESET_NIC_BIT 2
|
||||||
@@ -80,8 +78,6 @@
|
|||||||
|
|
||||||
#define RTL837X_REG_LINKS 0x63f0
|
#define RTL837X_REG_LINKS 0x63f0
|
||||||
#define RTL837X_REG_LINKS_89 0x63f4
|
#define RTL837X_REG_LINKS_89 0x63f4
|
||||||
#define RTL837X_REG_LINKS_STS 0x63E8
|
|
||||||
|
|
||||||
/* Each nibble encodes the link state of a port.
|
/* Each nibble encodes the link state of a port.
|
||||||
Port 0 appears to be the CPU port
|
Port 0 appears to be the CPU port
|
||||||
The RTL8372 serves ports 4-7, port 3 is the RTL8221
|
The RTL8372 serves ports 4-7, port 3 is the RTL8221
|
||||||
@@ -275,7 +271,6 @@
|
|||||||
#define EEE_100 0x01
|
#define EEE_100 0x01
|
||||||
#define EEE_1000 0x04
|
#define EEE_1000 0x04
|
||||||
#define EEE_2G5 0x10
|
#define EEE_2G5 0x10
|
||||||
#define EEE_NORESET 0x80
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RANDOM
|
* RANDOM
|
||||||
@@ -285,25 +280,6 @@
|
|||||||
#define RTL837X_RAND_NUM0 0x107C
|
#define RTL837X_RAND_NUM0 0x107C
|
||||||
#define RTL837X_RAND_NUM1 0x1080
|
#define RTL837X_RAND_NUM1 0x1080
|
||||||
|
|
||||||
/*
|
|
||||||
* Bandwidth control
|
|
||||||
*/
|
|
||||||
#define RTL837X_IGBW_CTRL 0x4c10
|
|
||||||
#define IGBW_INC_BYPASS_PKT 0x100
|
|
||||||
#define IGBW_INC_IFG 0x80
|
|
||||||
#define IGBW_ADM_DHCP 0x20
|
|
||||||
#define IGBW_ADM_ARPREQ 0x10
|
|
||||||
#define IGBW_ADM_RMA 0x08
|
|
||||||
#define IGBW_ADM_BPDU 0x04
|
|
||||||
#define IGBW_ADM_RTKPKT 0x02
|
|
||||||
#define IGBW_ADM_IGMP 0x01
|
|
||||||
#define RTL837X_IGBW_PORT_CTRL 0x4C18
|
|
||||||
#define RTL837X_IGBW_PORT_FC_CTRL 0x4C8C
|
|
||||||
#define RTL837X_EGBW_PORT_CTRL 0x1c34
|
|
||||||
#define RTL837X_EGBW_CTRL 0x447c
|
|
||||||
#define EGBW_INC_IFG 0x02
|
|
||||||
#define EGBW_CPUMODE 0x01
|
|
||||||
|
|
||||||
#ifdef REGDBG
|
#ifdef REGDBG
|
||||||
|
|
||||||
#define REG_SET(r, v) SFR_DATA_24 = (((uint32_t)v) >> 24) & 0xff; \
|
#define REG_SET(r, v) SFR_DATA_24 = (((uint32_t)v) >> 24) & 0xff; \
|
||||||
|
|||||||
@@ -40,9 +40,6 @@ __sfr __at(0x91) EXIF;
|
|||||||
__sfr __at(0xf8) EIP;
|
__sfr __at(0xf8) EIP;
|
||||||
__sbit __at(0xf9) PX3;
|
__sbit __at(0xf9) PX3;
|
||||||
|
|
||||||
/* MPAGE page (sdcc _XPAGE) register for "movx @Ri" */
|
|
||||||
__sfr __at(0x92) _XPAGE; /* _XPAGE is used by sdcc in xstack mode */
|
|
||||||
__sfr __at(0x92) MPAGE;
|
|
||||||
/* SFR Bank control register: 0x0-3f. A value of 0 is bank 1 */
|
/* SFR Bank control register: 0x0-3f. A value of 0 is bank 1 */
|
||||||
__sfr __at(0x96) PSBANK;
|
__sfr __at(0x96) PSBANK;
|
||||||
// SFR used to store return bank for trampoline
|
// SFR used to store return bank for trampoline
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
extern __code struct machine machine;
|
extern __code struct machine machine;
|
||||||
extern __xdata uint8_t sfr_data[4];
|
extern __xdata uint8_t sfr_data[4];
|
||||||
|
|
||||||
extern __xdata struct uip_eth_addr uip_ethaddr;
|
extern __code struct uip_eth_addr uip_ethaddr;
|
||||||
|
|
||||||
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE + 2];
|
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE + 2];
|
||||||
|
|
||||||
@@ -164,9 +164,9 @@ void stp_cnf_send(uint8_t port)
|
|||||||
STP_O->bpdu_type = 0x00; // Config
|
STP_O->bpdu_type = 0x00; // Config
|
||||||
STP_O->flags = 0x81;
|
STP_O->flags = 0x81;
|
||||||
|
|
||||||
memcpy(STP_O->src_addr, uip_ethaddr.addr, 6);
|
memcpyc(STP_O->src_addr, uip_ethaddr.addr, 6);
|
||||||
memcpy(STP_O->root.mac, root_bridge.mac, 6);
|
memcpy(STP_O->root.mac, root_bridge.mac, 6);
|
||||||
memcpy(STP_O->bridge.mac, uip_ethaddr.addr, 6);
|
memcpyc(STP_O->bridge.mac, uip_ethaddr.addr, 6);
|
||||||
|
|
||||||
STP_O->root.prio = root_bridge.prio;
|
STP_O->root.prio = root_bridge.prio;
|
||||||
STP_O->root.ext = 0x00;
|
STP_O->root.ext = 0x00;
|
||||||
@@ -221,7 +221,7 @@ void stp_setup(void) __banked
|
|||||||
|
|
||||||
root_bridge.prio = 0x80; // This corresponds to 32768
|
root_bridge.prio = 0x80; // This corresponds to 32768
|
||||||
root_bridge.ext = 0x00;
|
root_bridge.ext = 0x00;
|
||||||
memcpy(root_bridge.mac, uip_ethaddr.addr, 6);
|
memcpyc(root_bridge.mac, uip_ethaddr.addr, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,23 +14,25 @@
|
|||||||
#include "rtl837x_stp.h"
|
#include "rtl837x_stp.h"
|
||||||
#include "rtl837x_igmp.h"
|
#include "rtl837x_igmp.h"
|
||||||
#include "rtl837x_leds.h"
|
#include "rtl837x_leds.h"
|
||||||
#include "rtl837x_bandwidth.h"
|
|
||||||
#include "dhcp.h"
|
#include "dhcp.h"
|
||||||
#include "cmd_parser.h"
|
#include "cmd_parser.h"
|
||||||
#include "cmd_editor.h"
|
|
||||||
#include "uip/uipopt.h"
|
#include "uip/uipopt.h"
|
||||||
#include "uip/uip.h"
|
#include "uip/uip.h"
|
||||||
#include "uip/uip_arp.h"
|
#include "uip/uip_arp.h"
|
||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "phy.h"
|
#include "phy.h"
|
||||||
|
|
||||||
|
|
||||||
extern __code const struct machine machine;
|
extern __code const struct machine machine;
|
||||||
extern __xdata uint32_t flash_size;
|
|
||||||
|
|
||||||
extern __xdata uint16_t crc_value;
|
extern __xdata uint16_t crc_value;
|
||||||
|
__xdata uint8_t crc_testbytes[10];
|
||||||
__xdata struct machine_runtime machine_detected;
|
__xdata struct machine_runtime machine_detected;
|
||||||
void crc16(__xdata uint8_t *v) __naked;
|
void crc16(__xdata uint8_t *v) __naked;
|
||||||
|
|
||||||
|
// Upload Firmware to 1M
|
||||||
|
#define FIRMWARE_UPLOAD_START 0x100000
|
||||||
|
|
||||||
// See setup_serial_timer1() for valid baudrate settings!
|
// See setup_serial_timer1() for valid baudrate settings!
|
||||||
#define SERIAL_BAUD_RATE 115200
|
#define SERIAL_BAUD_RATE 115200
|
||||||
|
|
||||||
@@ -75,11 +77,10 @@ void crc16(__xdata uint8_t *v) __naked;
|
|||||||
__xdata uint8_t idle_ready;
|
__xdata uint8_t idle_ready;
|
||||||
|
|
||||||
__code uint8_t ownIP[] = { 192, 168, 2, 2 };
|
__code uint8_t ownIP[] = { 192, 168, 2, 2 };
|
||||||
|
__code struct uip_eth_addr uip_ethaddr = {{ 0x1c, 0x2a, 0xa3, 0x23, 0x00, 0x02 }};
|
||||||
__code uint8_t gatewayIP[] = { 192, 168, 2, 22};
|
__code uint8_t gatewayIP[] = { 192, 168, 2, 22};
|
||||||
__code uint8_t netmask[] = { 255, 255, 255, 0};
|
__code uint8_t netmask[] = { 255, 255, 255, 0};
|
||||||
|
|
||||||
__xdata struct uip_eth_addr uip_ethaddr;
|
|
||||||
|
|
||||||
volatile __xdata uint32_t ticks;
|
volatile __xdata uint32_t ticks;
|
||||||
volatile __xdata uint8_t sec_counter;
|
volatile __xdata uint8_t sec_counter;
|
||||||
volatile __xdata uint16_t sleep_ticks;
|
volatile __xdata uint16_t sleep_ticks;
|
||||||
@@ -88,13 +89,10 @@ extern __xdata struct dhcp_state dhcp_state;
|
|||||||
|
|
||||||
#define STP_TICK_DIVIDER 3
|
#define STP_TICK_DIVIDER 3
|
||||||
|
|
||||||
/* Buffer for serial input, SBUF_SIZE must be power of 2 < 256
|
|
||||||
* Writing to this buffer is under the sole control of the serial ISR
|
// Buffer for serial input, SBUF_SIZE must be power of 2 < 256
|
||||||
* Note that key-presses such as <cursor-left> can create multiple
|
|
||||||
* keys being sent via the serial line */
|
|
||||||
__xdata volatile uint8_t sbuf_ptr;
|
__xdata volatile uint8_t sbuf_ptr;
|
||||||
__xdata uint8_t sbuf[SBUF_SIZE];
|
__xdata uint8_t sbuf[SBUF_SIZE];
|
||||||
|
|
||||||
__xdata uint8_t sfr_data[4];
|
__xdata uint8_t sfr_data[4];
|
||||||
|
|
||||||
extern __xdata uint8_t gpio_last_value[8];
|
extern __xdata uint8_t gpio_last_value[8];
|
||||||
@@ -104,7 +102,7 @@ extern __xdata struct flash_region_t flash_region;
|
|||||||
__code uint8_t * __code greeting = "\nA minimal prompt to explore the RTL8372:\n";
|
__code uint8_t * __code greeting = "\nA minimal prompt to explore the RTL8372:\n";
|
||||||
__code uint8_t * __code hex = "0123456789abcdef";
|
__code uint8_t * __code hex = "0123456789abcdef";
|
||||||
|
|
||||||
__xdata uint8_t flash_buf[FLASH_BUF_SIZE];
|
__xdata uint8_t flash_buf[512];
|
||||||
|
|
||||||
// NIC buffers for packet RX/TX
|
// NIC buffers for packet RX/TX
|
||||||
__xdata uint8_t rx_headers[16]; // Packet header(s) on RX
|
__xdata uint8_t rx_headers[16]; // Packet header(s) on RX
|
||||||
@@ -129,8 +127,6 @@ __xdata char sfp_module_vendor[2][17];
|
|||||||
__xdata char sfp_module_model[2][17];
|
__xdata char sfp_module_model[2][17];
|
||||||
__xdata char sfp_module_serial[2][17];
|
__xdata char sfp_module_serial[2][17];
|
||||||
__xdata uint8_t sfp_options[2];
|
__xdata uint8_t sfp_options[2];
|
||||||
__xdata bool button_last;
|
|
||||||
__xdata uint8_t button_sec_counter_last;
|
|
||||||
__sbit tx_buf_empty;
|
__sbit tx_buf_empty;
|
||||||
|
|
||||||
#define ETHERTYPE_OFFSET (12 + VLAN_TAG_SIZE + RTL_TAG_SIZE)
|
#define ETHERTYPE_OFFSET (12 + VLAN_TAG_SIZE + RTL_TAG_SIZE)
|
||||||
@@ -241,7 +237,6 @@ uint16_t strtox(register __xdata uint8_t *dst, register __code const char *s)
|
|||||||
return dst - b;
|
return dst - b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t strlen(register __code const char *s)
|
uint16_t strlen(register __code const char *s)
|
||||||
{
|
{
|
||||||
uint16_t l = 0;
|
uint16_t l = 0;
|
||||||
@@ -262,45 +257,28 @@ uint16_t strlen_x(register __xdata const char *s)
|
|||||||
|
|
||||||
void print_short(uint16_t a)
|
void print_short(uint16_t a)
|
||||||
{
|
{
|
||||||
// allocating the registers first improves the sdcc code here
|
|
||||||
uint8_t h = a >> 8;
|
|
||||||
uint8_t l = a;
|
|
||||||
|
|
||||||
print_string("0x");
|
print_string("0x");
|
||||||
print_byte(h);
|
for (signed char i = 12; i >= 0; i -= 4) {
|
||||||
print_byte(l);
|
write_char(hex[(a >> i) & 0xf]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_long(uint32_t a)
|
|
||||||
{
|
|
||||||
// allocating the registers first improves the sdcc code here
|
|
||||||
uint8_t a24 = a >> 24;
|
|
||||||
uint8_t a16 = a >> 16;
|
|
||||||
uint8_t a8 = a >> 8;
|
|
||||||
uint8_t a0 = a;
|
|
||||||
|
|
||||||
|
void print_long(__xdata uint32_t a)
|
||||||
|
{
|
||||||
print_string("0x");
|
print_string("0x");
|
||||||
print_byte(a24);
|
for (signed char i = 28; i >= 0; i -= 4) {
|
||||||
print_byte(a16);
|
write_char(hex[(a >> i) & 0xf]);
|
||||||
print_byte(a8);
|
}
|
||||||
print_byte(a0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_byte(uint8_t a)
|
void print_byte(uint8_t a)
|
||||||
{
|
{
|
||||||
char high = (a >> 4) + '0';
|
write_char(hex[(a >> 4) & 0xf]);
|
||||||
if (high > '9') {
|
write_char(hex[a & 0xf]);
|
||||||
high += 'a' - ('0' + 10);
|
|
||||||
}
|
|
||||||
write_char(high);
|
|
||||||
|
|
||||||
char low = (a & 0xf) + '0';
|
|
||||||
if (low > '9') {
|
|
||||||
low += 'a' - ('0' + 10);
|
|
||||||
}
|
|
||||||
write_char(low);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* External IRQ 0 Service Routine: Called on link change?
|
* External IRQ 0 Service Routine: Called on link change?
|
||||||
* Note that all registers are being put on the STACK because of calling a subroutine
|
* Note that all registers are being put on the STACK because of calling a subroutine
|
||||||
@@ -457,23 +435,6 @@ void reg_bit_clear(uint16_t reg_addr, char bit)
|
|||||||
reg_write_m(reg_addr);
|
reg_write_m(reg_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This sets a bit in the 32bit wide switch register reg_addr
|
|
||||||
*/
|
|
||||||
uint8_t reg_bit_test(uint16_t reg_addr, char bit)
|
|
||||||
{
|
|
||||||
uint8_t bit_mask = 1 << (bit & 0x7);
|
|
||||||
|
|
||||||
bit >>= 3;
|
|
||||||
reg_read_m(reg_addr);
|
|
||||||
bit_mask = bit_mask;
|
|
||||||
if (sfr_data[3-bit] & bit_mask)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This masks the sfr data fields, first &-ing with ~mask, then setting the bits in set
|
* This masks the sfr data fields, first &-ing with ~mask, then setting the bits in set
|
||||||
*/
|
*/
|
||||||
@@ -584,6 +545,16 @@ uint8_t read_flash(uint8_t bank, __code uint8_t *addr)
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print_long_x(__xdata uint8_t v[])
|
||||||
|
{
|
||||||
|
write_char('0'); write_char('x');
|
||||||
|
for (uint8_t i=0; i < 4; i++) {
|
||||||
|
write_char(hex[v[i] >> 4]);
|
||||||
|
write_char(hex[v[i] & 0xf]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read a SerDes register in the SoC
|
* Read a SerDes register in the SoC
|
||||||
* Input must be: sds_id = 0/1, page < 128, reg <= 0xff
|
* Input must be: sds_id = 0/1, page < 128, reg <= 0xff
|
||||||
@@ -630,10 +601,14 @@ void print_sfr_data(void)
|
|||||||
{
|
{
|
||||||
write_char('0');
|
write_char('0');
|
||||||
write_char('x');
|
write_char('x');
|
||||||
print_byte(sfr_data[0]);
|
write_char(hex[sfr_data[0] >> 4]);
|
||||||
print_byte(sfr_data[1]);
|
write_char(hex[sfr_data[0] & 0xf]);
|
||||||
print_byte(sfr_data[2]);
|
write_char(hex[sfr_data[1] >> 4]);
|
||||||
print_byte(sfr_data[3]);
|
write_char(hex[sfr_data[1] & 0xf]);
|
||||||
|
write_char(hex[sfr_data[2] >> 4]);
|
||||||
|
write_char(hex[sfr_data[2] & 0xf]);
|
||||||
|
write_char(hex[sfr_data[3] >> 4]);
|
||||||
|
write_char(hex[sfr_data[3] & 0xf]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -641,8 +616,10 @@ void print_phy_data(void)
|
|||||||
{
|
{
|
||||||
write_char('0');
|
write_char('0');
|
||||||
write_char('x');
|
write_char('x');
|
||||||
print_byte(SFR_DATA_8);
|
write_char(hex[SFR_DATA_8 >> 4]);
|
||||||
print_byte(SFR_DATA_0);
|
write_char(hex[SFR_DATA_8 & 0xf]);
|
||||||
|
write_char(hex[SFR_DATA_0 >> 4]);
|
||||||
|
write_char(hex[SFR_DATA_0 & 0xf]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -949,12 +926,13 @@ void handle_rx(void)
|
|||||||
if (uip_len) {
|
if (uip_len) {
|
||||||
tcpip_output();
|
tcpip_output();
|
||||||
}
|
}
|
||||||
} else if (uip_buf[ETHERTYPE_OFFSET] == 0x08 && uip_buf[ETHERTYPE_OFFSET + 1] == 0x00) { // IP packet?
|
} else if (uip_buf[ETHERTYPE_OFFSET] == 0x08 && uip_buf[ETHERTYPE_OFFSET + 1] == 0x00) { // TCP?
|
||||||
if (!management_vlan || management_vlan == rx_packet_vlan) {
|
if (!management_vlan || management_vlan == rx_packet_vlan) {
|
||||||
uip_arp_ipin(); // Learn MAC addresses in TCP packets
|
uip_arp_ipin(); // Learn MAC addresses in TCP packets
|
||||||
uip_input();
|
uip_input();
|
||||||
if (uip_len) {
|
if (uip_len) {
|
||||||
uip_arp_out(); // Add ethernet frame
|
// Add ethernet frame
|
||||||
|
uip_arp_out();
|
||||||
tcpip_output();
|
tcpip_output();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1085,72 +1063,6 @@ void handle_sfp(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void flash_default_config(void)
|
|
||||||
{
|
|
||||||
__xdata uint32_t source = DEFAULT_CONFIG_START;
|
|
||||||
__xdata uint32_t dest = CONFIG_START;
|
|
||||||
|
|
||||||
flash_region.addr = CONFIG_START;
|
|
||||||
flash_sector_erase();
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 8; i++) // 8 * 512 Byte = 4 kByte (1 sector)
|
|
||||||
{
|
|
||||||
flash_region.addr = source;
|
|
||||||
flash_region.len = FLASH_BUF_SIZE;
|
|
||||||
flash_read_bulk(flash_buf);
|
|
||||||
flash_region.addr = dest;
|
|
||||||
flash_region.len = FLASH_BUF_SIZE;
|
|
||||||
flash_write_bytes(flash_buf);
|
|
||||||
dest += FLASH_BUF_SIZE;
|
|
||||||
source += FLASH_BUF_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_string("Written default config to flash\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void handle_button(void)
|
|
||||||
{
|
|
||||||
if (machine.reset_pin == GPIO_NA) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool button_pressed = !gpio_pin_test(machine.reset_pin);
|
|
||||||
if (button_last != button_pressed)
|
|
||||||
{
|
|
||||||
print_string(button_pressed ? "Button pressed\n" : "Button released\n");
|
|
||||||
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
|
||||||
uint8_t diff_sec_counter = sfr_data[3] - button_sec_counter_last;
|
|
||||||
button_last = button_pressed;
|
|
||||||
button_sec_counter_last = sfr_data[3];
|
|
||||||
|
|
||||||
if (!button_pressed)
|
|
||||||
{
|
|
||||||
if (diff_sec_counter > 10)
|
|
||||||
{
|
|
||||||
print_string(">10s button detected; reverting to default settings:\n");
|
|
||||||
flash_default_config();
|
|
||||||
print_string("Now resetting...\n");
|
|
||||||
reset_chip();
|
|
||||||
}
|
|
||||||
else if (diff_sec_counter > 3)
|
|
||||||
{
|
|
||||||
print_string(">3s button detected; resetting chip...\n");
|
|
||||||
reset_chip();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
print_string("Short button press detected; no action.\n");
|
|
||||||
set_sys_led_state(SYS_LED_ON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Give the user feedback for button press
|
|
||||||
set_sys_led_state(SYS_LED_SLOW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// An idle function that sleeps for 1 tick and does all the house-keeping
|
// An idle function that sleeps for 1 tick and does all the house-keeping
|
||||||
//
|
//
|
||||||
@@ -1183,10 +1095,6 @@ void idle(void)
|
|||||||
}
|
}
|
||||||
reg_write_m(RTL837X_REG_SEC_COUNTER);
|
reg_write_m(RTL837X_REG_SEC_COUNTER);
|
||||||
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
||||||
|
|
||||||
// Check for button presses once a second
|
|
||||||
handle_button();
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print_sfr_data();
|
print_sfr_data();
|
||||||
write_char('\n');
|
write_char('\n');
|
||||||
@@ -1226,6 +1134,11 @@ void idle(void)
|
|||||||
// Check for changes with SFP modules
|
// Check for changes with SFP modules
|
||||||
handle_sfp();
|
handle_sfp();
|
||||||
|
|
||||||
|
/* Button pressed on KL-8xhm-x2:
|
||||||
|
reg_read(RTL837X_REG_GPIO_32_63_INPUT);
|
||||||
|
if (!(sfr_data[2] & 0x40))
|
||||||
|
print_string("Button pressed\n");
|
||||||
|
*/
|
||||||
// Check new Packets RX
|
// Check new Packets RX
|
||||||
handle_rx();
|
handle_rx();
|
||||||
// Check UIP for packets to transmit
|
// Check UIP for packets to transmit
|
||||||
@@ -1640,9 +1553,6 @@ void rtl8373_init(void)
|
|||||||
|
|
||||||
reg_bit_set(RTL837X_REG_HW_CONF, 0);
|
reg_bit_set(RTL837X_REG_HW_CONF, 0);
|
||||||
|
|
||||||
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
|
|
||||||
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
|
|
||||||
|
|
||||||
// TODO: patch the PHYs
|
// TODO: patch the PHYs
|
||||||
|
|
||||||
// Re-enable PHY after configuration
|
// Re-enable PHY after configuration
|
||||||
@@ -1704,10 +1614,6 @@ void rtl8372_init(void)
|
|||||||
|
|
||||||
reg_bit_set(RTL837X_REG_HW_CONF, 0);
|
reg_bit_set(RTL837X_REG_HW_CONF, 0);
|
||||||
|
|
||||||
|
|
||||||
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
|
|
||||||
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
|
|
||||||
|
|
||||||
// TODO: patch the PHYs
|
// TODO: patch the PHYs
|
||||||
|
|
||||||
// Re-enable PHY after configuration
|
// Re-enable PHY after configuration
|
||||||
@@ -1886,92 +1792,7 @@ void setup_i2c(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void check_and_flash_update_image(void)
|
void bootloader(void)
|
||||||
{
|
|
||||||
flash_read_jedecid(); // This initializes also __xdata flash_size variable
|
|
||||||
|
|
||||||
print_string(get_flash_size_str()); print_string(" flash size detected. (1 MB is needed for image updating)\n");
|
|
||||||
if (flash_size < FIRMWARE_UPLOAD_START*2) {
|
|
||||||
print_string("Flash too small for updating; skipping update check\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_string("Checking for update image in flash... ");
|
|
||||||
// Check if an update image is in flash
|
|
||||||
flash_region.addr = FIRMWARE_UPLOAD_START;
|
|
||||||
flash_region.len = 0x100;
|
|
||||||
flash_read_bulk(flash_buf);
|
|
||||||
if (flash_buf[0] == 0x00 && flash_buf[1] == 0x40)
|
|
||||||
{
|
|
||||||
// Yes, flash the new image to the start of flash and reset
|
|
||||||
__xdata uint32_t dest = 0x0;
|
|
||||||
__xdata uint32_t source = FIRMWARE_UPLOAD_START;
|
|
||||||
__xdata uint16_t i = 0;
|
|
||||||
__xdata uint16_t j = 0;
|
|
||||||
__xdata uint8_t * __xdata bptr;
|
|
||||||
print_string("found update image! Checking integrity");
|
|
||||||
flash_init(0); // Re-initialize flash for non-DIO operation, otherwise flashing will fail
|
|
||||||
set_sys_led_state(SYS_LED_FAST);
|
|
||||||
crc_value = 0x0000;
|
|
||||||
for (i = 0; i < 1024; i++) {
|
|
||||||
flash_region.addr = source;
|
|
||||||
flash_region.len = FLASH_BUF_SIZE;
|
|
||||||
flash_read_bulk(flash_buf);
|
|
||||||
bptr = flash_buf;
|
|
||||||
for (j = 0; j < FLASH_BUF_SIZE; j++) {
|
|
||||||
crc16(bptr++);
|
|
||||||
}
|
|
||||||
source += FLASH_BUF_SIZE;
|
|
||||||
if (i%16 == 0) write_char('.');
|
|
||||||
}
|
|
||||||
if (crc_value == 0xb001) {
|
|
||||||
print_string("Checksum OK.\nUpdate in progress, moving firmware to start of flash");
|
|
||||||
source = FIRMWARE_UPLOAD_START;
|
|
||||||
// Don't copy the config area at the end of flash
|
|
||||||
for (i = 0; i < CONFIG_START/FLASH_BUF_SIZE; i++) {
|
|
||||||
flash_region.addr = source;
|
|
||||||
flash_region.len = FLASH_BUF_SIZE;
|
|
||||||
flash_read_bulk(flash_buf);
|
|
||||||
if (i%8 == 0) {
|
|
||||||
flash_region.addr = dest;
|
|
||||||
flash_sector_erase();
|
|
||||||
if (i%16 == 0) write_char('.');
|
|
||||||
}
|
|
||||||
flash_region.addr = dest;
|
|
||||||
flash_region.len = FLASH_BUF_SIZE;
|
|
||||||
flash_write_bytes(flash_buf);
|
|
||||||
dest += FLASH_BUF_SIZE;
|
|
||||||
source += FLASH_BUF_SIZE;
|
|
||||||
}
|
|
||||||
print_string("Done.\nDeleting uploaded flash image");
|
|
||||||
dest = FIRMWARE_UPLOAD_START;
|
|
||||||
for (register uint8_t i=0; i < 128; i++) // TODO: Erasing the entire 512kByte upload area is probably not necessary
|
|
||||||
{
|
|
||||||
flash_region.addr = dest;
|
|
||||||
flash_sector_erase();
|
|
||||||
dest += 0x1000;
|
|
||||||
if (i%4 == 0) write_char('.');
|
|
||||||
}
|
|
||||||
print_string("Done.\nResetting now");
|
|
||||||
delay(200);
|
|
||||||
reset_chip();
|
|
||||||
}
|
|
||||||
print_string("Checksum incorrect, please upload the image again\n");
|
|
||||||
print_string("Erasing bad uploaded flash image\n");
|
|
||||||
dest = FIRMWARE_UPLOAD_START;
|
|
||||||
for (register uint8_t i=0; i < 128; i++) {
|
|
||||||
flash_region.addr = dest;
|
|
||||||
flash_sector_erase();
|
|
||||||
dest += 0x1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
print_string("no update image found.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
{
|
||||||
ticks = 0;
|
ticks = 0;
|
||||||
stp_clock = STP_TICK_DIVIDER;
|
stp_clock = STP_TICK_DIVIDER;
|
||||||
@@ -2008,9 +1829,6 @@ void main(void)
|
|||||||
// We have not detected any link
|
// We have not detected any link
|
||||||
linkbits_last[0] = linkbits_last[1] = linkbits_last[2] = linkbits_last[3] = linkbits_last_p89 = 0;
|
linkbits_last[0] = linkbits_last[1] = linkbits_last[2] = linkbits_last[3] = linkbits_last_p89 = 0;
|
||||||
|
|
||||||
button_last = 0;
|
|
||||||
button_sec_counter_last = 0;
|
|
||||||
|
|
||||||
machine_detected.isRTL8373 = 0;
|
machine_detected.isRTL8373 = 0;
|
||||||
machine_detected.isN = 0;
|
machine_detected.isN = 0;
|
||||||
print_string("Detecting CPU: RTL837");
|
print_string("Detecting CPU: RTL837");
|
||||||
@@ -2047,44 +1865,97 @@ void main(void)
|
|||||||
uip_ipaddr(&uip_hostaddr, ownIP[0], ownIP[1], ownIP[2], ownIP[3]);
|
uip_ipaddr(&uip_hostaddr, ownIP[0], ownIP[1], ownIP[2], ownIP[3]);
|
||||||
uip_ipaddr(&uip_draddr, gatewayIP[0], gatewayIP[1], gatewayIP[2], gatewayIP[3]);
|
uip_ipaddr(&uip_draddr, gatewayIP[0], gatewayIP[1], gatewayIP[2], gatewayIP[3]);
|
||||||
uip_ipaddr(&uip_netmask, netmask[0], netmask[1], netmask[2], netmask[3]);
|
uip_ipaddr(&uip_netmask, netmask[0], netmask[1], netmask[2], netmask[3]);
|
||||||
reg_read_m(RTL837X_REG_CHIP_UUID);
|
|
||||||
#ifdef DEBUG
|
|
||||||
print_string("SoC UUID: "); print_sfr_data();
|
|
||||||
#endif
|
|
||||||
uip_ethaddr.addr[0] = 0x06; // LAA prefix
|
|
||||||
uip_ethaddr.addr[3] = sfr_data[0] ^ sfr_data[3];
|
|
||||||
uip_ethaddr.addr[4] = sfr_data[1] ^ sfr_data[3];
|
|
||||||
uip_ethaddr.addr[5] = sfr_data[2] ^ sfr_data[3];
|
|
||||||
reg_read_m(RTL837X_REG_CHIP_LOT_NO);
|
|
||||||
#ifdef DEBUG
|
|
||||||
print_string(", LOT: "); print_sfr_data(); write_char(' ');
|
|
||||||
#endif
|
|
||||||
uip_ethaddr.addr[1] = sfr_data[0] ^ sfr_data[2];
|
|
||||||
uip_ethaddr.addr[2] = sfr_data[1] ^ sfr_data[3];
|
|
||||||
print_string("Setting MAC to: ");
|
|
||||||
print_byte(uip_ethaddr.addr[0]); write_char(':'); print_byte(uip_ethaddr.addr[1]); write_char(':');
|
|
||||||
print_byte(uip_ethaddr.addr[2]); write_char(':'); print_byte(uip_ethaddr.addr[3]); write_char(':');
|
|
||||||
print_byte(uip_ethaddr.addr[4]); write_char(':'); print_byte(uip_ethaddr.addr[5]); write_char('\n');
|
|
||||||
|
|
||||||
REG_SET(RTL837X_PIN_MUX_2, 0x0); // Disable pins for ACL
|
REG_SET(RTL837X_PIN_MUX_2, 0x0); // Disable pins for ACL
|
||||||
init_smi();
|
init_smi();
|
||||||
|
|
||||||
rtl8373_revision();
|
rtl8373_revision();
|
||||||
|
|
||||||
leds_setup();
|
leds_setup();
|
||||||
machine_custom_init();
|
|
||||||
|
|
||||||
leds_dump();
|
leds_dump();
|
||||||
|
|
||||||
set_sys_led_state(SYS_LED_SLOW);
|
|
||||||
|
|
||||||
if (machine_detected.isRTL8373)
|
if (machine_detected.isRTL8373)
|
||||||
rtl8373_init();
|
rtl8373_init();
|
||||||
else
|
else
|
||||||
rtl8372_init();
|
rtl8372_init();
|
||||||
delay(1000);
|
delay(1000);
|
||||||
|
|
||||||
check_and_flash_update_image();
|
// Check update in progress and move blocks
|
||||||
|
flash_region.addr = FIRMWARE_UPLOAD_START;
|
||||||
|
flash_region.len = 0x100;
|
||||||
|
flash_read_bulk(flash_buf);
|
||||||
|
#ifndef MACHINE_HG0402XG_V1_1
|
||||||
|
if (flash_buf[0] == 0x00 && flash_buf[1] == 0x40) {
|
||||||
|
__xdata uint32_t dest = 0x0;
|
||||||
|
__xdata uint32_t source = FIRMWARE_UPLOAD_START;
|
||||||
|
__xdata uint16_t i = 0;
|
||||||
|
__xdata uint16_t j = 0;
|
||||||
|
__xdata uint8_t * __xdata bptr;
|
||||||
|
print_string("Identified update image. Checking integrity...");
|
||||||
|
|
||||||
|
flash_init(0); // Re-initialize flash for non-DIO operation, otherwise flashing will fail
|
||||||
|
set_sys_led_state(SYS_LED_FAST);
|
||||||
|
|
||||||
|
crc_value = 0x0000;
|
||||||
|
for (i = 0; i < 1024; i++) {
|
||||||
|
flash_region.addr = source;
|
||||||
|
flash_region.len = 0x200;
|
||||||
|
flash_read_bulk(flash_buf);
|
||||||
|
bptr = flash_buf;
|
||||||
|
for (j = 0; j < 0x200; j++) {
|
||||||
|
// print_byte(*bptr); write_char(' ');
|
||||||
|
crc16(bptr++);
|
||||||
|
// print_short(crc_value); write_char(':');
|
||||||
|
}
|
||||||
|
source += 0x200;
|
||||||
|
// write_char('\n'); print_short(crc_value); write_char(' ');
|
||||||
|
if (i%16 == 0)
|
||||||
|
write_char('.');
|
||||||
|
}
|
||||||
|
if (crc_value == 0xb001) {
|
||||||
|
print_string("\nChecksum OK\n");
|
||||||
|
print_string("Update in progress, moving firmware to start of FLASH.");
|
||||||
|
source = FIRMWARE_UPLOAD_START;
|
||||||
|
// A 512kByte = 4MBit Flash has 128*8=1024 512byte blocks, we copy only 896
|
||||||
|
// (don't overwrite config @ 0x700000)
|
||||||
|
for (i = 0; i < 896; i++) {
|
||||||
|
// print_string("Writing block: ");
|
||||||
|
// print_short(dest);
|
||||||
|
flash_region.addr = source;
|
||||||
|
flash_region.len = 0x200;
|
||||||
|
flash_read_bulk(flash_buf);
|
||||||
|
if (!(i & 0x7)) {
|
||||||
|
flash_region.addr = dest;
|
||||||
|
flash_sector_erase();
|
||||||
|
write_char('.');
|
||||||
|
}
|
||||||
|
flash_region.addr = dest;
|
||||||
|
flash_region.len = 0x200;
|
||||||
|
flash_write_bytes(flash_buf);
|
||||||
|
dest += 0x200;
|
||||||
|
source += 0x200;
|
||||||
|
}
|
||||||
|
print_string("\nDeleting uploaded flash image\n");
|
||||||
|
dest = FIRMWARE_UPLOAD_START;
|
||||||
|
for (register uint8_t i=0; i < 128; i++) {
|
||||||
|
flash_region.addr = dest;
|
||||||
|
flash_sector_erase();
|
||||||
|
dest += 0x1000;
|
||||||
|
}
|
||||||
|
print_string("Resetting now");
|
||||||
|
delay(200);
|
||||||
|
reset_chip();
|
||||||
|
}
|
||||||
|
print_string("Checksum incorrect, please upload the image again\n");
|
||||||
|
print_string("Erasing bad uploaded flash image\n");
|
||||||
|
dest = FIRMWARE_UPLOAD_START;
|
||||||
|
for (register uint8_t i=0; i < 128; i++) {
|
||||||
|
flash_region.addr = dest;
|
||||||
|
flash_sector_erase();
|
||||||
|
dest += 0x1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
set_sys_led_state(SYS_LED_SLOW);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// This register seems to work on the RTL8373 only if also the SDS
|
// This register seems to work on the RTL8373 only if also the SDS
|
||||||
@@ -2108,7 +1979,6 @@ void main(void)
|
|||||||
vlan_setup();
|
vlan_setup();
|
||||||
port_l2_setup();
|
port_l2_setup();
|
||||||
igmp_setup();
|
igmp_setup();
|
||||||
bandwidth_setup();
|
|
||||||
uip_init();
|
uip_init();
|
||||||
uip_arp_init();
|
uip_arp_init();
|
||||||
httpd_init();
|
httpd_init();
|
||||||
@@ -2116,7 +1986,6 @@ void main(void)
|
|||||||
management_vlan = 0; // Disabled
|
management_vlan = 0; // Disabled
|
||||||
|
|
||||||
setup_i2c();
|
setup_i2c();
|
||||||
setup_sfp_gpio();
|
|
||||||
|
|
||||||
print_string(greeting);
|
print_string(greeting);
|
||||||
|
|
||||||
@@ -2135,9 +2004,39 @@ void main(void)
|
|||||||
|
|
||||||
set_sys_led_state(SYS_LED_ON);
|
set_sys_led_state(SYS_LED_ON);
|
||||||
|
|
||||||
cmd_editor_init();
|
// Wait for commands on serial connection
|
||||||
|
// sbuf_ptr is moved forward by serial interrupt, l is the position until we have already
|
||||||
|
// printed out the entered characters
|
||||||
|
__xdata uint8_t l = sbuf_ptr; // We have printed out entered characters until l
|
||||||
|
__xdata uint8_t line_start = sbuf_ptr; // This is where the current line starts
|
||||||
|
cmd_available = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
cmd_edit();
|
while (l != sbuf_ptr) {
|
||||||
|
// If the command buffer is currently in use, we cannot copy to it
|
||||||
|
if (cmd_available)
|
||||||
|
break;
|
||||||
|
write_char(sbuf[l]);
|
||||||
|
// Check whether there is a full line:
|
||||||
|
if (sbuf[l] == '\n' || sbuf[l] == '\r') {
|
||||||
|
write_char('\n');
|
||||||
|
register uint8_t i = 0;
|
||||||
|
while (line_start != l) {
|
||||||
|
cmd_buffer[i++] = sbuf[line_start++];
|
||||||
|
line_start &= (SBUF_SIZE - 1);
|
||||||
|
}
|
||||||
|
line_start++;
|
||||||
|
line_start &= (SBUF_SIZE - 1);
|
||||||
|
cmd_buffer[i] = '\0';
|
||||||
|
// If there is a command we print the prompt after execution
|
||||||
|
// otherwise immediately because there is nothing to execute
|
||||||
|
if (i)
|
||||||
|
cmd_available = 1;
|
||||||
|
else
|
||||||
|
print_string("\n> ");
|
||||||
|
}
|
||||||
|
l++;
|
||||||
|
l &= (SBUF_SIZE - 1);
|
||||||
|
}
|
||||||
idle(); // Enter Idle mode until interrupt occurs
|
idle(); // Enter Idle mode until interrupt occurs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#define PASSWORD "1234"
|
#define PASSWORD "1234"
|
||||||
#define SESSION_TIMEOUT 2000
|
#define SESSION_TIMEOUT 2000
|
||||||
|
|
||||||
#define PORTS 6
|
#define PORTS 9
|
||||||
#define NSFP 1
|
#define NSFP 1
|
||||||
|
|
||||||
#define N_COUNTERS 52
|
#define N_COUNTERS 52
|
||||||
@@ -121,8 +121,7 @@ void send_basic_info(int socket)
|
|||||||
{
|
{
|
||||||
char *response = "HTTP/1.1 200 OK\r\n"
|
char *response = "HTTP/1.1 200 OK\r\n"
|
||||||
"Content-Type: application/json; charset=UTF-8\r\n\r\n"
|
"Content-Type: application/json; charset=UTF-8\r\n\r\n"
|
||||||
"{\"ip_address\":\"192.168.10.247\",\"ip_gateway\":\"192.168.2.22\",\"ip_netmask\":\"255.255.255.0\",\"mac_address\":\"1c:2a:a3:23:00:02\",\"sw_ver\":\"" VERSION_SW "\",\"hw_ver\":\"SWGT024-V2.0\""
|
"{\"ip_address\":\"192.168.10.247\",\"ip_gateway\":\"192.168.2.22\",\"ip_netmask\":\"255.255.255.0\",\"mac_address\":\"1c:2a:a3:23:00:02\",\"sw_ver\":\"" VERSION_SW "\",\"hw_ver\":\"SWGT024-V2.0\"}";
|
||||||
",\"dhcp_client\":1,\"dhcp_server\":0}";
|
|
||||||
write(socket, response, strlen(response));
|
write(socket, response, strlen(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +229,7 @@ void send_status(int s)
|
|||||||
|
|
||||||
void send_counters(int s, int port)
|
void send_counters(int s, int port)
|
||||||
{
|
{
|
||||||
struct json_object *counters;
|
struct json_object *v, *counters;
|
||||||
const char *jstring;
|
const char *jstring;
|
||||||
char *header = "HTTP/1.1 200 OK\r\n"
|
char *header = "HTTP/1.1 200 OK\r\n"
|
||||||
"Cache-Control: no-cache\r\n"
|
"Cache-Control: no-cache\r\n"
|
||||||
@@ -240,6 +239,7 @@ void send_counters(int s, int port)
|
|||||||
counters = json_object_new_array_ext(N_COUNTERS);
|
counters = json_object_new_array_ext(N_COUNTERS);
|
||||||
|
|
||||||
for (int i = 0; i < N_COUNTERS; i++) {
|
for (int i = 0; i < N_COUNTERS; i++) {
|
||||||
|
v = json_object_new_object();
|
||||||
sprintf(counter_buf, "0x%016lx", 0x1234UL + i);
|
sprintf(counter_buf, "0x%016lx", 0x1234UL + i);
|
||||||
json_object_array_add(counters, json_object_new_string(counter_buf));
|
json_object_array_add(counters, json_object_new_string(counter_buf));
|
||||||
}
|
}
|
||||||
@@ -283,56 +283,6 @@ void send_eee(int s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void send_bandwidth(int s)
|
|
||||||
{
|
|
||||||
struct json_object *ports, *v;
|
|
||||||
const char *jstring;
|
|
||||||
uint32_t bw;
|
|
||||||
int limited, fcEnabled;
|
|
||||||
char *header = "HTTP/1.1 200 OK\r\n"
|
|
||||||
"Content-Type: application/json; charset=UTF-8\r\n\r\n";
|
|
||||||
|
|
||||||
ports = json_object_new_array_ext(PORTS);
|
|
||||||
for (int i = 1; i <= PORTS; i++) {
|
|
||||||
v = json_object_new_object();
|
|
||||||
json_object_object_add(v, "portNum", json_object_new_int(i));
|
|
||||||
if (i % 2) {
|
|
||||||
limited = 1;
|
|
||||||
fcEnabled = i % 4 ? 1 : 0;
|
|
||||||
bw = 0x100;
|
|
||||||
} else {
|
|
||||||
limited = 0;
|
|
||||||
fcEnabled = 0;
|
|
||||||
bw = 0xfffff;
|
|
||||||
}
|
|
||||||
char bw_buf[20];
|
|
||||||
sprintf(bw_buf, "%08x", bw);
|
|
||||||
json_object_object_add(v, "iLimited", json_object_new_int(limited));
|
|
||||||
json_object_object_add(v, "iFC", json_object_new_int(fcEnabled));
|
|
||||||
json_object_object_add(v, "iBW", json_object_new_string(bw_buf));
|
|
||||||
|
|
||||||
if (i % 4) {
|
|
||||||
limited = 1;
|
|
||||||
bw = 0x1000;
|
|
||||||
} else {
|
|
||||||
limited = 0;
|
|
||||||
bw = 0xfffff;
|
|
||||||
}
|
|
||||||
sprintf(bw_buf, "%08x", bw);
|
|
||||||
json_object_object_add(v, "eLimited", json_object_new_int(limited));
|
|
||||||
json_object_object_add(v, "eBW", json_object_new_string(bw_buf));
|
|
||||||
|
|
||||||
json_object_array_add(ports, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
write(s, header, strlen(header));
|
|
||||||
|
|
||||||
jstring = json_object_to_json_string_ext(ports, JSON_C_TO_STRING_PLAIN);
|
|
||||||
write(s, jstring, strlen(jstring));
|
|
||||||
json_object_put(ports);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void send_mirror(int s)
|
void send_mirror(int s)
|
||||||
{
|
{
|
||||||
uint16_t mirror_tx, mirror_rx = 0;
|
uint16_t mirror_tx, mirror_rx = 0;
|
||||||
@@ -643,13 +593,6 @@ void launch(struct Server *server)
|
|||||||
else
|
else
|
||||||
send_eee(new_socket);
|
send_eee(new_socket);
|
||||||
goto done;
|
goto done;
|
||||||
} else if (!strncmp(&buffer[4], "/bandwidth.json", 15)) {
|
|
||||||
printf("Bandwidth request\n");
|
|
||||||
if (!authenticated)
|
|
||||||
send_unauthorized(new_socket);
|
|
||||||
else
|
|
||||||
send_bandwidth(new_socket);
|
|
||||||
goto done;
|
|
||||||
} else if (!strncmp(&buffer[4], "/information.json", 17)) {
|
} else if (!strncmp(&buffer[4], "/information.json", 17)) {
|
||||||
printf("Status request\n");
|
printf("Status request\n");
|
||||||
if (!authenticated)
|
if (!authenticated)
|
||||||
|
|||||||
@@ -106,10 +106,6 @@ int main(int argc, char **argv)
|
|||||||
printf("Error reading input file.\n");
|
printf("Error reading input file.\n");
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
if (buffer[0] != 2) {
|
|
||||||
printf("Expected LJMP at offset 0.\n");
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
for (int b = BANK0_SIZE; b < BANK_STRIDE + BANK0_SIZE; b ++) {
|
for (int b = BANK0_SIZE; b < BANK_STRIDE + BANK0_SIZE; b ++) {
|
||||||
if (buffer[b]) {
|
if (buffer[b]) {
|
||||||
printf("WARNING: Bank 0: code segment too large at 0x%x!\n", b);
|
printf("WARNING: Bank 0: code segment too large at 0x%x!\n", b);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ AFLAGS= -plosgff
|
|||||||
|
|
||||||
BUILDDIR = output/
|
BUILDDIR = output/
|
||||||
|
|
||||||
SRCS = timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-split.c
|
SRCS = timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-neighbor.c uip-split.c
|
||||||
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel}
|
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel}
|
||||||
|
|
||||||
all: create_build_dir $(OBJS)
|
all: create_build_dir $(OBJS)
|
||||||
|
|||||||
@@ -132,6 +132,8 @@ static __code const uip_ipaddr_t all_zeroes_addr =
|
|||||||
{0x0000,0x0000};
|
{0x0000,0x0000};
|
||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
|
|
||||||
|
extern __code struct uip_eth_addr uip_ethaddr;
|
||||||
|
|
||||||
#ifndef UIP_CONF_EXTERNAL_BUFFER
|
#ifndef UIP_CONF_EXTERNAL_BUFFER
|
||||||
u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains
|
u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains
|
||||||
incoming packets. */
|
incoming packets. */
|
||||||
@@ -919,7 +921,7 @@ uip_process(u8_t flag) __banked
|
|||||||
|
|
||||||
/* Check if we have a DHCP packet, otherwise check if the packet is destined for our IP address. */
|
/* Check if we have a DHCP packet, otherwise check if the packet is destined for our IP address. */
|
||||||
#if !UIP_CONF_IPV6
|
#if !UIP_CONF_IPV6
|
||||||
if(!(BUF->proto == UIP_PROTO_UDP && (UDPBUF->destport == HTONS(DHCP_CLIENT_PORT) || UDPBUF->destport == HTONS(DHCP_SERVER_PORT)) )) {
|
if(!(BUF->proto == UIP_PROTO_UDP && UDPBUF->destport == HTONS(DHCPC_CLIENT_PORT))) {
|
||||||
if(!uip_ipaddr_cmpx(BUF->destipaddr, uip_hostaddr)) {
|
if(!uip_ipaddr_cmpx(BUF->destipaddr, uip_hostaddr)) {
|
||||||
UIP_STAT(++uip_stat.ip.drop);
|
UIP_STAT(++uip_stat.ip.drop);
|
||||||
goto drop;
|
goto drop;
|
||||||
@@ -938,11 +940,7 @@ uip_process(u8_t flag) __banked
|
|||||||
}
|
}
|
||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
}
|
}
|
||||||
// If we serve only the designated DHCPD-VLAN, we drop the packet if not in that VLAN
|
|
||||||
if(BUF->proto == UIP_PROTO_UDP && dhcpd_vlan && UDPBUF->destport == HTONS(DHCP_SERVER_PORT) && dhcpd_vlan != rx_packet_vlan) {
|
|
||||||
UIP_STAT(++uip_stat.ip.drop);
|
|
||||||
goto drop;
|
|
||||||
}
|
|
||||||
#if !UIP_CONF_IPV6
|
#if !UIP_CONF_IPV6
|
||||||
// if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
|
// if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
|
||||||
// checksum. */
|
// checksum. */
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ struct arp_hdr_o {
|
|||||||
u16_t dipaddr[2];
|
u16_t dipaddr[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ethip_hdr_o {
|
struct ethip_hdr {
|
||||||
struct uip_eth_hdr ethhdr;
|
struct uip_eth_hdr ethhdr;
|
||||||
/* IP header. */
|
/* IP header. */
|
||||||
u8_t vhl,
|
u8_t vhl,
|
||||||
@@ -106,24 +106,6 @@ struct ethip_hdr_o {
|
|||||||
u16_t ipchksum;
|
u16_t ipchksum;
|
||||||
u16_t srcipaddr[2],
|
u16_t srcipaddr[2],
|
||||||
destipaddr[2];
|
destipaddr[2];
|
||||||
u16_t sport, dport;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ethip_hdr_i {
|
|
||||||
struct uip_eth_hdr ethhdr;
|
|
||||||
struct rtl_tag rtl_tag;
|
|
||||||
/* IP header. */
|
|
||||||
u8_t vhl,
|
|
||||||
tos,
|
|
||||||
len[2],
|
|
||||||
ipid[2],
|
|
||||||
ipoffset[2],
|
|
||||||
ttl,
|
|
||||||
proto;
|
|
||||||
u16_t ipchksum;
|
|
||||||
u16_t srcipaddr[2],
|
|
||||||
destipaddr[2];
|
|
||||||
u16_t sport, dport;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ARP_REQUEST 1
|
#define ARP_REQUEST 1
|
||||||
@@ -150,8 +132,7 @@ static __xdata u8_t tmpage;
|
|||||||
|
|
||||||
#define BUF ((__xdata struct arp_hdr_i *)&uip_buf[0])
|
#define BUF ((__xdata struct arp_hdr_i *)&uip_buf[0])
|
||||||
#define BUF_O ((__xdata struct arp_hdr_o *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE])
|
#define BUF_O ((__xdata struct arp_hdr_o *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE])
|
||||||
#define IPBUF_I ((__xdata struct ethip_hdr_i *)&uip_buf[0])
|
#define IPBUF ((__xdata struct ethip_hdr *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE])
|
||||||
#define IPBUF_O ((__xdata struct ethip_hdr_o *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE])
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* Initialize the ARP module.
|
* Initialize the ARP module.
|
||||||
@@ -257,26 +238,27 @@ uip_arp_update(__xdata u16_t *ipaddr, __xdata struct uip_eth_addr *ethaddr)
|
|||||||
* variable uip_len.
|
* variable uip_len.
|
||||||
*/
|
*/
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
#if 0
|
||||||
void
|
void
|
||||||
uip_arp_ipin(void) __banked
|
uip_arp_ipin(void)
|
||||||
{
|
{
|
||||||
uip_len -= sizeof(struct uip_eth_hdr);
|
uip_len -= sizeof(struct uip_eth_hdr);
|
||||||
|
|
||||||
/* Only insert/update an entry if the source IP address of the
|
/* Only insert/update an entry if the source IP address of the
|
||||||
incoming IP packet comes from a host on the local network. */
|
incoming IP packet comes from a host on the local network. */
|
||||||
if((IPBUF_I->srcipaddr[0] & uip_netmask[0]) !=
|
if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
|
||||||
(uip_hostaddr[0] & uip_netmask[0])) {
|
(uip_hostaddr[0] & uip_netmask[0])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if((IPBUF_I->srcipaddr[1] & uip_netmask[1]) !=
|
if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
|
||||||
(uip_hostaddr[1] & uip_netmask[1])) {
|
(uip_hostaddr[1] & uip_netmask[1])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uip_arp_update(IPBUF_I->srcipaddr, &(IPBUF_I->ethhdr.src));
|
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif /* 0 */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* ARP processing for incoming ARP packets.
|
* ARP processing for incoming ARP packets.
|
||||||
@@ -320,11 +302,12 @@ uip_arp_arpin(void) __banked
|
|||||||
with this host in the future. */
|
with this host in the future. */
|
||||||
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
|
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
|
||||||
|
|
||||||
BUF_O->opcode = HTONS(ARP_REPLY);
|
/* The reply opcode is 2. */
|
||||||
|
BUF_O->opcode = HTONS(2);
|
||||||
|
|
||||||
memcpy(BUF_O->dhwaddr.addr, BUF->shwaddr.addr, 6);
|
memcpy(BUF_O->dhwaddr.addr, BUF->shwaddr.addr, 6);
|
||||||
memcpy(BUF_O->shwaddr.addr, uip_ethaddr.addr, 6);
|
memcpyc(BUF_O->shwaddr.addr, uip_ethaddr.addr, 6);
|
||||||
memcpy(BUF_O->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
memcpyc(BUF_O->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
||||||
memcpy(BUF_O->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
|
memcpy(BUF_O->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
|
||||||
|
|
||||||
BUF_O->dipaddr[0] = BUF->sipaddr[0];
|
BUF_O->dipaddr[0] = BUF->sipaddr[0];
|
||||||
@@ -388,24 +371,19 @@ uip_arp_out(void) __banked
|
|||||||
If not ARP table entry is found, we overwrite the original IP
|
If not ARP table entry is found, we overwrite the original IP
|
||||||
packet with an ARP request for the IP address. */
|
packet with an ARP request for the IP address. */
|
||||||
|
|
||||||
if (IPBUF_O->sport == 0x4300 && !IPBUF_O->destipaddr[0] && !IPBUF_O->destipaddr[1]) {
|
|
||||||
IPBUF_O->destipaddr[0] = 0xffff;
|
|
||||||
IPBUF_O->destipaddr[1] = 0xffff;
|
|
||||||
IPBUF_O->dport = 0x4400;
|
|
||||||
}
|
|
||||||
/* First check if destination is a local broadcast. */
|
/* First check if destination is a local broadcast. */
|
||||||
if(uip_ipaddr_cmpc(IPBUF_O->destipaddr, broadcast_ipaddr)) {
|
if(uip_ipaddr_cmpc(IPBUF->destipaddr, broadcast_ipaddr)) {
|
||||||
memcpyc(IPBUF_O->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
|
memcpyc(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
|
||||||
} else {
|
} else {
|
||||||
/* Check if the destination address is on the local network. */
|
/* Check if the destination address is on the local network. */
|
||||||
if(!uip_ipaddr_maskcmp(IPBUF_O->destipaddr, uip_hostaddr, uip_netmask)) {
|
if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
|
||||||
/* Destination address was not on the local network, so we need to
|
/* Destination address was not on the local network, so we need to
|
||||||
use the default router's IP address instead of the destination
|
use the default router's IP address instead of the destination
|
||||||
address when determining the MAC address. */
|
address when determining the MAC address. */
|
||||||
uip_ipaddr_copy(ipaddr, uip_draddr);
|
uip_ipaddr_copy(ipaddr, uip_draddr);
|
||||||
} else {
|
} else {
|
||||||
/* Else, we use the destination IP address. */
|
/* Else, we use the destination IP address. */
|
||||||
uip_ipaddr_copy(ipaddr, IPBUF_O->destipaddr);
|
uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||||
@@ -421,8 +399,8 @@ uip_arp_out(void) __banked
|
|||||||
|
|
||||||
memset(BUF_O->ethhdr.dest.addr, 0xff, 6);
|
memset(BUF_O->ethhdr.dest.addr, 0xff, 6);
|
||||||
memset(BUF_O->dhwaddr.addr, 0x00, 6);
|
memset(BUF_O->dhwaddr.addr, 0x00, 6);
|
||||||
memcpy(BUF_O->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
memcpyc(BUF_O->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
||||||
memcpy(BUF_O->shwaddr.addr, uip_ethaddr.addr, 6);
|
memcpyc(BUF_O->shwaddr.addr, uip_ethaddr.addr, 6);
|
||||||
|
|
||||||
uip_ipaddr_copy(BUF_O->dipaddr, ipaddr);
|
uip_ipaddr_copy(BUF_O->dipaddr, ipaddr);
|
||||||
uip_ipaddr_copy(BUF_O->sipaddr, uip_hostaddr);
|
uip_ipaddr_copy(BUF_O->sipaddr, uip_hostaddr);
|
||||||
@@ -440,11 +418,11 @@ uip_arp_out(void) __banked
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Build an ethernet header. */
|
/* Build an ethernet header. */
|
||||||
memcpy(IPBUF_O->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
|
memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
|
||||||
}
|
}
|
||||||
memcpy(IPBUF_O->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
memcpyc(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
||||||
|
|
||||||
IPBUF_O->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
|
IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
|
||||||
|
|
||||||
uip_len += sizeof(struct uip_eth_hdr);
|
uip_len += sizeof(struct uip_eth_hdr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,8 @@
|
|||||||
#include "uip.h"
|
#include "uip.h"
|
||||||
#include "../rtl837x_common.h"
|
#include "../rtl837x_common.h"
|
||||||
|
|
||||||
|
extern __code struct uip_eth_addr uip_ethaddr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Ethernet header.
|
* The Ethernet header.
|
||||||
*/
|
*/
|
||||||
@@ -78,8 +80,8 @@ void uip_arp_init(void) __banked;
|
|||||||
inserts a new mapping if none exists. The function assumes that an
|
inserts a new mapping if none exists. The function assumes that an
|
||||||
IP packet with an Ethernet header is present in the uip_buf buffer
|
IP packet with an Ethernet header is present in the uip_buf buffer
|
||||||
and that the length of the packet is in the uip_len variable. */
|
and that the length of the packet is in the uip_len variable. */
|
||||||
void uip_arp_ipin(void) __banked;
|
/*void uip_arp_ipin(void);*/
|
||||||
// #define uip_arp_ipin()
|
#define uip_arp_ipin()
|
||||||
|
|
||||||
/* The uip_arp_arpin() should be called when an ARP packet is received
|
/* The uip_arp_arpin() should be called when an ARP packet is received
|
||||||
by the Ethernet driver. This function also assumes that the
|
by the Ethernet driver. This function also assumes that the
|
||||||
|
|||||||