mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Compare commits
64
Commits
80095ba617
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1db30f22de | ||
|
|
4c70e654d1 | ||
|
|
3c24f2bdea | ||
|
|
3e610392a9 | ||
|
|
146771f5ca | ||
|
|
bf0bea1edd | ||
|
|
907ad08830 | ||
|
|
7cf0115182 | ||
|
|
adfbead438 | ||
|
|
301774040b | ||
|
|
683037f410 | ||
|
|
57b820c4e8 | ||
|
|
801150431b | ||
|
|
45d0aac118 | ||
|
|
ee05cd4000 | ||
|
|
74013bb14f | ||
|
|
beb14deba5 | ||
|
|
1212def799 | ||
|
|
95b3bde822 | ||
|
|
f511453f79 | ||
|
|
8653216047 | ||
|
|
e62e0fc8bd | ||
|
|
2ff418f80f | ||
|
|
5d42e8843e | ||
|
|
3c183f73f8 | ||
|
|
3776f12f5c | ||
|
|
5ddec9710a | ||
|
|
f627559005 | ||
|
|
dca92d7f45 | ||
|
|
149dc8537f | ||
|
|
42f7b4fba1 | ||
|
|
17642699d4 | ||
|
|
724fd1e061 | ||
|
|
3eb2dfe0c9 | ||
|
|
73df006d39 | ||
|
|
175f3bb185 | ||
|
|
57061161b6 | ||
|
|
80f97a50e0 | ||
|
|
c265a20d83 | ||
|
|
4937618684 | ||
|
|
1a743b3889 | ||
|
|
425283b774 | ||
|
|
f582576b10 | ||
|
|
16b0f207ed | ||
|
|
fe2bcc7f2d | ||
|
|
a0628c7df5 | ||
|
|
cefe48fe51 | ||
|
|
e8e7fcbe7f | ||
|
|
8a28b4fc88 | ||
|
|
9a96c80af2 | ||
|
|
772e9dc526 | ||
|
|
025f72c876 | ||
|
|
52cf759bec | ||
|
|
cbbc6160f4 | ||
|
|
a8d3b7d39a | ||
|
|
a3d1a35e2f | ||
|
|
1d1e33f4d5 | ||
|
|
0998b7381f | ||
|
|
457f117216 | ||
|
|
dd52e8e85e | ||
|
|
ecf8c999b1 | ||
|
|
64a1d252cd | ||
|
|
d3e8698e40 | ||
|
|
7a7ffd3bf8 |
@@ -53,6 +53,7 @@ create_build_dir:
|
|||||||
# Keep machine.c in first position to fail immediately on invalid $MACHINE value
|
# Keep machine.c in first position to fail immediately on invalid $MACHINE value
|
||||||
SRCS = \
|
SRCS = \
|
||||||
machine.c \
|
machine.c \
|
||||||
|
machine_init.c \
|
||||||
cmd_editor.c \
|
cmd_editor.c \
|
||||||
cmd_parser.c \
|
cmd_parser.c \
|
||||||
dhcp.c \
|
dhcp.c \
|
||||||
@@ -138,10 +139,11 @@ $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.i
|
|||||||
machine_check:
|
machine_check:
|
||||||
@mkdir -p $(BUILDDIR)/tmp
|
@mkdir -p $(BUILDDIR)/tmp
|
||||||
@set -eo pipefail; \
|
@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 \
|
do \
|
||||||
echo "Checking $${MACHINE}"; \
|
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.c; \
|
||||||
|
$(CC) $(CC_FLAGS) -DMACHINE_$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine_init.c; \
|
||||||
done
|
done
|
||||||
@rm -rf $(BUILDDIR)/tmp
|
@rm -rf $(BUILDDIR)/tmp
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -193,7 +193,7 @@ void cmd_edit(void) __banked
|
|||||||
// Check whether return was pressed:
|
// Check whether return was pressed:
|
||||||
if (sbuf[l] == '\n' || sbuf[l] == '\r') {
|
if (sbuf[l] == '\n' || sbuf[l] == '\r') {
|
||||||
write_char('\n');
|
write_char('\n');
|
||||||
cmd_buffer[cmd_line_len] = '\0';
|
cmd_buffer[cmd_line_len] = NUL;
|
||||||
// write_char('>'); print_string_x(cmd_buffer); write_char('<');
|
// write_char('>'); print_string_x(cmd_buffer); write_char('<');
|
||||||
// If there is a command we print the prompt after execution
|
// If there is a command we print the prompt after execution
|
||||||
// otherwise immediately because there is nothing to execute
|
// otherwise immediately because there is nothing to execute
|
||||||
|
|||||||
+401
-291
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@ and sold by Mokerlink.
|
|||||||
The device is fully supported:
|
The device is fully supported:
|
||||||
- All 4 2.5GBASE-T RJ45 ports work at 10/100/1000/2500 Mbps
|
- All 4 2.5GBASE-T RJ45 ports work at 10/100/1000/2500 Mbps
|
||||||
- The SFP+ port supports 1G, 2.5G and 10G modules
|
- 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.
|
- untested due to missing Hardware: SFP+ ports equipped with 1G or 2.5G SFPs.
|
||||||
|
|
||||||
### Hardware overview
|
### Hardware overview
|
||||||
|
|||||||
@@ -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.
|
Using SPI clamp in-board is the only method for initial installation.
|
||||||
|
|
||||||
### Label specifications
|
### Label specifications
|
||||||
|
|
||||||
- **Name**: 4X 2.5G RJ45 Port + 2 X 10G SFP+ Port
|
- **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**:
|
- **Ports**:
|
||||||
- 4 × RJ45: 10/100/1000/2500 Mbps
|
- 4 × RJ45: 10/100/1000/2500 Mbps
|
||||||
- 2 × SFP+: 1000 / 2500 / 10000 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
|
### What works
|
||||||
|
|
||||||
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
- 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
|
- LEDs
|
||||||
- untested due to missing Hardware: SFP+ ports equipped with 1G or 2.5G SFPs.
|
- untested due to missing Hardware: SFP+ ports equipped with 1G or 2.5G SFPs.
|
||||||
|
|
||||||
### Hardware overview
|
### Hardware overview: 2M-PCB43-V2.1
|
||||||
|
|
||||||
Front side:
|
Front side:
|
||||||
|
|
||||||
@@ -44,6 +63,24 @@ Bottom
|
|||||||
|
|
||||||
<img src="photos/2M-PCB43-V2.1-unmanaged/2M-PCB43-V2.1-bottom.jpg" width="600" />
|
<img src="photos/2M-PCB43-V2.1-unmanaged/2M-PCB43-V2.1-bottom.jpg" width="600" />
|
||||||
|
|
||||||
|
### 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:
|
||||||
|
|
||||||
|
<img src="photos/KP-9000-6XHML-X2/label.jpg" width="600" />
|
||||||
|
|
||||||
|
Top side:
|
||||||
|
|
||||||
|
<img src="photos/KP-9000-6XHML-X2/pcb_top.jpg" width="600" />
|
||||||
|
|
||||||
|
Bottom:
|
||||||
|
|
||||||
|
<img src="photos/KP-9000-6XHML-X2/pcb_bottom.jpg" width="600" />
|
||||||
|
|
||||||
## Reset Button
|
## Reset Button
|
||||||
|
|
||||||
There's an unpopulated Reset button on the front left side of the PCB.
|
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
|
## Power supply
|
||||||
|
|
||||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
||||||
|
|
||||||
|
|||||||
@@ -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 | 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-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 |
|
| 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-V2.2](devices/2M-PCB23-V2_2.md) | 2M | 8 + 1 |
|
||||||
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V3.1](devices/2M-PCB23-V3_1.md) | 2M | 8 + 1 |
|
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V3.1](devices/2M-PCB23-V3_1.md) | 2M | 8 + 1 |
|
||||||
| LIANGUO | SWTG024AS | No | [SWTG024AS-v2.0-17452](devices/SWTG024AS.md) | 0.5M | 4 + 2 |
|
| LIANGUO | SWTG024AS | No | [SWTG024AS-v2.0-17452](devices/SWTG024AS.md) | 0.5M | 4 + 2 |
|
||||||
| Lianguo | ZX-SWTGW215AS | Yes | [PCB-SWTG115AS-V2.0](devices/SWTGW215AS.md) | 2M | 5 + 1 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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)
|
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
|
Many of the RTL8272/3 devices come in versions with PoE support. The RTLPlayground usually also
|
||||||
|
|||||||
+1
-1
@@ -180,7 +180,7 @@ function fillStats() {
|
|||||||
td = tr.insertCell(); td.appendChild(document.createTextNode(`${txB[i]}` + t('common_pkts')));
|
td = tr.insertCell(); td.appendChild(document.createTextNode(`${txB[i]}` + t('common_pkts')));
|
||||||
td = tr.insertCell(); td.appendChild(document.createTextNode(`${rxG[i]}` + t('common_pkts')));
|
td = tr.insertCell(); td.appendChild(document.createTextNode(`${rxG[i]}` + t('common_pkts')));
|
||||||
td = tr.insertCell(); td.appendChild(document.createTextNode(`${rxB[i]}` + t('common_pkts')));
|
td = tr.insertCell(); td.appendChild(document.createTextNode(`${rxB[i]}` + t('common_pkts')));
|
||||||
var button = '<button type="button" style="margin: 0 0 0 24px" onclick="getCounters(' + i + ');">' + t('stat_show') + '</button>';
|
var button = '<button type="button" style="margin: 0 0 0 24px" onclick="getCounters(' + (i + 1) + ');">' + t('stat_show') + '</button>';
|
||||||
td = tr.insertCell(); td.innerHTML = button;
|
td = tr.insertCell(); td.innerHTML = button;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+121
-32
@@ -41,8 +41,17 @@ __xdata uint32_t cont_addr;
|
|||||||
|
|
||||||
// HTTP header properties
|
// HTTP header properties
|
||||||
__xdata uint8_t boundary[72];
|
__xdata uint8_t boundary[72];
|
||||||
__xdata uint8_t *content_type = 0;
|
|
||||||
__xdata uint8_t *session = 0;
|
// a client may split the request anywhere, including inside a boundary or a
|
||||||
|
// part header, so a configuration upload is parsed only once it is complete;
|
||||||
|
// sized for a full config sector plus the multipart framing around it
|
||||||
|
#define CONFIG_UPLOAD_BUF (CONFIG_LEN + 384)
|
||||||
|
__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;
|
||||||
|
__xdata uint8_t cfg_bl;
|
||||||
|
__xdata uint8_t * __xdata content_type = 0;
|
||||||
|
__xdata uint8_t * __xdata session = 0;
|
||||||
|
|
||||||
// Global variables holding POST state
|
// Global variables holding POST state
|
||||||
__xdata uint16_t bindex; // Current index into the boundary
|
__xdata uint16_t bindex; // Current index into the boundary
|
||||||
@@ -54,7 +63,7 @@ __xdata char passwd[21];
|
|||||||
__xdata char session_id[SESSION_ID_LENGTH + 1];
|
__xdata char session_id[SESSION_ID_LENGTH + 1];
|
||||||
__xdata uint8_t authenticated;
|
__xdata uint8_t authenticated;
|
||||||
__xdata uint32_t now;
|
__xdata uint32_t now;
|
||||||
__xdata uint8_t *timeptr;
|
__xdata uint8_t * __xdata timeptr;
|
||||||
__xdata uint32_t last_session_use;
|
__xdata uint32_t last_session_use;
|
||||||
|
|
||||||
#define TSTATE_NONE 0
|
#define TSTATE_NONE 0
|
||||||
@@ -77,6 +86,7 @@ inline uint8_t is_separator(uint8_t c)
|
|||||||
|
|
||||||
void httpd_init(void) __banked
|
void httpd_init(void) __banked
|
||||||
{
|
{
|
||||||
|
config_upload = 0; // xdata is not zeroed by the startup code
|
||||||
__xdata struct httpd_state * __xdata s = &(uip_conn->appstate);
|
__xdata struct httpd_state * __xdata s = &(uip_conn->appstate);
|
||||||
// Start listening to port 80
|
// Start listening to port 80
|
||||||
uip_listen(HTONS(80));
|
uip_listen(HTONS(80));
|
||||||
@@ -109,8 +119,8 @@ bool is_word(__xdata uint8_t *xdata_str_p, __code uint8_t * __xdata code_str_p)
|
|||||||
u = *xdata_str_p++;
|
u = *xdata_str_p++;
|
||||||
c = *code_str_p++;
|
c = *code_str_p++;
|
||||||
|
|
||||||
if (c == '\0') {
|
if (c == NUL) {
|
||||||
if (u != '\0' && u != ' ' && u != '\t' && u != ':' && u != '?' && u != '=' && u != '\n' && u != '\r')
|
if (u != NUL && u != ' ' && u != '\t' && u != ':' && u != '?' && u != '=' && u != '\n' && u != '\r')
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -130,8 +140,8 @@ bool is_url_word_x(__xdata uint8_t *uri_str_p, __xdata uint8_t *src_str_p)
|
|||||||
u = *uri_str_p++;
|
u = *uri_str_p++;
|
||||||
s = *src_str_p++;
|
s = *src_str_p++;
|
||||||
|
|
||||||
if (s == '\0') {
|
if (s == NUL) {
|
||||||
if (u != '\0' && u != ' ' && u != '\t' && u != ':' && u != '?' && u != '=' && u != '\n' && u != '\r')
|
if (u != NUL && u != ' ' && u != '\t' && u != ':' && u != '?' && u != '=' && u != '\n' && u != '\r')
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -173,9 +183,9 @@ bool is_word_x(__xdata uint8_t *lhs_str_p, __xdata uint8_t *rhs_str_p)
|
|||||||
u = *lhs_str_p++;
|
u = *lhs_str_p++;
|
||||||
c = *rhs_str_p++;
|
c = *rhs_str_p++;
|
||||||
|
|
||||||
if (c == '\0') {
|
if (c == NUL) {
|
||||||
/* ';' separates cookies in a Cookie header, so it ends a value too. */
|
/* ';' separates cookies in a Cookie header, so it ends a value too. */
|
||||||
if (u != '\0' && u != ' ' && u != '\t' && u != ':' && u != '?' && u != '=' && u != '\n' && u != '\r' && u != ';')
|
if (u != NUL && u != ' ' && u != '\t' && u != ':' && u != '?' && u != '=' && u != '\n' && u != '\r' && u != ';')
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -241,7 +251,7 @@ __xdata uint8_t *skip_boundary(__xdata uint8_t *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
__xdata uint8_t *scan_header(__xdata uint8_t *p)
|
__xdata uint8_t *scan_header(__xdata uint8_t * __xdata p)
|
||||||
{
|
{
|
||||||
content_type = 0;
|
content_type = 0;
|
||||||
session = 0;
|
session = 0;
|
||||||
@@ -300,10 +310,12 @@ __xdata uint8_t *scan_header(__xdata uint8_t *p)
|
|||||||
return 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) {
|
while (bytes) {
|
||||||
if (!i)
|
if (!i)
|
||||||
get_random_32();
|
get_random_32();
|
||||||
@@ -315,6 +327,65 @@ void gen_random_bytes(__xdata uint8_t *b, uint8_t bytes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 0: body incomplete, 1: configuration stored, 2: malformed */
|
||||||
|
static uint8_t config_take(void)
|
||||||
|
{
|
||||||
|
cfg_bl = strlen_x(boundary);
|
||||||
|
|
||||||
|
// the body is complete once the closing boundary has arrived
|
||||||
|
cfg_last = 0;
|
||||||
|
while (1) {
|
||||||
|
if (cfg_last + cfg_bl + 1 >= write_len)
|
||||||
|
return 0;
|
||||||
|
if (strstart_x(&config_buf[cfg_last], boundary)
|
||||||
|
&& strstart(&config_buf[cfg_last + cfg_bl], "--"))
|
||||||
|
break;
|
||||||
|
cfg_last++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// every part lies ahead of the closing boundary, so it bounds the walk
|
||||||
|
cfg_pos = 0;
|
||||||
|
while (cfg_pos < cfg_last) {
|
||||||
|
if (!strstart_x(&config_buf[cfg_pos], boundary)) {
|
||||||
|
cfg_pos++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cfg_hdr = cfg_pos + cfg_bl;
|
||||||
|
cfg_body = cfg_hdr;
|
||||||
|
while (1) {
|
||||||
|
if (cfg_body + 3 >= cfg_last)
|
||||||
|
return 2;
|
||||||
|
if (strstart(&config_buf[cfg_body], "\r\n\r\n"))
|
||||||
|
break;
|
||||||
|
cfg_body++;
|
||||||
|
}
|
||||||
|
cfg_end = cfg_body;
|
||||||
|
cfg_body += 4;
|
||||||
|
// reaching cfg_last is a match: the last part ends at the closing boundary
|
||||||
|
while (cfg_end < cfg_last && !strstart_x(&config_buf[cfg_end], boundary))
|
||||||
|
cfg_end++;
|
||||||
|
while (cfg_hdr + 8 < cfg_body) {
|
||||||
|
// the part carrying a filename holds the configuration
|
||||||
|
if (strstart(&config_buf[cfg_hdr], "filename")) {
|
||||||
|
// the payload plus its terminator must fit the sector
|
||||||
|
if (cfg_end - cfg_body + 1 > CONFIG_LEN)
|
||||||
|
return 2;
|
||||||
|
config_buf[cfg_end] = 0;
|
||||||
|
flash_region.addr = CONFIG_START;
|
||||||
|
flash_sector_erase();
|
||||||
|
flash_region.addr = CONFIG_START;
|
||||||
|
flash_region.len = cfg_end - cfg_body + 1;
|
||||||
|
flash_write_bytes(config_buf + cfg_body);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cfg_hdr++;
|
||||||
|
}
|
||||||
|
cfg_pos = cfg_end;
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reads post data from the http stream and writes it into flash memory
|
* Reads post data from the http stream and writes it into flash memory
|
||||||
* Input: the current position in the TCP buffer (uip_appdata)
|
* Input: the current position in the TCP buffer (uip_appdata)
|
||||||
@@ -418,10 +489,10 @@ void handle_post(void)
|
|||||||
// Find end of request path
|
// Find end of request path
|
||||||
while (*p && !is_separator(*p))
|
while (*p && !is_separator(*p))
|
||||||
p++;
|
p++;
|
||||||
*p++ = '\0';
|
*p++ = NUL;
|
||||||
|
|
||||||
// Find end of request header
|
// Find end of request header
|
||||||
boundary[0] ='\0';
|
boundary[0] =NUL;
|
||||||
p = scan_header(p);
|
p = scan_header(p);
|
||||||
dbg_string("Boundary: >"); dbg_string_x(boundary); dbg_string("<\n");
|
dbg_string("Boundary: >"); dbg_string_x(boundary); dbg_string("<\n");
|
||||||
if (!*p || !content_type) {
|
if (!*p || !content_type) {
|
||||||
@@ -437,6 +508,7 @@ void handle_post(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
print_string("Firmware upload started.");
|
print_string("Firmware upload started.");
|
||||||
|
config_upload = 0;
|
||||||
uptr = FIRMWARE_UPLOAD_START;
|
uptr = FIRMWARE_UPLOAD_START;
|
||||||
verify_crc = 1;
|
verify_crc = 1;
|
||||||
max_upload = 1024576;
|
max_upload = 1024576;
|
||||||
@@ -445,12 +517,10 @@ void handle_post(void)
|
|||||||
send_unauthorized();
|
send_unauthorized();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dbg_string("Configuration upload, erasing config mem!\n");
|
dbg_string("Configuration upload\n");
|
||||||
uptr = CONFIG_START;
|
|
||||||
verify_crc = 0;
|
verify_crc = 0;
|
||||||
max_upload = 2048;
|
config_upload = 1;
|
||||||
flash_region.addr = CONFIG_START;
|
write_len = 0;
|
||||||
flash_sector_erase();
|
|
||||||
}
|
}
|
||||||
// Check for other POST requests, which are not multipart, below
|
// Check for other POST requests, which are not multipart, below
|
||||||
} else {
|
} else {
|
||||||
@@ -481,11 +551,11 @@ void handle_post(void)
|
|||||||
if (is_url_word_x(p, passwd)) {
|
if (is_url_word_x(p, passwd)) {
|
||||||
dbg_string("Password accepted!\n");
|
dbg_string("Password accepted!\n");
|
||||||
read_reg_timer(&last_session_use);
|
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] = '\0';
|
session_id[SESSION_ID_LENGTH] = NUL;
|
||||||
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\nConnection: close\r\nLocation: index.html\r\n" \
|
slen = strtox(outbuf, "HTTP/1.1 302 Found\r\nConnection: close\r\nLocation: index.html\r\n" \
|
||||||
"Set-Cookie: session=");
|
"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];
|
outbuf[slen++] = session_id[i];
|
||||||
slen += strtox(outbuf + slen, "; SameSite=Strict\r\n\r\n");
|
slen += strtox(outbuf + slen, "; SameSite=Strict\r\n\r\n");
|
||||||
} else {
|
} else {
|
||||||
@@ -504,6 +574,32 @@ void handle_post(void)
|
|||||||
send_bad_request();
|
send_bad_request();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (config_upload) {
|
||||||
|
cfg_pos = uip_len - (p - uip_appdata);
|
||||||
|
if (write_len + cfg_pos >= CONFIG_UPLOAD_BUF) {
|
||||||
|
print_string("Configuration too large, aborting.\n");
|
||||||
|
config_upload = 0;
|
||||||
|
s->tstate = TSTATE_NONE;
|
||||||
|
send_bad_request();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(config_buf + write_len, p, cfg_pos);
|
||||||
|
write_len += cfg_pos;
|
||||||
|
uint8_t taken = config_take();
|
||||||
|
|
||||||
|
if (!taken) {
|
||||||
|
s->tstate = TSTATE_MULTIPART;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
config_upload = 0;
|
||||||
|
s->tstate = TSTATE_NONE;
|
||||||
|
if (taken == 2) {
|
||||||
|
send_bad_request();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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
|
// We skip the intial parts as part of the header
|
||||||
do {
|
do {
|
||||||
p = skip_boundary(p);
|
p = skip_boundary(p);
|
||||||
@@ -642,7 +738,7 @@ void httpd_appcall(void)
|
|||||||
__xdata uint8_t *q = p;
|
__xdata uint8_t *q = p;
|
||||||
while (*p && !is_separator(*p))
|
while (*p && !is_separator(*p))
|
||||||
p++;
|
p++;
|
||||||
*p = '\0';
|
*p = NUL;
|
||||||
dbg_string_x(q);
|
dbg_string_x(q);
|
||||||
dbg_char('\n');
|
dbg_char('\n');
|
||||||
|
|
||||||
@@ -664,16 +760,9 @@ void httpd_appcall(void)
|
|||||||
parse_short(q + 15);
|
parse_short(q + 15);
|
||||||
send_vlan(short_parsed);
|
send_vlan(short_parsed);
|
||||||
} else if (is_word(q, "/counters.json")) {
|
} else if (is_word(q, "/counters.json")) {
|
||||||
/* The port is one raw character of the request line and
|
|
||||||
* indexes a nine entry table, so bound it here instead
|
|
||||||
* of trusting the client to have sent a digit. Anything
|
|
||||||
* below '0' wraps well past eight, so the one test
|
|
||||||
* covers both ends. */
|
|
||||||
uint8_t cport = q[20] - '0';
|
uint8_t cport = q[20] - '0';
|
||||||
if (cport > 8)
|
if (send_counters(cport))
|
||||||
send_bad_request();
|
send_bad_request();
|
||||||
else
|
|
||||||
send_counters(cport);
|
|
||||||
} else if (is_word(q, "/eee.json")) {
|
} else if (is_word(q, "/eee.json")) {
|
||||||
send_eee();
|
send_eee();
|
||||||
} else if (is_word(q, "/bandwidth.json")) {
|
} else if (is_word(q, "/bandwidth.json")) {
|
||||||
|
|||||||
+38
-43
@@ -157,14 +157,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);
|
reg_read_m(reg);
|
||||||
sfr_data_to_html();
|
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);
|
reg_read_m(reg);
|
||||||
byte_to_html(sfr_data[0]);
|
byte_to_html(sfr_data[0]);
|
||||||
@@ -177,10 +177,12 @@ void reg_to_html_long(register uint16_t reg)
|
|||||||
void send_sfp_info(uint8_t sfp)
|
void send_sfp_info(uint8_t sfp)
|
||||||
{
|
{
|
||||||
// This loops over the Vendor-name, Vendor OUI, Vendor PN and Vendor rev ASCII fields
|
// This loops over the Vendor-name, Vendor OUI, Vendor PN and Vendor rev ASCII fields
|
||||||
for (uint8_t i = 20; i < 60; i++) {
|
for (uint8_t i = 16; i < 64; i++) {
|
||||||
if (i >= 36 && i < 40) // Skip Non-ASCII codes
|
if (!(i & 0xf))
|
||||||
|
sfp_read_block(sfp, i, 16);
|
||||||
|
if (i < 20 || i >= 60 || (i >= 36 && i < 40)) // Skip Non-ASCII codes
|
||||||
continue;
|
continue;
|
||||||
uint8_t c = sfp_read_reg(sfp, i);
|
uint8_t c = sfp_buf[i & 0xf];
|
||||||
if (c && c != 0xa0) // a0 is the byte read from a non-existant I2C EEPROM
|
if (c && c != 0xa0) // a0 is the byte read from a non-existant I2C EEPROM
|
||||||
char_to_html(c);
|
char_to_html(c);
|
||||||
}
|
}
|
||||||
@@ -193,32 +195,10 @@ void sfp_send_data(uint8_t slot, uint8_t reg, uint8_t len)
|
|||||||
if (len > 16)
|
if (len > 16)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (reg & 0x80) { // Configure SFP readings address (0x51) as I2C device address
|
sfp_read_block(slot, reg, len);
|
||||||
reg &= 0x7f;
|
|
||||||
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | (len - 1) & 0xf, 0x51 >> 5, (0x51 << 3) & 0xff);
|
|
||||||
} else {
|
|
||||||
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | (len - 1) & 0xf, 0x50 >> 5, (0x50 << 3) & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
reg_read_m(RTL837X_REG_I2C_CTRL);
|
for (uint8_t i = 0; i < len; i++)
|
||||||
sfr_mask_data(1, 0xfc, i2c_bus_from_scl_pin(machine.sfp_port[slot].i2c.scl) << 5 | i2c_bus_from_sda_pin(machine.sfp_port[slot].i2c.sda) << 2);
|
byte_to_html(sfp_buf[i]);
|
||||||
reg_write_m(RTL837X_REG_I2C_CTRL);
|
|
||||||
|
|
||||||
REG_WRITE(RTL837X_REG_I2C_IN, 0, 0, 0, reg);
|
|
||||||
|
|
||||||
// Execute I2C Read
|
|
||||||
reg_bit_set(RTL837X_REG_I2C_CTRL, 0);
|
|
||||||
|
|
||||||
// Wait for execution to finish
|
|
||||||
do {
|
|
||||||
reg_read_m(RTL837X_REG_I2C_CTRL);
|
|
||||||
} while (sfr_data[3] & 0x1);
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
|
||||||
if (!(i & 0x3))
|
|
||||||
reg_read_m(RTL837X_REG_I2C_OUT + i);
|
|
||||||
byte_to_html(sfr_data[3 - (i & 0x3)]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -309,17 +289,26 @@ void send_vlan(uint16_t vlan)
|
|||||||
slen += strtox(outbuf + slen, "\"}");
|
slen += strtox(outbuf + slen, "\"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Send counters
|
||||||
void send_counters(char port)
|
* Only accepts physical port 1..9.
|
||||||
|
* Returns an error if the port physical don't exists.
|
||||||
|
*/
|
||||||
|
bool send_counters(uint8_t phys_port)
|
||||||
{
|
{
|
||||||
dbg_string("send_counters called: "); dbg_byte(port); dbg_char('\n');
|
uint8_t phys_port_idx = phys_port - 1;
|
||||||
|
if (phys_port_idx > 8)
|
||||||
|
goto err;
|
||||||
|
uint8_t log_port = machine.phys_to_log_port[phys_port_idx];
|
||||||
|
if (log_port == 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
dbg_string("send_counters called: "); dbg_byte(phys_port_idx); dbg_char('\n');
|
||||||
slen = strtox(outbuf, HTTP_RESPONCE_JSON);
|
slen = strtox(outbuf, HTTP_RESPONCE_JSON);
|
||||||
dbg_string("sending counters\n");
|
dbg_string("sending counters\n"); dbg_byte(phys_port_idx);
|
||||||
dbg_byte(port);
|
|
||||||
uint8_t i = machine.phys_to_log_port[port];
|
char_to_html('[');
|
||||||
slen += strtox(outbuf + slen, "[");
|
|
||||||
for (uint8_t counter = 0; counter < 0x37; counter++) {
|
for (uint8_t counter = 0; counter < 0x37; counter++) {
|
||||||
STAT_GET(counter, i);
|
STAT_GET(counter, log_port);
|
||||||
slen += strtox(outbuf + slen, "\"0x");
|
slen += strtox(outbuf + slen, "\"0x");
|
||||||
reg_to_html(RTL837X_STAT_V_HIGH);
|
reg_to_html(RTL837X_STAT_V_HIGH);
|
||||||
reg_to_html_long(RTL837X_STAT_V_LOW);
|
reg_to_html_long(RTL837X_STAT_V_LOW);
|
||||||
@@ -328,6 +317,12 @@ void send_counters(char port)
|
|||||||
char_to_html(',');
|
char_to_html(',');
|
||||||
}
|
}
|
||||||
char_to_html(']');
|
char_to_html(']');
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
err:
|
||||||
|
dbg_string("Error: counters: phy_port_idx don't exists\n");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -397,7 +392,7 @@ void send_l2(uint16_t idx)
|
|||||||
|
|
||||||
// type
|
// type
|
||||||
reg_read_m(RTL837x_L2_DATA_OUT_C);
|
reg_read_m(RTL837x_L2_DATA_OUT_C);
|
||||||
if (sfr_data[2] & 0x1)
|
if (sfr_data[1] & 0x1)
|
||||||
slen += strtox(outbuf + slen, "\",\"type\":\"s\",\"port\":");
|
slen += strtox(outbuf + slen, "\",\"type\":\"s\",\"port\":");
|
||||||
else
|
else
|
||||||
slen += strtox(outbuf + slen, "\",\"type\":\"l\",\"port\":");
|
slen += strtox(outbuf + slen, "\",\"type\":\"l\",\"port\":");
|
||||||
@@ -702,13 +697,13 @@ void send_status(void)
|
|||||||
sfp_send_data(sfp, 238, 1);
|
sfp_send_data(sfp, 238, 1);
|
||||||
}
|
}
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_vendor\":\"");
|
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];
|
outbuf[slen++] = sfp_module_vendor[sfp][s];
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_model\":\"");
|
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];
|
outbuf[slen++] = sfp_module_model[sfp][s];
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_serial\":\"");
|
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];
|
outbuf[slen++] = sfp_module_serial[sfp][s];
|
||||||
slen += strtox(outbuf + slen,"\",\"sfp_los\":");
|
slen += strtox(outbuf + slen,"\",\"sfp_los\":");
|
||||||
if (machine.sfp_port[sfp].pin_los == GPIO_NA) {
|
if (machine.sfp_port[sfp].pin_los == GPIO_NA) {
|
||||||
@@ -822,7 +817,7 @@ found_end:
|
|||||||
if (valid_len > (TCP_OUTBUF_SIZE - slen)) {
|
if (valid_len > (TCP_OUTBUF_SIZE - slen)) {
|
||||||
cont_len = valid_len - (TCP_OUTBUF_SIZE - slen);
|
cont_len = valid_len - (TCP_OUTBUF_SIZE - slen);
|
||||||
valid_len = TCP_OUTBUF_SIZE - slen;
|
valid_len = TCP_OUTBUF_SIZE - slen;
|
||||||
cont_addr = valid_len;
|
cont_addr = CONFIG_START + valid_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
flash_region.addr = CONFIG_START;
|
flash_region.addr = CONFIG_START;
|
||||||
|
|||||||
+3
-1
@@ -1,7 +1,9 @@
|
|||||||
#ifndef __PAGE_IMPL_H__
|
#ifndef __PAGE_IMPL_H__
|
||||||
#define __PAGE_IMPL_H__
|
#define __PAGE_IMPL_H__
|
||||||
|
|
||||||
void send_counters(char port);
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
bool send_counters(uint8_t phys_port);
|
||||||
void send_status(void);
|
void send_status(void);
|
||||||
void send_vlan(uint16_t vlan);
|
void send_vlan(uint16_t vlan);
|
||||||
void send_basic_info(void);
|
void send_basic_info(void);
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ uint8_t flash_read_status(void)
|
|||||||
* Reads bulk data of length len from the flash memory starging at address src
|
* Reads bulk data of length len from the flash memory starging at address src
|
||||||
* and writes the data into a buffer pointed to by dst in XMEM
|
* and writes the data into a buffer pointed to by dst in XMEM
|
||||||
*/
|
*/
|
||||||
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;
|
short status;
|
||||||
do {
|
do {
|
||||||
|
|||||||
@@ -5,9 +5,23 @@
|
|||||||
#include "rtl837x_regs.h"
|
#include "rtl837x_regs.h"
|
||||||
#include "rtl837x_common.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 = {
|
__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",
|
.machine_name = "keepLink KP-9000-6XHML-X2",
|
||||||
|
#endif
|
||||||
.isRTL8373 = 0,
|
.isRTL8373 = 0,
|
||||||
.min_port = 3,
|
.min_port = 3,
|
||||||
.max_port = 8,
|
.max_port = 8,
|
||||||
@@ -42,8 +56,6 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_KP_9000_6XH_X
|
#elif defined MACHINE_KP_9000_6XH_X
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "keepLink KP-9000-6XH-X",
|
.machine_name = "keepLink KP-9000-6XH-X",
|
||||||
@@ -72,11 +84,15 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
#elif defined(MACHINE_KP_9000_6XH_X2) || defined(MACHINE_KP_9000_6XH_X2_V2_1) || defined(MACHINE_KP_9000_6XHML_X2_V2_1)
|
||||||
|
|
||||||
#elif defined MACHINE_KP_9000_6XH_X2
|
|
||||||
__code const struct machine machine = {
|
__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",
|
.machine_name = "keepLink KP-9000-6XH-X2",
|
||||||
|
#endif
|
||||||
.isRTL8373 = 0,
|
.isRTL8373 = 0,
|
||||||
.min_port = 3,
|
.min_port = 3,
|
||||||
.max_port = 8,
|
.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
|
#elif defined MACHINE_KP_9000_9XH_X_EU
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "keepLink KP-9000-9XH-X-EU",
|
.machine_name = "keepLink KP-9000-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
|
#elif defined MACHINE_KP_9000_9XHML_X_V2_2
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "keepLink KP-9000-9XHML-X V2.2",
|
.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
|
#elif defined MACHINE_KP_9000_9XHML_X_V3_1
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "keepLink KP-9000-9XHML-X V3.1",
|
.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},
|
0x1a, 0x19, 0x1d, 0x1e, 0x1c, 0x1d, 0x20, 0x21},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_SWGT024_V2_0_MANAGED
|
#elif defined MACHINE_SWGT024_V2_0_MANAGED
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "SWGT024 V2.0 Managed",
|
.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
|
#elif defined MACHINE_SWGT024_V2_0_UNMANAGED
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "SWGT024 V2.0 Unmanaged",
|
.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
|
#elif defined MACHINE_SWTG018AS_A_V_2_0
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "SWTG018AS-A V2.0",
|
.machine_name = "SWTG018AS-A V2.0",
|
||||||
@@ -368,8 +370,6 @@ __code const struct machine machine = {
|
|||||||
0x1d, 0x20, 0x21 },
|
0x1d, 0x20, 0x21 },
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_HG0402XG_V1_1
|
#elif defined MACHINE_HG0402XG_V1_1
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "HG0402XG V1.1",
|
.machine_name = "HG0402XG V1.1",
|
||||||
@@ -408,8 +408,6 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_SWTGW218AS
|
#elif defined MACHINE_SWTGW218AS
|
||||||
|
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
@@ -443,7 +441,48 @@ __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 = {
|
||||||
|
.machine_name = "SWTGW218AS (SWTG018AS-V2.1.0)",
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.mac_flash_offset = 0x1FC000,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = GPIO38, // pulled low on module insert
|
||||||
|
.sfp_port[0].pin_los = GPIO_NA, // no LOS pin wired
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||||
|
.reset_pin = GPIO54_ACL_BIT2_EN,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
// LED wiring matches the SWTG018AS-A V2.0 (same PCB family)
|
||||||
|
.led_sets = {
|
||||||
|
{ /* RJ45: First LED, yellow, second LED: green */
|
||||||
|
LEDS_2G5 | LEDS_LINK,
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
}, { /* SFP set (superseded by the raw register override in machine_custom_init) */
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
}},
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = { 0x00, 0x01, 0x04, 0x05, 0x08, // 65e0
|
||||||
|
0x09, 0x0c, 0x09, 0x0d, 0x10, // 65e4
|
||||||
|
0x11, 0x0e, 0x14, 0x11, 0x12, // 65e8
|
||||||
|
0x15, 0x15, 0x16, 0x18, 0x19, // 65ec
|
||||||
|
0x1a, 0x19, 0x1d, 0x1e, 0x1c, // 65f0
|
||||||
|
0x1d, 0x20, 0x21 },
|
||||||
|
};
|
||||||
|
|
||||||
#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
|
#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 = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "Lianguo ZX-SWTGW215AS",
|
.machine_name = "Lianguo ZX-SWTGW215AS",
|
||||||
@@ -476,8 +515,6 @@ __code const struct machine machine = {
|
|||||||
.led_mux_custom = 0,
|
.led_mux_custom = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_DEFAULT_8C_1SFP
|
#elif defined MACHINE_DEFAULT_8C_1SFP
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "8+1 SFP Port Switch",
|
.machine_name = "8+1 SFP Port Switch",
|
||||||
@@ -503,8 +540,6 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_TRENDNET_TEG_S562
|
#elif defined MACHINE_TRENDNET_TEG_S562
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "Trendnet TEG-S562",
|
.machine_name = "Trendnet TEG-S562",
|
||||||
@@ -544,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/
|
#elif defined(MACHINE_PCB_K0402WS_V3) || defined(MACHINE_HI_K0402WS) // Sold as a variety of devices, see doc/
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "PCB-K0402WS-V3.0",
|
.machine_name = "PCB-K0402WS-V3.0",
|
||||||
@@ -592,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
|
#elif defined MACHINE_K0501W_V2_0
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "K0501W V2.0",
|
.machine_name = "K0501W V2.0",
|
||||||
@@ -630,8 +659,6 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_ZX310S_4T2XH
|
#elif defined MACHINE_ZX310S_4T2XH
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "ZX310S-4T2XH",
|
.machine_name = "ZX310S-4T2XH",
|
||||||
@@ -675,8 +702,6 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_STEAMEMO_IG204_V1
|
#elif defined MACHINE_STEAMEMO_IG204_V1
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "Steamemo IG204 V1",
|
.machine_name = "Steamemo IG204 V1",
|
||||||
@@ -727,8 +752,6 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_HI_K0801WS
|
#elif defined MACHINE_HI_K0801WS
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "Hi-Source HI-k0801WS",
|
.machine_name = "Hi-Source HI-k0801WS",
|
||||||
@@ -778,8 +801,6 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) { }
|
|
||||||
|
|
||||||
#elif defined MACHINE_FNS1200P
|
#elif defined MACHINE_FNS1200P
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "FNS-1200P",
|
.machine_name = "FNS-1200P",
|
||||||
@@ -835,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
|
#elif defined MACHINE_PCB_SWTG024AS_A_2_0_1
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
@@ -889,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
|
#elif defined MACHINE_SWTG024AS_A_2_0_1_5C_1SFP
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "SWTG024AS-A-V2.0.1-5C-1SFP",
|
.machine_name = "SWTG024AS-A-V2.0.1-5C-1SFP",
|
||||||
@@ -940,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
|
#elif defined MACHINE_SWTG024AS_V2_0
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "SWTG024AS-V2.0",
|
.machine_name = "SWTG024AS-V2.0",
|
||||||
@@ -1002,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
|
#elif defined MACHINE_ZX310S_4T2XT
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "ZX310S_4T2XT",
|
.machine_name = "ZX310S_4T2XT",
|
||||||
@@ -1058,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
|
#elif defined MACHINE_FG_4GT_2SX_V2_0
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "FG-4GT-2SX_V2.0",
|
.machine_name = "FG-4GT-2SX_V2.0",
|
||||||
@@ -1130,10 +1094,6 @@ __code const struct machine machine = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void) {
|
|
||||||
REG_SET(RTL837X_REG_LED_GLB_IO_EN, 0x7624155b);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "Please select a machine type in machine.h"
|
#error "Please select a machine type in machine.h"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,9 +6,19 @@
|
|||||||
/*
|
/*
|
||||||
* Select your machine type below
|
* 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_6XHML_X2
|
||||||
// #define MACHINE_KP_9000_6XH_X
|
|
||||||
// #define MACHINE_KP_9000_6XH_X2
|
// #define MACHINE_KP_9000_6XH_X2
|
||||||
|
|
||||||
|
// KP-9000 4+2 targets by PCB silkscreen revision.
|
||||||
|
// #define MACHINE_KP_9000_6XH_X2_V1_1
|
||||||
|
// #define MACHINE_KP_9000_6XHML_X2_V1_1
|
||||||
|
// #define MACHINE_KP_9000_6XH_X2_V1_2
|
||||||
|
// #define MACHINE_KP_9000_6XHML_X2_V1_2
|
||||||
|
// #define MACHINE_KP_9000_6XH_X2_V2_1
|
||||||
|
// #define MACHINE_KP_9000_6XHML_X2_V2_1
|
||||||
|
|
||||||
|
// #define MACHINE_KP_9000_6XH_X
|
||||||
// #define MACHINE_KP_9000_9XH_X_EU
|
// #define MACHINE_KP_9000_9XH_X_EU
|
||||||
// #define MACHINE_KP_9000_9XHML_X_V2_2
|
// #define MACHINE_KP_9000_9XHML_X_V2_2
|
||||||
// #define MACHINE_KP_9000_9XHML_X_V3_1
|
// #define MACHINE_KP_9000_9XHML_X_V3_1
|
||||||
@@ -18,6 +28,7 @@
|
|||||||
// #define MACHINE_HG0402XG_V1_1
|
// #define MACHINE_HG0402XG_V1_1
|
||||||
// #define MACHINE_SWTG018AS_A_V_2_0
|
// #define MACHINE_SWTG018AS_A_V_2_0
|
||||||
// #define MACHINE_SWTGW218AS
|
// #define MACHINE_SWTGW218AS
|
||||||
|
// #define MACHINE_PCB_SWTG018AS_V2_1_0
|
||||||
// #define MACHINE_PCB_K0402WS_V3
|
// #define MACHINE_PCB_K0402WS_V3
|
||||||
// #define MACHINE_K0501W_V2_0
|
// #define MACHINE_K0501W_V2_0
|
||||||
// #define MACHINE_LIANGUO_ZX_SWTGW215AS
|
// #define MACHINE_LIANGUO_ZX_SWTGW215AS
|
||||||
@@ -94,6 +105,6 @@ typedef struct machine_runtime
|
|||||||
uint8_t isN : 1;
|
uint8_t isN : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
void machine_custom_init(void);
|
void machine_custom_init(void) __banked;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+122
@@ -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 <stdint.h>
|
||||||
|
#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
|
||||||
+15
-9
@@ -8,6 +8,7 @@
|
|||||||
#define SYS_TICK_HZ 200
|
#define SYS_TICK_HZ 200
|
||||||
|
|
||||||
#define CPU_PORT 9
|
#define CPU_PORT 9
|
||||||
|
#define NUL '\0'
|
||||||
|
|
||||||
// Define Port-masks for 9-port devices and 6-port devices
|
// Define Port-masks for 9-port devices and 6-port devices
|
||||||
#define PMASK_9 0x1ff
|
#define PMASK_9 0x1ff
|
||||||
@@ -125,6 +126,7 @@ extern __xdata struct uip_eth_addr uip_ethaddr;
|
|||||||
|
|
||||||
// Headers for calls in the common code area (HOME/BANK0)
|
// Headers for calls in the common code area (HOME/BANK0)
|
||||||
void print_string_no_syslog(__code char *p);
|
void print_string_no_syslog(__code char *p);
|
||||||
|
void print_string_newline_no_syslog(__code char *p);
|
||||||
void print_string(__code char *p);
|
void print_string(__code char *p);
|
||||||
void print_string_x(__xdata char *p);
|
void print_string_x(__xdata char *p);
|
||||||
void print_long(uint32_t a);
|
void print_long(uint32_t a);
|
||||||
@@ -134,6 +136,7 @@ void itoa(uint8_t v);
|
|||||||
void print_sfr_data(void);
|
void print_sfr_data(void);
|
||||||
void print_phy_data(void);
|
void print_phy_data(void);
|
||||||
void print_cmd_prompt(void);
|
void print_cmd_prompt(void);
|
||||||
|
void print_phys_port(uint8_t port);
|
||||||
void phy_write_mask(uint16_t phy_mask, uint8_t dev_id, uint16_t reg, uint16_t v);
|
void phy_write_mask(uint16_t phy_mask, uint8_t dev_id, uint16_t reg, uint16_t v);
|
||||||
void phy_write(uint8_t phy_id, uint8_t dev_id, uint16_t reg, uint16_t v);
|
void phy_write(uint8_t phy_id, uint8_t dev_id, uint16_t reg, uint16_t v);
|
||||||
void phy_read(uint8_t phy_id, uint8_t dev_id, uint16_t reg);
|
void phy_read(uint8_t phy_id, uint8_t dev_id, uint16_t reg);
|
||||||
@@ -149,7 +152,8 @@ void sleep(uint16_t t);
|
|||||||
void write_char_no_syslog(char c);
|
void write_char_no_syslog(char c);
|
||||||
void write_char(char c);
|
void write_char(char c);
|
||||||
void print_reg(uint16_t reg);
|
void print_reg(uint16_t reg);
|
||||||
uint8_t sfp_read_reg(uint8_t slot, uint8_t reg);
|
bool sfp_read_block(uint8_t slot, uint8_t reg, uint8_t len) __banked __reentrant;
|
||||||
|
extern __xdata uint8_t sfp_buf[16];
|
||||||
void reg_bit_set(uint16_t reg_addr, char bit);
|
void reg_bit_set(uint16_t reg_addr, char bit);
|
||||||
void reg_bit_clear(uint16_t reg_addr, char bit);
|
void reg_bit_clear(uint16_t reg_addr, char bit);
|
||||||
uint8_t reg_bit_test(uint16_t reg_addr, char bit);
|
uint8_t reg_bit_test(uint16_t reg_addr, char bit);
|
||||||
@@ -157,18 +161,20 @@ void sfr_mask_data(uint8_t n, uint8_t mask, uint8_t set);
|
|||||||
void sfr_set_zero(void);
|
void sfr_set_zero(void);
|
||||||
void reset_chip(void);
|
void reset_chip(void);
|
||||||
void memcpy(__xdata void * __xdata dst, __xdata const void * __xdata src, uint16_t len);
|
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 memcpyc(__xdata uint8_t *dst, __code uint8_t *src, uint16_t len);
|
||||||
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);
|
||||||
uint16_t strlen(register __code const char *s);
|
uint16_t strlen(__code const char *s);
|
||||||
uint16_t strlen_x(register __xdata const char *s);
|
uint16_t strlen_x(__xdata const char *s);
|
||||||
uint16_t strtox(register __xdata uint8_t *dst, register __code const char *s);
|
uint16_t strtox(__xdata uint8_t *dst, __code const char *s);
|
||||||
uint16_t strcpy(register __xdata uint8_t *dst, register const char *s);
|
uint16_t strcpy(__xdata uint8_t *dst, 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);
|
||||||
|
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);
|
void tcpip_output(void);
|
||||||
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
|
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
|
||||||
void get_random_32(void);
|
void get_random_32(void);
|
||||||
void read_reg_timer(__xdata uint32_t * tmr);
|
void read_reg_timer(__xdata uint32_t * tmr);
|
||||||
void sfp_print_info(uint8_t sfp);
|
bool sfp_print_info(uint8_t sfp);
|
||||||
bool gpio_pin_test(uint8_t pin);
|
bool gpio_pin_test(uint8_t pin);
|
||||||
void set_sys_led_state(uint8_t state);
|
void set_sys_led_state(uint8_t state);
|
||||||
void sds_read(uint8_t sds_id, uint8_t page, uint8_t reg);
|
void sds_read(uint8_t sds_id, uint8_t page, uint8_t reg);
|
||||||
|
|||||||
+2
-2
@@ -262,7 +262,7 @@ void phy_set_speed(void) __banked
|
|||||||
{
|
{
|
||||||
uint16_t v;
|
uint16_t v;
|
||||||
|
|
||||||
print_string("Setting port "); write_char(machine.log_to_phys_port[phy_settings.port] + '0');
|
print_string("Setting port "); print_phys_port(phy_settings.port);
|
||||||
if (machine.n_10g && phy_settings.port == 3)
|
if (machine.n_10g && phy_settings.port == 3)
|
||||||
phy_settings.is10g_port = 1;
|
phy_settings.is10g_port = 1;
|
||||||
if (machine.n_10g == 2 && phy_settings.port == 8)
|
if (machine.n_10g == 2 && phy_settings.port == 8)
|
||||||
@@ -381,7 +381,7 @@ void phy_set_duplex(void) __banked
|
|||||||
{
|
{
|
||||||
uint16_t v;
|
uint16_t v;
|
||||||
|
|
||||||
print_string("Setting port "); write_char(machine.log_to_phys_port[phy_settings.port] + '0');
|
print_string("Setting port "); print_phys_port(phy_settings.port);
|
||||||
if (phy_settings.duplex)
|
if (phy_settings.duplex)
|
||||||
print_string(" to full duplex");
|
print_string(" to full duplex");
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
#include "rtl837x_pins.h"
|
#include "rtl837x_pins.h"
|
||||||
#include "rtl837x_common.h"
|
#include "rtl837x_common.h"
|
||||||
|
#include "rtl837x_sfr.h"
|
||||||
#include "rtl837x_regs.h"
|
#include "rtl837x_regs.h"
|
||||||
|
#include "machine.h"
|
||||||
|
|
||||||
|
extern __code const struct machine machine;
|
||||||
|
extern __xdata uint8_t sfr_data[4];
|
||||||
|
|
||||||
#pragma codeseg BANK2
|
#pragma codeseg BANK2
|
||||||
#pragma constseg BANK2
|
#pragma constseg BANK2
|
||||||
@@ -121,3 +126,56 @@ void gpio_output_setup(uint8_t pin, __xdata uint8_t initial_val) __banked{
|
|||||||
|
|
||||||
reg_bit_set(gpio_direction_reg(pin), (pin % 32));
|
reg_bit_set(gpio_direction_reg(pin), (pin % 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read up to 16 consecutive registers of the EEPROM via I2C into sfp_buf
|
||||||
|
*/
|
||||||
|
bool sfp_read_block(uint8_t slot, uint8_t reg, uint8_t len) __banked __reentrant
|
||||||
|
{
|
||||||
|
uint8_t dev;
|
||||||
|
uint8_t val;
|
||||||
|
|
||||||
|
len--;
|
||||||
|
if (len > 15)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
dev = (reg & 0x80) ? 0x51 : 0x50; // 0x51 holds the diagnostics, 0x50 the module data
|
||||||
|
reg &= 0x7f;
|
||||||
|
|
||||||
|
REG_WRITE(RTL837X_REG_I2C_IN, 0, 0, 0, reg);
|
||||||
|
|
||||||
|
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00,
|
||||||
|
0x1 << (I2C_MEM_ADDR_WIDTH - 16) | len,
|
||||||
|
(dev >> 5) | i2c_bus_from_scl_pin(machine.sfp_port[slot].i2c.scl) << 5
|
||||||
|
| i2c_bus_from_sda_pin(machine.sfp_port[slot].i2c.sda) << 2,
|
||||||
|
((dev << 3) & 0xff) | 0x1);
|
||||||
|
|
||||||
|
do {
|
||||||
|
reg_read(RTL837X_REG_I2C_CTRL);
|
||||||
|
} while (SFR_DATA_0 & 0x1);
|
||||||
|
|
||||||
|
if (SFR_DATA_0 & 0x2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i <= len; i++) {
|
||||||
|
switch (i & 0x3) {
|
||||||
|
case 0:
|
||||||
|
reg_read(RTL837X_REG_I2C_OUT + i);
|
||||||
|
val = SFR_DATA_0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
val = SFR_DATA_8;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
val = SFR_DATA_16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
val = SFR_DATA_24;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sfp_buf[i] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
+8
-21
@@ -30,7 +30,7 @@ __xdata uint32_t l2_head;
|
|||||||
|
|
||||||
__xdata struct vlan_settings vlan_settings;
|
__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("\nport_mirror_set called \n");
|
||||||
print_string("Mirroring port: "); print_byte(port); print_string(" with rx-mask: ");
|
print_string("Mirroring port: "); print_byte(port); print_string(" with rx-mask: ");
|
||||||
@@ -162,7 +162,7 @@ void vlan_name_remove(uint16_t vlan) __banked
|
|||||||
* Reads VLAN information from VLAN table
|
* Reads VLAN information from VLAN table
|
||||||
* Returns data in sfr_data
|
* 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
|
if (vlan >= 0xfff) // VLAN 4095 is special
|
||||||
return -1;
|
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 int16_t i = 0;
|
||||||
__xdata uint8_t begin = 1;
|
__xdata uint8_t begin = 1;
|
||||||
@@ -390,10 +390,7 @@ void port_l2_learned(void) __banked
|
|||||||
print_string("\tlearned\t");
|
print_string("\tlearned\t");
|
||||||
|
|
||||||
port |= (sfr_data[3] & 0x3) << 2;
|
port |= (sfr_data[3] & 0x3) << 2;
|
||||||
if (port < 9)
|
print_phys_port(port);
|
||||||
write_char(machine.log_to_phys_port[port] + '0');
|
|
||||||
else
|
|
||||||
print_string("CPU");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entry++;
|
entry++;
|
||||||
@@ -431,7 +428,7 @@ void port_stats_print(void) __banked
|
|||||||
{
|
{
|
||||||
print_string("\nPort\tState\tLink\tTxGood\t\tTxBad\t\tRxGood\t\tRxBad\n");
|
print_string("\nPort\tState\tLink\tTxGood\t\tTxBad\t\tRxGood\t\tRxBad\n");
|
||||||
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
|
||||||
write_char('0' + machine.log_to_phys_port[i]); write_char('\t');
|
print_phys_port(i); write_char('\t');
|
||||||
|
|
||||||
if (!machine.is_sfp[i]) {
|
if (!machine.is_sfp[i]) {
|
||||||
phy_read(i, PHY_MMD31, 0xa610);
|
phy_read(i, PHY_MMD31, 0xa610);
|
||||||
@@ -508,14 +505,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)
|
if (port <= machine.max_port)
|
||||||
REG_SET(RTL837X_PORT_ISOLATION_BASE + (port << 2), pmask);
|
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)
|
if (port > machine.max_port)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -606,7 +603,7 @@ void port_eee_disable(uint8_t port) __banked
|
|||||||
|
|
||||||
void port_eee_status(uint8_t port) __banked
|
void port_eee_status(uint8_t port) __banked
|
||||||
{
|
{
|
||||||
print_string("Port: "); write_char('0' + machine.log_to_phys_port[port]);
|
print_string("Port: "); print_phys_port(port);
|
||||||
print_string(": ");
|
print_string(": ");
|
||||||
if (machine.is_sfp[port]) {
|
if (machine.is_sfp[port]) {
|
||||||
print_string("SFP\n");
|
print_string("SFP\n");
|
||||||
@@ -801,16 +798,6 @@ void print_port_ingress_filter_mode(vlan_ingress_mode_t mode) __banked
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_phys_port(uint8_t port) __banked
|
|
||||||
{
|
|
||||||
if (port >= machine.min_port && port <= machine.max_port)
|
|
||||||
write_char(machine.log_to_phys_port[port] + '0');
|
|
||||||
else if (port == 9)
|
|
||||||
write_char('9');
|
|
||||||
else
|
|
||||||
write_char('?');
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_vlan_ingress_port(uint8_t log_port) __banked
|
void print_vlan_ingress_port(uint8_t log_port) __banked
|
||||||
{
|
{
|
||||||
print_phys_port(log_port);write_char('\t');
|
print_phys_port(log_port);write_char('\t');
|
||||||
|
|||||||
+5
-5
@@ -48,8 +48,8 @@ extern __xdata struct vlan_settings vlan_settings;
|
|||||||
uint8_t port_l2_forget(void) __banked;
|
uint8_t port_l2_forget(void) __banked;
|
||||||
void port_l2_learned(void) __banked;
|
void port_l2_learned(void) __banked;
|
||||||
void port_stats_print(void) __banked;
|
void port_stats_print(void) __banked;
|
||||||
int8_t vlan_get(register uint16_t vlan) __banked;
|
int8_t vlan_get(uint16_t vlan) __banked;
|
||||||
__xdata uint16_t vlan_name(register uint16_t vlan) __banked;
|
__xdata uint16_t vlan_name(uint16_t vlan) __banked;
|
||||||
void vlan_name_remove(uint16_t vlan) __banked;
|
void vlan_name_remove(uint16_t vlan) __banked;
|
||||||
void vlan_setup(void) __banked;
|
void vlan_setup(void) __banked;
|
||||||
void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked;
|
void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked;
|
||||||
@@ -57,7 +57,7 @@ uint16_t port_pvid_get(uint8_t port) __banked;
|
|||||||
void vlan_create(void) __banked;
|
void vlan_create(void) __banked;
|
||||||
void vlan_delete(uint16_t vlan) __banked;
|
void vlan_delete(uint16_t vlan) __banked;
|
||||||
void vlan_dump(void) __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;
|
void port_mirror_del(void) __banked;
|
||||||
bool port_ingress_filter(__xdata uint8_t port, __xdata vlan_ingress_mode_t type) __banked;
|
bool port_ingress_filter(__xdata uint8_t port, __xdata vlan_ingress_mode_t type) __banked;
|
||||||
void port_l2_setup(void) __banked;
|
void port_l2_setup(void) __banked;
|
||||||
@@ -73,7 +73,7 @@ void port_eee_status(uint8_t port) __banked;
|
|||||||
void print_port_ingress_filter_mode(vlan_ingress_mode_t mode) __banked;
|
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_set(__xdata uint8_t port, __xdata bool enabled) __banked;
|
||||||
bool port_ingress_vlan_filter_get(__xdata uint8_t port) __banked;
|
bool port_ingress_vlan_filter_get(__xdata uint8_t port) __banked;
|
||||||
void port_isolate(register uint8_t port, __xdata uint16_t pmask) __banked;
|
void port_isolate(uint8_t port, __xdata uint16_t pmask) __banked;
|
||||||
uint16_t port_isolation_get(register uint8_t port) __banked;
|
uint16_t port_isolation_get(uint8_t port) __banked;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -14,6 +14,11 @@
|
|||||||
#include "uip.h"
|
#include "uip.h"
|
||||||
#include "machine.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 __code struct machine machine;
|
||||||
extern __xdata uint8_t sfr_data[4];
|
extern __xdata uint8_t sfr_data[4];
|
||||||
|
|
||||||
|
|||||||
+114
-66
@@ -140,6 +140,7 @@ __xdata char sfp_module_vendor[2][17];
|
|||||||
__xdata char sfp_module_model[2][17];
|
__xdata char sfp_module_model[2][17];
|
||||||
__xdata char sfp_module_serial[2][17];
|
__xdata char sfp_module_serial[2][17];
|
||||||
__xdata uint8_t sfp_options[2];
|
__xdata uint8_t sfp_options[2];
|
||||||
|
__xdata uint8_t sfp_buf[16]; /* scratch for one I2C transaction, the controller reads at most 16 bytes */
|
||||||
__xdata uint8_t sfp_speed[2];
|
__xdata uint8_t sfp_speed[2];
|
||||||
__xdata uint8_t sfp_quirks[2];
|
__xdata uint8_t sfp_quirks[2];
|
||||||
__xdata bool button_last;
|
__xdata bool button_last;
|
||||||
@@ -289,6 +290,12 @@ void print_string_no_syslog(__code char *p)
|
|||||||
write_char_no_syslog(*p++);
|
write_char_no_syslog(*p++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_string_newline_no_syslog(__code char *p)
|
||||||
|
{
|
||||||
|
write_char_no_syslog('\n');
|
||||||
|
print_string_no_syslog(p);
|
||||||
|
}
|
||||||
|
|
||||||
void print_string_x(__xdata char *p)
|
void print_string_x(__xdata char *p)
|
||||||
{
|
{
|
||||||
while (*p)
|
while (*p)
|
||||||
@@ -304,20 +311,20 @@ void memcpy(__xdata void * __xdata dst, __xdata const void * __xdata src, uint16
|
|||||||
*d++ = *s++;
|
*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--)
|
while (len--)
|
||||||
*dst++ = *src++;
|
*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--)
|
while (len--)
|
||||||
*dst++ = v;
|
*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;
|
__xdata uint8_t *b = dst;
|
||||||
while (*s)
|
while (*s)
|
||||||
@@ -327,7 +334,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;
|
uint16_t l = 0;
|
||||||
while (s[l])
|
while (s[l])
|
||||||
@@ -336,7 +343,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;
|
uint16_t l = 0;
|
||||||
while (s[l])
|
while (s[l])
|
||||||
@@ -345,7 +352,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;
|
uint8_t i = 0;
|
||||||
|
|
||||||
@@ -360,6 +367,32 @@ char strcmp(register __xdata const uint8_t *a, register __code const uint8_t *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* True when b is a prefix of a. Unlike strcmp() the byte after the match is not
|
||||||
|
* compared, and unlike is_word_x() it need not be a separator.
|
||||||
|
*/
|
||||||
|
bool strstart(__xdata const uint8_t *a, __code const uint8_t *b)
|
||||||
|
{
|
||||||
|
uint8_t i = 0;
|
||||||
|
|
||||||
|
while (b[i] && (b[i] == a[i]))
|
||||||
|
i++;
|
||||||
|
|
||||||
|
return !b[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool strstart_x(__xdata const uint8_t *a, __xdata const uint8_t *b)
|
||||||
|
{
|
||||||
|
uint8_t i = 0;
|
||||||
|
|
||||||
|
while (b[i] && (b[i] == a[i]))
|
||||||
|
i++;
|
||||||
|
|
||||||
|
return !b[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void print_short(uint16_t a)
|
void print_short(uint16_t a)
|
||||||
{
|
{
|
||||||
// allocating the registers first improves the sdcc code here
|
// allocating the registers first improves the sdcc code here
|
||||||
@@ -634,7 +667,7 @@ void nic_rx_header(uint16_t ring_ptr)
|
|||||||
* data will be returned in the xmem buffer points to
|
* data will be returned in the xmem buffer points to
|
||||||
* ring_ptr is the current position of the RX Ring on the ASIC side
|
* ring_ptr is the current position of the RX Ring on the ASIC side
|
||||||
*/
|
*/
|
||||||
void nic_rx_packet(register uint16_t buffer, register uint16_t ring_ptr)
|
void nic_rx_packet(uint16_t buffer, uint16_t ring_ptr)
|
||||||
{
|
{
|
||||||
SFR_NIC_DATA_U16LE = buffer;
|
SFR_NIC_DATA_U16LE = buffer;
|
||||||
SFR_NIC_RING_U16LE = ring_ptr;
|
SFR_NIC_RING_U16LE = ring_ptr;
|
||||||
@@ -780,6 +813,19 @@ void print_reg(uint16_t reg)
|
|||||||
print_sfr_data();
|
print_sfr_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Print the physical port of a logical port number.
|
||||||
|
void print_phys_port(uint8_t port)
|
||||||
|
{
|
||||||
|
if (port < CPU_PORT)
|
||||||
|
write_char(machine.log_to_phys_port[port] + '0');
|
||||||
|
else if (port == CPU_PORT)
|
||||||
|
print_string("CPU");
|
||||||
|
else {
|
||||||
|
print_string("UNKNOWN ");
|
||||||
|
write_char(port + '0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// TODO: This uses 2 DSEG bytes and is not used!
|
// TODO: This uses 2 DSEG bytes and is not used!
|
||||||
@@ -1036,37 +1082,6 @@ void sds_config(uint8_t sds, uint8_t mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read a register of the EEPROM via I2C
|
|
||||||
*/
|
|
||||||
uint8_t sfp_read_reg(uint8_t slot, uint8_t reg)
|
|
||||||
{
|
|
||||||
if (reg & 0x80) { // Configure SFP readings address (0x51) as I2C device address
|
|
||||||
reg &= 0x7f;
|
|
||||||
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 0, 0x51 >> 5, (0x51 << 3) & 0xff);
|
|
||||||
} else {
|
|
||||||
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 0, 0x50 >> 5, (0x50 << 3) & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
reg_read_m(RTL837X_REG_I2C_CTRL);
|
|
||||||
sfr_mask_data(1, 0xfc, i2c_bus_from_scl_pin(machine.sfp_port[slot].i2c.scl) << 5 | i2c_bus_from_sda_pin(machine.sfp_port[slot].i2c.sda) << 2);
|
|
||||||
reg_write_m(RTL837X_REG_I2C_CTRL);
|
|
||||||
|
|
||||||
REG_WRITE(RTL837X_REG_I2C_IN, 0, 0, 0, reg);
|
|
||||||
|
|
||||||
// Execute I2C Read
|
|
||||||
reg_bit_set(RTL837X_REG_I2C_CTRL, 0);
|
|
||||||
|
|
||||||
// Wait for execution to finish
|
|
||||||
do {
|
|
||||||
reg_read_m(RTL837X_REG_I2C_CTRL);
|
|
||||||
} while (sfr_data[3] & 0x1);
|
|
||||||
|
|
||||||
reg_read_m(RTL837X_REG_I2C_OUT);
|
|
||||||
return sfr_data[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adds TX Header to uip_buf and calls nic_tx_packet to send the packet
|
* Adds TX Header to uip_buf and calls nic_tx_packet to send the packet
|
||||||
* over the wire
|
* over the wire
|
||||||
@@ -1205,7 +1220,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)
|
if (rate == 0x1 || rate == 0x2)
|
||||||
return SDS_100FX;
|
return SDS_100FX;
|
||||||
@@ -1219,36 +1234,46 @@ static inline uint8_t sfp_rate_to_sds_config(register uint8_t rate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sfp_print_info(uint8_t sfp)
|
bool sfp_print_info(uint8_t sfp)
|
||||||
{
|
{
|
||||||
// This loops over the Vendor-name, Vendor OUI, Vendor PN and Vendor rev ASCII fields
|
// This loops over the Vendor-name, Vendor OUI, Vendor PN and Vendor rev ASCII fields
|
||||||
for (uint8_t i = 20; i < 60; i++) {
|
for (uint8_t i = 16; i < 64; i++) {
|
||||||
if (i >= 36 && i < 40) // Skip Non-ASCII codes
|
if (!(i & 0xf) && !sfp_read_block(sfp, i, 16))
|
||||||
|
return false;
|
||||||
|
if (i < 20 || i >= 60 || (i >= 36 && i < 40)) // Skip Non-ASCII codes
|
||||||
continue;
|
continue;
|
||||||
uint8_t c = sfp_read_reg(sfp, i);
|
uint8_t c = sfp_buf[i & 0xf];
|
||||||
if (c)
|
if (c)
|
||||||
write_char(c);
|
write_char(c);
|
||||||
}
|
}
|
||||||
print_string("\n");
|
print_string("\n");
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize strings from EEPROM by removing any trailing spaces; this allows simpler comparisons
|
// Normalize strings from EEPROM by removing any trailing spaces; this allows simpler comparisons
|
||||||
void sfp_read_field(__xdata char *dst, uint8_t sfp, uint8_t start, uint8_t length) __reentrant
|
bool sfp_read_field(__xdata char *dst, uint8_t sfp, uint8_t start, uint8_t length) __reentrant
|
||||||
{
|
{
|
||||||
dst[length] = '\0';
|
if (!sfp_read_block(sfp, start, length))
|
||||||
|
return false;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < length; i++)
|
dst[length] = NUL;
|
||||||
dst[i] = sfp_read_reg(sfp, start + i);
|
memcpy(dst, sfp_buf, length);
|
||||||
|
|
||||||
while (length > 0 && dst[--length] == ' ')
|
while (length > 0 && dst[--length] == ' ')
|
||||||
dst[length] = '\0';
|
dst[length] = NUL;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfp_get_info(uint8_t sfp)
|
bool sfp_get_info(uint8_t sfp)
|
||||||
{
|
{
|
||||||
sfp_read_field(sfp_module_vendor[sfp], sfp, 20, 16);
|
if (!sfp_read_field(sfp_module_vendor[sfp], sfp, 20, 16))
|
||||||
sfp_read_field(sfp_module_model[sfp], sfp, 40, 16);
|
return false;
|
||||||
sfp_read_field(sfp_module_serial[sfp], sfp, 68, 16);
|
if (!sfp_read_field(sfp_module_model[sfp], sfp, 40, 16))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return sfp_read_field(sfp_module_serial[sfp], sfp, 68, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfp_apply_quirks(uint8_t sfp) __reentrant
|
void sfp_apply_quirks(uint8_t sfp) __reentrant
|
||||||
@@ -1267,7 +1292,7 @@ void sfp_apply_quirks(uint8_t sfp) __reentrant
|
|||||||
if (!(sfp_options[sfp] & 0x40)) {
|
if (!(sfp_options[sfp] & 0x40)) {
|
||||||
// The module reports that DDM is not implemented, but try a dummy read to confirm
|
// The module reports that DDM is not implemented, but try a dummy read to confirm
|
||||||
// 0xff would mean a failed I2C read or an impossible (per spec) voltage greater than 6.5V
|
// 0xff would mean a failed I2C read or an impossible (per spec) voltage greater than 6.5V
|
||||||
if (sfp_read_reg(sfp, 226) != 0xff) {
|
if (sfp_read_block(sfp, 226, 1) && sfp_buf[0] != 0xff) {
|
||||||
sfp_options[sfp] |= 0x40;
|
sfp_options[sfp] |= 0x40;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1291,17 +1316,17 @@ void setup_sfp_gpio(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_sfp(void)
|
static bool sfp_module_read(uint8_t sfp)
|
||||||
{
|
{
|
||||||
for (uint8_t sfp = 0; sfp < machine.n_sfp; sfp++) {
|
uint8_t rate;
|
||||||
if (!gpio_pin_test(machine.sfp_port[sfp].pin_detect)) {
|
|
||||||
if (sfp_pins_last & (0x1 << (sfp << 2))) {
|
|
||||||
sfp_pins_last &= ~(0x01 << (sfp << 2));
|
|
||||||
print_string("\n<MODULE INSERTED> Slot: "); write_char('1' + sfp);
|
|
||||||
// Read Reg 11: Encoding, see SFF-8472 and SFF-8024
|
// Read Reg 11: Encoding, see SFF-8472 and SFF-8024
|
||||||
// Read Reg 12: Signalling rate (including overhead) in 100Mbit: 0xd: 1Gbit, 0x67:10Gbit
|
// Read Reg 12: Signalling rate (including overhead) in 100Mbit: 0xd: 1Gbit, 0x67:10Gbit
|
||||||
delay(100); // Delay, because some modules need time to wake up
|
delay(100); // Delay, because some modules need time to wake up
|
||||||
uint8_t rate = sfp_read_reg(sfp, 12);
|
if (!sfp_read_block(sfp, 11, 2))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
rate = sfp_buf[1];
|
||||||
if (sfp_speed[sfp] == SFP_SPEED_100M)
|
if (sfp_speed[sfp] == SFP_SPEED_100M)
|
||||||
rate = 0x1;
|
rate = 0x1;
|
||||||
else if (sfp_speed[sfp] == SFP_SPEED_1G)
|
else if (sfp_speed[sfp] == SFP_SPEED_1G)
|
||||||
@@ -1311,13 +1336,36 @@ void handle_sfp(void)
|
|||||||
else if (sfp_speed[sfp] == SFP_SPEED_10G)
|
else if (sfp_speed[sfp] == SFP_SPEED_10G)
|
||||||
rate = 0x69;
|
rate = 0x69;
|
||||||
print_string(" Rate: "); print_byte(rate); // Normally 1, but 0 for DAC, can be ignored?
|
print_string(" Rate: "); print_byte(rate); // Normally 1, but 0 for DAC, can be ignored?
|
||||||
print_string(" Encoding: "); print_byte(sfp_read_reg(sfp, 11));
|
print_string(" Encoding: "); print_byte(sfp_buf[0]);
|
||||||
print_string(" Module: "); sfp_print_info(sfp);
|
print_string(" Module: ");
|
||||||
|
if (!sfp_print_info(sfp))
|
||||||
|
return false;
|
||||||
print_string("\n");
|
print_string("\n");
|
||||||
sfp_options[sfp] = sfp_read_reg(sfp, 92);
|
|
||||||
sfp_get_info(sfp);
|
if (!sfp_read_block(sfp, 92, 1))
|
||||||
|
return false;
|
||||||
|
sfp_options[sfp] = sfp_buf[0];
|
||||||
|
if (!sfp_get_info(sfp))
|
||||||
|
return false;
|
||||||
|
|
||||||
sfp_apply_quirks(sfp);
|
sfp_apply_quirks(sfp);
|
||||||
sds_config(machine.sfp_port[sfp].sds, sfp_rate_to_sds_config(rate));
|
sds_config(machine.sfp_port[sfp].sds, sfp_rate_to_sds_config(rate));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handle_sfp(void)
|
||||||
|
{
|
||||||
|
for (uint8_t sfp = 0; sfp < machine.n_sfp; sfp++) {
|
||||||
|
if (!gpio_pin_test(machine.sfp_port[sfp].pin_detect)) {
|
||||||
|
if (sfp_pins_last & (0x1 << (sfp << 2))) {
|
||||||
|
sfp_pins_last &= ~(0x01 << (sfp << 2));
|
||||||
|
print_string("\n<MODULE INSERTED> Slot: "); write_char('1' + sfp);
|
||||||
|
if (!sfp_module_read(sfp)) {
|
||||||
|
print_string("SFP: an I2C read failed, retrying on the next poll\n");
|
||||||
|
sfp_pins_last |= 0x01 << (sfp << 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!(sfp_pins_last & (0x1 << (sfp << 2)))) {
|
if (!(sfp_pins_last & (0x1 << (sfp << 2)))) {
|
||||||
@@ -2021,7 +2069,7 @@ void check_and_flash_update_image(void)
|
|||||||
* because itohex() is inline and brings its own frame. */
|
* because itohex() is inline and brings its own frame. */
|
||||||
void set_hostname_default(void)
|
void set_hostname_default(void)
|
||||||
{
|
{
|
||||||
if (hostname[0] != '\0')
|
if (hostname[0] != NUL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
strcpy((__xdata uint8_t *)hostname, "RTLPlayground-");
|
strcpy((__xdata uint8_t *)hostname, "RTLPlayground-");
|
||||||
@@ -2031,7 +2079,7 @@ void set_hostname_default(void)
|
|||||||
hostname[17] = hex[uip_ethaddr.addr[4] & 0xf];
|
hostname[17] = hex[uip_ethaddr.addr[4] & 0xf];
|
||||||
hostname[18] = hex[uip_ethaddr.addr[5] >> 4];
|
hostname[18] = hex[uip_ethaddr.addr[5] >> 4];
|
||||||
hostname[19] = hex[uip_ethaddr.addr[5] & 0xf];
|
hostname[19] = hex[uip_ethaddr.addr[5] & 0xf];
|
||||||
hostname[20] = '\0';
|
hostname[20] = NUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,16 +30,16 @@ void syslog_start(void) __banked
|
|||||||
uip_ipaddr(server_ip, state.server_ip[0], state.server_ip[1], state.server_ip[2], state.server_ip[3]);
|
uip_ipaddr(server_ip, state.server_ip[0], state.server_ip[1], state.server_ip[2], state.server_ip[3]);
|
||||||
state.syslog_conn = uip_udp_new(&server_ip, HTONS(514));
|
state.syslog_conn = uip_udp_new(&server_ip, HTONS(514));
|
||||||
if (state.syslog_conn == 0) {
|
if (state.syslog_conn == 0) {
|
||||||
print_string_no_syslog("Failed to create a new UDP client\n");
|
print_string_newline_no_syslog("Failed to create a new UDP client");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
print_string_no_syslog("Started syslog to IP ");
|
print_string_newline_no_syslog("Started syslog to IP ");
|
||||||
itoa(state.server_ip[0]); write_char('.'); itoa(state.server_ip[1]); write_char('.');
|
itoa(state.server_ip[0]); write_char('.'); itoa(state.server_ip[1]); write_char('.');
|
||||||
itoa(state.server_ip[2]); write_char('.'); itoa(state.server_ip[3]); write_char('\n');
|
itoa(state.server_ip[2]); write_char('.'); itoa(state.server_ip[3]); write_char('\n');
|
||||||
state.enabled = 1;
|
state.enabled = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print_string_no_syslog("Syslog is already running\n");
|
print_string_newline_no_syslog("Syslog is already running");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,9 +49,9 @@ void syslog_stop(void) __banked
|
|||||||
if (state.syslog_conn != 0) {
|
if (state.syslog_conn != 0) {
|
||||||
uip_udp_remove(state.syslog_conn);
|
uip_udp_remove(state.syslog_conn);
|
||||||
state.syslog_conn = 0;
|
state.syslog_conn = 0;
|
||||||
print_string_no_syslog("Stopped syslog\n");
|
print_string_newline_no_syslog("Stopped syslog");
|
||||||
} else {
|
} else {
|
||||||
print_string_no_syslog("Syslog is not running\n");
|
print_string_newline_no_syslog("Syslog is not running");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,19 +62,19 @@ void syslog_callback(uint16_t lport) __banked
|
|||||||
|
|
||||||
if ((state.readptr != state.writeptr) && state.line_available)
|
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)
|
if (log_size < 0)
|
||||||
log_size += LOGBUF_SIZE;
|
log_size += LOGBUF_SIZE;
|
||||||
|
|
||||||
// Skipping linefeeds at the start of the log line
|
// 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') {
|
while (log_size > 0 && logbuf[log_start] == '\n') {
|
||||||
log_start = (log_start + 1) & (LOGBUF_SIZE - 1);
|
log_start = (log_start + 1) & (LOGBUF_SIZE - 1);
|
||||||
log_size--;
|
log_size--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skipping linefeeds and whitespaces at the end of the log line
|
// 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) &&
|
while ( (log_size > 0) &&
|
||||||
((logbuf[(log_end-1) & (LOGBUF_SIZE - 1)] == '\n') ||
|
((logbuf[(log_end-1) & (LOGBUF_SIZE - 1)] == '\n') ||
|
||||||
(logbuf[(log_end-1) & (LOGBUF_SIZE - 1)] == ' ')))
|
(logbuf[(log_end-1) & (LOGBUF_SIZE - 1)] == ' ')))
|
||||||
|
|||||||
+9
-11
@@ -75,8 +75,7 @@
|
|||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
buf_setup(register __xdata struct psock_buf *buf,
|
buf_setup(__xdata struct psock_buf *buf, __xdata u8_t *bufptr, u16_t bufsize)
|
||||||
register __xdata u8_t *bufptr, register u16_t bufsize)
|
|
||||||
{
|
{
|
||||||
buf->ptr = bufptr;
|
buf->ptr = bufptr;
|
||||||
buf->left = bufsize;
|
buf->left = bufsize;
|
||||||
@@ -84,7 +83,7 @@ buf_setup(register __xdata struct psock_buf *buf,
|
|||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
inline u8_t
|
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) {
|
if(*datalen < buf->left) {
|
||||||
memcpy(buf->ptr, *dataptr, *datalen);
|
memcpy(buf->ptr, *dataptr, *datalen);
|
||||||
@@ -145,7 +144,7 @@ buf_bufto(__xdata struct psock_buf *buf, u8_t endmarker,
|
|||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static char
|
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->state != STATE_DATA_SENT || uip_rexmit()) {
|
||||||
if(s->sendlen > uip_mss()) {
|
if(s->sendlen > uip_mss()) {
|
||||||
@@ -160,7 +159,7 @@ send_data(register __xdata struct psock *s)
|
|||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static char
|
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->state == STATE_DATA_SENT && uip_acked()) {
|
||||||
if(s->sendlen > uip_mss()) {
|
if(s->sendlen > uip_mss()) {
|
||||||
@@ -176,8 +175,7 @@ data_acked(register __xdata struct psock *s)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
PT_THREAD(psock_send(register __xdata struct psock *s, register __xdata const char *buf,
|
PT_THREAD(psock_send(__xdata struct psock *s, __xdata const char *buf, uint16_t len))
|
||||||
register uint16_t len))
|
|
||||||
{
|
{
|
||||||
PT_BEGIN(&s->psockpt);
|
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))
|
// unsigned short (*generate)(void *), void *arg))
|
||||||
// {
|
// {
|
||||||
// PT_BEGIN(&s->psockpt);
|
// 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);
|
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_END(&psock->psockpt);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
PT_THREAD(psock_readbuf(register __xdata struct psock *psock))
|
PT_THREAD(psock_readbuf(__xdata struct psock *psock))
|
||||||
{
|
{
|
||||||
PT_BEGIN(&psock->psockpt);
|
PT_BEGIN(&psock->psockpt);
|
||||||
|
|
||||||
@@ -334,7 +332,7 @@ PT_THREAD(psock_readbuf(register __xdata struct psock *psock))
|
|||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
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->state = STATE_NONE;
|
||||||
psock->readlen = 0;
|
psock->readlen = 0;
|
||||||
|
|||||||
+2
-2
@@ -124,7 +124,7 @@ struct psock {
|
|||||||
u8_t state; /* The state of the protosocket. */
|
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.
|
* 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))
|
#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.
|
* Send data.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ __xdata u16_t uip_len, uip_slen;
|
|||||||
__xdata u8_t uip_flags; /* The uip_flags variable is used for
|
__xdata u8_t uip_flags; /* The uip_flags variable is used for
|
||||||
communication between the TCP/IP stack
|
communication between the TCP/IP stack
|
||||||
and the application program. */
|
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. */
|
connection. */
|
||||||
|
|
||||||
__xdata struct uip_conn uip_conns[UIP_CONNS];
|
__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
|
/* The uip_listenports list all currently
|
||||||
listning ports. */
|
listning ports. */
|
||||||
#if UIP_UDP
|
#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];
|
__xdata struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
|
||||||
#endif /* UIP_UDP */
|
#endif /* UIP_UDP */
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ __xdata struct uip_stats uip_stat;
|
|||||||
#endif /* UIP_STATISTICS == 1 */
|
#endif /* UIP_STATISTICS == 1 */
|
||||||
|
|
||||||
#if UIP_LOGGING == 1
|
#if UIP_LOGGING == 1
|
||||||
#define UIP_LOG(m) print_string_no_syslog(m);
|
#define UIP_LOG(m) print_string_newline_no_syslog(m);
|
||||||
#else
|
#else
|
||||||
#define UIP_LOG(m)
|
#define UIP_LOG(m)
|
||||||
#endif /* UIP_LOGGING == 1 */
|
#endif /* UIP_LOGGING == 1 */
|
||||||
@@ -400,7 +400,7 @@ uip_init(void) __banked
|
|||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if UIP_ACTIVE_OPEN
|
#if UIP_ACTIVE_OPEN
|
||||||
__xdata struct uip_conn *
|
__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;
|
__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
|
#if UIP_UDP
|
||||||
__xdata struct uip_udp_conn *
|
__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;
|
__xdata struct uip_udp_conn *conn;
|
||||||
|
|
||||||
@@ -677,7 +677,7 @@ uip_add_rcv_nxt(u16_t n)
|
|||||||
void
|
void
|
||||||
uip_process(u8_t flag) __banked
|
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 UIP_UDP
|
||||||
if(flag == UIP_UDP_SEND_CONN) {
|
if(flag == UIP_UDP_SEND_CONN) {
|
||||||
|
|||||||
@@ -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
|
* \return The uip_udp_conn structure for the new connection or NULL
|
||||||
* if no connection could be allocated.
|
* 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.
|
* Removed a UDP connection.
|
||||||
@@ -1193,7 +1193,7 @@ struct uip_conn {
|
|||||||
* The uip_conn pointer can be used to access the current TCP
|
* The uip_conn pointer can be used to access the current TCP
|
||||||
* connection.
|
* connection.
|
||||||
*/
|
*/
|
||||||
extern __xdata struct uip_conn *uip_conn;
|
extern __xdata struct uip_conn * __xdata uip_conn;
|
||||||
/* The array containing all uIP connections. */
|
/* The array containing all uIP connections. */
|
||||||
extern __xdata struct uip_conn uip_conns[UIP_CONNS];
|
extern __xdata struct uip_conn uip_conns[UIP_CONNS];
|
||||||
/**
|
/**
|
||||||
@@ -1226,7 +1226,7 @@ struct uip_udp_conn {
|
|||||||
/**
|
/**
|
||||||
* The current UDP connection.
|
* 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];
|
extern __xdata struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
|
||||||
#endif /* UIP_UDP */
|
#endif /* UIP_UDP */
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -175,7 +175,7 @@ uip_arp_timer(void) __banked
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
static void
|
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;
|
uint8_t i;
|
||||||
/* Walk through the ARP mapping table and try to find an entry to
|
/* Walk through the ARP mapping table and try to find an entry to
|
||||||
|
|||||||
Reference in New Issue
Block a user