Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b28ead65dc | ||
|
|
a079c803d9 | ||
|
|
cc3ae654a0 | ||
|
|
57d6337940 | ||
|
|
3b58eb36e5 | ||
|
|
34c0ef77d0 | ||
|
|
e6182dbe0d | ||
|
|
1d5e4cd722 | ||
|
|
a02116a24b | ||
|
|
98369c37fe | ||
|
|
138acfadb1 | ||
|
|
08f8498b39 | ||
|
|
dd521cc79d | ||
|
|
2c2349dcef | ||
|
|
6d1380fb36 | ||
|
|
eacf13690c | ||
|
|
4ed74f05db | ||
|
|
0de18ff457 | ||
|
|
3195a14870 | ||
|
|
3ffb311e95 | ||
|
|
41ed689ae0 | ||
|
|
11eadc5a49 | ||
|
|
24d2cd7bab | ||
|
|
28c09737b2 | ||
|
|
3e1d3f40d2 | ||
|
|
389dc2af76 | ||
|
|
4963fbe50a | ||
|
|
44b5ab0e64 | ||
|
|
088321deaf | ||
|
|
3af1b049ee | ||
|
|
6a5d3cdf2c | ||
|
|
d21ea52c46 | ||
|
|
c6cc3ee595 | ||
|
|
424a963301 | ||
|
|
1344e02fb7 | ||
|
|
2ae297bc20 | ||
|
|
ce77cc273d | ||
|
|
6376a10288 | ||
|
|
a202842107 | ||
|
|
6fad2836ae | ||
|
|
2415015a87 | ||
|
|
d9fc20addf | ||
|
|
c15b2d48da | ||
|
|
f17ca1c9fc | ||
|
|
be5dee04e3 | ||
|
|
496ac8b757 | ||
|
|
bf670aed0b | ||
|
|
6af5580433 | ||
|
|
6194356f66 | ||
|
|
bd56c1a8c5 | ||
|
|
d562fd661e | ||
|
|
0b6b613c03 | ||
|
|
f325bdbd11 | ||
|
|
adecc26ae2 | ||
|
|
44ae7a8d3b | ||
|
|
c3fc541339 | ||
|
|
6fdb19f18c | ||
|
|
70f8964918 | ||
|
|
aba58e7f99 | ||
|
|
2404e7a9b6 | ||
|
|
6a31b4a279 | ||
|
|
6cd1f683bb | ||
|
|
7e90f6a126 | ||
|
|
9bd301447b | ||
|
|
9745dfe6ae | ||
|
|
d4345c1bf8 | ||
|
|
fcaacd4429 | ||
|
|
0f63244ca1 | ||
|
|
913e9780b8 | ||
|
|
0d748fa808 | ||
|
|
bd974e0aaf | ||
|
|
56686185ce | ||
|
|
ed069b67fd | ||
|
|
b1026490a8 | ||
|
|
28ea2184c2 | ||
|
|
d5f84cc2fb | ||
|
|
682ac462c4 | ||
|
|
ecc8356f4d | ||
|
|
3a8d1d323f | ||
|
|
e125ebd097 | ||
|
|
4050555667 | ||
|
|
e890e429a5 | ||
|
|
813a62ca7d | ||
|
|
b096efd63a | ||
|
|
8a7c847ad9 | ||
|
|
b94d2aeabc | ||
|
|
0e85137e7a | ||
|
|
706dea63a2 |
No files matched your search
@@ -4,6 +4,17 @@
|
|||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
|
- Devices
|
||||||
|
- Support the hongyavision HYWS-SGT0204S (PCB marking `2G5F4_10G2_V1.01`), an
|
||||||
|
RTL8372 based 4x2.5G + 2xSFP+ unmanaged switch with a 512 KB Bright Moon
|
||||||
|
`T25S40` flash. It is a sibling of the KP-9000-6XH-X2 (2M-PCB43-V1.1) with
|
||||||
|
the two SFP+ cages wired the other way round (physical 5 is on SDS1,
|
||||||
|
physical 6 on SDS0), no reset button fitted, wrong silkscreen labels on the
|
||||||
|
serial header, `LED_GLB_IO_EN` bit 6 has to be set for the port LEDs to
|
||||||
|
work, and the fitted T25S40 cannot be read in DIO mode on this board, so the
|
||||||
|
target selects single-IO flash reads (`flash_sio`). New machine target
|
||||||
|
`MACHINE_2G5F4_10G2_V1_01`, see `doc/devices/2G5F4_10G2_V1.01.md`.
|
||||||
|
|
||||||
- Web UI
|
- Web UI
|
||||||
- Compress the embedded assets (minify + gzip) and switch to a single-page layout. #315
|
- Compress the embedded assets (minify + gzip) and switch to a single-page layout. #315
|
||||||
- Replace the multi-page UI with a themed single-page app: light, dark and Selenized themes following the browser by default,
|
- Replace the multi-page UI with a themed single-page app: light, dark and Selenized themes following the browser by default,
|
||||||
|
|||||||
@@ -99,9 +99,11 @@ SRCS = \
|
|||||||
# RTL837x
|
# RTL837x
|
||||||
SRCS += \
|
SRCS += \
|
||||||
rtl837x_bandwidth.c \
|
rtl837x_bandwidth.c \
|
||||||
|
rtl837x_cabletest.c \
|
||||||
rtl837x_flash.c \
|
rtl837x_flash.c \
|
||||||
rtl837x_igmp.c \
|
rtl837x_igmp.c \
|
||||||
rtl837x_init.c \
|
rtl837x_init.c \
|
||||||
|
rtl837x_nic.c \
|
||||||
rtl837x_leds.c \
|
rtl837x_leds.c \
|
||||||
rtl837x_leds_dump.c \
|
rtl837x_leds_dump.c \
|
||||||
rtl837x_phy.c \
|
rtl837x_phy.c \
|
||||||
|
|||||||
@@ -103,24 +103,29 @@ docker run --rm -p 8080:8080 -v $(pwd):/workspace rtlplayground-dev \
|
|||||||
tools/output/httpd_sim /workspace/html
|
tools/output/httpd_sim /workspace/html
|
||||||
```
|
```
|
||||||
|
|
||||||
Edit `machine.h` or `config.txt` on your host, then re-run `make` — the
|
Edit `config.txt` on your host, then re-run `make` — the
|
||||||
source directory is mounted into the container, so changes take effect
|
source directory is mounted into the container, so changes take effect
|
||||||
immediately. To build for a different machine, pass `MACHINE=...`.
|
immediately. To build for a different machine, pass `MACHINE=<name>`, which
|
||||||
|
selects `machine/<name>.c` (see [Adding a new device](doc/adding-a-device.md)).
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## (1) Compiling for direct chip flashing AND upgrading an existing RTLPlayground running device
|
## (1) Compiling for direct chip flashing AND upgrading an existing RTLPlayground running device
|
||||||
|
|
||||||
Edit machine.h with an editor like vi or nano. Select the correct machine the firmware should build for.
|
Pass the machine that matches your device, for example:
|
||||||
|
```
|
||||||
|
make MACHINE=DEFAULT_8C_1SFP
|
||||||
|
```
|
||||||
|
The name selects the board definition `machine/<name>.c`; `make` without a
|
||||||
|
`MACHINE` value stops with an error listing what is expected. If your board is
|
||||||
|
not in the list yet, see [Adding a new device](doc/adding-a-device.md).
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> You can write configuration parameters in config.txt (see below) in order your switch to get
|
> You can write configuration parameters in config.txt (see below) in order your switch to get
|
||||||
> straight at the first boot, a correct IP configuration.
|
> straight at the first boot, a correct IP configuration.
|
||||||
|
|
||||||
Now, building the firmware image should work:
|
Now, building the firmware image should work.
|
||||||
```
|
|
||||||
make
|
|
||||||
```
|
|
||||||
Note, that the image generated ends in .bin, not .img, in order to make IMSProg happy.
|
Note, that the image generated ends in .bin, not .img, in order to make IMSProg happy.
|
||||||
|
|
||||||
image location is stored in `RTLPlayground/output/rtlplayground_version_machine.bin`
|
image location is stored in `RTLPlayground/output/rtlplayground_version_machine.bin`
|
||||||
@@ -186,7 +191,7 @@ Go to "Firmware update" tab, select the correct file.
|
|||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> If your device already runs RTLPlayground, you must upload the binary file /RTLPlayground/output/rtlplayground_Version_Machine.bin
|
> If your device already runs RTLPlayground, you must upload the binary file /RTLPlayground/output/rtlplayground_Version_Machine.bin
|
||||||
> If your device is OEM, you must upload the binary file /RTLPlayground/installer/outputrtlplayground_oem_upgrade.bin
|
> If your device is OEM, you must upload the binary file /RTLPlayground/installer/output/rtlplayground_oem_upgrade.bin
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> Check one more time that your device matches the machine type before flashing.
|
> Check one more time that your device matches the machine type before flashing.
|
||||||
@@ -353,12 +358,13 @@ Enjoy playing!
|
|||||||
## (11) Other documents
|
## (11) Other documents
|
||||||
|
|
||||||
The following documents give further documentation on specific features of the RTL837x SoCs:
|
The following documents give further documentation on specific features of the RTL837x SoCs:
|
||||||
|
- [Adding a new device](doc/adding-a-device.md)
|
||||||
- [RTL8372/3 Feature support](doc/hardware.md)
|
- [RTL8372/3 Feature support](doc/hardware.md)
|
||||||
- [CPU Port](doc/CpuPort.md)
|
- [CPU Port](doc/CpuPort.md)
|
||||||
- [L2 learning](doc/l2.md)
|
- [L2 learning](doc/l2.md)
|
||||||
- [IGMP (IP-MC streaming)](doc/igmp.md)
|
- [IGMP (IP-MC streaming)](doc/igmp.md)
|
||||||
- [SFP+ ports](doc/sfp.md)
|
- [SFP+ ports](doc/sfp.md)
|
||||||
- [Trunking aka. port aggregation](doc/trunking.md)
|
- [Trunking aka. port aggregation](doc/link_aggregation.md)
|
||||||
- [LACP (802.3ad link aggregation)](doc/lacp.md)
|
- [LACP (802.3ad link aggregation)](doc/lacp.md)
|
||||||
- [VLAN](doc/vlan.md)
|
- [VLAN](doc/vlan.md)
|
||||||
- [Storm control](doc/storm_control.md)
|
- [Storm control](doc/storm_control.md)
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ void nic_setup(void) __banked
|
|||||||
|
|
||||||
// This sets the size of the RX buffer, the filling level is in 0x7874
|
// This sets the size of the RX buffer, the filling level is in 0x7874
|
||||||
// R7848-000004ff
|
// R7848-000004ff
|
||||||
REG_SET(RTL837X_REG_NIC_RXBUFF_RX, 0x4ff);
|
REG_SET(RTL837X_REG_NIC_RXBUFF_RX, RTL837X_NIC_RX_LAST_SLOT);
|
||||||
|
|
||||||
// R7844-000007fe
|
// R7844-000007fe
|
||||||
REG_SET(RTL837X_REG_NIC_BUFFSIZE_TX, 0x7fe);
|
REG_SET(RTL837X_REG_NIC_BUFFSIZE_TX, 0x7fe);
|
||||||
@@ -296,6 +296,7 @@ void nic_setup(void) __banked
|
|||||||
|
|
||||||
// Sequence number of TX packets
|
// Sequence number of TX packets
|
||||||
tx_seq = 0;
|
tx_seq = 0;
|
||||||
|
REG_SET(RTL837X_NIC_INT_MSK, NIC_INT_RXIE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "rtl837x_lldp.h"
|
#include "rtl837x_lldp.h"
|
||||||
#include "rtl837x_storm.h"
|
#include "rtl837x_storm.h"
|
||||||
#include "rtl837x_trap.h"
|
#include "rtl837x_trap.h"
|
||||||
|
#include "rtl837x_cabletest.h"
|
||||||
#include "sfp.h"
|
#include "sfp.h"
|
||||||
#include "dhcp.h"
|
#include "dhcp.h"
|
||||||
#include "syslog.h"
|
#include "syslog.h"
|
||||||
@@ -166,10 +167,15 @@ uint8_t atoi_hex(uint8_t idx)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (h_idx == 8) {
|
||||||
|
h_idx = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// swap hex nibbles
|
// swap hex nibbles
|
||||||
val = (val >> 4) | (val << 4);
|
val = (val >> 4) | (val << 4);
|
||||||
|
|
||||||
if (c - '0' < 10) {
|
if ((uint8_t)(c - '0') < 10) {
|
||||||
val |= c - '0';
|
val |= c - '0';
|
||||||
} else {
|
} else {
|
||||||
c |= 0x20;
|
c |= 0x20;
|
||||||
@@ -739,7 +745,7 @@ void parse_isolate(void)
|
|||||||
if (cmd_compare(2, "off")) {
|
if (cmd_compare(2, "off")) {
|
||||||
for (uint8_t i = machine.min_port; i <= machine.max_port; i++)
|
for (uint8_t i = machine.min_port; i <= machine.max_port; i++)
|
||||||
members |= ((uint16_t)1) << i;
|
members |= ((uint16_t)1) << i;
|
||||||
members |= 0x200; // CPU-port
|
members |= PMASK_CPU; // CPU-port
|
||||||
port_isolate(port_configured, members);
|
port_isolate(port_configured, members);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -903,6 +909,7 @@ void parse_port(void)
|
|||||||
"\nport <port> [show|on|off]" \
|
"\nport <port> [show|on|off]" \
|
||||||
"\nport <port> [10m|100m|1g|2g5|duplex] [half|full]" \
|
"\nport <port> [10m|100m|1g|2g5|duplex] [half|full]" \
|
||||||
"\nport <port> lldp [block|permit]" \
|
"\nport <port> lldp [block|permit]" \
|
||||||
|
"\nport <port> cabletest [show]" \
|
||||||
"\nport <port> name [custom port name]\n");
|
"\nport <port> name [custom port name]\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -945,6 +952,11 @@ void parse_port(void)
|
|||||||
}
|
}
|
||||||
} else if (machine.is_sfp[phy_settings.port]) {
|
} else if (machine.is_sfp[phy_settings.port]) {
|
||||||
print_string(" is SFP no PHY information available.\n");
|
print_string(" is SFP no PHY information available.\n");
|
||||||
|
} else if (cmd_compare(2, "cabletest")) {
|
||||||
|
if (cmd_words_len > 3 && cmd_compare(3, "show"))
|
||||||
|
cabletest_show();
|
||||||
|
else
|
||||||
|
cabletest_run();
|
||||||
} else if (cmd_compare(2, "10m")) {
|
} else if (cmd_compare(2, "10m")) {
|
||||||
print_string(" 10M\n");
|
print_string(" 10M\n");
|
||||||
phy_settings.speed = PHY_SPEED_10M;
|
phy_settings.speed = PHY_SPEED_10M;
|
||||||
@@ -2143,7 +2155,7 @@ void execute_config(void) __banked
|
|||||||
skipping = 1;
|
skipping = 1;
|
||||||
}
|
}
|
||||||
c = flash_buf[cfg_idx++];
|
c = flash_buf[cfg_idx++];
|
||||||
if (c == 0 || c == '\n') {
|
if (c == 0 || c == '\n' || c == '\r') {
|
||||||
if (skipping) {
|
if (skipping) {
|
||||||
skipping = 0;
|
skipping = 0;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ __xdata uip_ipaddr_t server;
|
|||||||
#define DHCP_END 255
|
#define DHCP_END 255
|
||||||
|
|
||||||
#pragma codeseg BANK3
|
#pragma codeseg BANK3
|
||||||
#pragma constseg BANK2
|
#pragma constseg BANK3
|
||||||
|
|
||||||
struct dhcp_pkt {
|
struct dhcp_pkt {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
|
|||||||
@@ -34,6 +34,21 @@ Next, transfer the actual packet over by repeating the SFR function with a
|
|||||||
pointer to the frame on the ASIC directly after the frame header and a
|
pointer to the frame on the ASIC directly after the frame header and a
|
||||||
length as given by the length in the frame header + 7, again divided by 8.
|
length as given by the length in the frame header + 7, again divided by 8.
|
||||||
|
|
||||||
|
The RX ring's inclusive last slot is configured as `0x4ff`, giving a byte
|
||||||
|
range of `0x0000` through `0x27ff`. If the descriptor occupies the last slot
|
||||||
|
at `0x27f8`, its payload starts at `0x0000`, not `0x2800`. The RX copy code
|
||||||
|
normalizes that starting address before DMA. It relies on the hardware to
|
||||||
|
wrap transfers that start inside the ring and cross its end, as observed
|
||||||
|
on SWTGW218AS. Programming an initial address of `0x2800` does not wrap
|
||||||
|
and can instead read zeros or stale TX data outside the RX ring.
|
||||||
|
|
||||||
|
Frame lengths are checked against `UIP_CONF_BUFFER_SIZE` before copying.
|
||||||
|
DMA works in whole eight-byte units. `UIP_CONF_BUFFER_ALLOC_SIZE` rounds
|
||||||
|
the backing storage up to the next complete word: 1,560 bytes for the
|
||||||
|
1,556-byte logical frame limit. This padding allows a maximum-size frame
|
||||||
|
to be transferred directly without a separate tail copy. The logical
|
||||||
|
frame limit and advertised MSS are unchanged.
|
||||||
|
|
||||||
The received frame will have an RTL proprietary Ethernet frame type of
|
The received frame will have an RTL proprietary Ethernet frame type of
|
||||||
0x8899 (RRPC) where normally the frame type 0x0800 for IPv4 would be located.
|
0x8899 (RRPC) where normally the frame type 0x0800 for IPv4 would be located.
|
||||||
Further 6 bytes follow describing the frame, before the normal IPv4 data
|
Further 6 bytes follow describing the frame, before the normal IPv4 data
|
||||||
|
|||||||
@@ -0,0 +1,196 @@
|
|||||||
|
# Adding a new device
|
||||||
|
|
||||||
|
A device is supported by adding one board definition `.h` and board configuration `.c` file
|
||||||
|
under `machine/`.
|
||||||
|
the build selects the definition by name, and CI compiles every file it finds.
|
||||||
|
|
||||||
|
To compile for your added device, do:
|
||||||
|
```
|
||||||
|
make MACHINE=<NAME>
|
||||||
|
```
|
||||||
|
|
||||||
|
## What a new device consists of
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `machine/<NAME>.c` | the `struct machine machine` board definition |
|
||||||
|
| `machine/<NAME>.h` | `MACHINE_MODEL`, the model string shown in the UI and the CLI |
|
||||||
|
| `doc/devices/<name>.md` + `doc/supported_devices.md` | (only if the board is verified and you want to support it publicly) user-facing documentation |
|
||||||
|
|
||||||
|
`<NAME>` is the machine symbol without its `MACHINE_` prefix, so `MACHINE` is
|
||||||
|
passed exactly as spelled on the command line: `make MACHINE=MY_BOARD_1_0`
|
||||||
|
needs `machine/MY_BOARD_1_0.c` and `machine/MY_BOARD_1_0.h`.
|
||||||
|
|
||||||
|
## Step 1: the model header
|
||||||
|
|
||||||
|
`machine/<NAME>.h` only carries the product string. Use the existing files as
|
||||||
|
the template:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#ifndef _MACHINE_MY_BOARD_1_0_H_
|
||||||
|
#define _MACHINE_MY_BOARD_1_0_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "Brand Model V1.0"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
The device product string is what the CLI or the Web-Interface will print to identify the device; `machine.h` includes it by name.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> `machine_name` is a `char[30]` and `MACHINE_MODEL` is copied into it at
|
||||||
|
> compile time. A longer model string still builds, but SDCC emits
|
||||||
|
> `warning 147: excess elements in array of chars initializer` and the name is
|
||||||
|
> truncated in the UI. Keep it to 29 characters or less.
|
||||||
|
|
||||||
|
## Step 2: the board definition
|
||||||
|
|
||||||
|
`machine/<NAME>.c` starts with the shared prelude and then defines the single
|
||||||
|
`machine` object. Copy the closest existing board and adjust it — do not start
|
||||||
|
from a blank file, the field meanings are easier to see in a real example.
|
||||||
|
The best choice is usually a device that has the same number and type of Ethernet
|
||||||
|
ports and the same number of SFP+ cages.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
|
||||||
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1 },
|
||||||
|
.led_sets = {
|
||||||
|
{ /* RJ45 ports */
|
||||||
|
LEDS_2G5 | LEDS_LINK,
|
||||||
|
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
}, { /* SFP port, single green LED */
|
||||||
|
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fields
|
||||||
|
|
||||||
|
| Field | Meaning |
|
||||||
|
|-------|---------|
|
||||||
|
| `machine_name` | always `MACHINE_MODEL` |
|
||||||
|
| `isRTL8373` | `1` for an RTL8373 SoC, `0` for RTL8372 |
|
||||||
|
| `min_port` / `max_port` | range of logical port numbers the device has; `min_port` is `0` for RTL8373 boards and `3` for RTL8372 boards (logical ports 1–2 are the SoC's internal ports on the 8372), `max_port` is usually 8. |
|
||||||
|
| `n_sfp` | number of SFP+ cages |
|
||||||
|
| `n_10g` | SerDes 10G capability used by the RTL837xN init: `0` none, `1` one, `2` two 10G-capable SerDes |
|
||||||
|
| `log_to_phys_port[9]` | logical port (0-based index) → physical front-panel port number |
|
||||||
|
| `phys_to_log_port[9]` | the inverse, physical port 1 is index 0, unused slots are 0 |
|
||||||
|
| `is_sfp[9]` | `0` for copper, `1` for left slot and `2` for right slot |
|
||||||
|
| `sfp_port[2]` | per-cage wiring, `sfp_port[0]` is the leftmost cage |
|
||||||
|
| `reset_pin` | GPIO of the reset button, `GPIO_NA` if unpopulated |
|
||||||
|
| `high_leds` | mux/enable for the LED pins 27–29 (`LED_27`, `LED_28_SYS`, `LED_29`) |
|
||||||
|
| `port_led_set[9]` | which LED set (0–3) each logical port uses |
|
||||||
|
| `led_sets[4][4]` | Each port can have up to 4 GPIO output pins assigned. 4 sets of LEDs with 4 LED-conditions per set; the conditions define which GPIO pins become active for a port given a port link-state. Which LEDs are then enabled depends on the wiring of the pins to up to 3 LEDs for that port, which can make a logical combination of the 4 LED output-pins. |
|
||||||
|
| `led_mux_custom` / `led_mux[28]` | `1` plus the 28 mux values when the stock LED muxing does not fit the board |
|
||||||
|
| `mac_flash_offset` | flash offset of the factory MAC address, omit or `0` if the board does not store one |
|
||||||
|
|
||||||
|
Each `struct sfp_port` entry holds `pin_detect`, `pin_los`, `pin_tx_disable`,
|
||||||
|
`sds` (which SerDes drives the cage) and `i2c` (built with `I2CBUS(sda, scl)`,
|
||||||
|
or `GPIO_NA`-based values where a cage has no such pin).
|
||||||
|
|
||||||
|
`I2CBUS(...)` only accepts the pin pairs listed in `machine_defs.h`. A wrong
|
||||||
|
pair is caught at compile time: SDCC reports
|
||||||
|
`error 176: sizeof applied to an incomplete type` pointing at the offending
|
||||||
|
`.i2c` line, because the macro deliberately turns an invalid bus number into an
|
||||||
|
array of size 0.
|
||||||
|
|
||||||
|
### Reusing an existing definition
|
||||||
|
|
||||||
|
If the new board is electrically identical to one that already exists — same
|
||||||
|
port mapping, same SFP wiring, same LEDs — do not copy the file. Make the new
|
||||||
|
`.c` a symlink and keep only a distinct `.h`, so the two boards cannot drift
|
||||||
|
apart:
|
||||||
|
|
||||||
|
```
|
||||||
|
ln -s KP_9000_6XHML_X2.c machine/MY_BOARD_1_0.c
|
||||||
|
```
|
||||||
|
|
||||||
|
The new board still needs `machine/MY_BOARD_1_0.h` (pick the version number on the PCB) with its own
|
||||||
|
`MACHINE_MODEL`, because `MACHINE_MODEL` is what distinguishes the products.
|
||||||
|
Existing examples: `machine/PCB_K0402WS_V3.c`, `machine/KP_9000_9XHML_X_V3_2.c`
|
||||||
|
and the six `KP_9000_*` revision variants.
|
||||||
|
|
||||||
|
Two files that differ only in whitespace or comments are duplicates and should
|
||||||
|
be collapsed this way.
|
||||||
|
|
||||||
|
## Step 3: build and verify
|
||||||
|
|
||||||
|
```
|
||||||
|
make MACHINE=MY_BOARD_1_0
|
||||||
|
```
|
||||||
|
|
||||||
|
The generated flash image appears as `output/rtlplayground-<version>-MY_BOARD_1_0.bin`. An
|
||||||
|
unknown or empty `MACHINE` fails immediately with a message naming the expected
|
||||||
|
file, before anything is compiled.
|
||||||
|
|
||||||
|
Then run the checks CI runs:
|
||||||
|
|
||||||
|
```
|
||||||
|
make machine_check # compiles machine/<NAME>.c and machine_init.c for every machine
|
||||||
|
make -C test # host-side unit tests
|
||||||
|
```
|
||||||
|
|
||||||
|
`make machine_check` discovers the definitions with
|
||||||
|
`$(wildcard machine/*.c)`, so a new file is covered without registering it
|
||||||
|
anywhere. CI (`.github/workflows/build.yml`) runs it on every push and pull
|
||||||
|
request, alongside full builds for a 4+2 and an 8+1 board.
|
||||||
|
|
||||||
|
A successful compile only proves the definition is syntactically valid. The
|
||||||
|
actual behaviour — port numbering, SFP detection, LEDs — has to be confirmed on
|
||||||
|
hardware, and the console commands (`port`, `stat`, `sfp`, `leds`) are the
|
||||||
|
tools for that.
|
||||||
|
|
||||||
|
## Step 4: documentation
|
||||||
|
|
||||||
|
Once the board has been tested on hardware:
|
||||||
|
|
||||||
|
1. Add a row to the table in [Supported devices](supported_devices.md).
|
||||||
|
2. Add `doc/devices/<name>.md` describing the board, the build target
|
||||||
|
(`make MACHINE=MY_BOARD_1_0`), what works and what is unverified, plus
|
||||||
|
photos and the PCB silkscreen marking.
|
||||||
|
3. If the board shares a PCB with other revisions, follow
|
||||||
|
`doc/devices/KP-9000-6XH-X2.md` and document which `MACHINE` to pick for
|
||||||
|
which silkscreen.
|
||||||
|
|
||||||
|
### Identifying the CPU variant
|
||||||
|
|
||||||
|
For RTL8373-based devices, use the read-only console command below to distinguish
|
||||||
|
the N and non-N CPU variants:
|
||||||
|
|
||||||
|
```text
|
||||||
|
regget 4
|
||||||
|
```
|
||||||
|
|
||||||
|
| Register 0x0004 value | CPU |
|
||||||
|
|---|---|
|
||||||
|
| `0x83730000` | RTL8373 (non-N) |
|
||||||
|
| `0x83737000` | RTL8373N |
|
||||||
|
|
||||||
|
Record the identified CPU in the device documentation. These values identify
|
||||||
|
only the CPU variant; document PHY and flash-chip models separately when verified.
|
||||||
|
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
hongyavision HYWS-SGT0204S
|
||||||
|
|
||||||
|
RTL8372-based 4×2.5G + 2×SFP+ unmanaged switch.
|
||||||
|
|
||||||
|
Also marked on the PCB as `2G5F4_10G2_V1.01`.
|
||||||
|
|
||||||
|
Stock firmware runs a factory test console on UART at 9600 baud 8N1 (banner
|
||||||
|
`RTL8371B start`, prompt `RTL8371B:`). There is no management CLI and no Web
|
||||||
|
interface.
|
||||||
|
|
||||||
|
Using SPI clamp in-board is the only method for initial installation and update.
|
||||||
|
Erase the whole chip and verify the write (`flashrom -v`) before powering the
|
||||||
|
board, so an incomplete write is caught before the board is powered up.
|
||||||
|
|
||||||
|
Stock flash chip is 512 KB (Bright Moon `T25S40`, 4 Mbit, SOP-8), which the
|
||||||
|
RTLPlayground image fills exactly.
|
||||||
|
|
||||||
|
### Label specifications
|
||||||
|
|
||||||
|
Case, top / front / nameplate:
|
||||||
|
|
||||||
|
<img src="photos/2G5F4_10G2_V1.01/assembled-top.jpg" width="300" />
|
||||||
|
<img src="photos/2G5F4_10G2_V1.01/assembled-front.jpg" width="300" />
|
||||||
|
<img src="photos/2G5F4_10G2_V1.01/assembled-bottom.jpg" width="300" />
|
||||||
|
|
||||||
|
- **Manufacturer**: hongyavision (Shenzhen Hongyavision Electronic Technology
|
||||||
|
Co., Ltd.)
|
||||||
|
- **Model**: HYWS-SGT0204S — the nameplate is printed in Chinese and reads
|
||||||
|
"10/100/1000/2500M fibre switch" and "4x 2.5G copper port + 2x 10G SFP+
|
||||||
|
optical port"
|
||||||
|
- **Ports**:
|
||||||
|
- 4 × RJ45: 10/100/1000/2500 Mbps
|
||||||
|
- 2 × SFP+: 1G / 2.5G / 10G
|
||||||
|
- **Power**: 12 V DC, 2 A
|
||||||
|
- **Serial number**: `S/N-YYYYMMDDNNNN`, e.g. `S/N-202312010028`
|
||||||
|
|
||||||
|
The top of the case only carries generic printing ("2.5G+10G High Speed Fiber
|
||||||
|
Transceiver / 4-Port 2.5G Ethernet Switch+10G Fiber"), so the nameplate on the
|
||||||
|
bottom is what identifies the device.
|
||||||
|
|
||||||
|
### What works
|
||||||
|
|
||||||
|
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
||||||
|
- Both SFP+ ports supporting 1G, 2.5G and 10G modules
|
||||||
|
- Copper LEDs: white (2.5G) and blue (link/activity)
|
||||||
|
- SFP LEDs: one single LED per port (link/activity)
|
||||||
|
- SFP EEPROM and DDM readable on both cages, verified with a 10G module
|
||||||
|
(`Rate: 0x67`, module identity and DDM values via the `sfp` console command)
|
||||||
|
- Serial console at 115200 8N1 (RTLPlayground) / 9600 8N1 (stock)
|
||||||
|
|
||||||
|
### Not verified
|
||||||
|
|
||||||
|
- The reset button footprint is unpopulated and the case has no opening for it,
|
||||||
|
so it could not be tested.
|
||||||
|
|
||||||
|
### PCB overview
|
||||||
|
|
||||||
|
**Board markings**
|
||||||
|
- Top silkscreen: `2G5F4_10G2_V1.01`
|
||||||
|
|
||||||
|
**Key components**
|
||||||
|
- Main switch: RTL8372 (RTL8371B family), reported as `RTL8372` (non-N) by
|
||||||
|
RTLPlayground. The chip sits under a heatsink and its package marking is not
|
||||||
|
readable.
|
||||||
|
- U1: SPI NOR flash, Bright Moon `T25S40`, 4 Mbit / 512 KB, SOP-8
|
||||||
|
- A 3-hole reset button footprint is present but unpopulated, and the case has
|
||||||
|
no opening for it, so there is no usable reset button
|
||||||
|
|
||||||
|
Top side:
|
||||||
|
|
||||||
|
<img src="photos/2G5F4_10G2_V1.01/pcb_top.jpg" width="600" />
|
||||||
|
|
||||||
|
Bottom:
|
||||||
|
|
||||||
|
<img src="photos/2G5F4_10G2_V1.01/pcb_bottom.jpg" width="600" />
|
||||||
|
|
||||||
|
The stock flash chip, Bright Moon `T25S40` (SOP-8, 4 Mbit / 512 KB):
|
||||||
|
|
||||||
|
<img src="photos/2G5F4_10G2_V1.01/flash_t25s40.jpg" width="300" />
|
||||||
|
|
||||||
|
### Port layout
|
||||||
|
|
||||||
|
| Front panel position | Logical port | Physical port | Type |
|
||||||
|
|----------------------|--------------|---------------|---------|
|
||||||
|
| SFP left | 8 | 5 | SFP+ |
|
||||||
|
| RJ45 1 | 4 | 1 | Copper |
|
||||||
|
| RJ45 2 | 5 | 2 | Copper |
|
||||||
|
| RJ45 3 | 6 | 3 | Copper |
|
||||||
|
| RJ45 4 | 7 | 4 | Copper |
|
||||||
|
| SFP right | 3 | 6 | SFP+ |
|
||||||
|
|
||||||
|
Copper ports 1–4 match the KP-9000-6XH-X2 (2M-PCB43-V1.1) layout, which this
|
||||||
|
board is a sibling of. The two SFP+ cages are wired the other way round
|
||||||
|
compared to that board: physical port 5 is on SDS1 and physical port 6 is on
|
||||||
|
SDS0.
|
||||||
|
|
||||||
|
### Serial console
|
||||||
|
|
||||||
|
The board has three through-holes used as the serial console, next to the
|
||||||
|
heatsink in the middle of the board and visible in the top side photo above (the
|
||||||
|
silkscreen labels are printed rotated by 90°). **The silkscreen labels are
|
||||||
|
wrong**: they are shifted relative to the actual signals.
|
||||||
|
|
||||||
|
| Silkscreen label | Actual signal |
|
||||||
|
|------------------|---------------|
|
||||||
|
| TX | GND |
|
||||||
|
| RX | TX |
|
||||||
|
| GND | RX |
|
||||||
|
|
||||||
|
Wiring (following the measured signals, not the labels):
|
||||||
|
|
||||||
|
| USB-TTL adapter | Board pad |
|
||||||
|
|-----------------|----------------------|
|
||||||
|
| GND | pad labelled `TX` |
|
||||||
|
| RX | pad labelled `RX` |
|
||||||
|
| TX | pad labelled `GND` |
|
||||||
|
|
||||||
|
- **Settings**: 115200 baud / 8N1 / 3.3V TTL (RTLPlayground), 9600 baud for the
|
||||||
|
stock firmware
|
||||||
|
- The stock firmware only prints a few bytes and a factory test menu
|
||||||
|
(`?`, `rst`, `f`, `r`, `10`, `100`, `g1`, `sd`, `eye`, …); it is not an
|
||||||
|
interactive management console
|
||||||
|
|
||||||
|
### LED configuration
|
||||||
|
|
||||||
|
Case silkscreen, below the RJ45 ports:
|
||||||
|
|
||||||
|
```
|
||||||
|
White : 2.5G Blue : 1000M/2500M L/A
|
||||||
|
```
|
||||||
|
|
||||||
|
The front panel also carries a `PWR` LED and one LED per SFP cage (`SFP1`,
|
||||||
|
`SFP2`) on the right hand side.
|
||||||
|
|
||||||
|
| Port | LED | Linked, idle | With traffic |
|
||||||
|
|------------|--------------|--------------|--------------|
|
||||||
|
| Copper | white | 2.5G only | same |
|
||||||
|
| Copper | blue | solid | blinks (L/A) |
|
||||||
|
| SFP | single LED | solid | blinks (L/A) |
|
||||||
|
|
||||||
|
Measured LED-ID mapping (from the RTL837x LED set registers):
|
||||||
|
|
||||||
|
| LED-ID | Function |
|
||||||
|
|--------|---------------------------------|
|
||||||
|
| LED-ID0| copper blue LED |
|
||||||
|
| LED-ID1| copper white LED |
|
||||||
|
| LED-ID2| SFP single LED |
|
||||||
|
|
||||||
|
**Important**: `RTL837X_REG_LED_GLB_IO_EN` bit 6 must be set in
|
||||||
|
`machine_custom_init()`. Without it the RTL837x "solid" conditions (LINK/speed)
|
||||||
|
do not drive the LEDs at all and only `ACT` does, which makes the white LED
|
||||||
|
glow faintly at non-2.5G speeds.
|
||||||
|
|
||||||
|
### SFP GPIO assignments
|
||||||
|
|
||||||
|
| SFP | pin\_detect (ModAbs) | pin\_los | SerDes | I2C SDA | I2C SCL |
|
||||||
|
|-------------------|-------------------------------|------------------|--------|-------------------------|--------------------------|
|
||||||
|
| Left (logical 8, physical 5) | GPIO30\_ACL\_BIT3\_EN | GPIO37 | SDS1 | GPIO39\_I2C\_SDA4 | GPIO40\_I2C\_SCL3\_MDC1 |
|
||||||
|
| Right (logical 3, physical 6)| GPIO50\_I2C\_SCL2\_UART1\_TX | GPIO10\_LED10 | SDS0 | GPIO41\_I2C\_SDA3\_MDIO1 | GPIO40\_I2C\_SCL3\_MDC1 |
|
||||||
|
|
||||||
|
`pin_tx_disable` is GPIO\_NA on both ports. Both I2C buses are confirmed
|
||||||
|
working: with the same 10G module inserted, the `sfp` console command reads its
|
||||||
|
vendor and model from the left cage (`Slot 1`) and from the right cage
|
||||||
|
(`Slot 2`), DDM values included. The insertion also shows which SerDes drives
|
||||||
|
each cage - the left cage reports `sds_config sds: 01` and the right cage
|
||||||
|
`sds: 00`, which matches the table above.
|
||||||
|
|
||||||
|
### Machine target
|
||||||
|
|
||||||
|
Build for this device with `make MACHINE=2G5F4_10G2_V1_01`, which selects the
|
||||||
|
`machine/2G5F4_10G2_V1_01.c` board definition. It is derived from
|
||||||
|
`machine/KP_9000_6XHML_X2.c` with the SFP cage order and the reset pin changed.
|
||||||
|
The fitted T25S40 cannot be read in DIO mode on this board: an image that leaves
|
||||||
|
DIO enabled does not come up at all, both at the default read clock divider of 4
|
||||||
|
and at 8 (two boards tested), while the same image with single-IO boots and runs
|
||||||
|
normally. The board definition therefore sets `flash_sio`, which makes
|
||||||
|
`flash_init()` use `CMD_FREAD` at divider 8. Only the management plane is
|
||||||
|
slower, the ASIC keeps forwarding in hardware.
|
||||||
@@ -17,8 +17,8 @@ The original web interface reports this board as hardware version V3.2
|
|||||||
The component placement matches [2M-PCB23-V3.1](2M-PCB23-V3_1.md): same
|
The component placement matches [2M-PCB23-V3.1](2M-PCB23-V3_1.md): same
|
||||||
positions for the flash (U8), the T7/T8/T9/T10 headers, the SFP cage and its
|
positions for the flash (U8), the T7/T8/T9/T10 headers, the SFP cage and its
|
||||||
LED, and the unpopulated U7/U9 footprints. Build with
|
LED, and the unpopulated U7/U9 footprints. Build with
|
||||||
`MACHINE=KP_9000_9XHML_X_V3_2`, which uses the V3.1 machine definition and
|
`make MACHINE=KP_9000_9XHML_X_V3_2`, whose board file is a symlink to the V3.1
|
||||||
only differs in the reported name.
|
definition and only differs in the reported name.
|
||||||
|
|
||||||
## Tested
|
## Tested
|
||||||
|
|
||||||
|
|||||||
@@ -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_V1_1 in machine.h if building yourself or the corresponding pre-compiled binary)
|
- LEDs work with the same indiciations as the OEM firmware (build with `make MACHINE=KP_9000_6XHML_X2_V1_1` if building yourself, or use 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
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# Hasivo S1100P-8GT-1SX-S
|
||||||
|
|
||||||
|
RTL8373N switch with 8 × 2.5G RJ45 ports and 1 × SFP port. GD25Q16 2 MiB flash.
|
||||||
|
|
||||||
|
## Port mapping
|
||||||
|
|
||||||
|
| Front port | ASIC MAC | Interface |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 1–8 | 0–7 | RJ45 |
|
||||||
|
| 9 | 8 | SFP (SDS1) |
|
||||||
|
|
||||||
|
## Board signals
|
||||||
|
|
||||||
|
| Function | GPIO |
|
||||||
|
| --- | --- |
|
||||||
|
| SFP detect | 38 |
|
||||||
|
| SFP LOS | 37 |
|
||||||
|
| SFP TX disable | Not connected (`GPIO_NA`) |
|
||||||
|
| SFP I2C SDA / SCL | 39 / 40 |
|
||||||
|
| Reset | 54 |
|
||||||
|
|
||||||
|
PoE is managed by an RTL8238B and a separate STC8H8K64U controller, not directly by the RTL8373N. RTLPlayground does not control PoE on this board.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
`make MACHINE=HASIVO_S1100P_8GT_1SX_S CI=1`
|
||||||
|
|
||||||
|
## Photos
|
||||||
|
|
||||||
|
Front panel:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
PCB top:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
PCB bottom:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
@@ -90,6 +90,8 @@ Custom mapping for ONT-S207CW-62TS-SE:
|
|||||||
## Flashing Instructions
|
## Flashing Instructions
|
||||||
|
|
||||||
See the [README.md](../../README.md) for general flashing instructions.
|
See the [README.md](../../README.md) for general flashing instructions.
|
||||||
|
For compilation, use command `make MACHINE=ONT_S207CW_62TS_SE` to specify the machine.
|
||||||
|
If you are using managed version of the switch, you can then also compile the installer and flash using GUI - run command `cd installer` and finally `make`.
|
||||||
|
|
||||||
## Stock Firmware Information
|
## Stock Firmware Information
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
# PCB-K0402WS-V1.0
|
||||||
|
|
||||||
|
This is the first revision of the PCB-K0402WS series of boards; it's very similar to 2.0 in terms of layout/wiring.
|
||||||
|
|
||||||
|
The board does have footprints for a VLAN modeswitch at the front and a second flash chip on the bottom of the PCB, but these have been seen to ship unpopulated.
|
||||||
|
|
||||||
|
### Brands
|
||||||
|
|
||||||
|
* YuanLey YS25-0402 <sup><sub>Note: there are [multiple revisions](PCB-K0402WS-V3.0.md) of the YS25-0402. This first revision lacks the "Vlan" switch cutout on the front of the enclosure.</sub></sup>
|
||||||
|
|
||||||
|
### Programming
|
||||||
|
|
||||||
|
Use a SOIC-8 clamp to the flash chip (U1 on silkscreen) at the top of the board, leaving it otherwise unpowered.
|
||||||
|
|
||||||
|
The board has been seen to ship with a single [BoyaMicro BY25Q16BSSIG](https://www.lcsc.com/datasheet/C382744.pdf) 16Mbit (2MiB) chip, though exact BOM may vary.
|
||||||
|
|
||||||
|
<a href="photos/PCB-K0402WS-V1.0/flash.jpg"><img src="photos/PCB-K0402WS-V1.0/flash.jpg" width="300" /></a>
|
||||||
|
|
||||||
|
### What works
|
||||||
|
|
||||||
|
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
||||||
|
- Both SFP ports supporting 1G, 2.5G and 10G modules
|
||||||
|
- LEDs (Power LED is always on)
|
||||||
|
|
||||||
|
### PCB overview
|
||||||
|
|
||||||
|
#### Board markings
|
||||||
|
- Top silkscreen: PCB-K0402W-V1.0 / DIP-K0402WS-V1.0
|
||||||
|
|
||||||
|
#### Key components
|
||||||
|
- U1: SPI NOR flash, 2 MiB
|
||||||
|
- S1: unpopulated slide switch footprint (three through-holes used as serial console)
|
||||||
|
|
||||||
|
Front panel
|
||||||
|
|
||||||
|
<a href="photos/PCB-K0402WS-V1.0/ports.jpg"><img src="photos/PCB-K0402WS-V1.0/ports.jpg" width="300" /></a>
|
||||||
|
|
||||||
|
PCB top
|
||||||
|
|
||||||
|
<a href="photos/PCB-K0402WS-V1.0/pcb-top.jpg"><img src="photos/PCB-K0402WS-V1.0/pcb-top.jpg" width="300" /></a>
|
||||||
|
|
||||||
|
PCB bottom
|
||||||
|
|
||||||
|
<a href="photos/PCB-K0402WS-V1.0/pcb-bottom.jpg"><img src="photos/PCB-K0402WS-V1.0/pcb-bottom.jpg" width="300" /></a>
|
||||||
|
|
||||||
|
Bottom and rear
|
||||||
|
|
||||||
|
<a href="photos/PCB-K0402WS-V1.0/bottom.jpg"><img src="photos/PCB-K0402WS-V1.0/bottom.jpg" width="300" /></a>
|
||||||
|
|
||||||
|
### Power supply
|
||||||
|
|
||||||
|
Input power is delivered via a standard DC barrel jack (5.5x2.1mm) with an included 12V 1A adapter.
|
||||||
|
|
||||||
|
There is an optional grounding screw next to the DC input.
|
||||||
|
|
||||||
|
### Serial console
|
||||||
|
|
||||||
|
The PCB has a slide switch footprint (unpopulated) at the front right that is connected to the UART. It is labeled as "S1" on the silkscreen.
|
||||||
|
|
||||||
|
Facing the top front (port) side of the board, the pinout from left to right is:
|
||||||
|
|
||||||
|
| Position | Signal | GPIO |
|
||||||
|
|----------|--------|-------------------|
|
||||||
|
| 1 | RX | GPIO32\_UART0\_RX |
|
||||||
|
| 2 | GND | N/A |
|
||||||
|
| 3 | TX | GPIO31\_UART0\_TX |
|
||||||
|
|
||||||
|
Standard 0.1" / 2.54mm pin headers will not fit, so wires or clips may be used instead.
|
||||||
|
|
||||||
|
The image below shows some oversized clips clumsily attached.
|
||||||
|
|
||||||
|
<a href="photos/PCB-K0402WS-V1.0/uart.jpg"><img src="photos/PCB-K0402WS-V1.0/uart.jpg" width="300" /></a>
|
||||||
@@ -19,9 +19,14 @@ of the device just above the big label, might be covered by a QC sticker.
|
|||||||
|
|
||||||
<img src="photos/PCB-K0402WS-V3.0/Ztyuav_Z-QWYT0402_label.jpg" width="300" />
|
<img src="photos/PCB-K0402WS-V3.0/Ztyuav_Z-QWYT0402_label.jpg" width="300" />
|
||||||
|
|
||||||
* Siscolink SL-G0402F
|
* SICSOLINK SL-G0402F
|
||||||
|
|
||||||
|
<img src="photos/PCB-K0402WS-V3.0/SICSOLINK SL-G0402F.jpg" width="300"/>
|
||||||
|
|
||||||
|
* YuanLey YS25-0402 <sup><sub>Note: there are [multiple revisions](PCB-K0402WS-V1.0.md) of the YS25-0402. This is the newer revision that has a "Vlan" switch on the front.</sub></sup>
|
||||||
|
|
||||||
|
<img src="photos/PCB-K0402WS-V3.0/YuanLey_YS25-0402.jpg" width="300"/>
|
||||||
|
|
||||||
<img src="photos/PCB-K0402WS-V3.0/Siscolink SL-G0402F.jpg" width="300"/>
|
|
||||||
### Programming
|
### Programming
|
||||||
|
|
||||||
Using SPI clamp in-board is the only method for initial installation.
|
Using SPI clamp in-board is the only method for initial installation.
|
||||||
@@ -43,7 +48,7 @@ For the initial flash (at least with flashrom), the bin file produced by the bui
|
|||||||
### PCB overview
|
### PCB overview
|
||||||
|
|
||||||
**Board markings**
|
**Board markings**
|
||||||
- Top silkscreen: PCB-KO4022W-V3.0 / DIP-KO4022WS-V3.0
|
- Top silkscreen: PCB-K0402W-V3.0 / DIP-K0402WS-V3.0
|
||||||
|
|
||||||
Top side
|
Top side
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
### SIRIVISION_S25G2206FP_V1_1
|
||||||
|
|
||||||
|
## Brands
|
||||||
|
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| YuanLey | YS25-0402M | Yes | SIRIVISION_S25G2206FP_V1_1 | 2M | 8372 |
|
||||||
|
|
||||||
|
### Label specifications
|
||||||
|
|
||||||
|
- **Name**:
|
||||||
|
- **Ports**:
|
||||||
|
- 4 × RJ45: 10/100/1000/2500 Mbps
|
||||||
|
- 2 × SFP+: 1000 / 2500 / 10000 Mbps
|
||||||
|
- **Power**: 12V DC, 1A 5525 connector
|
||||||
|
|
||||||
|
### What works
|
||||||
|
The device is fully supported:
|
||||||
|
- ALL 2.5GBASE-T RJ45 ports work at 10/100/1000/2500 Mbps
|
||||||
|
- ALL SFP+ ports support 1G, 2.5G and 10G modules
|
||||||
|
- LEDs work with the same indiciations as the OEM firmware
|
||||||
|
### PCB overview
|
||||||
|
|
||||||
|
**Board markings**
|
||||||
|
- Top silkscreen: SIRIVISION S25G2206FP V1.1
|
||||||
|
|
||||||
|
Top side
|
||||||
|
|
||||||
|
<img src="photos/SIRIVISION_S25G2206FP_V1_1/dev_pcb_top.jpg" width="300" />
|
||||||
|
|
||||||
|
## Power supply
|
||||||
|
|
||||||
|
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
||||||
@@ -4,7 +4,8 @@
|
|||||||
|---------|------------------|-------|------------------|-----------------|---------------|
|
|---------|------------------|-------|------------------|-----------------|---------------|
|
||||||
| Ampcom | SWTG018AS-A V2.0 | No | SWTG018AS-A V2.0 | 2MB | 8273N + 8224N |
|
| Ampcom | SWTG018AS-A V2.0 | No | SWTG018AS-A V2.0 | 2MB | 8273N + 8224N |
|
||||||
| Horaco | HC-SWTGW218AS-A | Yes | SWTG018AS-A V2.0 | 2MB(25Q16JVSIQ) | 8273N + 8224N |
|
| Horaco | HC-SWTGW218AS-A | Yes | SWTG018AS-A V2.0 | 2MB(25Q16JVSIQ) | 8273N + 8224N |
|
||||||
| GoodTop | GT-ST018M | Yes | SWTG018AS-A V2.0 | ? | 8273N + 8224N |
|
| GoodTop | GT-ST018M | Yes | SWTG018AS-A V2.0 | 2MB | 8273N + 8224N |
|
||||||
|
| MokerLink | 2G08110GSN | No | SWTG018AS-A V2.0 | 512KB(25Q40) | 8273N + 8224N |
|
||||||
|
|
||||||
|
|
||||||
The following is a documentation for the unmanaged switch marked as `SWTG018AS-A V2.0`.
|
The following is a documentation for the unmanaged switch marked as `SWTG018AS-A V2.0`.
|
||||||
@@ -14,7 +15,7 @@ The original software is running UART on 9600 baud rate.
|
|||||||
|
|
||||||
Using a SOIC clamp in-board is the only method for initial installation.
|
Using a SOIC clamp in-board is the only method for initial installation.
|
||||||
|
|
||||||
The board has a single flash chips `BS` with 4M-bit size. The front switch, switches between the two flash chips.
|
The board has a single flash chips `BS` with 2M-byte size. The front switch, switches between the two flash chips.
|
||||||
These can be programed independently by using said switch - so it is e.g. possible to run the original and new firmware in parallel.
|
These can be programed independently by using said switch - so it is e.g. possible to run the original and new firmware in parallel.
|
||||||
|
|
||||||
### Label specifications
|
### Label specifications
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
It is highly similar to SWTG024AS-V2.0, with the only difference being the GPIO configuration for the SFP port.
|
It is highly similar to SWTG024AS-V2.0, with the only difference being the GPIO configuration for the SFP port.
|
||||||
|
|
||||||
## Brands
|
## Brands
|
||||||
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
|Brand |Type |Managed|PCB |Flash |Chip RTL|
|
||||||
|---|---|---|---|---|---|
|
|---------|--------------|-------|------------------------------|----------------|--------|
|
||||||
| Horaco | ZX-SG4T2 | | PCB-SWTG024AS-A-V2.0.1_19650 | P25D40SH | ??? |
|
| Horaco | ZX-SG4T2 | No | PCB-SWTG024AS-A-V2.0.1_19650 | 512K (P25D40SH)| 8372N |
|
||||||
|
| Horaco | HC-SWTG124AS | Yes | PCB-SWTG024AS-A-V2.0.1 | 2M (W25Q16JV)| 8372N |
|
||||||
|
| GoodTop | GT-ST024M | Yes | PCB-SWTG024AS-A-V2.0.1 | 2M | 8372N |
|
||||||
|
|
||||||
### Label specifications
|
### Label specifications
|
||||||
|
|
||||||
|
|||||||
@@ -46,4 +46,4 @@ Note,`R52`、`R53`may not be installed.You need to bridge them using either sold
|
|||||||
|
|
||||||
## 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.
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
## RTLPlayground target
|
## RTLPlayground target
|
||||||
|
|
||||||
Use machine target `MACHINE_LIANGUO_ZX_SWTGW215AS` for this device.
|
Build for this device with `make MACHINE=LIANGUO_ZX_SWTGW215AS`, which selects the `machine/LIANGUO_ZX_SWTGW215AS.c` board definition.
|
||||||
|
|
||||||
Physical hardware verification: 5x RJ45 ports + 1x SFP port.
|
Physical hardware verification: 5x RJ45 ports + 1x SFP port.
|
||||||
Port 5 RJ45 is interfaced through a RTL8221B IC.
|
Port 5 RJ45 is interfaced through a RTL8221B IC.
|
||||||
|
|||||||
@@ -5,9 +5,15 @@
|
|||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| Mokerlink | ZX-SWTGW218AS | Yes| SWTG118AS-V2.0-16029 | 2MB (FM25Q16A)| 8273N + 8224N |
|
| Mokerlink | ZX-SWTGW218AS | Yes| SWTG118AS-V2.0-16029 | 2MB (FM25Q16A)| 8273N + 8224N |
|
||||||
| Sodola | | | | | |
|
| Sodola | | | | | |
|
||||||
| Horaco | | | | | |
|
| Horaco | HC-SWTGW218AS | Yes | SWTG118AS-V2.1 | 2MB | 8373 (non-N) |
|
||||||
| XikeStor | SKS3200-8E1X | Yes | SWTG118AS-V2.1-17462 | 2MB (25Q16JVSIQ) | |
|
| XikeStor | SKS3200-8E1X | Yes | SWTG118AS-V2.1-17462 | 2MB (25Q16JVSIQ) | |
|
||||||
|
|
||||||
|
All boards in this table use `MACHINE=SWTGW218AS`. The Horaco HC-SWTGW218AS is also sold with the
|
||||||
|
[SWTG018AS-A V2.0](SWTG018AS_A_V2_0.md) board, which needs a different firmware. Check the marking
|
||||||
|
on the PCB before flashing.
|
||||||
|
|
||||||
|
The PHY and flash-chip models for the tested Horaco units remain unverified.
|
||||||
|
|
||||||
|
|
||||||
## Photos
|
## Photos
|
||||||
|
|
||||||
|
|||||||
|
After Width: | Height: | Size: 254 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 234 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 434 KiB |
|
After Width: | Height: | Size: 565 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 308 KiB |
|
After Width: | Height: | Size: 262 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 944 KiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 229 KiB |
|
After Width: | Height: | Size: 804 KiB |
|
After Width: | Height: | Size: 1.7 MiB |
@@ -4,44 +4,52 @@ The following devices have been tested and are fully working:
|
|||||||
| Brand | Type | Managed | PCB | Flash | Ports |
|
| Brand | Type | Managed | PCB | Flash | Ports |
|
||||||
|----------|-----------------|---------|---------------------------------------------------------------------------|-------|-------|
|
|----------|-----------------|---------|---------------------------------------------------------------------------|-------|-------|
|
||||||
| Ampcom | WAM902-SWTG018AS| No | [SWTG018AS-A V2.0](devices/SWTG018AS_A_V2_0.md) | | 8 + 1 |
|
| Ampcom | WAM902-SWTG018AS| No | [SWTG018AS-A V2.0](devices/SWTG018AS_A_V2_0.md) | | 8 + 1 |
|
||||||
|
| Binardat | 2G06-04210GSM | No | [PCB-SWTG024AS-A-2.0.1](devices/ONT-S207CW-62TS-SE.md) | 0.5M | 4 + 2 |
|
||||||
| Davuaz | Da-K6501W | No | [PCB-K0501W-V2.0](devices/K0501W_V2_0.md) | | 5 + 1 |
|
| Davuaz | Da-K6501W | No | [PCB-K0501W-V2.0](devices/K0501W_V2_0.md) | | 5 + 1 |
|
||||||
| FOXNEO | FNS-1200P | No | [PCB-K0402W-U13-V2.0](devices/FNS-1200P.md) | 2M | 4 + 2 |
|
| FOXNEO | FNS-1200P | No | [PCB-K0402W-U13-V2.0](devices/FNS-1200P.md) | 2M | 4 + 2 |
|
||||||
| Goalake | IG108 | No | [PB-2132](devices/PB-2132.md) | 4M | 8 + 1 |
|
| Goalake | IG108 | No | [PB-2132](devices/PB-2132.md) | 4M | 8 + 1 |
|
||||||
| GoodTop | GT-ST018M | Yes | [SWTG018AS-A V2.0](devices/SWTG018AS_A_V2_0.md) | ? | 8 + 1 |
|
| GoodTop | GT-ST018M | Yes | [SWTG018AS-A V2.0](devices/SWTG018AS_A_V2_0.md) | 2M | 8 + 1 |
|
||||||
|
| GoodTop | GT-ST024M | Yes | [SWTG024AS-A V2.0.1](devices/SWTG024AS-A-V2.0.1_4C_2SFP.md) | 2M | 4 + 2 |
|
||||||
|
| Guangnianwei | 7018-2.5G | No | [F7008-2.5GPOE-V1.2](devices/F7008-2.5.md) | 8M | 8 + 1 |
|
||||||
| Hasivo | S1100WP_8GT_1SX_SE | Yes | [S1100WP_8GT_1SX_SE-V1.05](devices/HASIVO_S1100WP_8GT_1SX_SE.md) | 2M | 8 + 1 |
|
| Hasivo | S1100WP_8GT_1SX_SE | Yes | [S1100WP_8GT_1SX_SE-V1.05](devices/HASIVO_S1100WP_8GT_1SX_SE.md) | 2M | 8 + 1 |
|
||||||
| Hisource | Hi-K0402WS | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
|
|
||||||
| Hisource | Hi-K0402WS | No | [PCB-K0402WS-V2.0](devices/PCB-K0402WS-V2.0.md) | 2M | 4 + 2 |
|
| Hisource | Hi-K0402WS | No | [PCB-K0402WS-V2.0](devices/PCB-K0402WS-V2.0.md) | 2M | 4 + 2 |
|
||||||
|
| Hisource | Hi-K0402WS | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
|
||||||
| Hisource | Hi-K0801WS | No | [PCB-KO801W-V2.0](devices/HI-K0801WS.md) | | 8 + 1 |
|
| Hisource | Hi-K0801WS | No | [PCB-KO801W-V2.0](devices/HI-K0801WS.md) | | 8 + 1 |
|
||||||
|
| hongyavision | HYWS-SGT0204S | No | [2G5F4_10G2_V1.01](devices/2G5F4_10G2_V1.01.md) | 0.5M | 4 + 2 |
|
||||||
| hongyavision | LG-SG5T1 | No | [PCB-SWTG024AS-V2.0_16895](devices/SWTG024AS-V2.0.md) | 0.5M | 5 + 1 |
|
| hongyavision | LG-SG5T1 | No | [PCB-SWTG024AS-V2.0_16895](devices/SWTG024AS-V2.0.md) | 0.5M | 5 + 1 |
|
||||||
|
| Horaco | HC-SWTG124AS | Yes | [SWTG024AS-A-V2.0.1](devices/SWTG024AS-A-V2.0.1_4C_2SFP.md) | 2M | 4 + 2 |
|
||||||
| Horaco | HC-SWTGW215AS | Yes | [SWTG024AS-A-V2.0.1_19650 5C 1SFP](devices/SWTG024AS-A-V2.0.1_5C_1SFP.md) | ? | 5 + 1 |
|
| Horaco | HC-SWTGW215AS | Yes | [SWTG024AS-A-V2.0.1_19650 5C 1SFP](devices/SWTG024AS-A-V2.0.1_5C_1SFP.md) | ? | 5 + 1 |
|
||||||
| Horaco | HC-SWTGW218AS | Yes | [SWTG018AS-A V2.0](devices/SWTG018AS_A_V2_0.md) | | 8 + 1 |
|
| Horaco | HC-SWTGW218AS | Yes | [SWTG018AS-A V2.0](devices/SWTG018AS_A_V2_0.md) | | 8 + 1 |
|
||||||
|
| Horaco | HC-SWTGW218AS | Yes | [SWTG118AS-V2.1](devices/SWTGW218AS.md) | 2M | 8 + 1 |
|
||||||
| Horaco | ZX310S-4T2XH | Yes | [PCB-SL310S-4T1T1X-V1.0.1-24107](devices/ZX310S-4T2XH.md) | 2M | 5 + 1 |
|
| Horaco | ZX310S-4T2XH | Yes | [PCB-SL310S-4T1T1X-V1.0.1-24107](devices/ZX310S-4T2XH.md) | 2M | 5 + 1 |
|
||||||
| 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 / KP-9000-6XHML-X2 | No/Yes | [2M-PCB43-V1.2 / 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 |
|
||||||
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V3.2](devices/2M-PCB23-V3_2.md) | 2M | 8 + 1 |
|
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V3.2](devices/2M-PCB23-V3_2.md) | 2M | 8 + 1 |
|
||||||
|
| LIANGUO | HYWS-SGT0108S | No | [2G5F_20G_V1.01](devices/HYWS-SGT0108S.md) | 0.5M | 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 / PCB-SWTG115AS-V2.1](devices/SWTGW215AS.md) | 2M | 5 + 1 |
|
| LIANGUO | ZX-SWTGW215AS | Yes | [PCB-SWTG115AS-V2.0 / PCB-SWTG115AS-V2.1](devices/SWTGW215AS.md) | 2M | 5 + 1 |
|
||||||
| Lianguo | HYWS-SGT0108S | No | [2G5F_20G_V1.01](devices/HYWS-SGT0108S.md) | 0.5M | 8 + 1 |
|
| MokerLink| 2G040210GSM | Yes | [2M-PCB43-V1.1](devices/2M-PCB43-V1.1.md) | | 4 + 2 |
|
||||||
| 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| POE-2G080110GS | No | [2M-PCB51-ML-V1.1](devices/2M-PCB51-ML-V1_1.md) | 4M | 8 + 1 |
|
| MokerLink| POE-2G080110GS | No | [2M-PCB51-ML-V1.1](devices/2M-PCB51-ML-V1_1.md) | 4M | 8 + 1 |
|
||||||
| Binardat | 2G06-04210GSM | No | [PCB-SWTG024AS-A-2.0.1](devices/ONT-S207CW-62TS-SE.md) | 0.5M | 4 + 2 |
|
| MokerLink| ZX-SWTGW218AS | Yes | [SWTG118AS-V2.0-16029](devices/SWTGW218AS.md) | 2M | 8 + 1 |
|
||||||
| ONT | ONT-S207CW-62TS-SE | No | [PCB-SWTG024AS-A-2.0.1](devices/ONT-S207CW-62TS-SE.md) | 0.5M | 4 + 2 |
|
| MokerLink| 2G08110GSN | No | [SWTG018AS-A V2.0](devices/SWTG018AS_A_V2_0.md) | 0.5M | 8 + 1 |
|
||||||
| Netcore | GS9 | No | [PB-2132](devices/PB-2132.md) | 4M | 8 + 1 |
|
| Netcore | GS9 | No | [PB-2132](devices/PB-2132.md) | 4M | 8 + 1 |
|
||||||
|
| ONT | ONT-S207CW-62TS-SE | No | [PCB-SWTG024AS-A-2.0.1](devices/ONT-S207CW-62TS-SE.md) | 0.5M | 4 + 2 |
|
||||||
| 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 |
|
||||||
| Ruiying | RY-8GT-1SX | No | [FG-8GT-1SX](devices/FG-8GT-1SX.md) | 1M | 8 + 1 |
|
| Ruiying | RY-8GT-1SX | No | [FG-8GT-1SX](devices/FG-8GT-1SX.md) | 1M | 8 + 1 |
|
||||||
| SiscoLink | SL-G0402F | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
|
| SICSOLINK| SL-G0402F | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | | 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 |
|
||||||
| Steamemo | IG204-V1 | No | [PB-2131](devices/STEAMEMO_IG204_V1.md) | | 4 + 2 |
|
| Steamemo | IG204-V1 | No | [PB-2131](devices/STEAMEMO_IG204_V1.md) | | 4 + 2 |
|
||||||
| TrendNet | TEG-S562 | No | [TEG-S563/EU H/W: V1.0R](devices/TEG-S562.md) | 2M | 4 + 2 |
|
| TRENDnet | TEG-S562 | No | [TEG-S563/EU H/W: V1.0R](devices/TEG-S562.md) | 2M | 4 + 2 |
|
||||||
| Xikestore| SKS3200M-4GPY2XF| Yes | [SWTG024AS-v1.0](devices/SWTG024AS.md) | | 4 + 2 |
|
| XikeStor | SKS3200M-4GPY2XF| Yes | [SWTG024AS-v1.0](devices/SWTG024AS.md) | | 4 + 2 |
|
||||||
| 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 |
|
||||||
|
| YuanLey | YS25-0402 | No | [PCB-K0402WS-V1.0](devices/PCB-K0402WS-V1.0.md) | 2M | 4 + 2 |
|
||||||
|
| YuanLey | YS25-0402 | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | 2M | 4 + 2 |
|
||||||
|
| YuanLey | YS25-0402M | Yes | [SIRIVISION_S25G2206FP_V1_1](devices/SIRIVISION_S25G2206FP_V1_1.md) | 2M | 4 + 2 |
|
||||||
| 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 |
|
||||||
| Guangnianwei | 7018-2.5G | No | [F7008-2.5GPOE-V1.2](devices/F7008-2.5.md) | 8M | 8 + 1 |
|
|
||||||
|
|
||||||
For KP-9000-6XH-X2 / KP-9000-6XHML-X2 / Mokerlink 2G040210GSM devices, select
|
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
|
the machine target by PCB revision. The ML/non-ML or managed/unmanaged label
|
||||||
|
|||||||
@@ -11,15 +11,15 @@ th_sel_light:"Selenized Light",th_sel_dark:"Selenized Dark",
|
|||||||
c_port:"Port",c_name:"Name",c_link:"Link",c_apply:"Apply",c_cancel:"Cancel",c_confirm:"Confirm",
|
c_port:"Port",c_name:"Name",c_link:"Link",c_apply:"Apply",c_cancel:"Cancel",c_confirm:"Confirm",
|
||||||
c_close:"Close",c_refresh:"Refresh",c_off:"off",c_offc:"Off",c_down:"down",c_on:"On",c_auto:"Auto",c_delete:"Delete",
|
c_close:"Close",c_refresh:"Refresh",c_off:"off",c_offc:"Off",c_down:"down",c_on:"On",c_auto:"Auto",c_delete:"Delete",
|
||||||
c_type:"Type",c_state:"State",c_enabled:"Enabled",c_load:"Load",c_disable:"Disable",c_sfp:"SFP",
|
c_type:"Type",c_state:"State",c_enabled:"Enabled",c_load:"Load",c_disable:"Disable",c_sfp:"SFP",
|
||||||
c_full:"full",c_half:"half",c_devices:"devices",c_yes:"yes",c_no:"no",
|
c_full:"full",c_half:"half",c_yes:"yes",c_no:"no",
|
||||||
d_ports:"Ports",d_ports_h:"click a port for details",d_system:"System",d_traffic:"Traffic",
|
d_system:"System",d_traffic:"Traffic",
|
||||||
d_traffic_h:"packets/s, live",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX bad",d_rxbad:"RX bad",
|
d_traffic_h:"packets/s, live",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX bad",d_rxbad:"RX bad",
|
||||||
i_host:"Hostname",i_ip:"IP address",i_mask:"Netmask",i_gw:"Gateway",i_mac:"MAC",i_fw:"Firmware",
|
i_host:"Hostname",i_ip:"IP address",i_mask:"Netmask",i_gw:"Gateway",i_mac:"MAC",i_fw:"Firmware",
|
||||||
i_built:"Built",i_hw:"Hardware",i_temp:"Temperature",i_flash:"Flash",i_syslog:"Syslog",
|
i_built:"Built",i_hw:"Hardware",i_temp:"Temperature",i_flash:"Flash",i_syslog:"Syslog",
|
||||||
p_state:"State",p_disabled:"disabled",p_up:"up",p_txgb:"TX good / bad",p_rxgb:"RX good / bad",
|
p_state:"State",p_disabled:"disabled",p_up:"up",p_txgb:"TX good / bad",p_rxgb:"RX good / bad",
|
||||||
p_pkts:"pkts",p_module:"Module",p_temp:"Temperature",p_vcc:"Vcc",p_txbias:"TX bias",p_txpower:"TX power",
|
p_pkts:"pkts",p_module:"Module",p_temp:"Temperature",p_vcc:"Vcc",p_txbias:"TX bias",p_txpower:"TX power",
|
||||||
p_rxpower:"RX power",p_txfault:"TX fault",p_txdis:"TX disabled",p_rxlos:"RX LOS",p_adv:"Advertising",
|
p_rxpower:"RX power",p_txfault:"TX fault",p_txdis:"TX disabled",p_rxlos:"RX LOS",p_adv:"Advertising",
|
||||||
pt_title:"Port configuration",pt_conn:"Connected",pt_speed:"Speed",pt_mtu:"MTU",
|
pt_title:"Port configuration",pt_conn:"Devices learned",pt_speed:"Speed",pt_mtu:"MTU",
|
||||||
pt_sfp_note:"SFP speed is set per slot and is not saved in the startup config.",
|
pt_sfp_note:"SFP speed is set per slot and is not saved in the startup config.",
|
||||||
pt_name_err:"Port name: 1-15 characters, no spaces",pt_mtu_err:"MTU must be 64-16383",
|
pt_name_err:"Port name: 1-15 characters, no spaces",pt_mtu_err:"MTU must be 64-16383",
|
||||||
stp_title:"Spanning tree",stp_h:"RSTP, 802.1w",stp_version:"Version",stp_v_stp:"STP compatible",
|
stp_title:"Spanning tree",stp_h:"RSTP, 802.1w",stp_version:"Version",stp_v_stp:"STP compatible",
|
||||||
@@ -142,15 +142,15 @@ th_sel_light:"Selenized ライト",th_sel_dark:"Selenized ダーク",
|
|||||||
c_port:"ポート",c_name:"名前",c_link:"リンク",c_apply:"適用",c_cancel:"キャンセル",c_confirm:"確認",
|
c_port:"ポート",c_name:"名前",c_link:"リンク",c_apply:"適用",c_cancel:"キャンセル",c_confirm:"確認",
|
||||||
c_close:"閉じる",c_refresh:"更新",c_off:"オフ",c_offc:"オフ",c_down:"リンクダウン",c_on:"オン",c_auto:"自動",c_delete:"削除",
|
c_close:"閉じる",c_refresh:"更新",c_off:"オフ",c_offc:"オフ",c_down:"リンクダウン",c_on:"オン",c_auto:"自動",c_delete:"削除",
|
||||||
c_type:"タイプ",c_state:"状態",c_enabled:"有効",c_load:"読み込み",c_disable:"無効化",c_sfp:"SFP",
|
c_type:"タイプ",c_state:"状態",c_enabled:"有効",c_load:"読み込み",c_disable:"無効化",c_sfp:"SFP",
|
||||||
c_full:"全二重",c_half:"半二重",c_devices:"デバイス",c_yes:"はい",c_no:"いいえ",
|
c_full:"全二重",c_half:"半二重",c_yes:"はい",c_no:"いいえ",
|
||||||
d_ports:"ポート",d_ports_h:"ポートをクリックすると詳細を表示",d_system:"システム",d_traffic:"トラフィック",
|
d_system:"システム",d_traffic:"トラフィック",
|
||||||
d_traffic_h:"パケット/秒、リアルタイム",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX 異常",d_rxbad:"RX 異常",
|
d_traffic_h:"パケット/秒、リアルタイム",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX 異常",d_rxbad:"RX 異常",
|
||||||
i_host:"ホスト名",i_ip:"IP アドレス",i_mask:"ネットマスク",i_gw:"ゲートウェイ",i_mac:"MAC",i_fw:"ファームウェア",
|
i_host:"ホスト名",i_ip:"IP アドレス",i_mask:"ネットマスク",i_gw:"ゲートウェイ",i_mac:"MAC",i_fw:"ファームウェア",
|
||||||
i_built:"ビルド日",i_hw:"ハードウェア",i_temp:"温度",i_flash:"フラッシュ",i_syslog:"Syslog",
|
i_built:"ビルド日",i_hw:"ハードウェア",i_temp:"温度",i_flash:"フラッシュ",i_syslog:"Syslog",
|
||||||
p_state:"状態",p_disabled:"無効",p_up:"アップ",p_txgb:"TX 正常 / 異常",p_rxgb:"RX 正常 / 異常",
|
p_state:"状態",p_disabled:"無効",p_up:"アップ",p_txgb:"TX 正常 / 異常",p_rxgb:"RX 正常 / 異常",
|
||||||
p_pkts:"pkts",p_module:"モジュール",p_temp:"温度",p_vcc:"電圧",p_txbias:"TX バイアス",p_txpower:"TX 電力",
|
p_pkts:"pkts",p_module:"モジュール",p_temp:"温度",p_vcc:"電圧",p_txbias:"TX バイアス",p_txpower:"TX 電力",
|
||||||
p_rxpower:"RX 電力",p_txfault:"TX 障害",p_txdis:"TX 無効",p_rxlos:"RX 信号ロス",p_adv:"アドバタイズ",
|
p_rxpower:"RX 電力",p_txfault:"TX 障害",p_txdis:"TX 無効",p_rxlos:"RX 信号ロス",p_adv:"アドバタイズ",
|
||||||
pt_title:"ポート設定",pt_conn:"接続デバイス",pt_speed:"速度",pt_mtu:"MTU",
|
pt_title:"ポート設定",pt_conn:"学習済みデバイス",pt_speed:"速度",pt_mtu:"MTU",
|
||||||
pt_sfp_note:"SFP の速度はスロット単位で設定され、起動設定には保存されません。",
|
pt_sfp_note:"SFP の速度はスロット単位で設定され、起動設定には保存されません。",
|
||||||
pt_name_err:"ポート名: 1〜15 文字、空白不可",pt_mtu_err:"MTU は 64〜16383 の範囲で指定してください",
|
pt_name_err:"ポート名: 1〜15 文字、空白不可",pt_mtu_err:"MTU は 64〜16383 の範囲で指定してください",
|
||||||
stp_title:"スパニングツリー",stp_h:"RSTP, 802.1w",stp_version:"バージョン",stp_v_stp:"STP 互換",
|
stp_title:"スパニングツリー",stp_h:"RSTP, 802.1w",stp_version:"バージョン",stp_v_stp:"STP 互換",
|
||||||
@@ -255,15 +255,15 @@ th_sel_light:"Selenized 浅色",th_sel_dark:"Selenized 深色",
|
|||||||
c_port:"端口",c_name:"名称",c_link:"链路",c_apply:"应用",c_cancel:"取消",c_confirm:"确认",
|
c_port:"端口",c_name:"名称",c_link:"链路",c_apply:"应用",c_cancel:"取消",c_confirm:"确认",
|
||||||
c_close:"关闭",c_refresh:"刷新",c_off:"关",c_offc:"关",c_down:"未连接",c_on:"开",c_auto:"自动",c_delete:"删除",
|
c_close:"关闭",c_refresh:"刷新",c_off:"关",c_offc:"关",c_down:"未连接",c_on:"开",c_auto:"自动",c_delete:"删除",
|
||||||
c_type:"类型",c_state:"状态",c_enabled:"启用",c_load:"读取",c_disable:"禁用",c_sfp:"SFP",
|
c_type:"类型",c_state:"状态",c_enabled:"启用",c_load:"读取",c_disable:"禁用",c_sfp:"SFP",
|
||||||
c_full:"全双工",c_half:"半双工",c_devices:"台设备",c_yes:"是",c_no:"否",
|
c_full:"全双工",c_half:"半双工",c_yes:"是",c_no:"否",
|
||||||
d_ports:"端口",d_ports_h:"点击端口查看详情",d_system:"系统",d_traffic:"流量",
|
d_system:"系统",d_traffic:"流量",
|
||||||
d_traffic_h:"包/秒,实时",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX 错误",d_rxbad:"RX 错误",
|
d_traffic_h:"包/秒,实时",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX 错误",d_rxbad:"RX 错误",
|
||||||
i_host:"主机名",i_ip:"IP 地址",i_mask:"子网掩码",i_gw:"网关",i_mac:"MAC",i_fw:"固件",
|
i_host:"主机名",i_ip:"IP 地址",i_mask:"子网掩码",i_gw:"网关",i_mac:"MAC",i_fw:"固件",
|
||||||
i_built:"构建日期",i_hw:"硬件",i_temp:"温度",i_flash:"Flash",i_syslog:"Syslog",
|
i_built:"构建日期",i_hw:"硬件",i_temp:"温度",i_flash:"Flash",i_syslog:"Syslog",
|
||||||
p_state:"状态",p_disabled:"已禁用",p_up:"已连接",p_txgb:"TX 正常 / 错误",p_rxgb:"RX 正常 / 错误",
|
p_state:"状态",p_disabled:"已禁用",p_up:"已连接",p_txgb:"TX 正常 / 错误",p_rxgb:"RX 正常 / 错误",
|
||||||
p_pkts:"个包",p_module:"模块",p_temp:"温度",p_vcc:"供电电压",p_txbias:"TX 偏置电流",p_txpower:"TX 光功率",
|
p_pkts:"个包",p_module:"模块",p_temp:"温度",p_vcc:"供电电压",p_txbias:"TX 偏置电流",p_txpower:"TX 光功率",
|
||||||
p_rxpower:"RX 光功率",p_txfault:"TX 故障",p_txdis:"TX 禁用",p_rxlos:"RX 信号丢失",p_adv:"通告能力",
|
p_rxpower:"RX 光功率",p_txfault:"TX 故障",p_txdis:"TX 禁用",p_rxlos:"RX 信号丢失",p_adv:"通告能力",
|
||||||
pt_title:"端口配置",pt_conn:"已连接设备",pt_speed:"速率",pt_mtu:"MTU",
|
pt_title:"端口配置",pt_conn:"已学习设备",pt_speed:"速率",pt_mtu:"MTU",
|
||||||
pt_sfp_note:"SFP 速率按插槽设置,不会保存到启动配置。",
|
pt_sfp_note:"SFP 速率按插槽设置,不会保存到启动配置。",
|
||||||
pt_name_err:"端口名称: 1-15 个字符,不能包含空格",pt_mtu_err:"MTU 范围为 64-16383",
|
pt_name_err:"端口名称: 1-15 个字符,不能包含空格",pt_mtu_err:"MTU 范围为 64-16383",
|
||||||
stp_title:"生成树",stp_h:"RSTP, 802.1w",stp_version:"版本",stp_v_stp:"STP 兼容",
|
stp_title:"生成树",stp_h:"RSTP, 802.1w",stp_version:"版本",stp_v_stp:"STP 兼容",
|
||||||
@@ -368,15 +368,15 @@ th_sel_light:"Selenized claro",th_sel_dark:"Selenized oscuro",
|
|||||||
c_port:"Puerto",c_name:"Nombre",c_link:"Enlace",c_apply:"Aplicar",c_cancel:"Cancelar",c_confirm:"Confirmar",
|
c_port:"Puerto",c_name:"Nombre",c_link:"Enlace",c_apply:"Aplicar",c_cancel:"Cancelar",c_confirm:"Confirmar",
|
||||||
c_close:"Cerrar",c_refresh:"Actualizar",c_off:"apagado",c_offc:"Apagado",c_down:"caído",c_on:"Encendido",c_auto:"Auto",c_delete:"Eliminar",
|
c_close:"Cerrar",c_refresh:"Actualizar",c_off:"apagado",c_offc:"Apagado",c_down:"caído",c_on:"Encendido",c_auto:"Auto",c_delete:"Eliminar",
|
||||||
c_type:"Tipo",c_state:"Estado",c_enabled:"Habilitado",c_load:"Cargar",c_disable:"Deshabilitar",c_sfp:"SFP",
|
c_type:"Tipo",c_state:"Estado",c_enabled:"Habilitado",c_load:"Cargar",c_disable:"Deshabilitar",c_sfp:"SFP",
|
||||||
c_full:"dúplex completo",c_half:"semidúplex",c_devices:"dispositivos",c_yes:"sí",c_no:"no",
|
c_full:"dúplex completo",c_half:"semidúplex",c_yes:"sí",c_no:"no",
|
||||||
d_ports:"Puertos",d_ports_h:"pulsa un puerto para ver detalles",d_system:"Sistema",d_traffic:"Tráfico",
|
d_system:"Sistema",d_traffic:"Tráfico",
|
||||||
d_traffic_h:"paquetes/s, en vivo",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX erróneos",d_rxbad:"RX erróneos",
|
d_traffic_h:"paquetes/s, en vivo",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX erróneos",d_rxbad:"RX erróneos",
|
||||||
i_host:"Nombre de host",i_ip:"Dirección IP",i_mask:"Máscara de red",i_gw:"Puerta de enlace",i_mac:"MAC",i_fw:"Firmware",
|
i_host:"Nombre de host",i_ip:"Dirección IP",i_mask:"Máscara de red",i_gw:"Puerta de enlace",i_mac:"MAC",i_fw:"Firmware",
|
||||||
i_built:"Compilado",i_hw:"Hardware",i_flash:"Flash",i_syslog:"Syslog",
|
i_built:"Compilado",i_hw:"Hardware",i_flash:"Flash",i_syslog:"Syslog",
|
||||||
p_state:"Estado",p_disabled:"deshabilitado",p_up:"activo",p_txgb:"TX correctos / erróneos",p_rxgb:"RX correctos / erróneos",
|
p_state:"Estado",p_disabled:"deshabilitado",p_up:"activo",p_txgb:"TX correctos / erróneos",p_rxgb:"RX correctos / erróneos",
|
||||||
p_pkts:"paquetes",p_module:"Módulo",p_temp:"Temperatura",p_vcc:"Vcc",p_txbias:"Polarización TX",p_txpower:"Potencia TX",
|
p_pkts:"paquetes",p_module:"Módulo",p_temp:"Temperatura",p_vcc:"Vcc",p_txbias:"Polarización TX",p_txpower:"Potencia TX",
|
||||||
p_rxpower:"Potencia RX",p_txfault:"Fallo TX",p_txdis:"TX deshabilitado",p_rxlos:"Pérdida RX (LOS)",p_adv:"Anunciado",
|
p_rxpower:"Potencia RX",p_txfault:"Fallo TX",p_txdis:"TX deshabilitado",p_rxlos:"Pérdida RX (LOS)",p_adv:"Anunciado",
|
||||||
pt_title:"Configuración de puerto",pt_conn:"Conectado",pt_speed:"Velocidad",pt_mtu:"MTU",
|
pt_title:"Configuración de puerto",pt_conn:"Dispositivos aprendidos",pt_speed:"Velocidad",pt_mtu:"MTU",
|
||||||
pt_sfp_note:"La velocidad del SFP se ajusta por ranura y no se guarda en la configuración de inicio.",
|
pt_sfp_note:"La velocidad del SFP se ajusta por ranura y no se guarda en la configuración de inicio.",
|
||||||
pt_name_err:"Nombre de puerto: 1-15 caracteres, sin espacios",pt_mtu_err:"El MTU debe estar entre 64 y 16383",
|
pt_name_err:"Nombre de puerto: 1-15 caracteres, sin espacios",pt_mtu_err:"El MTU debe estar entre 64 y 16383",
|
||||||
stp_title:"Árbol de expansión",stp_h:"RSTP, 802.1w",stp_version:"Versión",stp_v_stp:"STP compatible",
|
stp_title:"Árbol de expansión",stp_h:"RSTP, 802.1w",stp_version:"Versión",stp_v_stp:"STP compatible",
|
||||||
@@ -480,15 +480,15 @@ th_sel_light:"Clair (sélénisé)",th_sel_dark:"Sombre (sélénisé)",
|
|||||||
c_port:"Port",c_name:"Nom",c_link:"Lien",c_apply:"Appliquer",c_cancel:"Annuler",c_confirm:"Confirmer",
|
c_port:"Port",c_name:"Nom",c_link:"Lien",c_apply:"Appliquer",c_cancel:"Annuler",c_confirm:"Confirmer",
|
||||||
c_close:"Fermer",c_refresh:"Raffraichir",c_off:"arrêt",c_offc:"Arrêt",c_down:"arrêt",c_on:"Marche",c_auto:"Auto",c_delete:"Supprimer",
|
c_close:"Fermer",c_refresh:"Raffraichir",c_off:"arrêt",c_offc:"Arrêt",c_down:"arrêt",c_on:"Marche",c_auto:"Auto",c_delete:"Supprimer",
|
||||||
c_type:"Type",c_state:"Etat",c_enabled:"Activé",c_load:"Charger",c_disable:"Désactivé",c_sfp:"SFP",
|
c_type:"Type",c_state:"Etat",c_enabled:"Activé",c_load:"Charger",c_disable:"Désactivé",c_sfp:"SFP",
|
||||||
c_full:"full",c_half:"half",c_devices:"Equipements",c_yes:"oui",c_no:"non",
|
c_full:"full",c_half:"half",c_yes:"oui",c_no:"non",
|
||||||
d_ports:"Ports",d_ports_h:"Cliquez ou survollez pour plus de détails",d_system:"Système",d_traffic:"Trafic",
|
d_system:"Système",d_traffic:"Trafic",
|
||||||
d_traffic_h:"paquets/s (en direct)",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX KO",d_rxbad:"RX KO",
|
d_traffic_h:"paquets/s (en direct)",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX KO",d_rxbad:"RX KO",
|
||||||
i_host:"Nom d'hote",i_ip:"Adresse IP",i_mask:"Masque réseau",i_gw:"Passerelle",i_mac:"Adresse MAC",i_fw:"Micro logiciel",
|
i_host:"Nom d'hote",i_ip:"Adresse IP",i_mask:"Masque réseau",i_gw:"Passerelle",i_mac:"Adresse MAC",i_fw:"Micro logiciel",
|
||||||
i_built:"Compilé le",i_hw:"Matériel",i_temp:"Température",i_flash:"Taille Flash",i_syslog:"Journal système",
|
i_built:"Compilé le",i_hw:"Matériel",i_temp:"Température",i_flash:"Taille Flash",i_syslog:"Journal système",
|
||||||
p_state:"Etat",p_disabled:"Inactif",p_up:"Actif",p_txgb:"TX bon / mauvais",p_rxgb:"RX bon / mauvais",
|
p_state:"Etat",p_disabled:"Inactif",p_up:"Actif",p_txgb:"TX bon / mauvais",p_rxgb:"RX bon / mauvais",
|
||||||
p_pkts:"paquets",p_module:"Module",p_temp:"Température",p_vcc:"Vcc",p_txbias:"TX biais",p_txpower:"TX puissance",
|
p_pkts:"paquets",p_module:"Module",p_temp:"Température",p_vcc:"Vcc",p_txbias:"TX biais",p_txpower:"TX puissance",
|
||||||
p_rxpower:"RX puissance",p_txfault:"TX erreur",p_txdis:"TX désactivé",p_rxlos:"RX pertes de signaux",p_adv:"Capacités",
|
p_rxpower:"RX puissance",p_txfault:"TX erreur",p_txdis:"TX désactivé",p_rxlos:"RX pertes de signaux",p_adv:"Capacités",
|
||||||
pt_title:"Configuration du port",pt_conn:"Connecté à",pt_speed:"Vitesse",pt_mtu:"MTU",
|
pt_title:"Configuration du port",pt_conn:"Appareils appris",pt_speed:"Vitesse",pt_mtu:"MTU",
|
||||||
pt_sfp_note:"La vitesse SFP est paramétrée pour le port et n'est pas enregistrée dans la configuration de démarrage.",
|
pt_sfp_note:"La vitesse SFP est paramétrée pour le port et n'est pas enregistrée dans la configuration de démarrage.",
|
||||||
pt_name_err:"Nom du port: 1 à 15 caractères, sans espaces",pt_mtu_err:"MTU doit être comrpis entre 64 et 16383",
|
pt_name_err:"Nom du port: 1 à 15 caractères, sans espaces",pt_mtu_err:"MTU doit être comrpis entre 64 et 16383",
|
||||||
stp_title:"Arborescence",stp_h:"RSTP, 802.1w",stp_version:"Protocole",stp_v_stp:"Compatible STP",
|
stp_title:"Arborescence",stp_h:"RSTP, 802.1w",stp_version:"Protocole",stp_v_stp:"Compatible STP",
|
||||||
@@ -588,7 +588,7 @@ fw_timeout:"Le commutateur n'est plus joignable depuis 150 s: verifiez l'aliment
|
|||||||
},
|
},
|
||||||
de:{
|
de:{
|
||||||
nav_dash:"Übersicht",nav_ports:"Ports",nav_stp:"Spanning Tree",nav_stats:"Statistik",
|
nav_dash:"Übersicht",nav_ports:"Ports",nav_stp:"Spanning Tree",nav_stats:"Statistik",
|
||||||
nav_vlan:"VLANs",nav_l2:"MAC-Tabelle",nav_mirror:"Spiegelung",nav_lag:"LAG",nav_eee:"EEE",
|
nav_vlan:"VLANs",nav_l2:"MAC-Tabelle",nav_mirror:"Spiegelung",nav_isolate:"Isolation",nav_lag:"LAG",nav_eee:"EEE",
|
||||||
nav_bw:"Bandbreite",nav_system:"System",nav_fw:"Firmware",
|
nav_bw:"Bandbreite",nav_system:"System",nav_fw:"Firmware",
|
||||||
hdr_dirty:"ungespeicherte Änderungen",hdr_dirty_t:"Laufende Konfiguration weicht von der Startkonfiguration ab",
|
hdr_dirty:"ungespeicherte Änderungen",hdr_dirty_t:"Laufende Konfiguration weicht von der Startkonfiguration ab",
|
||||||
hdr_save:"Im Flash speichern",hdr_save_t:"Laufende Konfiguration dauerhaft im Flash speichern",
|
hdr_save:"Im Flash speichern",hdr_save_t:"Laufende Konfiguration dauerhaft im Flash speichern",
|
||||||
@@ -597,15 +597,15 @@ th_sel_light:"Selenized Hell",th_sel_dark:"Selenized Dunkel",
|
|||||||
c_port:"Port",c_name:"Name",c_link:"Link",c_apply:"Übernehmen",c_cancel:"Abbrechen",c_confirm:"Bestätigen",
|
c_port:"Port",c_name:"Name",c_link:"Link",c_apply:"Übernehmen",c_cancel:"Abbrechen",c_confirm:"Bestätigen",
|
||||||
c_close:"Schliessen",c_refresh:"Aktualisieren",c_off:"aus",c_offc:"Aus",c_down:"getrennt",c_on:"Ein",c_auto:"Auto",c_delete:"Löschen",
|
c_close:"Schliessen",c_refresh:"Aktualisieren",c_off:"aus",c_offc:"Aus",c_down:"getrennt",c_on:"Ein",c_auto:"Auto",c_delete:"Löschen",
|
||||||
c_type:"Typ",c_state:"Zustand",c_enabled:"Aktiviert",c_load:"Laden",c_disable:"Deaktivieren",c_sfp:"SFP",
|
c_type:"Typ",c_state:"Zustand",c_enabled:"Aktiviert",c_load:"Laden",c_disable:"Deaktivieren",c_sfp:"SFP",
|
||||||
c_full:"voll",c_half:"halb",c_devices:"Geräte",c_yes:"ja",c_no:"nein",
|
c_full:"voll",c_half:"halb",c_yes:"ja",c_no:"nein",
|
||||||
d_ports:"Ports",d_ports_h:"Port anklicken für Details",d_system:"System",d_traffic:"Datenverkehr",
|
d_system:"System",d_traffic:"Datenverkehr",
|
||||||
d_traffic_h:"Pakete/s, live",d_txpps:"TX Pakete/s",d_rxpps:"RX Pakete/s",d_txbad:"TX fehlerhaft",d_rxbad:"RX fehlerhaft",
|
d_traffic_h:"Pakete/s, live",d_txpps:"TX Pakete/s",d_rxpps:"RX Pakete/s",d_txbad:"TX fehlerhaft",d_rxbad:"RX fehlerhaft",
|
||||||
i_host:"Hostname",i_ip:"IP-Adresse",i_mask:"Netzmaske",i_gw:"Gateway",i_mac:"MAC",i_fw:"Firmware",
|
i_host:"Hostname",i_ip:"IP-Adresse",i_mask:"Netzmaske",i_gw:"Gateway",i_mac:"MAC",i_fw:"Firmware",
|
||||||
i_built:"Erstellt",i_hw:"Hardware",i_temp:"Temperatur",i_flash:"Flash",i_syslog:"Syslog",
|
i_built:"Erstellt",i_hw:"Hardware",i_temp:"Temperatur",i_flash:"Flash",i_syslog:"Syslog",
|
||||||
p_state:"Zustand",p_disabled:"deaktiviert",p_up:"verbunden",p_txgb:"TX gut / fehlerhaft",p_rxgb:"RX gut / fehlerhaft",
|
p_state:"Zustand",p_disabled:"deaktiviert",p_up:"verbunden",p_txgb:"TX gut / fehlerhaft",p_rxgb:"RX gut / fehlerhaft",
|
||||||
p_pkts:"Pakete",p_module:"Modul",p_temp:"Temperatur",p_vcc:"Vcc",p_txbias:"TX-Bias",p_txpower:"Sendeleistung",
|
p_pkts:"Pakete",p_module:"Modul",p_temp:"Temperatur",p_vcc:"Vcc",p_txbias:"TX-Bias",p_txpower:"Sendeleistung",
|
||||||
p_rxpower:"Empfangsleistung",p_txfault:"TX-Fehler",p_txdis:"TX deaktiviert",p_rxlos:"RX LOS",p_adv:"Angeboten",
|
p_rxpower:"Empfangsleistung",p_txfault:"TX-Fehler",p_txdis:"TX deaktiviert",p_rxlos:"RX LOS",p_adv:"Angeboten",
|
||||||
pt_title:"Port-Konfiguration",pt_conn:"Verbunden",pt_speed:"Geschwindigkeit",pt_mtu:"MTU",
|
pt_title:"Port-Konfiguration",pt_conn:"Gelernte Geräte",pt_speed:"Geschwindigkeit",pt_mtu:"MTU",
|
||||||
pt_sfp_note:"Die SFP-Geschwindigkeit wird pro Steckplatz gesetzt und nicht in der Startkonfiguration gespeichert.",
|
pt_sfp_note:"Die SFP-Geschwindigkeit wird pro Steckplatz gesetzt und nicht in der Startkonfiguration gespeichert.",
|
||||||
pt_name_err:"Port-Name: 1-15 Zeichen, keine Leerzeichen",pt_mtu_err:"MTU muss zwischen 64 und 16383 liegen",
|
pt_name_err:"Port-Name: 1-15 Zeichen, keine Leerzeichen",pt_mtu_err:"MTU muss zwischen 64 und 16383 liegen",
|
||||||
stp_title:"Spanning Tree",stp_h:"RSTP, 802.1w",stp_version:"Version",stp_v_stp:"STP-kompatibel",
|
stp_title:"Spanning Tree",stp_h:"RSTP, 802.1w",stp_version:"Version",stp_v_stp:"STP-kompatibel",
|
||||||
@@ -626,6 +626,7 @@ stp_en_q:"Spanning Tree aktivieren?",
|
|||||||
stp_en_d:"Die Ports starten blockiert und brauchen bis zum doppelten Forward Delay, bis sie weiterleiten; Edge-Ports sind sofort wieder aktiv.",
|
stp_en_d:"Die Ports starten blockiert und brauchen bis zum doppelten Forward Delay, bis sie weiterleiten; Edge-Ports sind sofort wieder aktiv.",
|
||||||
stp_dis_q:"Spanning Tree deaktivieren?",stp_dis_d:"Alle Ports leiten sofort weiter; der Schutz vor Netzwerkschleifen entfällt.",
|
stp_dis_q:"Spanning Tree deaktivieren?",stp_dis_d:"Alle Ports leiten sofort weiter; der Schutz vor Netzwerkschleifen entfällt.",
|
||||||
stp_cost_err:"Pfadkosten müssen zwischen 0 und 200000000 liegen",
|
stp_cost_err:"Pfadkosten müssen zwischen 0 und 200000000 liegen",
|
||||||
|
nav_lldp:"LLDP",lldp_enabled:"LLDP aktiv",lldp_title:"Dienststatus",lldp_portname:"Name",lldp_enable:"Pakete senden",
|
||||||
st_title:"Port-Statistik",st_h:"Summen seit dem Start",st_txg:"TX gut",st_txb:"TX fehlerhaft",st_rxg:"RX gut",
|
st_title:"Port-Statistik",st_h:"Summen seit dem Start",st_txg:"TX gut",st_txb:"TX fehlerhaft",st_rxg:"RX gut",
|
||||||
st_rxb:"RX fehlerhaft",st_details:"Details",st_counters:"MIB-Zähler",st_nonzero:"nur ungleich null",
|
st_rxb:"RX fehlerhaft",st_details:"Details",st_counters:"MIB-Zähler",st_nonzero:"nur ungleich null",
|
||||||
st_autoref:"automatisch aktualisieren",st_counter:"Zähler",st_value:"Wert",st_fail:"Zähler konnten nicht geladen werden",
|
st_autoref:"automatisch aktualisieren",st_counter:"Zähler",st_value:"Wert",st_fail:"Zähler konnten nicht geladen werden",
|
||||||
@@ -648,8 +649,12 @@ l2_learned:"gelernt",l2_loading:"lädt...",l2_failed:"Laden fehlgeschlagen",l2_e
|
|||||||
l2_del_t:"Eintrag löschen",l2_flush_q:"Alle gelernten MAC-Einträge löschen?",
|
l2_del_t:"Eintrag löschen",l2_flush_q:"Alle gelernten MAC-Einträge löschen?",
|
||||||
m_title:"Port-Spiegelung",m_active:"aktiv",m_monitor:"Monitor-Port",m_mirror:"Spiegeln",m_both:"Beide",
|
m_title:"Port-Spiegelung",m_active:"aktiv",m_monitor:"Monitor-Port",m_mirror:"Spiegeln",m_both:"Beide",
|
||||||
m_note:"Beide = RX und TX des Ports auf den Monitor-Port spiegeln.",m_none:"Mindestens einen zu spiegelnden Port wählen",
|
m_note:"Beide = RX und TX des Ports auf den Monitor-Port spiegeln.",m_none:"Mindestens einen zu spiegelnden Port wählen",
|
||||||
|
iso_title:"Port-Isolation",iso_from:"Von Port",iso_to:"Zu Port",iso_all:"Alle erlauben",
|
||||||
|
iso_intro:"Ein Paket, das über einen Port hereinkommt, darf den Switch nur über die Ports verlassen, die in seiner Zeile angehakt sind. Die Isolation wirkt vor der Weiterleitung: Ein nicht angehakter Port ist direkt nicht erreichbar, egal was in der MAC-Tabelle steht.",
|
||||||
|
iso_legend:"Das Feld des Ports selbst ist immer erlaubt. Eine rote Portnummer markiert einen Port, der nicht ganz offen ist.",
|
||||||
lag_hash:"Hash:",lag_note:"Eine LAG braucht mindestens ein Mitglied, um in der Startkonfiguration gespeichert zu werden; eine leere Gruppe zu übernehmen löscht sie.",
|
lag_hash:"Hash:",lag_note:"Eine LAG braucht mindestens ein Mitglied, um in der Startkonfiguration gespeichert zu werden; eine leere Gruppe zu übernehmen löscht sie.",
|
||||||
lag_clear_q:"LAG {n} auflösen?",lag_clear_d:"Alle Mitglieds-Ports kehren in den Normalbetrieb zurück.",
|
lag_clear_q:"LAG {n} auflösen?",lag_clear_d:"Alle Mitglieds-Ports kehren in den Normalbetrieb zurück.",
|
||||||
|
lacp_heading:"LACP (802.3ad)",lag_mode:"Modus",lag_static:"Statisch",lacp_neg:"wird ausgehandelt",lacp_agg:"Aggregator",lacp_members:"aktive Mitglieder",lacp_hint:"LACP: Ports auswählen und Übernehmen drücken, um die Aushandlung zu starten",lacp_actor:"Lokal",lacp_partner:"Partner",lacp_rxstate:"Empfangsstatus",lacp_rx:"Empfangene LACPDUs",lacp_psys:"Partner-System",
|
||||||
e_title:"Energy Efficient Ethernet",e_adv:"Angeboten",e_lp:"Gegenstelle",e_active:"Aktiv",e_enable:"Aktivieren",
|
e_title:"Energy Efficient Ethernet",e_adv:"Angeboten",e_lp:"Gegenstelle",e_active:"Aktiv",e_enable:"Aktivieren",
|
||||||
e_note:"Angebotene und von der Gegenstelle unterstützte Stufen je Geschwindigkeit: 100M, 1G, 2.5G. SFP-Ports unterstützen kein EEE.",
|
e_note:"Angebotene und von der Gegenstelle unterstützte Stufen je Geschwindigkeit: 100M, 1G, 2.5G. SFP-Ports unterstützen kein EEE.",
|
||||||
e_idle:"inaktiv",e_na:"k. A.",
|
e_idle:"inaktiv",e_na:"k. A.",
|
||||||
@@ -672,7 +677,8 @@ sy_ip_err:"Ungültige IP / Netzmaske / Gateway",sy_host_err:"Hostname: 1-23 druc
|
|||||||
sy_net_q:"Netzwerkeinstellungen übernehmen?",sy_net_d:"Die Management-IP ändert sich auf {ip}: Diese Seite muss dort neu geöffnet werden.",
|
sy_net_q:"Netzwerkeinstellungen übernehmen?",sy_net_d:"Die Management-IP ändert sich auf {ip}: Diese Seite muss dort neu geöffnet werden.",
|
||||||
sy_ip_changed:"IP geändert, neu verbinden unter http://{ip}/",sy_dhcp_q:"Auf DHCP umstellen?",
|
sy_ip_changed:"IP geändert, neu verbinden unter http://{ip}/",sy_dhcp_q:"Auf DHCP umstellen?",
|
||||||
sy_dhcp_d:"Der Switch bezieht seine Adresse per DHCP. Du musst seine neue IP herausfinden, um dich wieder zu verbinden.",
|
sy_dhcp_d:"Der Switch bezieht seine Adresse per DHCP. Du musst seine neue IP herausfinden, um dich wieder zu verbinden.",
|
||||||
sy_sysip_err:"Ungültige IP des Syslog-Servers",sy_sysport_err:"Syslog-Port muss zwischen 1 und 65535 liegen",
|
sy_sysip_err:"Ungültige IP des Syslog-Servers",sy_dns1:"DNS-Server",sy_dns2:"Zweiter DNS-Server",sy_dns_err:"Ungültige IP des DNS-Servers",sy_dns_dhcp:"von DHCP: {ip}",sy_sysport_err:"Syslog-Port muss zwischen 1 und 65535 liegen",
|
||||||
|
sy_time:"Uhrzeit",sy_ntp:"NTP",sy_ntpsrv:"NTP-Server",sy_ntpsrv_p:"Hostname oder IPv4-Adresse",sy_ntpint:"Abfrageintervall [min]",sy_tz:"Zeitzone",sy_dst:"Sommerzeit",sy_dst_eu:"Europa",sy_dst_us:"USA",sy_now:"Lokale Zeit",sy_sync:"Letzte Synchronisation",sy_ntpaddr:"Server-Adresse",sy_nosync:"nicht synchronisiert",sy_waiting:"warte auf den Server",sy_ago:"vor {n} min",sy_ntp_err:"Hostname oder IPv4-Adresse des NTP-Servers eingeben",sy_ntpint_err:"Abfrageintervall muss zwischen 1 und 1440 liegen",sy_time_note:"Der Switch hat keine batteriegepufferte Uhr: Die Zeit geht bei jedem Neustart verloren und wird neu vom NTP-Server bezogen, sobald das Netzwerk bereit ist. Im Flash speichern, damit die Einstellungen erhalten bleiben.",
|
||||||
sy_pw_len:"Passwort: 1-20 Zeichen",sy_pw_space:"Das Passwort darf keine Leerzeichen enthalten",sy_pw_match:"Die Passwörter stimmen nicht überein",
|
sy_pw_len:"Passwort: 1-20 Zeichen",sy_pw_space:"Das Passwort darf keine Leerzeichen enthalten",sy_pw_match:"Die Passwörter stimmen nicht überein",
|
||||||
sy_pw_q:"Admin-Passwort ändern?",sy_pw_d:"Gilt sofort für neue Anmeldungen. Im Flash speichern, damit es erhalten bleibt.",
|
sy_pw_q:"Admin-Passwort ändern?",sy_pw_d:"Gilt sofort für neue Anmeldungen. Im Flash speichern, damit es erhalten bleibt.",
|
||||||
sy_reboot_q:"Switch neu starten?",sy_reboot_d:"Es gibt UNGESPEICHERTE Änderungen, sie gehen verloren. Zuerst im Flash speichern, wenn du sie behalten willst.",
|
sy_reboot_q:"Switch neu starten?",sy_reboot_d:"Es gibt UNGESPEICHERTE Änderungen, sie gehen verloren. Zuerst im Flash speichern, wenn du sie behalten willst.",
|
||||||
@@ -958,6 +964,7 @@ function pollStatus(){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
var statusPoller=new Poller(pollStatus,2500);
|
var statusPoller=new Poller(pollStatus,2500);
|
||||||
|
statusPoller.start();
|
||||||
function needPorts(fn){
|
function needPorts(fn){
|
||||||
if(S.n)return fn();
|
if(S.n)return fn();
|
||||||
pollStatus().then(fn).catch(function(){});
|
pollStatus().then(fn).catch(function(){});
|
||||||
@@ -1102,8 +1109,7 @@ function dashStatus(){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
tabHooks.dash={
|
tabHooks.dash={
|
||||||
enter:function(){statusPoller.start();pollInfo().catch(function(){})},
|
enter:function(){pollInfo().catch(function(){})},
|
||||||
leave:function(){statusPoller.stop()},
|
|
||||||
status:dashStatus,
|
status:dashStatus,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1147,31 +1153,12 @@ function loadMtu(){
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/* One learned MAC is the attached device; several means a switch or AP
|
|
||||||
* sits behind the port, so only the count is shown. */
|
|
||||||
function portsMacs(){
|
|
||||||
l2Load().then(function(all){
|
|
||||||
var by={};
|
|
||||||
all.forEach(function(e){
|
|
||||||
if(e.pport==="CPU")return;
|
|
||||||
var l=by[e.pport]=by[e.pport]||[];
|
|
||||||
if(l.indexOf(e.mac)<0)l.push(e.mac);
|
|
||||||
});
|
|
||||||
S.ports.forEach(function(p){
|
|
||||||
var el=$("pmac"+(p.portNum-1));
|
|
||||||
if(!el)return;
|
|
||||||
var m=by[p.portNum]||[];
|
|
||||||
el.textContent=!m.length?"-":(m.length===1?m[0]:m.length+" "+t("c_devices"));
|
|
||||||
el.title=m.join("\n");
|
|
||||||
});
|
|
||||||
}).catch(function(){});
|
|
||||||
}
|
|
||||||
var _macTick=0;
|
|
||||||
function portsStatus(){
|
function portsStatus(){
|
||||||
buildPorts();
|
buildPorts();
|
||||||
if(++_macTick%10===0)portsMacs();
|
|
||||||
S.ports.forEach(function(p){
|
S.ports.forEach(function(p){
|
||||||
var i=p.portNum-1,el=$("plink"+i);
|
var i=p.portNum-1,el=$("plink"+i);
|
||||||
|
var mc=$("pmac"+i);
|
||||||
|
if(mc)mc.textContent=parseInt(p.macs,16)&0x1fff;
|
||||||
if(el)el.innerHTML=linkBadge(p);
|
if(el)el.innerHTML=linkBadge(p);
|
||||||
var sel=$("pspd"+i),v=p.isSFP?0:ADVSEL[parseInt(p.adv,2)];
|
var sel=$("pspd"+i),v=p.isSFP?0:ADVSEL[parseInt(p.adv,2)];
|
||||||
if(sel&&v&&document.activeElement!==sel)sel.value=v;
|
if(sel&&v&&document.activeElement!==sel)sel.value=v;
|
||||||
@@ -1199,8 +1186,7 @@ function applyPort(i){
|
|||||||
postCmds(cmds).then(loadMtu).catch(function(){});
|
postCmds(cmds).then(loadMtu).catch(function(){});
|
||||||
}
|
}
|
||||||
tabHooks.ports={
|
tabHooks.ports={
|
||||||
enter:function(){statusPoller.start();needPorts(function(){buildPorts();portsMacs()})},
|
enter:function(){needPorts(buildPorts)},
|
||||||
leave:function(){statusPoller.stop();l2Gen++},
|
|
||||||
status:portsStatus,
|
status:portsStatus,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1456,8 +1442,7 @@ function statsStatus(){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
tabHooks.stats={
|
tabHooks.stats={
|
||||||
enter:function(){statusPoller.start()},
|
leave:function(){if(ctrPoll)ctrPoll.stop()},
|
||||||
leave:function(){statusPoller.stop();if(ctrPoll)ctrPoll.stop()},
|
|
||||||
status:statsStatus,
|
status:statsStatus,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -55,11 +55,11 @@ a{color:var(--ac);text-decoration:none}
|
|||||||
#navfoot{padding:10px 16px;border-top:1px solid var(--bd);font-size:12px;color:var(--fg2)}
|
#navfoot{padding:10px 16px;border-top:1px solid var(--bd);font-size:12px;color:var(--fg2)}
|
||||||
#wrap{flex:1;min-width:0;display:flex;flex-direction:column}
|
#wrap{flex:1;min-width:0;display:flex;flex-direction:column}
|
||||||
#top{
|
#top{
|
||||||
display:flex;align-items:center;gap:10px;padding:10px 20px;
|
display:flex;align-items:center;flex-wrap:wrap;gap:10px;padding:8px 20px;
|
||||||
background:var(--panel);border-bottom:1px solid var(--bd);position:sticky;top:0;z-index:5;
|
background:var(--panel);border-bottom:1px solid var(--bd);position:sticky;top:0;z-index:5;
|
||||||
}
|
}
|
||||||
#burger{display:none;background:none;border:0;cursor:pointer;padding:4px}
|
#burger{display:none;background:none;border:0;cursor:pointer;padding:4px}
|
||||||
#ttitle{font-size:16px;font-weight:650;flex:1}
|
#ttitle{font-size:16px;font-weight:650;min-width:120px}
|
||||||
#dirty{
|
#dirty{
|
||||||
display:none;font-size:12px;font-weight:600;color:var(--warn);
|
display:none;font-size:12px;font-weight:600;color:var(--warn);
|
||||||
border:1px solid var(--warn);border-radius:20px;padding:2px 10px;
|
border:1px solid var(--warn);border-radius:20px;padding:2px 10px;
|
||||||
@@ -112,19 +112,21 @@ label.row span.lb{width:110px;flex:none;color:var(--fg2);font-size:13px}
|
|||||||
}
|
}
|
||||||
.switch input:checked+i{background:var(--ok)}
|
.switch input:checked+i{background:var(--ok)}
|
||||||
.switch input:checked+i:before{transform:translateX(15px)}
|
.switch input:checked+i:before{transform:translateX(15px)}
|
||||||
#strip{display:flex;gap:8px;flex-wrap:wrap;padding:4px 0 2px}
|
#strip{display:flex;gap:6px;flex:1;min-width:0;overflow-x:auto;scrollbar-width:thin}
|
||||||
|
.port:first-child{margin-left:auto}
|
||||||
|
.port:last-child{margin-right:auto}
|
||||||
.port{
|
.port{
|
||||||
width:46px;border:2px solid var(--bd);border-radius:7px;padding:5px 0 3px;
|
width:40px;border:2px solid var(--bd);border-radius:7px;padding:3px 0 2px;
|
||||||
text-align:center;cursor:pointer;background:var(--panel2);position:relative;
|
text-align:center;cursor:pointer;background:var(--panel2);position:relative;
|
||||||
}
|
}
|
||||||
.port.sfp{width:56px}
|
.port.sfp{width:50px}
|
||||||
.port .pn{font-weight:650;font-size:13px}
|
.port .pn{font-weight:650;font-size:12px}
|
||||||
.port .ps{font-size:10px;color:var(--fg2);display:block;line-height:1.2}
|
.port .ps{font-size:9px;color:var(--fg2);display:block;line-height:1.2}
|
||||||
.port .jack{
|
.port .jack{
|
||||||
display:block;width:18px;height:12px;margin:3px auto 2px;border-radius:2px;
|
display:block;width:16px;height:10px;margin:2px auto 1px;border-radius:2px;
|
||||||
border:2px solid var(--fg2);border-top-width:5px;opacity:.55;
|
border:2px solid var(--fg2);border-top-width:4px;opacity:.55;
|
||||||
}
|
}
|
||||||
.port.sfp .jack{width:28px;height:10px;border-top-width:3px}
|
.port.sfp .jack{width:24px;height:9px;border-top-width:3px}
|
||||||
.port.up{border-color:var(--pc);background:color-mix(in srgb,var(--pc) 10%,var(--panel2))}
|
.port.up{border-color:var(--pc);background:color-mix(in srgb,var(--pc) 10%,var(--panel2))}
|
||||||
.port.up .jack{border-color:var(--pc);opacity:1}
|
.port.up .jack{border-color:var(--pc);opacity:1}
|
||||||
.port.up .ps{color:var(--pc);font-weight:600}
|
.port.up .ps{color:var(--pc);font-weight:600}
|
||||||
@@ -183,6 +185,10 @@ button.danger{background:var(--bad);color:#fff;border-color:transparent}
|
|||||||
#ttitle{font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
#ttitle{font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||||||
#dirty{padding:2px 7px}
|
#dirty{padding:2px 7px}
|
||||||
}
|
}
|
||||||
|
@media (max-width:720px){
|
||||||
|
#ttitle{flex:1}
|
||||||
|
#strip{order:3;flex-basis:100%}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
(function(){
|
(function(){
|
||||||
@@ -215,15 +221,13 @@ button.danger{background:var(--bad);color:#fff;border-color:transparent}
|
|||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--fg)" stroke-width="2"><path d="M4 6h16M4 12h16M4 18h16"/></svg>
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--fg)" stroke-width="2"><path d="M4 6h16M4 12h16M4 18h16"/></svg>
|
||||||
</button>
|
</button>
|
||||||
<span id="ttitle"></span>
|
<span id="ttitle"></span>
|
||||||
|
<div id="strip"></div>
|
||||||
<span id="dirty" data-i18n="hdr_dirty" data-i18n-t="hdr_dirty_t">unsaved changes</span>
|
<span id="dirty" data-i18n="hdr_dirty" data-i18n-t="hdr_dirty_t">unsaved changes</span>
|
||||||
<button class="ctl pri" id="saveBtn" data-i18n="hdr_save" data-i18n-t="hdr_save_t">Save to flash</button>
|
<button class="ctl pri" id="saveBtn" data-i18n="hdr_save" data-i18n-t="hdr_save_t">Save to flash</button>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<section class="tab act" id="tab-dash">
|
<section class="tab act" id="tab-dash">
|
||||||
<div class="card"><h2><span data-i18n="d_ports">Ports</span> <span class="hint" data-i18n="d_ports_h">click a port for details</span></h2>
|
|
||||||
<div id="strip"></div>
|
|
||||||
</div>
|
|
||||||
<div class="grid2">
|
<div class="grid2">
|
||||||
<div class="card"><h2 data-i18n="d_system">System</h2><table class="t" id="sysinfo"></table></div>
|
<div class="card"><h2 data-i18n="d_system">System</h2><table class="t" id="sysinfo"></table></div>
|
||||||
<div class="card"><h2><span data-i18n="d_traffic">Traffic</span> <span class="hint" data-i18n="d_traffic_h">packets/s, live</span></h2>
|
<div class="card"><h2><span data-i18n="d_traffic">Traffic</span> <span class="hint" data-i18n="d_traffic_h">packets/s, live</span></h2>
|
||||||
@@ -237,7 +241,7 @@ button.danger{background:var(--bad);color:#fff;border-color:transparent}
|
|||||||
<section class="tab" id="tab-ports">
|
<section class="tab" id="tab-ports">
|
||||||
<div class="card"><h2 data-i18n="pt_title">Port configuration</h2>
|
<div class="card"><h2 data-i18n="pt_title">Port configuration</h2>
|
||||||
<div class="scrollx"><table class="t" id="ptable">
|
<div class="scrollx"><table class="t" id="ptable">
|
||||||
<thead><tr><th data-i18n="c_port">Port</th><th data-i18n="c_name">Name</th><th data-i18n="c_link">Link</th><th data-i18n="pt_conn">Connected</th><th data-i18n="pt_speed">Speed</th><th data-i18n="c_enabled">Enabled</th><th data-i18n="pt_mtu">MTU</th><th></th></tr></thead>
|
<thead><tr><th data-i18n="c_port">Port</th><th data-i18n="c_name">Name</th><th data-i18n="c_link">Link</th><th data-i18n="pt_conn">Devices learned</th><th data-i18n="pt_speed">Speed</th><th data-i18n="c_enabled">Enabled</th><th data-i18n="pt_mtu">MTU</th><th></th></tr></thead>
|
||||||
<tbody></tbody></table></div>
|
<tbody></tbody></table></div>
|
||||||
<p class="small mut" style="margin-top:8px" data-i18n="pt_sfp_note">SFP speed is set per slot and is not saved in the startup config.</p>
|
<p class="small mut" style="margin-top:8px" data-i18n="pt_sfp_note">SFP speed is set per slot and is not saved in the startup config.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1111,6 +1111,9 @@ void send_status(void)
|
|||||||
slen += strtox(outbuf + slen, "\",\"rxB\":\"0x");
|
slen += strtox(outbuf + slen, "\",\"rxB\":\"0x");
|
||||||
STAT_GET(STAT_COUNTER_ERR_PKTS, i);
|
STAT_GET(STAT_COUNTER_ERR_PKTS, i);
|
||||||
reg_to_html(RTL837X_STAT_V_HIGH); // 32bit RX packet errors
|
reg_to_html(RTL837X_STAT_V_HIGH); // 32bit RX packet errors
|
||||||
|
|
||||||
|
slen += strtox(outbuf + slen, "\",\"macs\":\"0x");
|
||||||
|
reg_to_html(RTL837X_L2_LRN_PORT_CONSTRT_CNT + (i << 2));
|
||||||
slen += strtox(outbuf + slen, "\"}");
|
slen += strtox(outbuf + slen, "\"}");
|
||||||
if (i < machine.max_port)
|
if (i < machine.max_port)
|
||||||
char_to_html(',');
|
char_to_html(',');
|
||||||
|
|||||||
@@ -64,6 +64,12 @@ struct machine {
|
|||||||
uint8_t led_mux_custom;
|
uint8_t led_mux_custom;
|
||||||
uint8_t led_mux[28];
|
uint8_t led_mux[28];
|
||||||
uint32_t mac_flash_offset;
|
uint32_t mac_flash_offset;
|
||||||
|
// Read the flash with single-IO (CMD_FREAD) instead of DIO for MMIO/code
|
||||||
|
// fetch. Set for boards whose flash chip is not usable in DIO mode, which
|
||||||
|
// shows up as a board that does not boot at all, garbled console output or
|
||||||
|
// random resets. Costs management-plane speed only, the ASIC keeps
|
||||||
|
// forwarding in hardware.
|
||||||
|
uint8_t flash_sio;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct machine_runtime
|
struct machine_runtime
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
SWTG018AS_A_V_2_0.c
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_2G08110GSN_H_
|
||||||
|
#define _MACHINE_2G08110GSN_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "MokerLink 2G08110GSN"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
/* Same 2M-PCB43-V1.1 board family as the KP-9000-6XH-X2 (see
|
||||||
|
* machine/KP_9000_6XHML_X2.c), but the two SFP+ cages (physical ports 5 and
|
||||||
|
* 6) are wired the other way round: physical 5 is on SDS1, physical 6 on
|
||||||
|
* SDS0. Copper ports 1-4 match the KP-9000 layout. */
|
||||||
|
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
|
// Left SFP cage (physical port 5) = SDS1
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
// Right SFP cage (physical port 6) = SDS0
|
||||||
|
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
||||||
|
.sfp_port[1].pin_los = GPIO10_LED10,
|
||||||
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 0,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
/* The board has a 3-hole reset button footprint, but it is unpopulated and
|
||||||
|
* the case has no opening for it, so reset_pin stays GPIO_NA. GPIO54, the
|
||||||
|
* reset pin on the KP-9000 layout, reads as permanently pressed here. */
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
/* The fitted T25S40 does not work in DIO mode on this board, so read the flash
|
||||||
|
* with single-IO; see doc/devices/2G5F4_10G2_V1.01.md. */
|
||||||
|
.flash_sio = 1,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
/* Conditions for LED on:
|
||||||
|
* dual led orange: ledset_0 & ledset_2
|
||||||
|
* dual led green: ledset_2 & !ledset_0
|
||||||
|
* single right led green: ledset_0 & !ledset_1
|
||||||
|
*
|
||||||
|
* Measured on this board: LED-ID0 is the copper blue LED, LED-ID1 the
|
||||||
|
* copper white one (setting LED-ID0 to 0 killed blue while leaving white on
|
||||||
|
* at 2.5G only) and LED-ID2 carries the SFP single LED. The "solid"
|
||||||
|
* conditions (LINK/speed) barely drive the LEDs here and ACT is what
|
||||||
|
* actually lights them, which is why the white LED used to glow faintly at
|
||||||
|
* non-2.5G speeds; the fix for that is LED_GLB_IO_EN bit 6, set in
|
||||||
|
* machine_init.c. */
|
||||||
|
.led_sets = { { LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_10G,
|
||||||
|
LEDS_1G | LEDS_LINK,
|
||||||
|
0 },
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_2G5F4_10G2_V1_01_H_
|
||||||
|
#define _MACHINE_2G5F4_10G2_V1_01_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "2G5F4_10G2_V1.01 / SGT0204S"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#include "machine_defs.h"
|
|
||||||
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = MACHINE_MODEL,
|
|
||||||
.isRTL8373 = 1,
|
|
||||||
.min_port = 0,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 1,
|
|
||||||
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
|
||||||
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
|
||||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
|
||||||
.sfp_port[0].pin_los = GPIO37,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
|
||||||
.reset_pin = GPIO_NA,
|
|
||||||
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
||||||
.led_sets = { { LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
|
|
||||||
LEDS_2G5 | LEDS_LINK,
|
|
||||||
LEDS_1G | LEDS_LINK,
|
|
||||||
LEDS_2G5 | LEDS_LINK | LEDS_ACT },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
KP_9000_9XH_X_EU.c
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
#include "machine_defs.h"
|
|
||||||
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = MACHINE_MODEL,
|
|
||||||
.isRTL8373 = 0,
|
|
||||||
.min_port = 3,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 2,
|
|
||||||
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
|
||||||
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
|
||||||
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
|
||||||
|
|
||||||
/* Left SFP (logical 8, SDS1): GPIO30=ModAbs, GPIO37=RX_LOS */
|
|
||||||
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
|
||||||
.sfp_port[0].pin_los = GPIO37,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
|
||||||
|
|
||||||
/* Right SFP (logical 3, SDS0): GPIO50=ModAbs, GPIO51=RX_LOS */
|
|
||||||
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
|
||||||
.sfp_port[1].pin_los = GPIO51_I2C_SDA2_UART1_RX,
|
|
||||||
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[1].sds = 0,
|
|
||||||
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
|
|
||||||
|
|
||||||
.reset_pin = GPIO_NA,
|
|
||||||
|
|
||||||
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
|
|
||||||
|
|
||||||
/* Copper ports use SET0; SFP ports use SET1 */
|
|
||||||
.port_led_set = {0, 0, 0, 1, 0, 0, 0, 0, 1},
|
|
||||||
|
|
||||||
.led_sets = {
|
|
||||||
{ /* SET0: copper — LED0=amber (2.5G), LED2=green (1G/100M/10M) */
|
|
||||||
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
0
|
|
||||||
},
|
|
||||||
{ /* SET1: SFP — all speeds link/act */
|
|
||||||
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
|
||||||
0,
|
|
||||||
0, 0
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
.led_mux_custom = 1,
|
|
||||||
.led_mux = {
|
|
||||||
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, /* GPIO0-7: unused */
|
|
||||||
0x0f, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12, /* GPIO8-14 */
|
|
||||||
0x14, 0x15, 0x16, 0x18, 0x19, 0x1a, /* GPIO15-20 */
|
|
||||||
0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x23 /* GPIO21-27 */
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
PCB_K0402WS_V2.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
SWTG018AS_A_V_2_0.c
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_GT_ST018M_H_
|
||||||
|
#define _MACHINE_GT_ST018M_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "GoodTop GT-ST018M"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
PCB_SWTG024AS_A_2_0_1.c
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_GT_ST024M_H_
|
||||||
|
#define _MACHINE_GT_ST024M_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "GoodTop GT-ST024M"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 1,
|
||||||
|
.mac_flash_offset = 0x1FC000,
|
||||||
|
.min_port = 0,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 1,
|
||||||
|
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||||
|
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.sfp_port[0].pin_detect = GPIO38,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
.reset_pin = GPIO54_ACL_BIT2_EN,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
|
.led_sets = {
|
||||||
|
{
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // LED0: orange
|
||||||
|
0,
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT, // LED2: green
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT, // SFP LED0: green (both SFP LEDs are green)
|
||||||
|
0, 0, 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = {
|
||||||
|
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x09,
|
||||||
|
0x0e, 0x10, 0x12, 0x0e, 0x14, 0x11, 0x12, 0x16,
|
||||||
|
0x15, 0x16, 0x18, 0x19, 0x1a, 0x1a, 0x1d, 0x1e,
|
||||||
|
0x1c, 0x1e, 0x20, 0x21
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_HASIVO_S1100P_8GT_1SX_S_H_
|
||||||
|
#define _MACHINE_HASIVO_S1100P_8GT_1SX_S_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "Hasivo S1100P-8GT-1SX-S"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#include "machine_defs.h"
|
|
||||||
|
|
||||||
__code const struct machine machine = {
|
|
||||||
.machine_name = MACHINE_MODEL,
|
|
||||||
.isRTL8373 = 1,
|
|
||||||
.mac_flash_offset = 0x1FC000,
|
|
||||||
.min_port = 0,
|
|
||||||
.max_port = 8,
|
|
||||||
.n_sfp = 1,
|
|
||||||
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
|
|
||||||
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
|
|
||||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
|
||||||
.sfp_port[0].pin_los = GPIO37,
|
|
||||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
|
||||||
.sfp_port[0].sds = 1,
|
|
||||||
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
|
||||||
.reset_pin = GPIO54_ACL_BIT2_EN,
|
|
||||||
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
|
|
||||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
|
||||||
.led_sets = { { LEDS_2G5 | LEDS_LINK | LEDS_ACT, // Green LED (right)
|
|
||||||
0,
|
|
||||||
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // Amber LED (left)
|
|
||||||
0
|
|
||||||
},
|
|
||||||
{ LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT, // SFP LED
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
SWTGW218AS.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
PCB_SWTG024AS_A_2_0_1.c
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_HC_SWTG124AS_H_
|
||||||
|
#define _MACHINE_HC_SWTG124AS_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "Horaco HC-SWTG124AS"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
||||||
|
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
|
/* Left SFP (logical 8, SDS1): GPIO30=ModAbs, GPIO37=RX_LOS */
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
/* Right SFP (logical 3, SDS0): GPIO50=ModAbs, GPIO51=RX_LOS */
|
||||||
|
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
||||||
|
.sfp_port[1].pin_los = GPIO51_I2C_SDA2_UART1_RX,
|
||||||
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 0,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
|
||||||
|
|
||||||
|
.reset_pin = GPIO_NA,
|
||||||
|
|
||||||
|
/* These don't appear to be populated / wired-up; the power LED is always on */
|
||||||
|
.high_leds = { 0 },
|
||||||
|
|
||||||
|
/* Copper ports use SET0; SFP ports use SET1 */
|
||||||
|
.port_led_set = {0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
|
|
||||||
|
.led_sets = {
|
||||||
|
{ /* SET0: copper — LED0=amber (2.5G), LED2=green (1G/100M/10M) */
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{ /* SET1: SFP — all speeds link/act */
|
||||||
|
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
.led_mux_custom = 1,
|
||||||
|
.led_mux = {
|
||||||
|
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, /* GPIO0-7: unused */
|
||||||
|
0x0f, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12, /* GPIO8-14 */
|
||||||
|
0x14, 0x15, 0x16, 0x18, 0x19, 0x1a, /* GPIO15-20 */
|
||||||
|
0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x23 /* GPIO21-27 */
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_PCB_K0402WS_V1_H_
|
||||||
|
#define _MACHINE_PCB_K0402WS_V1_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "PCB-K0402WS-V1.0"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "machine_defs.h"
|
#include "machine_defs.h"
|
||||||
|
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = MACHINE_MODEL,
|
.machine_name = MACHINE_MODEL,
|
||||||
.isRTL8373 = 0,
|
.isRTL8373 = 0,
|
||||||
.min_port = 3,
|
.min_port = 3,
|
||||||
.max_port = 8,
|
.max_port = 8,
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#include "machine_defs.h"
|
||||||
|
|
||||||
|
__code const struct machine machine = {
|
||||||
|
.machine_name = MACHINE_MODEL,
|
||||||
|
.isRTL8373 = 0,
|
||||||
|
.min_port = 3,
|
||||||
|
.max_port = 8,
|
||||||
|
.n_sfp = 2,
|
||||||
|
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
|
||||||
|
.phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
|
||||||
|
.is_sfp= {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
|
// Left SFP port (J4)
|
||||||
|
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||||
|
.sfp_port[0].pin_los = GPIO37,
|
||||||
|
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[0].sds = 1,
|
||||||
|
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), /* GPIO 39 */
|
||||||
|
// Right SFP port (J2)
|
||||||
|
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
|
||||||
|
.sfp_port[1].pin_los = GPIO51_I2C_SDA2_UART1_RX,
|
||||||
|
.sfp_port[1].pin_tx_disable = GPIO_NA,
|
||||||
|
.sfp_port[1].sds = 0,
|
||||||
|
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), /* GPIO 40 */
|
||||||
|
.reset_pin = GPIO36_PWM_OUT,
|
||||||
|
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||||
|
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
|
||||||
|
.led_sets = {
|
||||||
|
{ /* RJ45: Green LED */
|
||||||
|
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
|
||||||
|
0,
|
||||||
|
/* Amber LED */
|
||||||
|
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||||
|
0
|
||||||
|
}, { /* SFP PORT: SINGLE GREEN LED */
|
||||||
|
LEDS_10M | LEDS_100M | LEDS_1G | LEDS_2G5 | LEDS_10G | LEDS_LINK | LEDS_ACT,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_SIRIVISION_S25G2206FP_V1_1_H_
|
||||||
|
#define _MACHINE_SIRIVISION_S25G2206FP_V1_1_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "SIRIVISION S25G2206FP V1.1"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
PCB_SWTG018AS_V2_1_0.c
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef _MACHINE_SKS3200_8E1X_H_
|
||||||
|
#define _MACHINE_SKS3200_8E1X_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "XikeStor SKS3200-8E1X"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -38,4 +38,5 @@ __code const struct machine machine = {
|
|||||||
0,
|
0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
.mac_flash_offset = 0x1FC000,
|
||||||
};
|
};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
SIRIVISION_S25G2206FP_V1_1.c
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _MACHINE_YS25_0402M_H_
|
||||||
|
#define _MACHINE_YS25_0402M_H_
|
||||||
|
|
||||||
|
#define MACHINE_MODEL "YuanLey YS25-0402M"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
defined(MACHINE_HI_K0402WS) || \
|
defined(MACHINE_HI_K0402WS) || \
|
||||||
defined(MACHINE_PCB_K0402WS_V2) || \
|
defined(MACHINE_PCB_K0402WS_V2) || \
|
||||||
defined(MACHINE_PCB_K0402WS_V3) || \
|
defined(MACHINE_PCB_K0402WS_V3) || \
|
||||||
|
defined(MACHINE_2G5F4_10G2_V1_01) || \
|
||||||
defined(MACHINE_FNS1200P)
|
defined(MACHINE_FNS1200P)
|
||||||
void machine_custom_init(void) __banked
|
void machine_custom_init(void) __banked
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,216 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "rtl837x_common.h"
|
||||||
|
#include "rtl837x_sfr.h"
|
||||||
|
#include "rtl837x_cabletest.h"
|
||||||
|
#include "rtl837x_phy.h"
|
||||||
|
#include "phy.h"
|
||||||
|
#include "machine.h"
|
||||||
|
|
||||||
|
#pragma codeseg BANK3
|
||||||
|
#pragma constseg BANK3
|
||||||
|
|
||||||
|
#define RTCT_CTRL 0xa422
|
||||||
|
#define RTCT_CTRL_START 0x00f1
|
||||||
|
#define RTCT_CTRL_DONE 0x8000
|
||||||
|
#define RTCT_SRAM_ADDR 0xa436
|
||||||
|
#define RTCT_SRAM_DATA 0xa438
|
||||||
|
#define RTCT_SRAM_STATUS 0x8026
|
||||||
|
#define RTCT_SRAM_LEN 0x8028
|
||||||
|
|
||||||
|
#define RTCT_ST_BUSY 0x01
|
||||||
|
#define RTCT_ST_MISMATCH 0x06
|
||||||
|
#define RTCT_ST_OPEN 0x08
|
||||||
|
#define RTCT_ST_SHORT 0x10
|
||||||
|
#define RTCT_ST_OK 0x20
|
||||||
|
#define RTCT_ST_DONE 0x40
|
||||||
|
#define RTCT_ST_CROSS_SHORT 0x80
|
||||||
|
|
||||||
|
#define RTCT_LEN_ZERO 150
|
||||||
|
#define RTCT_LEN_PER_50CM 43
|
||||||
|
|
||||||
|
#define PHY_POWER 0xa610
|
||||||
|
#define PHY_POWER_OFF 0x0800
|
||||||
|
|
||||||
|
#define BMCR_PDOWN_1G_FULL 0x0940
|
||||||
|
#define BMCR_1G_FULL 0x0140
|
||||||
|
#define BMCR_ANRESTART 0x0200
|
||||||
|
|
||||||
|
#define CT_IDLE 0
|
||||||
|
#define CT_SILENCE 1
|
||||||
|
#define CT_RUN 2
|
||||||
|
#define CT_POLL_TICKS (SYS_TICK_HZ / 20)
|
||||||
|
#define CT_POLLS 100
|
||||||
|
|
||||||
|
extern volatile __xdata uint32_t ticks;
|
||||||
|
extern __code const struct machine machine;
|
||||||
|
extern __xdata struct machine_runtime machine_detected;
|
||||||
|
|
||||||
|
__xdata uint8_t ct_state = CT_IDLE;
|
||||||
|
__xdata uint8_t ct_port;
|
||||||
|
__xdata uint8_t ct_last;
|
||||||
|
__xdata uint8_t ct_polls;
|
||||||
|
__xdata uint8_t ct_valid;
|
||||||
|
__xdata uint8_t ct_have = 0;
|
||||||
|
__xdata uint8_t ct_pair;
|
||||||
|
__xdata uint8_t ct_flags;
|
||||||
|
__xdata uint16_t ct_bmcr;
|
||||||
|
__xdata uint8_t ct_result[4];
|
||||||
|
__xdata uint16_t ct_len[4];
|
||||||
|
|
||||||
|
void rtl_phy_cable_test_start(uint8_t port) __banked
|
||||||
|
{
|
||||||
|
phy_write(port, PHY_MMD31, PHY_MMD31_FEDCR, BMCR_1G_FULL);
|
||||||
|
phy_write(port, PHY_MMD31, RTCT_CTRL, RTCT_CTRL_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rtl_phy_cable_test_get_status(uint8_t port) __banked
|
||||||
|
{
|
||||||
|
phy_read(port, PHY_MMD31, RTCT_CTRL);
|
||||||
|
if (!(SFR_DATA_U16 & RTCT_CTRL_DONE))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (ct_pair = 0; ct_pair < 4; ct_pair++) {
|
||||||
|
// The flags are the low byte of the word, not the high one.
|
||||||
|
phy_write(port, PHY_MMD31, RTCT_SRAM_ADDR, RTCT_SRAM_STATUS + (ct_pair << 2));
|
||||||
|
phy_read(port, PHY_MMD31, RTCT_SRAM_DATA);
|
||||||
|
ct_flags = SFR_DATA_U16;
|
||||||
|
if (!(ct_flags & RTCT_ST_DONE))
|
||||||
|
return false;
|
||||||
|
if (ct_flags & RTCT_ST_OK)
|
||||||
|
ct_result[ct_pair] = CABLE_RESULT_OK;
|
||||||
|
else if (ct_flags & RTCT_ST_OPEN)
|
||||||
|
ct_result[ct_pair] = CABLE_RESULT_OPEN;
|
||||||
|
else if (ct_flags & RTCT_ST_SHORT)
|
||||||
|
ct_result[ct_pair] = CABLE_RESULT_SAME_SHORT;
|
||||||
|
else if (ct_flags & RTCT_ST_BUSY)
|
||||||
|
ct_result[ct_pair] = CABLE_RESULT_UNSPEC;
|
||||||
|
else if (ct_flags & RTCT_ST_CROSS_SHORT)
|
||||||
|
ct_result[ct_pair] = CABLE_RESULT_CROSS_SHORT;
|
||||||
|
else if (ct_flags & RTCT_ST_MISMATCH)
|
||||||
|
ct_result[ct_pair] = CABLE_RESULT_MISMATCH;
|
||||||
|
else
|
||||||
|
ct_result[ct_pair] = CABLE_RESULT_UNSPEC;
|
||||||
|
|
||||||
|
phy_write(port, PHY_MMD31, RTCT_SRAM_ADDR, RTCT_SRAM_LEN + (ct_pair << 2));
|
||||||
|
phy_read(port, PHY_MMD31, RTCT_SRAM_DATA);
|
||||||
|
ct_len[ct_pair] = SFR_DATA_U16;
|
||||||
|
ct_len[ct_pair] = ct_len[ct_pair] > RTCT_LEN_ZERO ? ct_len[ct_pair] - RTCT_LEN_ZERO : 0;
|
||||||
|
ct_len[ct_pair] = ct_len[ct_pair] * 5 / RTCT_LEN_PER_50CM;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cabletest_print(void)
|
||||||
|
{
|
||||||
|
print_string("Cable test port ");
|
||||||
|
print_phys_port(ct_port);
|
||||||
|
if (!ct_valid) {
|
||||||
|
print_string(": timed out\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
write_char('\n');
|
||||||
|
for (ct_pair = 0; ct_pair < 4; ct_pair++) {
|
||||||
|
print_string("Pair ");
|
||||||
|
write_char('A' + ct_pair);
|
||||||
|
switch (ct_result[ct_pair]) {
|
||||||
|
case CABLE_RESULT_OK:
|
||||||
|
print_string(": ok\n");
|
||||||
|
continue;
|
||||||
|
case CABLE_RESULT_OPEN:
|
||||||
|
print_string(": open at ");
|
||||||
|
break;
|
||||||
|
case CABLE_RESULT_SAME_SHORT:
|
||||||
|
print_string(": short at ");
|
||||||
|
break;
|
||||||
|
case CABLE_RESULT_CROSS_SHORT:
|
||||||
|
print_string(": short to another pair at ");
|
||||||
|
break;
|
||||||
|
case CABLE_RESULT_MISMATCH:
|
||||||
|
print_string(": impedance mismatch at ");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_string(": unknown\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
itoa_short(ct_len[ct_pair] / 10);
|
||||||
|
write_char('.');
|
||||||
|
write_char('0' + ct_len[ct_pair] % 10);
|
||||||
|
print_string(" m\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cabletest_run(void) __banked
|
||||||
|
{
|
||||||
|
if (ct_state) {
|
||||||
|
print_string("Cable test running on port ");
|
||||||
|
print_phys_port(ct_port);
|
||||||
|
write_char('\n');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!machine_detected.isRTL8373 && (phy_settings.port < 4 || phy_settings.port > 7)) {
|
||||||
|
print_string("No cable test on this PHY\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A test started on a port that is off never ends and blocks the PHY until reset.
|
||||||
|
phy_read(phy_settings.port, PHY_MMD31, PHY_POWER);
|
||||||
|
if (SFR_DATA_U16 & PHY_POWER_OFF) {
|
||||||
|
print_string("Port is off\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ct_port = phy_settings.port;
|
||||||
|
phy_read(ct_port, PHY_MMD31, PHY_MMD31_FEDCR);
|
||||||
|
ct_bmcr = SFR_DATA_U16;
|
||||||
|
|
||||||
|
// Forcing the speed leaves the link up; only a power-down silences the partner.
|
||||||
|
phy_write(ct_port, PHY_MMD31, PHY_MMD31_FEDCR, BMCR_PDOWN_1G_FULL);
|
||||||
|
ct_last = ticks;
|
||||||
|
ct_have = 0;
|
||||||
|
ct_state = CT_SILENCE;
|
||||||
|
print_string("Cable test started\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void cabletest_show(void) __banked
|
||||||
|
{
|
||||||
|
if (ct_state)
|
||||||
|
print_string("Cable test running\n");
|
||||||
|
else if (ct_port != phy_settings.port || !ct_have)
|
||||||
|
print_string("No cable test result\n");
|
||||||
|
else
|
||||||
|
cabletest_print();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cabletest_tick(void) __banked
|
||||||
|
{
|
||||||
|
if (ct_state == CT_SILENCE) {
|
||||||
|
if (!TICKS_DUE(ct_last, SYS_TICK_HZ))
|
||||||
|
return;
|
||||||
|
phy_read(ct_port, PHY_MMD31, PHY_POWER);
|
||||||
|
if (SFR_DATA_U16 & PHY_POWER_OFF) {
|
||||||
|
phy_write(ct_port, PHY_MMD31, PHY_MMD31_FEDCR, ct_bmcr);
|
||||||
|
ct_state = CT_IDLE;
|
||||||
|
print_string("Cable test aborted, port is off\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rtl_phy_cable_test_start(ct_port);
|
||||||
|
ct_polls = CT_POLLS;
|
||||||
|
ct_last = ticks;
|
||||||
|
ct_state = CT_RUN;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ct_state != CT_RUN || !TICKS_DUE(ct_last, CT_POLL_TICKS))
|
||||||
|
return;
|
||||||
|
ct_last = ticks;
|
||||||
|
|
||||||
|
ct_valid = rtl_phy_cable_test_get_status(ct_port);
|
||||||
|
if (!ct_valid && --ct_polls)
|
||||||
|
return;
|
||||||
|
|
||||||
|
phy_write(ct_port, PHY_MMD31, RTCT_CTRL, 0);
|
||||||
|
phy_write(ct_port, PHY_MMD31, PHY_MMD31_FEDCR, ct_bmcr | BMCR_ANRESTART);
|
||||||
|
ct_have = 1;
|
||||||
|
ct_state = CT_IDLE;
|
||||||
|
cabletest_print();
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef _RTL837X_CABLETEST_H_
|
||||||
|
#define _RTL837X_CABLETEST_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define CABLE_RESULT_UNSPEC 0
|
||||||
|
#define CABLE_RESULT_OK 1
|
||||||
|
#define CABLE_RESULT_OPEN 2
|
||||||
|
#define CABLE_RESULT_SAME_SHORT 3
|
||||||
|
#define CABLE_RESULT_CROSS_SHORT 4
|
||||||
|
#define CABLE_RESULT_MISMATCH 5
|
||||||
|
|
||||||
|
void rtl_phy_cable_test_start(uint8_t port) __banked;
|
||||||
|
bool rtl_phy_cable_test_get_status(uint8_t port) __banked;
|
||||||
|
|
||||||
|
void cabletest_run(void) __banked;
|
||||||
|
void cabletest_show(void) __banked;
|
||||||
|
void cabletest_tick(void) __banked;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
// 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
|
||||||
#define PMASK_6 0x1f8
|
#define PMASK_6 0x1f8
|
||||||
#define PMASK_CPU 0x200
|
#define PMASK_CPU ((uint16_t)(1 << CPU_PORT))
|
||||||
|
|
||||||
// Defines a port mask for dropping all packets on Lookup-miss
|
// Defines a port mask for dropping all packets on Lookup-miss
|
||||||
#define LOOKUP_MISS_DROP_6 0x00015540
|
#define LOOKUP_MISS_DROP_6 0x00015540
|
||||||
@@ -142,7 +142,7 @@ extern __xdata bool stp_enabled;
|
|||||||
* advertises it as the System Name TLV) read it from here. */
|
* advertises it as the System Name TLV) read it from here. */
|
||||||
extern __xdata char hostname[24];
|
extern __xdata char hostname[24];
|
||||||
|
|
||||||
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
|
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_ALLOC_SIZE];
|
||||||
extern __xdata struct uip_eth_addr uip_ethaddr;
|
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)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ extern __xdata uint8_t igmpEnabled;
|
|||||||
extern __xdata uint8_t cpuPort;
|
extern __xdata uint8_t cpuPort;
|
||||||
extern __xdata uint8_t sfr_data[4];
|
extern __xdata uint8_t sfr_data[4];
|
||||||
extern __xdata struct machine_runtime machine_detected;
|
extern __xdata struct machine_runtime machine_detected;
|
||||||
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE + 2];
|
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_ALLOC_SIZE];
|
||||||
|
|
||||||
__xdata uint16_t idx;
|
__xdata uint16_t idx;
|
||||||
#define IGMP_IP_HDR offsetof(struct igmp_pkt, hlen)
|
#define IGMP_IP_HDR offsetof(struct igmp_pkt, hlen)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ extern __code const struct machine machine;
|
|||||||
extern __xdata struct machine_runtime machine_detected;
|
extern __xdata struct machine_runtime machine_detected;
|
||||||
extern __xdata uint16_t management_vlan;
|
extern __xdata uint16_t management_vlan;
|
||||||
extern __xdata struct uip_eth_addr uip_ethaddr;
|
extern __xdata struct uip_eth_addr uip_ethaddr;
|
||||||
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE + 2];
|
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_ALLOC_SIZE];
|
||||||
|
|
||||||
/* 20-byte Actor/Partner information body (802.3ad 43.4.2.2), network byte order */
|
/* 20-byte Actor/Partner information body (802.3ad 43.4.2.2), network byte order */
|
||||||
struct lacp_info {
|
struct lacp_info {
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
#include "rtl837x_common.h"
|
||||||
|
#include "rtl837x_regs.h"
|
||||||
|
#include "rtl837x_sfr.h"
|
||||||
|
#include "rtl837x_nic.h"
|
||||||
|
|
||||||
|
extern __xdata uint8_t rx_headers[16];
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef RTLP_HOST_TEST
|
||||||
|
/* One RX DMA operation, starting inside the configured ring. The hardware
|
||||||
|
* wraps transfers that cross its end; the initial address must be normalized.
|
||||||
|
* Host tests supply a simulated DMA engine for this hardware boundary. */
|
||||||
|
bool nic_rx_dma(__xdata uint8_t *buffer, uint16_t ring_ptr, uint8_t words) __reentrant
|
||||||
|
{
|
||||||
|
uint16_t guard = 0;
|
||||||
|
|
||||||
|
SFR_NIC_DATA_U16LE = (uint16_t)buffer;
|
||||||
|
SFR_NIC_RING_U16LE = ring_ptr;
|
||||||
|
SFR_NIC_CTRL = words;
|
||||||
|
while (SFR_NIC_CTRL != 0) {
|
||||||
|
if (++guard == 0) {
|
||||||
|
print_string("NIC: RX transfer did not complete\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool nic_rx_copy(__xdata uint8_t *buffer, uint16_t ring_ptr, uint8_t words) __reentrant
|
||||||
|
{
|
||||||
|
if (ring_ptr > RTL837X_NIC_RX_RING_BYTES || (ring_ptr & 7))
|
||||||
|
return false;
|
||||||
|
if (ring_ptr == RTL837X_NIC_RX_RING_BYTES)
|
||||||
|
ring_ptr = 0;
|
||||||
|
|
||||||
|
return nic_rx_dma(buffer, ring_ptr, words);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool nic_rx_header(uint16_t ring_ptr) __reentrant
|
||||||
|
{
|
||||||
|
if (ring_ptr >= RTL837X_NIC_RX_RING_BYTES)
|
||||||
|
return false;
|
||||||
|
return nic_rx_copy(rx_headers, ring_ptr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool nic_rx_packet(__xdata uint8_t *buffer, uint16_t ring_ptr) __reentrant
|
||||||
|
{
|
||||||
|
uint16_t len = ((uint16_t)rx_headers[5] << 8) | rx_headers[4];
|
||||||
|
|
||||||
|
if (!len || len > UIP_CONF_BUFFER_SIZE)
|
||||||
|
return false;
|
||||||
|
return nic_rx_copy(buffer, ring_ptr, (len + 7) >> 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Transfers data in XMEM to the ASIC for transmission by the NIC
|
||||||
|
*/
|
||||||
|
void nic_tx_packet(__xdata uint8_t *buffer, uint16_t len, uint16_t ring_ptr)
|
||||||
|
{
|
||||||
|
uint16_t guard = 0;
|
||||||
|
|
||||||
|
SFR_NIC_DATA_U16LE = (uint16_t)(uintptr_t)buffer;
|
||||||
|
|
||||||
|
#ifdef RXTXDBG
|
||||||
|
print_string("TX: \n");
|
||||||
|
for (uint8_t i = 0; i < 100; i++) {
|
||||||
|
print_byte(uip_buf[i]);
|
||||||
|
write_char(' ');
|
||||||
|
}
|
||||||
|
write_char('\n');
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ring_ptr <<= 3;
|
||||||
|
ring_ptr |= 0x8000;
|
||||||
|
SFR_NIC_RING_U16LE = ring_ptr;
|
||||||
|
|
||||||
|
len += 0xf;
|
||||||
|
len >>= 3;
|
||||||
|
SFR_NIC_CTRL = len;
|
||||||
|
while (SFR_NIC_CTRL != 0) {
|
||||||
|
if (++guard == 0) {
|
||||||
|
print_string("NIC: TX transfer did not complete\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef RTL837X_NIC_H
|
||||||
|
#define RTL837X_NIC_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// #define RXTXDBG 1
|
||||||
|
|
||||||
|
bool nic_rx_header(uint16_t ring_ptr) __reentrant;
|
||||||
|
bool nic_rx_packet(__xdata uint8_t *buffer, uint16_t ring_ptr) __reentrant;
|
||||||
|
|
||||||
|
/* buffer starts at the eight-byte NIC descriptor; len excludes that
|
||||||
|
* descriptor. ring_ptr is the ASIC TX position in eight-byte slots. */
|
||||||
|
void nic_tx_packet(__xdata uint8_t *buffer, uint16_t len, uint16_t ring_ptr);
|
||||||
|
|
||||||
|
/* RX DMA in eight-byte units. ring_ptr must start inside the configured
|
||||||
|
* RX ring; the hardware wraps transfers that cross its end. */
|
||||||
|
bool nic_rx_dma(__xdata uint8_t *buffer, uint16_t ring_ptr, uint8_t words) __reentrant;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -57,7 +57,7 @@ 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
|
||||||
{
|
{
|
||||||
if (port > 9 || type >= VLAN_INVALID) {
|
if (port > CPU_PORT || type >= VLAN_INVALID) {
|
||||||
print_string("Invalid port or ingress filter type\n");
|
print_string("Invalid port or ingress filter type\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -510,7 +510,7 @@ void port_media_show(uint8_t port) __banked
|
|||||||
|
|
||||||
void port_stats_print(void) __banked
|
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\t\tMACs\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++) {
|
||||||
print_phys_port(i); write_char('\t');
|
print_phys_port(i); write_char('\t');
|
||||||
|
|
||||||
@@ -584,6 +584,9 @@ void port_stats_print(void) __banked
|
|||||||
|
|
||||||
STAT_GET(STAT_COUNTER_ERR_PKTS, i);
|
STAT_GET(STAT_COUNTER_ERR_PKTS, i);
|
||||||
print_reg(RTL837X_STAT_V_HIGH); write_char('\t');
|
print_reg(RTL837X_STAT_V_HIGH); write_char('\t');
|
||||||
|
|
||||||
|
reg_read(RTL837X_L2_LRN_PORT_CONSTRT_CNT + (i << 2));
|
||||||
|
itoa_short(SFR_DATA_U16 & L2_LRN_PORT_CNT_MASK);
|
||||||
print_string("\n");
|
print_string("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,6 +147,9 @@
|
|||||||
*/
|
*/
|
||||||
#define RTL837X_REG_NIC_BUFFSIZE_TX 0x7844
|
#define RTL837X_REG_NIC_BUFFSIZE_TX 0x7844
|
||||||
#define RTL837X_REG_NIC_RXBUFF_RX 0x7848
|
#define RTL837X_REG_NIC_RXBUFF_RX 0x7848
|
||||||
|
/* RX ring: inclusive final eight-byte slot, as programmed by nic_setup(). */
|
||||||
|
#define RTL837X_NIC_RX_LAST_SLOT 0x04ff
|
||||||
|
#define RTL837X_NIC_RX_RING_BYTES ((RTL837X_NIC_RX_LAST_SLOT + 1U) * 8U)
|
||||||
#define RTL837X_REG_NIC_RXCMD 0x784c
|
#define RTL837X_REG_NIC_RXCMD 0x784c
|
||||||
#define RTL837X_REG_NIC_TXCMD 0x7850
|
#define RTL837X_REG_NIC_TXCMD 0x7850
|
||||||
#define RTL837X_REG_RX_CTRL 0x785c
|
#define RTL837X_REG_RX_CTRL 0x785c
|
||||||
@@ -214,6 +217,8 @@
|
|||||||
#define RTL837x_L2_TBL_FLUSH_CNF 0x53dc
|
#define RTL837x_L2_TBL_FLUSH_CNF 0x53dc
|
||||||
#define RTL837X_L2_LRN_PORT_CONSTRAINT 0x5384
|
#define RTL837X_L2_LRN_PORT_CONSTRAINT 0x5384
|
||||||
#define RTL837X_L2_LRN_PORT_CONSTRT_ACT 0x4f80
|
#define RTL837X_L2_LRN_PORT_CONSTRT_ACT 0x4f80
|
||||||
|
#define RTL837X_L2_LRN_PORT_CONSTRT_CNT 0x53ac
|
||||||
|
#define L2_LRN_PORT_CNT_MASK 0x1fff
|
||||||
#define RTL8373_REG_MAC_L2_PORT_MAX_LEN 0x1250
|
#define RTL8373_REG_MAC_L2_PORT_MAX_LEN 0x1250
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ extern __xdata struct machine_runtime machine_detected;
|
|||||||
|
|
||||||
extern __xdata struct uip_eth_addr uip_ethaddr;
|
extern __xdata struct uip_eth_addr uip_ethaddr;
|
||||||
|
|
||||||
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE + 2];
|
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_ALLOC_SIZE];
|
||||||
|
|
||||||
extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
||||||
extern __xdata uint8_t cmd_words_len;
|
extern __xdata uint8_t cmd_words_len;
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ extern __xdata uint8_t stp_pflags[STP_ENTITIES];
|
|||||||
extern __xdata uint32_t stp_pcost[STP_ENTITIES]; /* path cost; 0 = auto (20000) */
|
extern __xdata uint32_t stp_pcost[STP_ENTITIES]; /* path cost; 0 = auto (20000) */
|
||||||
extern __xdata uint8_t stp_pprio[STP_ENTITIES];
|
extern __xdata uint8_t stp_pprio[STP_ENTITIES];
|
||||||
extern __xdata uint8_t stp_pp2p[STP_ENTITIES];
|
extern __xdata uint8_t stp_pp2p[STP_ENTITIES];
|
||||||
extern __xdata uint8_t stp_ent_of[10]; /* the STP entity a port answers to: itself, or its lag */
|
extern __xdata uint8_t stp_ent_of[STP_PORTS]; /* the STP entity a port answers to: itself, or its lag */
|
||||||
extern __xdata uint16_t stp_lag_mask[STP_LAG_COUNT]; /* member ports of each lag; 0 = not part of STP */
|
extern __xdata uint16_t stp_lag_mask[STP_LAG_COUNT]; /* member ports of each lag; 0 = not part of STP */
|
||||||
|
|
||||||
/* Last-heard designated info per port (from received BPDUs); consult
|
/* Last-heard designated info per port (from received BPDUs); consult
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// #define REGDBG 1
|
// #define REGDBG 1
|
||||||
// #define RXTXDBG 1
|
|
||||||
|
|
||||||
#include "rtl837x_sfr.h"
|
#include "rtl837x_sfr.h"
|
||||||
#include "rtl837x_regs.h"
|
#include "rtl837x_regs.h"
|
||||||
@@ -12,6 +11,7 @@
|
|||||||
#include "rtl837x_phy.h"
|
#include "rtl837x_phy.h"
|
||||||
#include "rtl837x_port.h"
|
#include "rtl837x_port.h"
|
||||||
#include "rtl837x_trap.h"
|
#include "rtl837x_trap.h"
|
||||||
|
#include "rtl837x_nic.h"
|
||||||
#include "rtl837x_stp.h"
|
#include "rtl837x_stp.h"
|
||||||
#include "rtl837x_lacp.h"
|
#include "rtl837x_lacp.h"
|
||||||
#include "rtl837x_igmp.h"
|
#include "rtl837x_igmp.h"
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "rtl837x_bandwidth.h"
|
#include "rtl837x_bandwidth.h"
|
||||||
#include "rtl837x_init.h"
|
#include "rtl837x_init.h"
|
||||||
#include "rtl837x_lldp.h"
|
#include "rtl837x_lldp.h"
|
||||||
|
#include "rtl837x_cabletest.h"
|
||||||
#include "dhcp.h"
|
#include "dhcp.h"
|
||||||
#include "cmd_parser.h"
|
#include "cmd_parser.h"
|
||||||
#include "cmd_editor.h"
|
#include "cmd_editor.h"
|
||||||
@@ -122,8 +123,8 @@ __code const uint8_t * __code const hex = "0123456789abcdef";
|
|||||||
__xdata uint8_t flash_buf[FLASH_BUF_SIZE];
|
__xdata uint8_t flash_buf[FLASH_BUF_SIZE];
|
||||||
|
|
||||||
// NIC buffers for packet RX/TX
|
// NIC buffers for packet RX/TX
|
||||||
__xdata uint8_t rx_headers[16]; // Packet header(s) on RX
|
__xdata uint8_t rx_headers[16]; // RX descriptor
|
||||||
__xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
|
__xdata uint8_t uip_buf[UIP_CONF_BUFFER_ALLOC_SIZE];
|
||||||
|
|
||||||
__xdata uint16_t rx_packet_vlan;
|
__xdata uint16_t rx_packet_vlan;
|
||||||
__xdata uint16_t management_vlan;
|
__xdata uint16_t management_vlan;
|
||||||
@@ -713,108 +714,6 @@ void get_random_32(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Transfer Network Interface RX data from the ASIC to the 8051 XMEM
|
|
||||||
* data will be stored in the rx_header structure
|
|
||||||
* len is the length of data to be transferred
|
|
||||||
*/
|
|
||||||
bool nic_rx_header(uint16_t ring_ptr)
|
|
||||||
{
|
|
||||||
uint16_t buffer = (uint16_t) &rx_headers[0];
|
|
||||||
uint16_t guard = 0;
|
|
||||||
|
|
||||||
SFR_NIC_DATA_U16LE = buffer;
|
|
||||||
SFR_NIC_RING_U16LE = ring_ptr;
|
|
||||||
SFR_NIC_CTRL = 1;
|
|
||||||
while (SFR_NIC_CTRL != 0) {
|
|
||||||
if (++guard == 0) {
|
|
||||||
print_string("NIC: RX header transfer did not complete\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Transfer Network Interface RX data from the ASIC to the 8051 XMEM
|
|
||||||
* the description of the packet must be in the rx_headers data structure
|
|
||||||
* data will be returned in the xmem buffer points to
|
|
||||||
* ring_ptr is the current position of the RX Ring on the ASIC side
|
|
||||||
*/
|
|
||||||
bool nic_rx_packet(uint16_t buffer, uint16_t ring_ptr)
|
|
||||||
{
|
|
||||||
uint16_t guard = 0;
|
|
||||||
|
|
||||||
SFR_NIC_DATA_U16LE = buffer;
|
|
||||||
SFR_NIC_RING_U16LE = ring_ptr;
|
|
||||||
|
|
||||||
uint16_t len = (((uint16_t)rx_headers[5]) << 8) | rx_headers[4];
|
|
||||||
len += 7;
|
|
||||||
len >>= 3;
|
|
||||||
#ifdef RXTXDBG
|
|
||||||
print_string(" len: ");
|
|
||||||
print_short(len);
|
|
||||||
#endif
|
|
||||||
SFR_NIC_CTRL = len;
|
|
||||||
while (SFR_NIC_CTRL != 0) {
|
|
||||||
if (++guard == 0) {
|
|
||||||
print_string("NIC: RX transfer did not complete\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Transfers data in XMEM to the ASIC for transmission by the nic
|
|
||||||
*/
|
|
||||||
void nic_tx_packet(uint16_t ring_ptr)
|
|
||||||
{
|
|
||||||
uint16_t len;
|
|
||||||
uint16_t guard = 0;
|
|
||||||
|
|
||||||
/* A frame that got a dot1Q tag was shifted forward over its padding, so it
|
|
||||||
* starts at uip_buf and carries the q_frame layout. One that did not keeps
|
|
||||||
* the padding in front and the nonq_frame layout, so the padding is skipped.
|
|
||||||
*/
|
|
||||||
if (frame_tagged) {
|
|
||||||
SFR_NIC_DATA_U16LE = (uint16_t) uip_buf;
|
|
||||||
len = FRAME_Q->len;
|
|
||||||
/*
|
|
||||||
(__xdata struct rtl_dot1q_frame *)uip_buf
|
|
||||||
#define FRAME (((__xdata struct rtl_dot1q_frame *)&uip_buf[0]).nonq_frame)*/
|
|
||||||
} else {
|
|
||||||
SFR_NIC_DATA_U16LE = (uint16_t) uip_buf + VLAN_TAG_SIZE;
|
|
||||||
len = FRAME->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RXTXDBG
|
|
||||||
print_string("TX: \n");
|
|
||||||
for (uint8_t i = 0; i < 100; i++) {
|
|
||||||
print_byte(uip_buf[i]);
|
|
||||||
write_char(' ');
|
|
||||||
}
|
|
||||||
write_char('\n');
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ring_ptr <<= 3;
|
|
||||||
ring_ptr |= 0x8000;
|
|
||||||
SFR_NIC_RING_U16LE = ring_ptr;
|
|
||||||
|
|
||||||
len += 0xf;
|
|
||||||
len >>= 3;
|
|
||||||
SFR_NIC_CTRL = len;
|
|
||||||
while (SFR_NIC_CTRL != 0) {
|
|
||||||
if (++guard == 0) {
|
|
||||||
print_string("NIC: TX transfer did not complete\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Read flash using the MMIO capabilities of the DW8051 core
|
/* Read flash using the MMIO capabilities of the DW8051 core
|
||||||
* Bank is < 0x3f and is the MSB
|
* Bank is < 0x3f and is the MSB
|
||||||
* addr gives the address in the bank
|
* addr gives the address in the bank
|
||||||
@@ -998,8 +897,12 @@ void tcpip_output(void)
|
|||||||
uint16_t ring_ptr = ((uint16_t)sfr_data[2]) << 8;
|
uint16_t ring_ptr = ((uint16_t)sfr_data[2]) << 8;
|
||||||
ring_ptr |= sfr_data[3];
|
ring_ptr |= sfr_data[3];
|
||||||
|
|
||||||
// Move data over from xmem buffer to ASIC side using DMA
|
// Move data over from xmem buffer to ASIC side using DMA. A VLAN-tagged
|
||||||
nic_tx_packet(ring_ptr);
|
// frame starts at uip_buf; an untagged frame retains four bytes of padding.
|
||||||
|
if (frame_tagged)
|
||||||
|
nic_tx_packet(uip_buf, FRAME_Q->len, ring_ptr);
|
||||||
|
else
|
||||||
|
nic_tx_packet(uip_buf + VLAN_TAG_SIZE, FRAME->len, ring_ptr);
|
||||||
|
|
||||||
// New position of the ring-pointer on the NIC-side indicates number of bytes transmitted
|
// New position of the ring-pointer on the NIC-side indicates number of bytes transmitted
|
||||||
reg_read_m(RTL837X_REG_NIC_TX_CURR_PKT);
|
reg_read_m(RTL837X_REG_NIC_TX_CURR_PKT);
|
||||||
@@ -1036,7 +939,7 @@ void handle_rx(void)
|
|||||||
write_char(' ');
|
write_char(' ');
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!nic_rx_packet((uint16_t) &uip_buf[0], ring_ptr + 8)) {
|
if (!nic_rx_packet(uip_buf, ring_ptr + 8)) {
|
||||||
REG_SET(RTL837X_REG_NIC_RXCMD, 1);
|
REG_SET(RTL837X_REG_NIC_RXCMD, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1301,6 +1204,7 @@ static void handle_tick(void)
|
|||||||
health_phase(HEALTH_PH_STP);
|
health_phase(HEALTH_PH_STP);
|
||||||
lldp_tick();
|
lldp_tick();
|
||||||
health_phase(HEALTH_LLDP);
|
health_phase(HEALTH_LLDP);
|
||||||
|
cabletest_tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1682,7 +1586,7 @@ void main(void)
|
|||||||
// Flash controller should be initialized before any code in other banks is being fetched
|
// Flash controller should be initialized before any code in other banks is being fetched
|
||||||
// See this issue: https://github.com/logicog/RTLPlayground/issues/70
|
// See this issue: https://github.com/logicog/RTLPlayground/issues/70
|
||||||
print_string("\nInitializing Flash controller\n");
|
print_string("\nInitializing Flash controller\n");
|
||||||
flash_init(1);
|
flash_init(machine.flash_sio ? 0 : 1);
|
||||||
|
|
||||||
// Set default for SFP pins so we can start up a module already inserted
|
// Set default for SFP pins so we can start up a module already inserted
|
||||||
sfp_pins_last = 0x33; // signal LOS and no module inserted (for both slots, even if only 1 present)
|
sfp_pins_last = 0x33; // signal LOS and no module inserted (for both slots, even if only 1 present)
|
||||||
@@ -1803,7 +1707,6 @@ void main(void)
|
|||||||
lacpEnabled = 0;
|
lacpEnabled = 0;
|
||||||
lacp_init();
|
lacp_init();
|
||||||
nic_setup();
|
nic_setup();
|
||||||
REG_SET(RTL837X_NIC_INT_MSK, NIC_INT_RXIE);
|
|
||||||
trap_init();
|
trap_init();
|
||||||
vlan_setup();
|
vlan_setup();
|
||||||
port_l2_setup();
|
port_l2_setup();
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ TESTS = $(BUILDDIR)/test_cmd_editor \
|
|||||||
$(BUILDDIR)/test_page_json \
|
$(BUILDDIR)/test_page_json \
|
||||||
$(BUILDDIR)/test_httpd_tx \
|
$(BUILDDIR)/test_httpd_tx \
|
||||||
$(BUILDDIR)/test_tick_gate \
|
$(BUILDDIR)/test_tick_gate \
|
||||||
|
$(BUILDDIR)/test_nic_rx \
|
||||||
$(BUILDDIR)/test_lacp
|
$(BUILDDIR)/test_lacp
|
||||||
|
|
||||||
# The table tests link the register mock and one environment file; stub/
|
# The table tests link the register mock and one environment file; stub/
|
||||||
@@ -52,6 +53,11 @@ $(BUILDDIR)/test_port_tables: test_port_tables.c $(TABLE_ENV) hw_mock.h | $(BUIL
|
|||||||
$(BUILDDIR)/test_tick_gate: test_tick_gate.c support.c $(SRCROOT)/cmd_editor.c | $(BUILDDIR)
|
$(BUILDDIR)/test_tick_gate: test_tick_gate.c support.c $(SRCROOT)/cmd_editor.c | $(BUILDDIR)
|
||||||
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
|
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
|
# Exercise the production RX ring reader; only the hardware DMA edge is mocked.
|
||||||
|
# Discard unused TX functions so this RX fixture needs no TX register mocks.
|
||||||
|
$(BUILDDIR)/test_nic_rx: test_nic_rx.c $(SRCROOT)/rtl837x_nic.c $(SRCROOT)/rtl837x_nic.h | $(BUILDDIR)
|
||||||
|
$(CC) $(CFLAGS) -ffunction-sections -fdata-sections $(filter %.c,$^) -o $@ $(LDFLAGS) -Wl,--gc-sections
|
||||||
|
|
||||||
$(BUILDDIR)/test_page_json: test_page_json.c $(TABLE_ENV) hw_mock.h | $(BUILDDIR)
|
$(BUILDDIR)/test_page_json: test_page_json.c $(TABLE_ENV) hw_mock.h | $(BUILDDIR)
|
||||||
$(CC) $(CFLAGS) $(filter %.c,$^) -o $@ $(LDFLAGS)
|
$(CC) $(CFLAGS) $(filter %.c,$^) -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ void read_reg_timer(uint32_t *tmr) { *tmr = 0; }
|
|||||||
|
|
||||||
/* uip-conf.h asks uIP not to define the packet buffer: on the switch it lives
|
/* uip-conf.h asks uIP not to define the packet buffer: on the switch it lives
|
||||||
* at a fixed XDATA address, so the bench provides the storage itself. */
|
* at a fixed XDATA address, so the bench provides the storage itself. */
|
||||||
u8_t uip_buf[UIP_BUFSIZE + 2];
|
u8_t uip_buf[UIP_CONF_BUFFER_ALLOC_SIZE];
|
||||||
|
|
||||||
uint16_t strlen_x(const char *s) { return (uint16_t)strlen(s); }
|
uint16_t strlen_x(const char *s) { return (uint16_t)strlen(s); }
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
/* ---------- platform mocks ---------- */
|
/* ---------- platform mocks ---------- */
|
||||||
|
|
||||||
uint8_t uip_buf[UIP_CONF_BUFFER_SIZE + 2];
|
uint8_t uip_buf[UIP_CONF_BUFFER_ALLOC_SIZE];
|
||||||
uint16_t uip_len;
|
uint16_t uip_len;
|
||||||
struct uip_eth_addr uip_ethaddr = { .addr = {0x02,0x11,0x22,0x33,0x44,0x55} };
|
struct uip_eth_addr uip_ethaddr = { .addr = {0x02,0x11,0x22,0x33,0x44,0x55} };
|
||||||
const struct machine machine = { .min_port = 0, .max_port = 7,
|
const struct machine machine = { .min_port = 0, .max_port = 7,
|
||||||
|
|||||||
@@ -0,0 +1,277 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "rtl837x_common.h"
|
||||||
|
#include "rtl837x_regs.h"
|
||||||
|
#include "rtl837x_nic.h"
|
||||||
|
|
||||||
|
uint8_t rx_headers[16];
|
||||||
|
|
||||||
|
/* Model the DMA behavior reported on SWTGW218AS: a transfer starting inside
|
||||||
|
* the RX ring wraps at its end. An initial address outside the ring instead
|
||||||
|
* reads flat ASIC memory, including stale TX bytes at 0x2800. */
|
||||||
|
static uint8_t asic[0x8000];
|
||||||
|
static struct {
|
||||||
|
uint8_t before[16];
|
||||||
|
uint8_t data[UIP_CONF_BUFFER_ALLOC_SIZE];
|
||||||
|
uint8_t after[16];
|
||||||
|
} destination;
|
||||||
|
|
||||||
|
struct dma_request {
|
||||||
|
uint8_t *buffer;
|
||||||
|
uint16_t ring;
|
||||||
|
uint8_t words;
|
||||||
|
};
|
||||||
|
static struct dma_request requests[8];
|
||||||
|
static unsigned request_count, fail_request;
|
||||||
|
static int failures;
|
||||||
|
|
||||||
|
static void check(bool condition, const char *what)
|
||||||
|
{
|
||||||
|
if (!condition) {
|
||||||
|
printf(" FAIL: %s\n", what);
|
||||||
|
failures++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nic_rx_dma(uint8_t *buffer, uint16_t ring, uint8_t words)
|
||||||
|
{
|
||||||
|
size_t bytes = (size_t)words * 8;
|
||||||
|
unsigned call = ++request_count;
|
||||||
|
|
||||||
|
if (call <= sizeof(requests) / sizeof(requests[0]))
|
||||||
|
requests[call - 1] = (struct dma_request){ buffer, ring, words };
|
||||||
|
if (call == fail_request || !words || (size_t)ring + bytes > sizeof(asic))
|
||||||
|
return false;
|
||||||
|
if (ring < RTL837X_NIC_RX_RING_BYTES) {
|
||||||
|
for (size_t i = 0; i < bytes; i++)
|
||||||
|
buffer[i] = asic[((size_t)ring + i) % RTL837X_NIC_RX_RING_BYTES];
|
||||||
|
} else {
|
||||||
|
memcpy(buffer, asic + ring, bytes);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fixture_reset(void)
|
||||||
|
{
|
||||||
|
memset(asic, 0xd7, sizeof(asic));
|
||||||
|
memset(&destination, 0xa5, sizeof(destination));
|
||||||
|
memset(rx_headers, 0x6c, sizeof(rx_headers));
|
||||||
|
memset(requests, 0, sizeof(requests));
|
||||||
|
request_count = 0;
|
||||||
|
fail_request = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool filled(const uint8_t *data, size_t len, uint8_t value)
|
||||||
|
{
|
||||||
|
while (len--)
|
||||||
|
if (*data++ != value)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool guards_intact(void)
|
||||||
|
{
|
||||||
|
return filled(destination.before, sizeof(destination.before), 0xa5)
|
||||||
|
&& filled(destination.after, sizeof(destination.after), 0xa5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool requests_start_in_rx_ring(void)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < request_count; i++) {
|
||||||
|
if (i >= sizeof(requests) / sizeof(requests[0]) || !requests[i].words
|
||||||
|
|| (requests[i].ring & 7)
|
||||||
|
|| requests[i].ring >= RTL837X_NIC_RX_RING_BYTES)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ring_write(uint16_t offset, const uint8_t *data, size_t len)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < len; i++)
|
||||||
|
asic[((size_t)offset + i) % RTL837X_NIC_RX_RING_BYTES] = data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_descriptor(uint16_t offset, uint16_t len)
|
||||||
|
{
|
||||||
|
uint8_t descriptor[8] = { 0x03, 0x00, 0xb0, 0xc8, len, len >> 8, 0, 0 };
|
||||||
|
ring_write(offset, descriptor, sizeof(descriptor));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void expect_descriptor(uint16_t len)
|
||||||
|
{
|
||||||
|
uint8_t descriptor[8] = { 0x03, 0x00, 0xb0, 0xc8, len, len >> 8, 0, 0 };
|
||||||
|
check(!memcmp(rx_headers, descriptor, sizeof(descriptor)), "the first eight descriptor bytes stay intact");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pattern(uint8_t *data, size_t len)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < len; i++)
|
||||||
|
data[i] = (uint8_t)(i * 37 + (i >> 8) + 0x13);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void t_last_descriptor(void)
|
||||||
|
{
|
||||||
|
static const uint8_t root_bpdu[68] = {
|
||||||
|
0x01, 0x80, 0xc2, 0, 0, 0, 0xd0, 0xea, 0x11, 0x12, 0x34, 0x56,
|
||||||
|
0x88, 0x99, 0x04, 0, 0, 0, 0, 8,
|
||||||
|
0, 0x27, 0x42, 0x42, 3, 0, 0, 2, 2, 0x3c,
|
||||||
|
0x10, 0, 0xd0, 0xea, 0x11, 0x12, 0x34, 0x56, 0, 0, 0, 0,
|
||||||
|
0x10, 0, 0xd0, 0xea, 0x11, 0x12, 0x34, 0x56, 0x80, 0x0a,
|
||||||
|
0, 0, 0x14, 0, 2, 0, 0x0f, 0, 0
|
||||||
|
};
|
||||||
|
uint8_t stale_tx[72] = { 0 };
|
||||||
|
uint16_t last = RTL837X_NIC_RX_RING_BYTES - 8;
|
||||||
|
|
||||||
|
printf("[test] the last RX descriptor wraps its BPDU payload before DMA\n");
|
||||||
|
fixture_reset();
|
||||||
|
put_descriptor(last, sizeof(root_bpdu));
|
||||||
|
ring_write(0, root_bpdu, sizeof(root_bpdu));
|
||||||
|
memcpy(stale_tx, root_bpdu, sizeof(root_bpdu));
|
||||||
|
stale_tx[17] = 0x20;
|
||||||
|
stale_tx[19] = 1; /* retained TX destination mask, not ingress port 8 */
|
||||||
|
memcpy(asic + RTL837X_NIC_RX_RING_BYTES, stale_tx, sizeof(stale_tx));
|
||||||
|
check(nic_rx_header(last), "the final descriptor is readable");
|
||||||
|
expect_descriptor(sizeof(root_bpdu));
|
||||||
|
check(nic_rx_packet(destination.data, last + 8), "a payload address at the RX ring limit wraps to zero");
|
||||||
|
check(!memcmp(destination.data, root_bpdu, sizeof(root_bpdu)), "the complete upstream BPDU is read instead of stale TX bytes");
|
||||||
|
check(destination.data[19] == 8, "the upstream ingress tag survives the ring boundary");
|
||||||
|
check(request_count == 2 && requests[0].ring == last && requests[0].words == 1
|
||||||
|
&& requests[1].ring == 0 && requests[1].words == 9,
|
||||||
|
"descriptor and rounded payload DMA both start in the RX ring");
|
||||||
|
check(requests_start_in_rx_ring() && guards_intact(), "DMA starts inside the RX ring and preserves destination guards");
|
||||||
|
expect_descriptor(sizeof(root_bpdu));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void t_payload_layouts(void)
|
||||||
|
{
|
||||||
|
static const struct {
|
||||||
|
uint16_t descriptor, len;
|
||||||
|
} cases[] = {
|
||||||
|
{ 0x0100, 8 }, { 0x0100, 16 }, { 0x0100, 64 },
|
||||||
|
{ 0x0100, 68 }, { 0x0100, 72 },
|
||||||
|
{ RTL837X_NIC_RX_RING_BYTES - 16, 8 },
|
||||||
|
{ RTL837X_NIC_RX_RING_BYTES - 16, 16 },
|
||||||
|
{ RTL837X_NIC_RX_RING_BYTES - 16, 68 },
|
||||||
|
{ RTL837X_NIC_RX_RING_BYTES - 72, 64 },
|
||||||
|
{ RTL837X_NIC_RX_RING_BYTES - 48, 68 }
|
||||||
|
};
|
||||||
|
uint8_t frame[80];
|
||||||
|
|
||||||
|
printf("[test] payload DMA handles ordinary, exact-boundary, and crossing frames\n");
|
||||||
|
pattern(frame, sizeof(frame));
|
||||||
|
for (unsigned i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||||
|
size_t rounded = (cases[i].len + 7u) & ~7u;
|
||||||
|
fixture_reset();
|
||||||
|
put_descriptor(cases[i].descriptor, cases[i].len);
|
||||||
|
ring_write(cases[i].descriptor + 8, frame, rounded);
|
||||||
|
check(nic_rx_header(cases[i].descriptor), "the descriptor transfer completes");
|
||||||
|
check(nic_rx_packet(destination.data, cases[i].descriptor + 8), "the payload transfer completes");
|
||||||
|
check(!memcmp(destination.data, frame, rounded), "every payload and permitted padding byte reaches the correct destination offset");
|
||||||
|
check(filled(destination.data + rounded, sizeof(destination.data) - rounded, 0xa5), "DMA does not write beyond the rounded frame");
|
||||||
|
check(request_count == 2, "the payload uses one DMA request even when crossing the ring end");
|
||||||
|
check(requests_start_in_rx_ring() && guards_intact(), "crossing DMA starts inside the RX ring and preserves destination guards");
|
||||||
|
expect_descriptor(cases[i].len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void t_maximum_frames(void)
|
||||||
|
{
|
||||||
|
uint8_t frame[(UIP_CONF_BUFFER_SIZE + 7u) & ~7u];
|
||||||
|
static const uint16_t lengths[] = { 1, 7, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556 };
|
||||||
|
|
||||||
|
printf("[test] rounded maximum frames fit without overwriting their descriptor\n");
|
||||||
|
pattern(frame, sizeof(frame));
|
||||||
|
for (unsigned layout = 0; layout < 3; layout++) {
|
||||||
|
uint16_t descriptor = layout == 0 ? 0x0100
|
||||||
|
: RTL837X_NIC_RX_RING_BYTES - (layout == 1 ? 16 : 8);
|
||||||
|
for (unsigned i = 0; i < sizeof(lengths) / sizeof(lengths[0]); i++) {
|
||||||
|
uint16_t len = lengths[i];
|
||||||
|
size_t rounded = (len + 7u) & ~7u;
|
||||||
|
fixture_reset();
|
||||||
|
put_descriptor(descriptor, len);
|
||||||
|
ring_write(descriptor + 8, frame, rounded);
|
||||||
|
check(nic_rx_header(descriptor), "the maximum-frame descriptor transfer completes");
|
||||||
|
check(nic_rx_packet(destination.data, descriptor + 8), "all supported frame lengths fit the destination");
|
||||||
|
check(!memcmp(destination.data, frame, rounded), "the full rounded frame is preserved");
|
||||||
|
check(filled(destination.data + rounded, sizeof(destination.data) - rounded, 0xa5), "rounded DMA writes no bytes beyond the available destination");
|
||||||
|
check(request_count == 2, "maximum frames use a single payload DMA request");
|
||||||
|
check(requests_start_in_rx_ring() && guards_intact(), "rounded DMA starts inside the RX ring and preserves destination guards");
|
||||||
|
expect_descriptor(len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void t_invalid_frames(void)
|
||||||
|
{
|
||||||
|
static const uint16_t invalid_lengths[] = { 0, UIP_CONF_BUFFER_SIZE + 1, 0xffff };
|
||||||
|
static const uint16_t invalid_pointers[] = { 1, 7, RTL837X_NIC_RX_RING_BYTES + 8, 0xfff8 };
|
||||||
|
|
||||||
|
printf("[test] invalid lengths and DMA addresses are rejected before transfer\n");
|
||||||
|
for (unsigned i = 0; i < sizeof(invalid_lengths) / sizeof(invalid_lengths[0]); i++) {
|
||||||
|
fixture_reset();
|
||||||
|
rx_headers[4] = invalid_lengths[i];
|
||||||
|
rx_headers[5] = invalid_lengths[i] >> 8;
|
||||||
|
check(!nic_rx_packet(destination.data, 0x0100), "unsupported or overflowing lengths are rejected");
|
||||||
|
check(!request_count && filled(destination.data, sizeof(destination.data), 0xa5) && guards_intact(),
|
||||||
|
"invalid frame lengths cause no DMA or destination changes");
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < sizeof(invalid_pointers) / sizeof(invalid_pointers[0]); i++) {
|
||||||
|
fixture_reset();
|
||||||
|
rx_headers[4] = 68;
|
||||||
|
rx_headers[5] = 0;
|
||||||
|
check(!nic_rx_header(invalid_pointers[i]), "an invalid descriptor address is rejected");
|
||||||
|
check(!nic_rx_packet(destination.data, invalid_pointers[i]), "an invalid payload address is rejected");
|
||||||
|
check(!request_count && guards_intact(), "invalid addresses never reach DMA");
|
||||||
|
}
|
||||||
|
fixture_reset();
|
||||||
|
check(!nic_rx_header(RTL837X_NIC_RX_RING_BYTES) && !request_count,
|
||||||
|
"a descriptor at the ring limit is rejected rather than wrapped");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void t_dma_failure(void)
|
||||||
|
{
|
||||||
|
uint8_t frame[UIP_CONF_BUFFER_ALLOC_SIZE];
|
||||||
|
static const uint16_t lengths[] = { 68, UIP_CONF_BUFFER_SIZE };
|
||||||
|
|
||||||
|
printf("[test] failed descriptor and single-payload DMA transfers propagate failure\n");
|
||||||
|
fixture_reset();
|
||||||
|
fail_request = 1;
|
||||||
|
check(!nic_rx_header(0x0100) && request_count == 1, "descriptor DMA failure reaches the caller");
|
||||||
|
pattern(frame, sizeof(frame));
|
||||||
|
for (unsigned layout = 0; layout < 3; layout++) {
|
||||||
|
uint16_t descriptor = layout == 0 ? 0x0100
|
||||||
|
: RTL837X_NIC_RX_RING_BYTES - (layout == 1 ? 16 : 8);
|
||||||
|
for (unsigned i = 0; i < sizeof(lengths) / sizeof(lengths[0]); i++) {
|
||||||
|
uint16_t len = lengths[i];
|
||||||
|
fixture_reset();
|
||||||
|
put_descriptor(descriptor, len);
|
||||||
|
ring_write(descriptor + 8, frame, (len + 7u) & ~7u);
|
||||||
|
check(nic_rx_header(descriptor), "the descriptor precedes the injected payload failure");
|
||||||
|
fail_request = 2;
|
||||||
|
check(!nic_rx_packet(destination.data, descriptor + 8), "payload DMA failure reaches the caller");
|
||||||
|
check(request_count == fail_request, "a failed payload DMA is not retried or split");
|
||||||
|
check(filled(destination.data, sizeof(destination.data), 0xa5) && guards_intact(),
|
||||||
|
"an injected failure before DMA preserves the destination and guards");
|
||||||
|
expect_descriptor(len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
t_last_descriptor();
|
||||||
|
t_payload_layouts();
|
||||||
|
t_maximum_frames();
|
||||||
|
t_invalid_frames();
|
||||||
|
t_dma_failure();
|
||||||
|
if (failures) {
|
||||||
|
printf("%d NIC RX check(s) failed\n", failures);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
puts("all NIC RX checks passed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -185,6 +185,23 @@ static void t_l2_page(void)
|
|||||||
CHECK(balanced(), "every page is valid JSON");
|
CHECK(balanced(), "every page is valid JSON");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void t_status_macs(void)
|
||||||
|
{
|
||||||
|
const char *p1, *end, *mac;
|
||||||
|
|
||||||
|
printf("[test] /status.json reports the MAC addresses learned on each port\n");
|
||||||
|
hw_reset(); out_reset();
|
||||||
|
hw_reg_set(RTL837X_L2_LRN_PORT_CONSTRT_CNT + (1 << 2), 0x21);
|
||||||
|
send_status();
|
||||||
|
p1 = strstr(body(), "\"logPort\":1,");
|
||||||
|
end = p1 ? strchr(p1, '}') : NULL;
|
||||||
|
mac = p1 ? strstr(p1, "\"macs\":\"0x21\"") : NULL;
|
||||||
|
CHECK(mac && mac < end, "port 1 shows its learned count");
|
||||||
|
CHECK(has("\"macs\":\"0x0\""), "a port without learned addresses shows 0");
|
||||||
|
CHECK(slen <= TCP_OUTBUF_SIZE, "fits the buffer");
|
||||||
|
CHECK(balanced(), "valid JSON");
|
||||||
|
}
|
||||||
|
|
||||||
static void t_status_counters(void)
|
static void t_status_counters(void)
|
||||||
{
|
{
|
||||||
printf("[test] /status.json prints 64-bit packet counters in full\n");
|
printf("[test] /status.json prints 64-bit packet counters in full\n");
|
||||||
@@ -211,6 +228,7 @@ int main(void)
|
|||||||
t_l2();
|
t_l2();
|
||||||
t_l2_page();
|
t_l2_page();
|
||||||
t_status_counters();
|
t_status_counters();
|
||||||
|
t_status_macs();
|
||||||
printf("\n%d checks, %d failed\n", tests_run, tests_failed);
|
printf("\n%d checks, %d failed\n", tests_run, tests_failed);
|
||||||
return tests_failed ? 1 : 0;
|
return tests_failed ? 1 : 0;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Compile the current firmware execute_config() with mocked flash/tokenizer edges."""
|
||||||
|
import pathlib, subprocess
|
||||||
|
root=pathlib.Path(__file__).resolve().parent.parent
|
||||||
|
src=(root/'cmd_parser.c').read_text()
|
||||||
|
start=src.index('void execute_config(void) __banked')
|
||||||
|
end=src.index('// Execute multiple commands',start)
|
||||||
|
body=src[start:end]
|
||||||
|
out=root/'test/build';out.mkdir(exist_ok=True)
|
||||||
|
harness=r"""
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#define __xdata
|
||||||
|
#define __banked
|
||||||
|
#define CONFIG_START 0
|
||||||
|
#define CONFIG_LEN 1024
|
||||||
|
#define FLASH_READ_BURST_SIZE 256
|
||||||
|
#define CMD_BUF_SIZE 64
|
||||||
|
#define ERR_OK 0
|
||||||
|
#define NUL 0
|
||||||
|
#define PASSWORD "test-default"
|
||||||
|
uint8_t flash_buf[256],cmd_buffer[64],save_cmd,err_status;
|
||||||
|
char passwd[32],image[1024],seen[16][64];int count;
|
||||||
|
struct {uint32_t addr;uint16_t len;} flash_region;
|
||||||
|
void strtox(char*d,const char*s){strcpy(d,s);}
|
||||||
|
void flash_read_bulk(uint8_t*d){memcpy(d,image+flash_region.addr,256);}
|
||||||
|
void print_string(const char*s){(void)s;}
|
||||||
|
void print_string_x(uint8_t*s){(void)s;}
|
||||||
|
void write_char(char c){(void)c;}
|
||||||
|
void clear_command_history(void){}
|
||||||
|
void cmd_tokenize(void){err_status=cmd_buffer[0]=='#'?1:0;}
|
||||||
|
void cmd_parser(void){assert(count<16);strcpy(seen[count++],(char*)cmd_buffer);}
|
||||||
|
"""
|
||||||
|
tests=r"""
|
||||||
|
void run(const char*s){memset(image,0,sizeof image);strncpy(image,s,sizeof image-1);count=0;execute_config();assert(save_cmd==1);}
|
||||||
|
int main(void){
|
||||||
|
run("one\ntwo\n");assert(count==2&&!strcmp(seen[1],"two"));
|
||||||
|
run("one\rtwo\r");assert(count==2&&!strcmp(seen[0],"one"));
|
||||||
|
run("one\r\ntwo\r\n");assert(count==2&&!strcmp(seen[1],"two"));
|
||||||
|
run("\r\n# ignored\r\none\r\n\r\ntwo");assert(count==2&&!strcmp(seen[0],"one"));
|
||||||
|
run("one\0ignored");assert(count==1&&!strcmp(seen[0],"one"));
|
||||||
|
char longline[300];memset(longline,'x',sizeof longline);strcpy(longline+280,"\r\nok\r\n");run(longline);assert(count==1&&!strcmp(seen[0],"ok"));
|
||||||
|
/* CR at the end of a flash burst, LF at the start of the next. */
|
||||||
|
char boundary[300];memset(boundary,'\n',255);strcpy(boundary+255,"\r\nok\r\n");run(boundary);assert(count==1&&!strcmp(seen[0],"ok"));
|
||||||
|
puts("startup CR/LF/CRLF, comments, NUL, overlong and burst-boundary cases passed");return 0;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
(out/'startup_crlf.c').write_text(harness+body+tests)
|
||||||
|
subprocess.run(['gcc','-std=gnu11','-Wall','-Wextra','-Werror','-g','-fsanitize=address,undefined','-fno-omit-frame-pointer','-no-pie',str(out/'startup_crlf.c'),'-o',str(out/'test_startup_crlf')],check=True)
|
||||||
|
subprocess.run([str(out/'test_startup_crlf')],check=True)
|
||||||
@@ -56,6 +56,7 @@ time_t last_session_use;
|
|||||||
|
|
||||||
uint64_t txG[PORTS], txB[PORTS], rxG[PORTS], rxB[PORTS];
|
uint64_t txG[PORTS], txB[PORTS], rxG[PORTS], rxB[PORTS];
|
||||||
char txG_buff[20], txB_buff[20], rxG_buff[20], rxB_buff[20], counter_buf[20], counter_name[20];
|
char txG_buff[20], txB_buff[20], rxG_buff[20], rxB_buff[20], counter_buf[20], counter_name[20];
|
||||||
|
char macs_buff[8];
|
||||||
char sfp_temp[8], sfp_vcc[8], sfp_txbias[8], sfp_txpower[8], sfp_rxpower[8], sfp_laser[8], sfp_options[6];
|
char sfp_temp[8], sfp_vcc[8], sfp_txbias[8], sfp_txpower[8], sfp_rxpower[8], sfp_laser[8], sfp_options[6];
|
||||||
char num_buff[20];
|
char num_buff[20];
|
||||||
char l2_idx_buff[20];
|
char l2_idx_buff[20];
|
||||||
@@ -180,6 +181,12 @@ void send_status(int s)
|
|||||||
json_object_object_add(v, "txB", json_object_new_string(txB_buff));
|
json_object_object_add(v, "txB", json_object_new_string(txB_buff));
|
||||||
json_object_object_add(v, "rxG", json_object_new_string(rxG_buff));
|
json_object_object_add(v, "rxG", json_object_new_string(rxG_buff));
|
||||||
json_object_object_add(v, "rxB", json_object_new_string(rxB_buff));
|
json_object_object_add(v, "rxB", json_object_new_string(rxB_buff));
|
||||||
|
uint16_t macs = 0;
|
||||||
|
for (int e = 0; e < L2_ENTRY_NUM; e++)
|
||||||
|
if (l2_entries[e].port == physToLogPort[i-1] && l2_entries[e].type != 's')
|
||||||
|
macs++;
|
||||||
|
sprintf(macs_buff, "0x%04x", macs);
|
||||||
|
json_object_object_add(v, "macs", json_object_new_string(macs_buff));
|
||||||
if (i >= PORTS - NSFP) {
|
if (i >= PORTS - NSFP) {
|
||||||
uint16_t temp = 0x28fb + rand() / (RAND_MAX / 100);
|
uint16_t temp = 0x28fb + rand() / (RAND_MAX / 100);
|
||||||
uint16_t vcc = 0x7eda + rand() / (RAND_MAX / 100);
|
uint16_t vcc = 0x7eda + rand() / (RAND_MAX / 100);
|
||||||
|
|||||||
@@ -132,6 +132,10 @@ typedef unsigned short uip_stats_t;
|
|||||||
*/
|
*/
|
||||||
#define UIP_CONF_BUFFER_SIZE 1556
|
#define UIP_CONF_BUFFER_SIZE 1556
|
||||||
|
|
||||||
|
/* Backing storage includes padding for the NIC's eight-byte DMA transfers.
|
||||||
|
* Keep UIP_CONF_BUFFER_SIZE as the logical frame/MSS limit. */
|
||||||
|
#define UIP_CONF_BUFFER_ALLOC_SIZE ((UIP_CONF_BUFFER_SIZE + 7U) & ~7U)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bytes of the buffer kept out of the advertised MSS.
|
* Bytes of the buffer kept out of the advertised MSS.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ static __code const uip_ipaddr_t all_zeroes_addr =
|
|||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
|
|
||||||
#ifndef UIP_CONF_EXTERNAL_BUFFER
|
#ifndef UIP_CONF_EXTERNAL_BUFFER
|
||||||
u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains
|
u8_t uip_buf[UIP_CONF_BUFFER_ALLOC_SIZE]; /* The packet buffer that contains
|
||||||
incoming packets. */
|
incoming packets. */
|
||||||
#endif /* UIP_CONF_EXTERNAL_BUFFER */
|
#endif /* UIP_CONF_EXTERNAL_BUFFER */
|
||||||
|
|
||||||
|
|||||||
@@ -419,7 +419,7 @@
|
|||||||
#endif /* UIP_CONF_BUFFER_EXTRA */
|
#endif /* UIP_CONF_BUFFER_EXTRA */
|
||||||
|
|
||||||
|
|
||||||
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
|
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_ALLOC_SIZE];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if statistics support should be compiled in.
|
* Determines if statistics support should be compiled in.
|
||||||
|
|||||||