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