diff --git a/Makefile b/Makefile
index ec66eb6..2a3f01f 100644
--- a/Makefile
+++ b/Makefile
@@ -53,6 +53,7 @@ create_build_dir:
# Keep machine.c in first position to fail immediately on invalid $MACHINE value
SRCS = \
machine.c \
+ machine_init.c \
cmd_editor.c \
cmd_parser.c \
dhcp.c \
@@ -138,10 +139,11 @@ $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.i
machine_check:
@mkdir -p $(BUILDDIR)/tmp
@set -eo pipefail; \
- for MACHINE in `grep -e ' MACHINE_' machine.c | sed -e 's%^.* MACHINE_%%' -e 's%[ ]*//.*$$%%' | sort -u`; \
+ for MACHINE in `grep -E '^[[:space:]]*(//[[:space:]]*)?#define MACHINE_' machine.h | sed -E 's%^[[:space:]]*(//[[:space:]]*)?#define MACHINE_%%' | awk '{print $$1}' | sort -u`; \
do \
echo "Checking $${MACHINE}"; \
$(CC) $(CC_FLAGS) -DMACHINE_$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine.c; \
+ $(CC) $(CC_FLAGS) -DMACHINE_$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine_init.c; \
done
@rm -rf $(BUILDDIR)/tmp
diff --git a/doc/devices/2M-PCB43-V1.1.md b/doc/devices/2M-PCB43-V1.1.md
index 28673e8..97343f0 100644
--- a/doc/devices/2M-PCB43-V1.1.md
+++ b/doc/devices/2M-PCB43-V1.1.md
@@ -15,7 +15,7 @@ and sold by Mokerlink.
The device is fully supported:
- All 4 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 (use KP_9000_6XHML_X2 in machine.h if building yourself or the corresponding pre-compiled binary)
+- LEDs work with the same indiciations as the OEM firmware (use KP_9000_6XHML_X2_V1_1 in machine.h if building yourself or the corresponding pre-compiled binary)
- untested due to missing Hardware: SFP+ ports equipped with 1G or 2.5G SFPs.
### Hardware overview
diff --git a/doc/devices/KP-9000-6XH-X2.md b/doc/devices/KP-9000-6XH-X2.md
index 4cc21d7..d0f19b9 100644
--- a/doc/devices/KP-9000-6XH-X2.md
+++ b/doc/devices/KP-9000-6XH-X2.md
@@ -1,17 +1,36 @@
-# Keeplink KP-9000-6XH-X2
+# Keeplink KP-9000-6XH-X2 / KP-9000-6XHML-X2
-Following is documentation for unmanaged switch marked as `KP-9000-6XH-X2`.
+Following is documentation for switches marked as `KP-9000-6XH-X2` or
+`KP-9000-6XHML-X2`.
Using SPI clamp in-board is the only method for initial installation.
### Label specifications
- **Name**: 4X 2.5G RJ45 Port + 2 X 10G SFP+ Port
-- **Model**: KP-9000-6XH-X2
+- **Model**: KP-9000-6XH-X2 / KP-9000-6XHML-X2
- **Ports**:
- 4 × RJ45: 10/100/1000/2500 Mbps
- 2 × SFP+: 1000 / 2500 / 10000 Mbps
+### Machine target
+
+These devices exist with different PCB revisions. Select the machine target by
+the PCB silkscreen, not by the label on the case. The `6XH` / `6XHML`
+distinction appears to be a stock firmware, SKU or label difference, not a
+reliable indicator of PCB wiring. The PCB revision defines the hardware layout.
+
+| PCB silkscreen | Known labels / devices | Recommended machine target | Equivalent target | Legacy target |
+| --- | --- | --- | --- | --- |
+| `2M-PCB43-V1.1` | Mokerlink 2G040210GSM web-managed 4+2 switch | `MACHINE_KP_9000_6XHML_X2_V1_1` | `MACHINE_KP_9000_6XH_X2_V1_1` | `MACHINE_KP_9000_6XHML_X2` |
+| `2M-PCB43-V1.2` | `KP-9000-6XHML-X2` | `MACHINE_KP_9000_6XHML_X2_V1_2` | `MACHINE_KP_9000_6XH_X2_V1_2` | `MACHINE_KP_9000_6XHML_X2` |
+| `2M-PCB43-V2.1` | `KP-9000-6XH-X2`, `KP-9000-6XHML-X2` | `MACHINE_KP_9000_6XH_X2_V2_1` or `MACHINE_KP_9000_6XHML_X2_V2_1` | same V2.1 layout | `MACHINE_KP_9000_6XH_X2` |
+
+The V1.1 and V1.2 boards currently use the same V1.x GPIO, SFP, port and LED
+layout. The V2.1 board uses a different V2.1 layout with custom LED muxing.
+Legacy targets are preserved for compatibility with already-tested devices, but
+new builds should prefer the explicit PCB-revision targets.
+
### What works
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
@@ -19,7 +38,7 @@ Using SPI clamp in-board is the only method for initial installation.
- LEDs
- untested due to missing Hardware: SFP+ ports equipped with 1G or 2.5G SFPs.
-### Hardware overview
+### Hardware overview: 2M-PCB43-V2.1
Front side:
@@ -44,6 +63,24 @@ Bottom
+### Hardware overview: 2M-PCB43-V1.1 / V1.2
+
+The V1.1 board has been reported in the Mokerlink 2G040210GSM web-managed 4+2
+switch. The V1.2 board has been seen in managed `KP-9000-6XHML-X2` devices.
+Both use the same V1.x layout.
+
+Label:
+
+
+
+Top side:
+
+
+
+Bottom:
+
+
+
## Reset Button
There's an unpopulated Reset button on the front left side of the PCB.
@@ -54,4 +91,3 @@ The front case has already the hole in the metal case, you just have to punch a
## Power supply
Input power is delivered via barell plug, `12V 1A` adapter was provided.
-
diff --git a/doc/supported_devices.md b/doc/supported_devices.md
index bb187bf..3a8c462 100644
--- a/doc/supported_devices.md
+++ b/doc/supported_devices.md
@@ -15,11 +15,12 @@ The following devices have been tested and are fully working:
| Horaco | ZX310S-4T2XT | Yes | [PCB-SL310S-4T2XT-V1.0.0-22273](devices/ZX310S-4T2XT.md) | 2M | 6 |
| Horaco | ZX-SG4T2 | No | [SWTG024AS-A-V2.0.1_19650_4C_2SFP](devices/SWTG024AS-A-V2.0.1_4C_2SFP.md) | 0.5M | 4 + 2 |
| Horaco | ZX-SWTG124AS | Yes | [SWTG024AS-v2.0](devices/SWTG024AS.md) | | 4 + 2 |
-| Keeplink | KP-9000-6XH-X2 | No | [2M-PCB43-V2.1](devices/KP-9000-6XH-X2.md) | | 4 + 2 |
+| Keeplink | KP-9000-6XH-X2 / KP-9000-6XHML-X2 | No/Yes | [2M-PCB43-V1.2 / V2.1](devices/KP-9000-6XH-X2.md) | | 4 + 2 |
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V2.2](devices/2M-PCB23-V2_2.md) | 2M | 8 + 1 |
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V3.1](devices/2M-PCB23-V3_1.md) | 2M | 8 + 1 |
| LIANGUO | SWTG024AS | No | [SWTG024AS-v2.0-17452](devices/SWTG024AS.md) | 0.5M | 4 + 2 |
| Lianguo | ZX-SWTGW215AS | Yes | [PCB-SWTG115AS-V2.0](devices/SWTGW215AS.md) | 2M | 5 + 1 |
+| Mokerlink| 2G040210GSM | Yes | [2M-PCB43-V1.1](devices/2M-PCB43-V1.1.md) | | 4 + 2 |
| Mokerlink| ZX-SWTGW218AS | Yes | [SWTG118AS-V2.0-16029](devices/SWTGW218AS.md) | 2M | 8 + 1 |
| Ruiying | RY-4GT-2SX | No | [FG-4GT-2SX_V2.0](devices/FG-4GT-2SX_V2.0.md) | 4M | 4 + 2 |
| Sodola | SL-SWTG124AS-D | Yes | [SWTG024AS-v2.0-17452](devices/SWTG024AS.md) | 2M | 4 + 2 |
@@ -29,6 +30,10 @@ The following devices have been tested and are fully working:
| XikeStor | SKS3200-8E1X | Yes | [SWTG118AS-V2.1-17462](devices/SWTGW218AS.md) | 2M | 8 + 1 |
| Ztyuav | Z-QWYT0402 | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
+For KP-9000-6XH-X2 / KP-9000-6XHML-X2 / Mokerlink 2G040210GSM devices, select
+the machine target by PCB revision. The ML/non-ML or managed/unmanaged label
+alone does not identify the wiring.
+
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)
Many of the RTL8272/3 devices come in versions with PoE support. The RTLPlayground usually also
diff --git a/httpd/httpd.c b/httpd/httpd.c
index 2027013..9728254 100644
--- a/httpd/httpd.c
+++ b/httpd/httpd.c
@@ -50,6 +50,8 @@ __xdata uint8_t boundary[72];
__xdata uint8_t config_upload;
__xdata uint8_t config_buf[CONFIG_UPLOAD_BUF];
__xdata uint16_t cfg_pos, cfg_hdr, cfg_body, cfg_end, cfg_last;
+// part-header bytes buffered so far; accumulates across TCP segments
+__xdata uint16_t pre_acc;
__xdata uint8_t cfg_bl;
__xdata uint8_t * __xdata content_type = 0;
__xdata uint8_t * __xdata session = 0;
@@ -61,6 +63,9 @@ __xdata uint32_t max_upload;
__xdata uint16_t short_parsed;
__xdata char passwd[21];
+// Set when a verified firmware upload awaits its response ACK, after
+// which the chip resets to apply the staged image
+__xdata uint8_t fw_reset_pending;
__xdata char session_id[SESSION_ID_LENGTH + 1];
__xdata uint8_t authenticated;
__xdata uint32_t now;
@@ -92,6 +97,7 @@ void httpd_init(void) __banked
// Start listening to port 80
uip_listen(HTONS(80));
s->tstate = TSTATE_CLOSED;
+ fw_reset_pending = 0; // xdata is not zeroed by the startup code
}
@@ -176,7 +182,7 @@ bool is_url_word_x(__xdata uint8_t *uri_str_p, __xdata uint8_t *src_str_p)
}
-bool is_word_x(__xdata uint8_t *lhs_str_p, __xdata uint8_t *rhs_str_p)
+bool is_word_x(__xdata uint8_t * lhs_str_p, __xdata uint8_t * rhs_str_p)
{
uint8_t u, c;
@@ -241,18 +247,7 @@ void send_unauthorized(void)
}
-__xdata uint8_t *skip_boundary(__xdata uint8_t *p)
-{
- while (*p) {
- if (is_word_x(p, boundary))
- return p + strlen_x(boundary);
- p++;
- }
- return p;
-}
-
-
-__xdata uint8_t *scan_header(__xdata uint8_t *p)
+__xdata uint8_t *scan_header(__xdata uint8_t * __xdata p)
{
content_type = 0;
session = 0;
@@ -311,10 +306,12 @@ __xdata uint8_t *scan_header(__xdata uint8_t *p)
return p;
}
-
-void gen_random_bytes(__xdata uint8_t *b, uint8_t bytes)
+/*
+ * Generate random HEX-chars at the buffer location.
+ */
+void gen_random_hex_chars(__xdata uint8_t * b, __xdata uint8_t bytes)
{
- __xdata uint8_t i = 0;
+ uint8_t i = 0;
while (bytes) {
if (!i)
get_random_32();
@@ -385,21 +382,47 @@ static uint8_t config_take(void)
}
+// unlike scan_header(), keeps no auth state, so it may run on every buffered segment
+static uint16_t preamble_payload_start(uint16_t n)
+{
+ uint16_t pos;
+
+ for (pos = 0; pos + 24 <= n; pos++) {
+ if (strstart(&config_buf[pos], "application/octet-stream"))
+ break;
+ }
+ if (pos + 24 > n)
+ return 0;
+ pos += 24;
+ while (pos + 3 < n && !strstart(&config_buf[pos], "\r\n\r\n"))
+ pos++;
+ if (pos + 3 >= n)
+ return 0;
+ return pos + 4;
+}
+
+
+// Source window for stream_upload(); filled by the caller before the call
+__xdata struct {
+ __xdata uint8_t *p;
+ uint16_t bptr;
+ uint16_t plen;
+} upload_settings;
+
/*
* Reads post data from the http stream and writes it into flash memory
- * Input: the current position in the TCP buffer (uip_appdata)
+ * Input: upload_settings, set by the caller
* Returns 1: More data to read, 0: Upload complete, all parts reads
*/
-uint8_t stream_upload(uint16_t bptr)
+uint8_t stream_upload(void)
{
- __xdata uint8_t *p = uip_appdata;
__xdata struct httpd_state * __xdata s = &(uip_conn->appstate);
dbg_string("Stream_upload called: ");
- dbg_short(bptr); dbg_char('\n');
+ dbg_short(upload_settings.bptr); dbg_char('\n');
do {
- if (bptr >= uip_len) {
+ if (upload_settings.bptr >= upload_settings.plen) {
s->tstate = TSTATE_POST;
return 1;
}
@@ -412,17 +435,23 @@ uint8_t stream_upload(uint16_t bptr)
flash_write_bytes(flash_buf);
uptr += write_len;
write_len = 0;
- // TODO: This is a bit premature, what about a nice web-page saying the device will reset???
if (verify_crc) {
dbg_string("CRC16: "); dbg_short(crc_final); dbg_char('\n');
+ // Both bodies are 33 bytes; Content-Length lets the
+ // browser complete the response without waiting for
+ // the connection close (which a reset would swallow)
if (crc_final == 0xb001) {
print_string("Checksum OK.\nUpload to flash done, will reset!\n");
- // close connection to avoid retries by browser
- uip_close();
- reset_chip();
+ slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nContent-Length: 33\r\n"
+ "Content-Type: text/plain\r\n\r\n"
+ "OK: checksum verified, rebooting\n");
+ // Reset once the response is fully ACKed
+ fw_reset_pending = 1;
} else {
print_string("Checksum incorrect! Aborting.\n");
- uip_close();
+ slen = strtox(outbuf, "HTTP/1.1 400 Bad Request\r\nContent-Length: 33\r\n"
+ "Content-Type: text/plain\r\n\r\n"
+ "NO: checksum failed, not applied\n");
}
}
// Make sure there is a 0 at the end of the uploaded data
@@ -430,18 +459,15 @@ uint8_t stream_upload(uint16_t bptr)
flash_region.addr = uptr;
flash_region.len = 1;
flash_write_bytes(flash_buf);
- if (bptr >= uip_len)
+ if (upload_settings.bptr >= upload_settings.plen)
return 0;
- if(!verify_crc)
- //ugly hack to signal connection finished after config upload.
- uip_close();
return 1;
}
- if (p[bptr] == boundary[bindex]) {
+ if (upload_settings.p[upload_settings.bptr] == boundary[bindex]) {
if (!bindex)
crc_final = crc_value;
- crc16(p + bptr);
- bptr++;
+ crc16(upload_settings.p + upload_settings.bptr);
+ upload_settings.bptr++;
bindex++;
} else {
if (bindex) {
@@ -449,8 +475,8 @@ uint8_t stream_upload(uint16_t bptr)
write_len += bindex;
bindex = 0;
}
- crc16(p + bptr);
- flash_buf[write_len++] = p[bptr++];
+ crc16(upload_settings.p + upload_settings.bptr);
+ flash_buf[write_len++] = upload_settings.p[upload_settings.bptr++];
if (write_len >= FLASH_PAGE_SIZE) {
dbg_string("len: "); dbg_short(write_len); dbg_char(' ');
dbg_string("CRC16: "); dbg_short(crc_value); dbg_char('\n');
@@ -511,6 +537,7 @@ void handle_post(void)
uptr = FIRMWARE_UPLOAD_START;
verify_crc = 1;
max_upload = 1024576;
+ pre_acc = 0;
} else if (is_word(request_path, "config")) {
if (!authenticated) {
send_unauthorized();
@@ -550,11 +577,11 @@ void handle_post(void)
if (is_url_word_x(p, passwd)) {
dbg_string("Password accepted!\n");
read_reg_timer(&last_session_use);
- gen_random_bytes(session_id, SESSION_ID_LENGTH);
+ gen_random_hex_chars(session_id, SESSION_ID_LENGTH);
session_id[SESSION_ID_LENGTH] = NUL;
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\nConnection: close\r\nLocation: index.html\r\n" \
"Set-Cookie: session=");
- for (register uint8_t i = 0; i < SESSION_ID_LENGTH; i++)
+ for (uint8_t i = 0; i < SESSION_ID_LENGTH; i++)
outbuf[slen++] = session_id[i];
slen += strtox(outbuf + slen, "; SameSite=Strict\r\n\r\n");
} else {
@@ -599,21 +626,21 @@ void handle_post(void)
slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n");
return;
}
- // We skip the intial parts as part of the header
- do {
- p = skip_boundary(p);
- if (!*p) {
- s->tstate = TSTATE_MULTIPART;
- return;
- }
- p = scan_header(p);
- if (!*p)
- goto bad_request;
- if (!content_type) // We are waiting for the part with the octet stream
- continue;
- } while (!is_word(content_type, "application/octet-stream"));
+ cfg_pos = uip_len - (p - uip_appdata);
+ if (pre_acc + cfg_pos >= CONFIG_UPLOAD_BUF) {
+ print_string("Firmware upload header too large, aborting.\n");
+ s->tstate = TSTATE_NONE;
+ send_bad_request();
+ return;
+ }
+ memcpy(config_buf + pre_acc, p, cfg_pos);
+ pre_acc += cfg_pos;
+ cfg_end = preamble_payload_start(pre_acc);
+ if (!cfg_end) {
+ s->tstate = TSTATE_MULTIPART;
+ return;
+ }
dbg_string("Have content octets\n");
- p += 4; // Skip \r\n\r\n sequence at end of preamble of part
flash_init(0); // Re-initialize flash for non-DIO operation, otherwise flashing fails
set_sys_led_state(SYS_LED_FAST);
@@ -621,7 +648,14 @@ void handle_post(void)
crc_value = 0;
bindex = 0;
write_len = 0;
- stream_upload(p - uip_appdata);
+ // A verdict is only built once the upload part completes;
+ // clear any stale response so the completion check in the
+ // appcall POST branch cannot send leftovers
+ slen = 0;
+ upload_settings.p = config_buf;
+ upload_settings.bptr = cfg_end;
+ upload_settings.plen = pre_acc;
+ stream_upload();
dbg_string("Done reading first fragment\n");
return;
@@ -632,9 +666,6 @@ void handle_post(void)
}
slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n");
return;
-bad_request:
- send_bad_request();
- return;
}
@@ -698,11 +729,23 @@ void httpd_appcall(void)
cont_len -= slen;
cont_addr += slen;
s->tstate = TSTATE_TX;
+ } else if (fw_reset_pending) {
+ // The upload verdict has been fully ACKed by the client;
+ // now it is safe to reset and apply the staged image
+ print_string("Resetting to apply update\n");
+ reset_chip();
}
} else if (uip_newdata() && s->tstate == TSTATE_POST) {
// Check here maxupload by subtracting uip_len and close socekt if fails!
if (max_upload - uip_len > 0) {
- stream_upload(0);
+ upload_settings.p = uip_appdata;
+ upload_settings.bptr = 0;
+ upload_settings.plen = uip_len;
+ stream_upload();
+ // A completed part with a built verdict must go out
+ // through the normal TX path
+ if (s->tstate == TSTATE_NONE && slen)
+ goto do_send;
write_char('.');
} else {
send_bad_request();
diff --git a/httpd/page_impl.c b/httpd/page_impl.c
index 40117ff..9abd0ca 100644
--- a/httpd/page_impl.c
+++ b/httpd/page_impl.c
@@ -158,14 +158,14 @@ void sfr_data_to_html(void)
}
-void reg_to_html(register uint16_t reg)
+void reg_to_html(uint16_t reg)
{
reg_read_m(reg);
sfr_data_to_html();
}
-void reg_to_html_long(register uint16_t reg)
+void reg_to_html_long(uint16_t reg)
{
reg_read_m(reg);
byte_to_html(sfr_data[0]);
@@ -811,13 +811,13 @@ void send_status(void)
sfp_send_data(sfp, 238, 1);
}
slen += strtox(outbuf + slen,"\",\"sfp_vendor\":\"");
- for (register uint8_t s = 0; s < 16 && sfp_module_vendor[sfp][s]; s++)
+ for (uint8_t s = 0; s < 16 && sfp_module_vendor[sfp][s]; s++)
outbuf[slen++] = sfp_module_vendor[sfp][s];
slen += strtox(outbuf + slen,"\",\"sfp_model\":\"");
- for (register uint8_t s = 0; s < 16 && sfp_module_model[sfp][s]; s++)
+ for (uint8_t s = 0; s < 16 && sfp_module_model[sfp][s]; s++)
outbuf[slen++] = sfp_module_model[sfp][s];
slen += strtox(outbuf + slen,"\",\"sfp_serial\":\"");
- for (register uint8_t s = 0; s < 16 && sfp_module_serial[sfp][s]; s++)
+ for (uint8_t s = 0; s < 16 && sfp_module_serial[sfp][s]; s++)
outbuf[slen++] = sfp_module_serial[sfp][s];
slen += strtox(outbuf + slen,"\",\"sfp_los\":");
if (machine.sfp_port[sfp].pin_los == GPIO_NA) {
diff --git a/installer/installer.c b/installer/installer.c
index 675a142..f86b782 100644
--- a/installer/installer.c
+++ b/installer/installer.c
@@ -213,7 +213,7 @@ uint8_t flash_read_status(void)
* 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
*/
-void flash_read_bulk(register __xdata uint8_t *dst, __xdata uint32_t src, register uint16_t len)
+void flash_read_bulk(__xdata uint8_t *dst, __xdata uint32_t src, uint16_t len)
{
short status;
do {
diff --git a/machine.c b/machine.c
index d7d4823..7f4a512 100644
--- a/machine.c
+++ b/machine.c
@@ -5,9 +5,23 @@
#include "rtl837x_regs.h"
#include "rtl837x_common.h"
-#ifdef MACHINE_KP_9000_6XHML_X2
+#if defined(MACHINE_KP_9000_6XHML_X2) || \
+ defined(MACHINE_KP_9000_6XH_X2_V1_1) || \
+ defined(MACHINE_KP_9000_6XHML_X2_V1_1) || \
+ defined(MACHINE_KP_9000_6XH_X2_V1_2) || \
+ defined(MACHINE_KP_9000_6XHML_X2_V1_2)
__code const struct machine machine = {
+#if defined(MACHINE_KP_9000_6XH_X2_V1_1)
+ .machine_name = "keepLink KP-9000-6XH V1.1",
+#elif defined(MACHINE_KP_9000_6XHML_X2_V1_1)
+ .machine_name = "keepLink KP-9000-6XHML V1.1",
+#elif defined(MACHINE_KP_9000_6XH_X2_V1_2)
+ .machine_name = "keepLink KP-9000-6XH V1.2",
+#elif defined(MACHINE_KP_9000_6XHML_X2_V1_2)
+ .machine_name = "keepLink KP-9000-6XHML V1.2",
+#else
.machine_name = "keepLink KP-9000-6XHML-X2",
+#endif
.isRTL8373 = 0,
.min_port = 3,
.max_port = 8,
@@ -42,8 +56,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) { }
-
#elif defined MACHINE_KP_9000_6XH_X
__code const struct machine machine = {
.machine_name = "keepLink KP-9000-6XH-X",
@@ -72,11 +84,15 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) { }
-
-#elif defined MACHINE_KP_9000_6XH_X2
+#elif defined(MACHINE_KP_9000_6XH_X2) || defined(MACHINE_KP_9000_6XH_X2_V2_1) || defined(MACHINE_KP_9000_6XHML_X2_V2_1)
__code const struct machine machine = {
+#if defined(MACHINE_KP_9000_6XHML_X2_V2_1)
+ .machine_name = "keepLink KP-9000-6XHML V2.1",
+#elif defined(MACHINE_KP_9000_6XH_X2_V2_1)
+ .machine_name = "keepLink KP-9000-6XH-X2 V2.1",
+#else
.machine_name = "keepLink KP-9000-6XH-X2",
+#endif
.isRTL8373 = 0,
.min_port = 3,
.max_port = 8,
@@ -122,10 +138,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) {
- reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
-}
-
#elif defined MACHINE_KP_9000_9XH_X_EU
__code const struct machine machine = {
.machine_name = "keepLink KP-9000-9XH-X-EU",
@@ -151,8 +163,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) { }
-
#elif defined MACHINE_KP_9000_9XHML_X_V2_2
__code const struct machine machine = {
.machine_name = "keepLink KP-9000-9XHML-X V2.2",
@@ -204,8 +214,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) { }
-
#elif defined MACHINE_KP_9000_9XHML_X_V3_1
__code const struct machine machine = {
.machine_name = "keepLink KP-9000-9XHML-X V3.1",
@@ -241,8 +249,6 @@ __code const struct machine machine = {
0x1a, 0x19, 0x1d, 0x1e, 0x1c, 0x1d, 0x20, 0x21},
};
-void machine_custom_init(void) { }
-
#elif defined MACHINE_SWGT024_V2_0_MANAGED
__code const struct machine machine = {
.machine_name = "SWGT024 V2.0 Managed",
@@ -284,8 +290,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) { }
-
#elif defined MACHINE_SWGT024_V2_0_UNMANAGED
__code const struct machine machine = {
.machine_name = "SWGT024 V2.0 Unmanaged",
@@ -327,8 +331,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",
@@ -368,8 +370,6 @@ __code const struct machine machine = {
0x1d, 0x20, 0x21 },
};
-void machine_custom_init(void) { }
-
#elif defined MACHINE_HG0402XG_V1_1
__code const struct machine machine = {
.machine_name = "HG0402XG V1.1",
@@ -408,8 +408,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) { }
-
#elif defined MACHINE_SWTGW218AS
__code const struct machine machine = {
@@ -443,8 +441,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) { }
-
#elif defined MACHINE_PCB_SWTG018AS_V2_1_0 // Sold as Sodola SL902 / Horaco "SWTGW218AS"; the SWTGW218AS label also covers other PCBs with different SFP and LED wiring (see MACHINE_SWTGW218AS)
__code const struct machine machine = {
@@ -487,44 +483,6 @@ __code const struct machine machine = {
0x1d, 0x20, 0x21 },
};
-// The LED-set encoding cannot express this board's bi-color SFP LED (green <= 2.5G,
-// blue at 10G), so program the LED register block with the values the stock firmware
-// uses. Runs after leds_setup() and overrides the values computed there.
-// The final entry routes the blue-LED pin to the LED controller via PIN_MUX_0;
-// as a GPIO (the default) no LED register can light it. PIN_MUX_1/2 stay
-// untouched so SFP detect (GPIO38) and i2c remain GPIOs.
-static __code const struct { uint16_t reg; uint32_t val; } custom_init_regs[] = {
- { 0x6520, 0x0023e430UL }, // LED_MODE
- { 0x6524, 0xff001400UL }, // LED3_0_SET3
- { 0x6528, 0x00100000UL }, // LED3_0_SET1
- { 0x652c, 0x007f013fUL }, // LED3_2_SET3
- { 0x6530, 0x02000400UL }, // LED1_0_SET3
- { 0x6534, 0x01400141UL }, // LED3_2_SET2
- { 0x6538, 0x01440170UL }, // LED1_0_SET2
- { 0x653c, 0x18000041UL }, // LED3_2_SET1
- { 0x6540, 0x01400155UL }, // LED1_0_SET1
- { 0x6544, 0x01411000UL }, // LED3_2_SET0
- { 0x6548, 0x01740141UL }, // LED1_0_SET0
- { 0x654c, 0x00010000UL }, // LED_PORT_SET_SEL
- { 0x65d8, 0x3ffb6dffUL }, // LED_GLB_ACTIVE
- { 0x65dc, 0x7f24977fUL }, // LED_GLB_IO_EN
- { 0x65e0, 0x08144040UL }, // LED_GLB_MUX_1
- { 0x65e4, 0x10349309UL }, // LED_GLB_MUX_2
- { 0x65e8, 0x12454391UL }, // LED_GLB_MUX_3
- { 0x65ec, 0x19616555UL }, // LED_GLB_MUX_4
- { 0x65f0, 0x1c79d65aUL }, // LED_GLB_MUX_5
- { 0x65f4, 0x0002181dUL }, // LED_GLB_MUX_6
- { 0x7f8c, 0x20db6880UL }, // PIN_MUX_0
-};
-
-void machine_custom_init(void) {
- uint8_t i;
- // REG_SET is a multi-statement macro without a do-while wrapper: braces required
- for (i = 0; i < sizeof(custom_init_regs) / sizeof(custom_init_regs[0]); i++) {
- REG_SET(custom_init_regs[i].reg, custom_init_regs[i].val);
- }
-}
-
#elif defined MACHINE_LIANGUO_ZX_SWTGW215AS // Has PCB branded PCB-SWTG115AS-V2.0 but is labeled and reports as a ZX-SWTGW215AS, seems to be identical to the "real" ZX-SWTGW215AS except for the LEDs
__code const struct machine machine = {
.machine_name = "Lianguo ZX-SWTGW215AS",
@@ -557,8 +515,6 @@ __code const struct machine machine = {
.led_mux_custom = 0,
};
-void machine_custom_init(void) { }
-
#elif defined MACHINE_DEFAULT_8C_1SFP
__code const struct machine machine = {
.machine_name = "8+1 SFP Port Switch",
@@ -584,8 +540,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) { }
-
#elif defined MACHINE_TRENDNET_TEG_S562
__code const struct machine machine = {
.machine_name = "Trendnet TEG-S562",
@@ -625,8 +579,6 @@ __code const struct machine machine = {
};
-void machine_custom_init(void) { }
-
#elif defined(MACHINE_PCB_K0402WS_V3) || defined(MACHINE_HI_K0402WS) // Sold as a variety of devices, see doc/
__code const struct machine machine = {
.machine_name = "PCB-K0402WS-V3.0",
@@ -673,10 +625,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) {
- reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
-}
-
#elif defined MACHINE_K0501W_V2_0
__code const struct machine machine = {
.machine_name = "K0501W V2.0",
@@ -711,8 +659,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) { }
-
#elif defined MACHINE_ZX310S_4T2XH
__code const struct machine machine = {
.machine_name = "ZX310S-4T2XH",
@@ -756,8 +702,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) { }
-
#elif defined MACHINE_STEAMEMO_IG204_V1
__code const struct machine machine = {
.machine_name = "Steamemo IG204 V1",
@@ -808,8 +752,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) { }
-
#elif defined MACHINE_HI_K0801WS
__code const struct machine machine = {
.machine_name = "Hi-Source HI-k0801WS",
@@ -859,8 +801,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) { }
-
#elif defined MACHINE_FNS1200P
__code const struct machine machine = {
.machine_name = "FNS-1200P",
@@ -916,11 +856,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void)
-{
- reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
-}
-
#elif defined MACHINE_PCB_SWTG024AS_A_2_0_1
__code const struct machine machine = {
@@ -970,14 +905,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void)
-{
- reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
- reg_bit_set(RTL837X_REG_LED_MODE, 17);
- reg_bit_clear(RTL837X_REG_LED_MODE, 9);
- reg_bit_clear(RTL837X_REG_LED_MODE, 7);
-}
-
#elif defined MACHINE_SWTG024AS_A_2_0_1_5C_1SFP
__code const struct machine machine = {
.machine_name = "SWTG024AS-A-V2.0.1-5C-1SFP",
@@ -1021,25 +948,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void)
-{
- uint16_t pval;
-
- reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
- reg_bit_set(RTL837X_REG_LED_MODE, 17);
- reg_bit_clear(RTL837X_REG_LED_MODE, 9);
- reg_bit_clear(RTL837X_REG_LED_MODE, 7);
-
- // OEM firmware sets these companion SDS0 polarity bits for the RTL8221B.
- sds_read(0, 0, 0);
- pval = SFR_DATA_U16;
- sds_write_v(0, 0, 0, pval | 0x100);
-
- sds_read(0, 6, 2);
- pval = SFR_DATA_U16;
- sds_write_v(0, 6, 2, pval | 0x4000);
-}
-
#elif defined MACHINE_SWTG024AS_V2_0
__code const struct machine machine = {
.machine_name = "SWTG024AS-V2.0",
@@ -1083,25 +991,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void)
-{
- uint16_t pval;
-
- reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
- reg_bit_set(RTL837X_REG_LED_MODE, 17);
- reg_bit_clear(RTL837X_REG_LED_MODE, 9);
- reg_bit_clear(RTL837X_REG_LED_MODE, 7);
-
- // OEM firmware sets these companion SDS0 polarity bits for the RTL8221B.
- sds_read(0, 0, 0);
- pval = SFR_DATA_U16;
- sds_write_v(0, 0, 0, pval | 0x100);
-
- sds_read(0, 6, 2);
- pval = SFR_DATA_U16;
- sds_write_v(0, 6, 2, pval | 0x4000);
-}
-
#elif defined MACHINE_ZX310S_4T2XT
__code const struct machine machine = {
.machine_name = "ZX310S_4T2XT",
@@ -1139,12 +1028,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) {
- // For this device, the reset value of RTL837X_PIN_MUX_0 is 0x30000000,
- // which would disables all LEDS, enable them manually:
- REG_SET(RTL837X_PIN_MUX_0, 0x30db68bf);
-}
-
#elif defined MACHINE_FG_4GT_2SX_V2_0
__code const struct machine machine = {
.machine_name = "FG-4GT-2SX_V2.0",
@@ -1211,10 +1094,6 @@ __code const struct machine machine = {
},
};
-void machine_custom_init(void) {
- REG_SET(RTL837X_REG_LED_GLB_IO_EN, 0x7624155b);
-}
-
#else
#error "Please select a machine type in machine.h"
#endif
diff --git a/machine.h b/machine.h
index 29fe39f..9efa675 100644
--- a/machine.h
+++ b/machine.h
@@ -6,9 +6,19 @@
/*
* Select your machine type below
*/
+// Legacy KP-9000 4+2 targets. Prefer the PCB-revision-specific targets below.
// #define MACHINE_KP_9000_6XHML_X2
-// #define MACHINE_KP_9000_6XH_X
// #define MACHINE_KP_9000_6XH_X2
+
+// KP-9000 4+2 targets by PCB silkscreen revision.
+// #define MACHINE_KP_9000_6XH_X2_V1_1
+// #define MACHINE_KP_9000_6XHML_X2_V1_1
+// #define MACHINE_KP_9000_6XH_X2_V1_2
+// #define MACHINE_KP_9000_6XHML_X2_V1_2
+// #define MACHINE_KP_9000_6XH_X2_V2_1
+// #define MACHINE_KP_9000_6XHML_X2_V2_1
+
+// #define MACHINE_KP_9000_6XH_X
// #define MACHINE_KP_9000_9XH_X_EU
// #define MACHINE_KP_9000_9XHML_X_V2_2
// #define MACHINE_KP_9000_9XHML_X_V3_1
@@ -95,6 +105,6 @@ typedef struct machine_runtime
uint8_t isN : 1;
};
-void machine_custom_init(void);
+void machine_custom_init(void) __banked;
#endif
diff --git a/machine_init.c b/machine_init.c
new file mode 100644
index 0000000..e11e7f2
--- /dev/null
+++ b/machine_init.c
@@ -0,0 +1,122 @@
+/*
+ * Per-machine one-shot boot hooks, hosted in BANK2 so board-specific
+ * tables and code do not consume the common bank.
+ */
+#include
+#include "machine.h"
+#include "rtl837x_pins.h"
+#include "rtl837x_leds.h"
+#include "rtl837x_sfr.h"
+#include "rtl837x_regs.h"
+#include "rtl837x_common.h"
+
+#pragma codeseg BANK2
+#pragma constseg BANK2
+
+#if defined(MACHINE_KP_9000_6XH_X2) || \
+ defined(MACHINE_KP_9000_6XH_X2_V2_1) || \
+ defined(MACHINE_KP_9000_6XHML_X2_V2_1)
+void machine_custom_init(void) __banked
+{
+ reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
+}
+
+#elif defined MACHINE_PCB_SWTG018AS_V2_1_0
+// Stock-firmware values for what the LED-set encoding cannot express: the
+// bi-color SFP LED (blue pin at 10G) and the PIN_MUX_0 routing of that pin
+// to the LED controller. Runs after leds_setup(), which covers the rest.
+static __code const struct { uint16_t reg; uint32_t val; } custom_init_regs[] = {
+ { RTL837X_REG_LED3_0_SET1, 0x00100000UL },
+ { RTL837X_REG_LED1_0_SET1, 0x01400155UL },
+ { RTL837X_REG_LED1_0_SET0, 0x01740141UL },
+ { RTL837X_REG_LED_GLB_IO_EN, 0x7f24977fUL },
+ { RTL837X_PIN_MUX_0, 0x20db6880UL },
+};
+
+void machine_custom_init(void) __banked
+{
+ uint8_t i;
+ // REG_SET is a multi-statement macro without a do-while wrapper: braces required
+ for (i = 0; i < sizeof(custom_init_regs) / sizeof(custom_init_regs[0]); i++) {
+ REG_SET(custom_init_regs[i].reg, custom_init_regs[i].val);
+ }
+}
+
+#elif defined(MACHINE_PCB_K0402WS_V3) || defined(MACHINE_HI_K0402WS)
+void machine_custom_init(void) __banked
+{
+ reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
+}
+
+#elif defined MACHINE_FNS1200P
+void machine_custom_init(void) __banked
+{
+ reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
+}
+
+#elif defined MACHINE_PCB_SWTG024AS_A_2_0_1
+void machine_custom_init(void) __banked
+{
+ reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
+ reg_bit_set(RTL837X_REG_LED_MODE, 17);
+ reg_bit_clear(RTL837X_REG_LED_MODE, 9);
+ reg_bit_clear(RTL837X_REG_LED_MODE, 7);
+}
+
+#elif defined MACHINE_SWTG024AS_A_2_0_1_5C_1SFP
+void machine_custom_init(void) __banked
+{
+ uint16_t pval;
+
+ reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
+ reg_bit_set(RTL837X_REG_LED_MODE, 17);
+ reg_bit_clear(RTL837X_REG_LED_MODE, 9);
+ reg_bit_clear(RTL837X_REG_LED_MODE, 7);
+
+ // OEM firmware sets these companion SDS0 polarity bits for the RTL8221B.
+ sds_read(0, 0, 0);
+ pval = SFR_DATA_U16;
+ sds_write_v(0, 0, 0, pval | 0x100);
+
+ sds_read(0, 6, 2);
+ pval = SFR_DATA_U16;
+ sds_write_v(0, 6, 2, pval | 0x4000);
+}
+
+#elif defined MACHINE_SWTG024AS_V2_0
+void machine_custom_init(void) __banked
+{
+ uint16_t pval;
+
+ reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
+ reg_bit_set(RTL837X_REG_LED_MODE, 17);
+ reg_bit_clear(RTL837X_REG_LED_MODE, 9);
+ reg_bit_clear(RTL837X_REG_LED_MODE, 7);
+
+ // OEM firmware sets these companion SDS0 polarity bits for the RTL8221B.
+ sds_read(0, 0, 0);
+ pval = SFR_DATA_U16;
+ sds_write_v(0, 0, 0, pval | 0x100);
+
+ sds_read(0, 6, 2);
+ pval = SFR_DATA_U16;
+ sds_write_v(0, 6, 2, pval | 0x4000);
+}
+
+#elif defined MACHINE_ZX310S_4T2XT
+void machine_custom_init(void) __banked
+{
+ // For this device, the reset value of RTL837X_PIN_MUX_0 is 0x30000000,
+ // which would disables all LEDS, enable them manually:
+ REG_SET(RTL837X_PIN_MUX_0, 0x30db68bf);
+}
+
+#elif defined MACHINE_FG_4GT_2SX_V2_0
+void machine_custom_init(void) __banked
+{
+ REG_SET(RTL837X_REG_LED_GLB_IO_EN, 0x7624155b);
+}
+
+#else
+void machine_custom_init(void) __banked { }
+#endif
diff --git a/rtl837x_common.h b/rtl837x_common.h
index 194bfeb..923d02a 100644
--- a/rtl837x_common.h
+++ b/rtl837x_common.h
@@ -166,13 +166,13 @@ void sfr_mask_data(uint8_t n, uint8_t mask, uint8_t set);
void sfr_set_zero(void);
void reset_chip(void);
void memcpy(__xdata void * __xdata dst, __xdata const void * __xdata src, uint16_t len);
-void memcpyc(register __xdata uint8_t *dst, register __code uint8_t *src, register uint16_t len);
-void memset(register __xdata uint8_t *dst, register __xdata uint8_t v, register uint8_t len);
-uint16_t strlen(register __code 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 strcpy(register __xdata uint8_t *dst, register const char *s);
-char strcmp(register __xdata const uint8_t *a, register __code const uint8_t *b);
+void memcpyc(__xdata uint8_t *dst, __code uint8_t *src, uint16_t len);
+void memset(__xdata uint8_t *dst, __xdata uint8_t v, uint8_t len);
+uint16_t strlen(__code const char *s);
+uint16_t strlen_x(__xdata const char *s);
+uint16_t strtox(__xdata uint8_t *dst, __code const char *s);
+uint16_t strcpy(__xdata uint8_t *dst, const char *s);
+char strcmp(__xdata const uint8_t *a, __code const uint8_t *b);
bool strstart(__xdata const uint8_t *a, __code const uint8_t *b);
bool strstart_x(__xdata const uint8_t *a, __xdata const uint8_t *b);
void tcpip_output(void);
diff --git a/rtl837x_port.c b/rtl837x_port.c
index 95acd2b..b357e58 100644
--- a/rtl837x_port.c
+++ b/rtl837x_port.c
@@ -30,7 +30,7 @@ __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(uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked
{
print_string("\nport_mirror_set called \n");
print_string("Mirroring port: "); print_byte(port); print_string(" with rx-mask: ");
@@ -162,7 +162,7 @@ void vlan_name_remove(uint16_t vlan) __banked
* Reads VLAN information from VLAN table
* Returns data in sfr_data
*/
-int8_t vlan_get(register uint16_t vlan) __banked
+int8_t vlan_get(uint16_t vlan) __banked
{
if (vlan >= 0xfff) // VLAN 4095 is special
return -1;
@@ -177,7 +177,7 @@ int8_t vlan_get(register uint16_t vlan) __banked
}
-__xdata uint16_t vlan_name(register uint16_t vlan) __banked
+__xdata uint16_t vlan_name(uint16_t vlan) __banked
{
__xdata int16_t i = 0;
__xdata uint8_t begin = 1;
@@ -540,14 +540,14 @@ void port_stats_print(void) __banked
}
-void port_isolate(register uint8_t port, __xdata uint16_t pmask) __banked
+void port_isolate(uint8_t port, __xdata uint16_t pmask) __banked
{
if (port <= machine.max_port)
REG_SET(RTL837X_PORT_ISOLATION_BASE + (port << 2), pmask);
}
-uint16_t port_isolation_get(register uint8_t port) __banked
+uint16_t port_isolation_get(uint8_t port) __banked
{
if (port > machine.max_port)
return 0;
diff --git a/rtl837x_port.h b/rtl837x_port.h
index 56397ee..2c88cf0 100644
--- a/rtl837x_port.h
+++ b/rtl837x_port.h
@@ -48,8 +48,8 @@ extern __xdata struct vlan_settings vlan_settings;
uint8_t port_l2_forget(void) __banked;
void port_l2_learned(void) __banked;
void port_stats_print(void) __banked;
-int8_t vlan_get(register uint16_t vlan) __banked;
-__xdata uint16_t vlan_name(register uint16_t vlan) __banked;
+int8_t vlan_get(uint16_t vlan) __banked;
+__xdata uint16_t vlan_name(uint16_t vlan) __banked;
void vlan_name_remove(uint16_t vlan) __banked;
void vlan_setup(void) __banked;
void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked;
@@ -59,7 +59,7 @@ void port_l2_forget_port(uint8_t port) __banked;
void vlan_create(void) __banked;
void vlan_delete(uint16_t vlan) __banked;
void vlan_dump(void) __banked;
-void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked;
+void port_mirror_set(uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked;
void port_mirror_del(void) __banked;
bool port_ingress_filter(__xdata uint8_t port, __xdata vlan_ingress_mode_t type) __banked;
void port_l2_setup(void) __banked;
@@ -76,7 +76,7 @@ void print_port_ingress_filter_mode(vlan_ingress_mode_t mode) __banked;
bool port_ingress_vlan_filter_set(__xdata uint8_t port, __xdata bool enabled) __banked;
bool port_ingress_vlan_filter_get(__xdata uint8_t port) __banked;
vlan_ingress_mode_t port_ingress_filter_get(__xdata uint8_t port) __banked;
-void port_isolate(register uint8_t port, __xdata uint16_t pmask) __banked;
-uint16_t port_isolation_get(register uint8_t port) __banked;
+void port_isolate(uint8_t port, __xdata uint16_t pmask) __banked;
+uint16_t port_isolation_get(uint8_t port) __banked;
#endif
diff --git a/rtl837x_stp.c b/rtl837x_stp.c
index 00c27ca..2dc8337 100644
--- a/rtl837x_stp.c
+++ b/rtl837x_stp.c
@@ -6,9 +6,6 @@
// #define REGDBG
// #define DEBUG
-#pragma codeseg BANK2
-#pragma constseg BANK2
-
#include
#include "rtl837x_common.h"
#include "rtl837x_sfr.h"
@@ -18,6 +15,11 @@
#include "uip.h"
#include "machine.h"
+// All entry points are __banked and nothing here runs from an interrupt,
+// so the module does not need to stay in the resident bank
+#pragma codeseg BANK2
+#pragma constseg BANK2
+
extern __code struct machine machine;
extern __xdata uint8_t sfr_data[4];
extern __xdata struct machine_runtime machine_detected;
diff --git a/rtlplayground.c b/rtlplayground.c
index ce9ed83..b63eed1 100644
--- a/rtlplayground.c
+++ b/rtlplayground.c
@@ -314,20 +314,20 @@ void memcpy(__xdata void * __xdata dst, __xdata const void * __xdata src, uint16
*d++ = *s++;
}
-void memcpyc(register __xdata uint8_t *dst, register __code uint8_t *src, register uint16_t len)
+void memcpyc(__xdata uint8_t *dst, __code uint8_t *src, uint16_t len)
{
while (len--)
*dst++ = *src++;
}
-void memset(register __xdata uint8_t *dst, register __xdata uint8_t v, register uint8_t len)
+void memset(__xdata uint8_t *dst, __xdata uint8_t v, uint8_t len)
{
while (len--)
*dst++ = v;
}
-uint16_t strtox(register __xdata uint8_t *dst, register __code const char *s)
+uint16_t strtox(__xdata uint8_t *dst, __code const char *s)
{
__xdata uint8_t *b = dst;
while (*s)
@@ -337,7 +337,7 @@ uint16_t strtox(register __xdata uint8_t *dst, register __code const char *s)
}
-uint16_t strlen(register __code const char *s)
+uint16_t strlen(__code const char *s)
{
uint16_t l = 0;
while (s[l])
@@ -346,7 +346,7 @@ uint16_t strlen(register __code const char *s)
}
-uint16_t strlen_x(register __xdata const char *s)
+uint16_t strlen_x(__xdata const char *s)
{
uint16_t l = 0;
while (s[l])
@@ -355,7 +355,7 @@ uint16_t strlen_x(register __xdata const char *s)
}
-char strcmp(register __xdata const uint8_t *a, register __code const uint8_t *b)
+char strcmp(__xdata const uint8_t *a, __code const uint8_t *b)
{
uint8_t i = 0;
@@ -678,7 +678,7 @@ bool nic_rx_header(uint16_t ring_ptr)
* data will be returned in the xmem buffer points to
* ring_ptr is the current position of the RX Ring on the ASIC side
*/
-bool nic_rx_packet(register uint16_t buffer, register uint16_t ring_ptr)
+bool nic_rx_packet(uint16_t buffer, uint16_t ring_ptr)
{
uint16_t guard = 0;
@@ -1252,7 +1252,7 @@ void handle_tx(void)
}
-static inline uint8_t sfp_rate_to_sds_config(register uint8_t rate)
+static inline uint8_t sfp_rate_to_sds_config(uint8_t rate)
{
if (rate == 0x1 || rate == 0x2)
return SDS_100FX;
diff --git a/syslog.c b/syslog.c
index 989e8cc..021ef72 100644
--- a/syslog.c
+++ b/syslog.c
@@ -62,19 +62,19 @@ void syslog_callback(uint16_t lport) __banked
if ((state.readptr != state.writeptr) && state.line_available)
{
- int16_t log_size = state.writeptr - state.readptr;
+ __xdata int16_t log_size = state.writeptr - state.readptr;
if (log_size < 0)
log_size += LOGBUF_SIZE;
// Skipping linefeeds at the start of the log line
- uint16_t log_start = state.readptr;
+ __xdata uint16_t log_start = state.readptr;
while (log_size > 0 && logbuf[log_start] == '\n') {
log_start = (log_start + 1) & (LOGBUF_SIZE - 1);
log_size--;
}
// Skipping linefeeds and whitespaces at the end of the log line
- uint16_t log_end = state.writeptr;
+ __xdata uint16_t log_end = state.writeptr;
while ( (log_size > 0) &&
((logbuf[(log_end-1) & (LOGBUF_SIZE - 1)] == '\n') ||
(logbuf[(log_end-1) & (LOGBUF_SIZE - 1)] == ' ')))
@@ -95,7 +95,7 @@ void syslog_callback(uint16_t lport) __banked
memcpy(SYSLOG_P + 4, logbuf + log_start, LOGBUF_SIZE - log_start);
memcpy(SYSLOG_P + 4 + LOGBUF_SIZE - log_start, logbuf, log_end);
} else {
- memcpy(SYSLOG_P + 4, logbuf + log_start, log_end - log_start);
+ memcpy(SYSLOG_P + 4, logbuf + log_start, log_end - log_start);
}
uip_udp_send(log_size+4);
diff --git a/uip/psock.c b/uip/psock.c
index eb4d1af..f1c1115 100644
--- a/uip/psock.c
+++ b/uip/psock.c
@@ -75,8 +75,7 @@
/*---------------------------------------------------------------------------*/
inline void
-buf_setup(register __xdata struct psock_buf *buf,
- register __xdata u8_t *bufptr, register u16_t bufsize)
+buf_setup(__xdata struct psock_buf *buf, __xdata u8_t *bufptr, u16_t bufsize)
{
buf->ptr = bufptr;
buf->left = bufsize;
@@ -84,7 +83,7 @@ buf_setup(register __xdata struct psock_buf *buf,
/*---------------------------------------------------------------------------*/
inline u8_t
-buf_bufdata(register __xdata struct psock_buf *buf, register __xdata u8_t **dataptr, register __xdata u16_t *datalen)
+buf_bufdata(__xdata struct psock_buf *buf, __xdata u8_t **dataptr, __xdata u16_t *datalen)
{
if(*datalen < buf->left) {
memcpy(buf->ptr, *dataptr, *datalen);
@@ -145,7 +144,7 @@ buf_bufto(__xdata struct psock_buf *buf, u8_t endmarker,
}
/*---------------------------------------------------------------------------*/
static char
-send_data(register __xdata struct psock *s)
+send_data(__xdata struct psock *s)
{
if(s->state != STATE_DATA_SENT || uip_rexmit()) {
if(s->sendlen > uip_mss()) {
@@ -160,7 +159,7 @@ send_data(register __xdata struct psock *s)
}
/*---------------------------------------------------------------------------*/
static char
-data_acked(register __xdata struct psock *s)
+data_acked(__xdata struct psock *s)
{
if(s->state == STATE_DATA_SENT && uip_acked()) {
if(s->sendlen > uip_mss()) {
@@ -176,8 +175,7 @@ data_acked(register __xdata struct psock *s)
return 0;
}
/*---------------------------------------------------------------------------*/
-PT_THREAD(psock_send(register __xdata struct psock *s, register __xdata const char *buf,
- register uint16_t len))
+PT_THREAD(psock_send(__xdata struct psock *s, __xdata const char *buf, uint16_t len))
{
PT_BEGIN(&s->psockpt);
@@ -218,7 +216,7 @@ PT_THREAD(psock_send(register __xdata struct psock *s, register __xdata const ch
/*---------------------------------------------------------------------------*/
-// PT_THREAD(psock_generator_send(register __xdata struct psock *s,
+// PT_THREAD(psock_generator_send(__xdata struct psock *s,
// unsigned short (*generate)(void *), void *arg))
// {
// PT_BEGIN(&s->psockpt);
@@ -275,7 +273,7 @@ psock_newdata(__xdata struct psock *s)
}
}
/*---------------------------------------------------------------------------*/
-PT_THREAD(psock_readto(register __xdata struct psock *psock, unsigned char c))
+PT_THREAD(psock_readto(__xdata struct psock *psock, unsigned char c))
{
PT_BEGIN(&psock->psockpt);
@@ -304,7 +302,7 @@ PT_THREAD(psock_readto(register __xdata struct psock *psock, unsigned char c))
PT_END(&psock->psockpt);
}
/*---------------------------------------------------------------------------*/
-PT_THREAD(psock_readbuf(register __xdata struct psock *psock))
+PT_THREAD(psock_readbuf(__xdata struct psock *psock))
{
PT_BEGIN(&psock->psockpt);
@@ -334,7 +332,7 @@ PT_THREAD(psock_readbuf(register __xdata struct psock *psock))
}
/*---------------------------------------------------------------------------*/
void
-psock_init(register __xdata struct psock *psock, register __xdata char *buffer, register uint16_t buffersize)
+psock_init(__xdata struct psock *psock, __xdata char *buffer, uint16_t buffersize)
{
psock->state = STATE_NONE;
psock->readlen = 0;
diff --git a/uip/psock.h b/uip/psock.h
index a4967d2..3a6e7e4 100644
--- a/uip/psock.h
+++ b/uip/psock.h
@@ -124,7 +124,7 @@ struct psock {
u8_t state; /* The state of the protosocket. */
};
-void psock_init(__xdata struct psock *psock, register __xdata char *buffer, register uint16_t buffersize);
+void psock_init(__xdata struct psock *psock, __xdata char *buffer, uint16_t buffersize);
/**
* Initialize a protosocket.
*
@@ -158,7 +158,7 @@ void psock_init(__xdata struct psock *psock, register __xdata char *buffer, regi
*/
#define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt))
-PT_THREAD(psock_send(register __xdata struct psock *psock, register __xdata const char *buf, register uint16_t len));
+PT_THREAD(psock_send(__xdata struct psock *psock, __xdata const char *buf, uint16_t len));
/**
* Send data.
*
diff --git a/uip/uip.c b/uip/uip.c
index 6a194c1..1d015fc 100644
--- a/uip/uip.c
+++ b/uip/uip.c
@@ -157,7 +157,7 @@ __xdata u16_t uip_len, uip_slen;
__xdata u8_t uip_flags; /* The uip_flags variable is used for
communication between the TCP/IP stack
and the application program. */
-__xdata struct uip_conn *uip_conn; /* uip_conn always points to the current
+__xdata struct uip_conn * __xdata uip_conn; /* uip_conn always points to the current
connection. */
__xdata struct uip_conn uip_conns[UIP_CONNS];
@@ -167,7 +167,7 @@ __xdata u16_t uip_listenports[UIP_LISTENPORTS];
/* The uip_listenports list all currently
listning ports. */
#if UIP_UDP
-__xdata struct uip_udp_conn *uip_udp_conn;
+__xdata struct uip_udp_conn * __xdata uip_udp_conn;
__xdata struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
#endif /* UIP_UDP */
@@ -400,7 +400,7 @@ uip_init(void) __banked
/*---------------------------------------------------------------------------*/
#if UIP_ACTIVE_OPEN
__xdata struct uip_conn *
-uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banked
+uip_connect(__xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banked
{
__xdata struct uip_conn *conn, *cconn;
@@ -466,7 +466,7 @@ uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banke
/*---------------------------------------------------------------------------*/
#if UIP_UDP
__xdata struct uip_udp_conn *
-uip_udp_new(__xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banked
+uip_udp_new(__xdata uip_ipaddr_t * __xdata ripaddr, __xdata u16_t rport) __banked
{
__xdata struct uip_udp_conn *conn;
@@ -677,7 +677,7 @@ uip_add_rcv_nxt(u16_t n)
void
uip_process(u8_t flag) __banked
{
- register __xdata struct uip_conn *uip_connr = uip_conn;
+ __xdata struct uip_conn *uip_connr = uip_conn;
#if UIP_UDP
if(flag == UIP_UDP_SEND_CONN) {
diff --git a/uip/uip.h b/uip/uip.h
index 7cd12e2..5f4d8e2 100644
--- a/uip/uip.h
+++ b/uip/uip.h
@@ -763,7 +763,7 @@ void uip_send(__xdata const void *data, __xdata uint16_t len) __banked;
* \return The uip_udp_conn structure for the new connection or NULL
* if no connection could be allocated.
*/
-__xdata struct uip_udp_conn *uip_udp_new(__xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banked;
+__xdata struct uip_udp_conn *uip_udp_new(__xdata uip_ipaddr_t * __xdata ripaddr, __xdata u16_t rport) __banked;
/**
* Removed a UDP connection.
@@ -1193,7 +1193,7 @@ struct uip_conn {
* The uip_conn pointer can be used to access the current TCP
* connection.
*/
-extern __xdata struct uip_conn *uip_conn;
+extern __xdata struct uip_conn * __xdata uip_conn;
/* The array containing all uIP connections. */
extern __xdata struct uip_conn uip_conns[UIP_CONNS];
/**
@@ -1226,7 +1226,7 @@ struct uip_udp_conn {
/**
* The current UDP connection.
*/
-extern __xdata struct uip_udp_conn *uip_udp_conn;
+extern __xdata struct uip_udp_conn * __xdata uip_udp_conn;
extern __xdata struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
#endif /* UIP_UDP */
diff --git a/uip/uip_arp.c b/uip/uip_arp.c
index 8b8bd00..44bee6c 100644
--- a/uip/uip_arp.c
+++ b/uip/uip_arp.c
@@ -175,7 +175,7 @@ uip_arp_timer(void) __banked
}
/*-----------------------------------------------------------------------------------*/
static void
-uip_arp_update(__xdata u16_t *ipaddr, __xdata struct uip_eth_addr *ethaddr)
+uip_arp_update(__xdata u16_t * __xdata ipaddr, __xdata struct uip_eth_addr * __xdata ethaddr)
{
uint8_t i;
/* Walk through the ARP mapping table and try to find an entry to