diff --git a/doc/devices/2M-PCB23-V3_1.md b/doc/devices/2M-PCB23-V3_1.md
index d347465..8ec817d 100644
--- a/doc/devices/2M-PCB23-V3_1.md
+++ b/doc/devices/2M-PCB23-V3_1.md
@@ -5,13 +5,30 @@
|---|---|---|---|---|---|
| keepLINK | KP-9000-9XHML-X | Yes| 2M-PCB23-V3.1 | 2M| 8273N + 8224N |
+## PCB
+
+
+
+## Port overview
+
+```
+┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
+│ ┌──────────┐ │
+│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ SFP (J4) │ │
+│ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ PORT 9 │ │
+│ │ PORT 1 │ │ PORT 2 │ │ PORT 3 │ │ PORT 4 │ │ PORT 5 │ │ PORT 6 │ │ PORT 7 │ │ PORT 8 │ │ MAC 8 │ O (PWR) │
+│ O │ MAC 0 │ │ MAC 1 │ │ MAC 2 │ │ MAC 3 │ │ MAC 4 │ │ MAC 5 │ │ MAC 6 │ │ MAC 7 │ │ SerDes 1 │ O (SFP) │
+│ RST └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘ │
+└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
+```
+
# Connectors
|`J4` SFP PINs | Signal | Component | GPIO | Notes |
|---|---|---|---|---|
|2| TX_FAULT | | --- | |
|3| TX_DISABLE | | --- | Pull down - 0R |
-|4| MODDEF2 – SDA | b-r273 | GPIO39 | |
-|5| MODDEF1 – SCL | b-r274 | GPIO40 | |
+|4| MODDEF2 – SDA | b-r273 | GPIO39-SDA4 | |
+|5| MODDEF1 – SCL | b-r274 | GPIO40-SCL3 | |
|6| MODDEF0 – PRESENT | B-R275 | GPIO38 | |
|7| RATE SEL | | --- | |
|8| LOS | B-R276 | GPIO38 | |
@@ -31,15 +48,26 @@ Note: component numbering `--`
| 3 | GPIO32 | U0RXD (Input) |
| 4 | 3V3 | PWR |
-### T7
-|`T7` pin|what|Signal|
-|---|---|---|
-| 1 | GPIO | |
-| 2 | GND | |
-| 3 | GPIO | |
-| 4 | 3V3 | |
-| 5 | GPIO | |
-| 6 | GPIO | |
+### T7, Slave Interface
+|`T7` pin|what|Signal|Components|
+|---|---|---|---|
+| 1 | Slave Interface | Slave SCK/SCL/MDC/EE_SCL | U7-6 |
+| 2 | GND | | |
+| 3 | Slave Interface | Slave SDI/SDA/MDIO/EE_SDA | U7-5 |
+| 4 | 3V3 | | |
+| 5 | GPIO? | | |
+| 6 | GPIO? | | |
+
+`U7` can be a standard I2C eeprom memory, like `24LC32`.
+
+The Slave Interface allows an extenal host to controll the SOC even if the internal MCU is used.
+Depending on the `IF_SEL` bootstrap resistors, this can me `I2C`, `SPI` or `SMI`.
+On this device it is `I2C` on address `0b1011100` or `0x5c` (7-bit notation).
+
+* I2c Read: must be a write_read opperation `` ``.
+* I2c Write: ``.
+
+Example register `0x0004` return chip id `0x00, 0x00, 0x72, 0x83` = `0x83720000`.
### T9
|`T9` SMI | Signal | Component | GPIO | Notes |
@@ -67,23 +95,23 @@ Reset-line found at `T-D6-L`, `T-R83`, `T-R97`, `T-R94`, `T-R93` active-low.
| HEX VAL. | GPIO | Component | What | | GPIO | Component | What |
| -------- | ------ | ---- | ---- | ---- | ---- | ---- | ---- |
| 00000001 | GPIO00 | T-R34-R, P1-LED-YL |? | | GPIO32 | B-r126-r | U0RXD |
-| 00000002 | GPIO01 | T-R99-R, P1-LED-GR |? | | GPIO33 | | |
-| 00000004 | GPIO02 | |? | | GPIO34 | B-R172, To RTL8225 | Already driver HIGH INT? |
-| 00000008 | GPIO03 | T-R113-R, P2-LED-GR |? | | GPIO35 | B-R173, To RTL8225 | Easy to pulldown Reset? |
-| 00000010 | GPIO04 | T-R115-R, P3-LED-YL |? | | GPIO36 || | |
-| 00000020 | GPIO05 | T-R117-R, P3-LED-GR |? | | GPIO37 | To RTL8225 | Already driver low I2C-SCL? | |
-| 00000040 | GPIO06 | |? | | GPIO38 | sfp-6 via B-R275, sfp-8 via B-R276 | |
-| 00000080 | GPIO07 | |? | | GPIO39 | sfp-4, b-r273, B-r143 | |
-| 00000100 | GPIO08 | | | | GPIO40 | T9-2, sfp-5 b-r274, B-r146 | SMI-MDC |
-| 00000200 | GPIO09 | |LEDx[^1] | | GPIO41 | T9-1, | SMI-MDO , B-r143 |
+| 00000002 | GPIO01 | T-R99-R, P1-LED-GR |? | | GPIO33 | | |
+| 00000004 | GPIO02 | |? | | GPIO34 | B-R172, To RTL8224 | SMI-MDC0 |
+| 00000008 | GPIO03 | T-R113-R, P2-LED-GR |? | | GPIO35 | B-R173, To RTL8224 | SMI-MDIO0 |
+| 00000010 | GPIO04 | T-R115-R, P3-LED-YL |? | | GPIO36 | | | |
+| 00000020 | GPIO05 | T-R117-R, P3-LED-GR |? | | GPIO37 | To RTL8224 ?? | Already driver low | |
+| 00000040 | GPIO06 | |? | | GPIO38 | sfp-6 via B-R275, sfp-8 via B-R276 | SFP-PRESENT |
+| 00000080 | GPIO07 | |? | | GPIO39 | sfp-4, b-r273, B-r143 | I2C4-SDA |
+| 00000100 | GPIO08 | | | | GPIO40 | T9-2, sfp-5 b-r274, B-r146 | I2C3-SCL |
+| 00000200 | GPIO09 | |LEDx[^1] | | GPIO41 | T9-1, B-r143 | | I2C3-SDA (Unused) |
| 00000400 | GPIO10 | | | | GPIO42 | U6?8?-P6, T-R | SPI-MEMORY, CLK |
| 00000800 | GPIO11 | |LEDx[^1] | | GPIO43 | U6?8?-P5, T-R | SPI-MEMORY, DI,IO0 |
| 00001000 | GPIO12 | |LEDx[^1] | | GPIO44 | U6?8?-P2, T-R | SPI-MEMORY, DO,IO1 |
| 00002000 | GPIO13 | |LEDx[^1] | | GPIO45 | U6?8?-P1, T-R | SPI-MEMORY, CS |
-| 00004000 | GPIO14 | |LEDx[^1] | | GPIO46 | T10-6 | |
-| 00008000 | GPIO15 | |LEDx[^1] | | GPIO47 | T10-2 | |
-| 00010000 | GPIO16 | |LEDx[^1] | | GPIO48 | T10-4, J6 (BUTTON RESET) | |
-| 00020000 | GPIO17 | |LEDx[^1] | | GPIO49 | T10-1 | |
+| 00004000 | GPIO14 | |LEDx[^1] | | GPIO46 | T10-6 | SPI0-SCK |
+| 00008000 | GPIO15 | |LEDx[^1] | | GPIO47 | T10-2 | SPI0-SDA |
+| 00010000 | GPIO16 | |LEDx[^1] | | GPIO48 | T10-4, J6 (BUTTON RESET) | SPI1-SCK |
+| 00020000 | GPIO17 | |LEDx[^1] | | GPIO49 | T10-1 | SPI1-SDA |
| 00040000 | GPIO18 | |LEDx[^1] | | GPIO50 | | |
| 00080000 | GPIO19 | |LEDx[^1] | | GPIO51 | | |
| 00100000 | GPIO20 | |LEDx[^1] | | GPIO52 | | |
@@ -96,8 +124,8 @@ Reset-line found at `T-D6-L`, `T-R83`, `T-R97`, `T-R94`, `T-R93` active-low.
| 08000000 | GPIO27 | |? | | GPIO59 | | |
| 10000000 | GPIO28 | | | | GPIO60 | | |
| 20000000 | GPIO29 | | | | GPIO61 | | |
-| 40000000 | GPIO30 | |SFP-DETE | | GPIO62 | To RTL8225 | Already driver INT? | |
-| 80000000 | GPIO31 | B-r129-r? |U0TXD | | GPIO63 | | |
+| 40000000 | GPIO30 | RTL8224N Reset |RTL8224 | | GPIO62 | To RTL8224 | Already driver | |
+| 80000000 | GPIO31 | B-r129-r? |U0TXD | | GPIO63 | | |
## GPIO Register Input value
@@ -130,4 +158,4 @@ Chip can deliver up to 5A and the sweetspot is at 2A.
So higher power SFP-modules should work.
-[^1]: LEDs are found by just plugin a RJ45 connector and see with cmd `gpio` the status change. But the bit pattern for port 1,2 are diffrent from port 3,4.
\ No newline at end of file
+[^1]: LEDs are found by just plugin a RJ45 connector and see with cmd `gpio` the status change. But the bit pattern for port 1,2 are diffrent from port 3,4.
diff --git a/doc/devices/HI-K0402WS.md b/doc/devices/HI-K0402WS.md
new file mode 100644
index 0000000..15b62a0
--- /dev/null
+++ b/doc/devices/HI-K0402WS.md
@@ -0,0 +1,62 @@
+# Hisource Hi-K0402WS
+
+Following is documentation for unmanaged switch marked as `Hi-K0402WS`.
+
+Original software is running UART on 9600 baud rate.
+
+Using SPI clamp in-board is the only method for initial installation.
+
+The board has two flash chips `BY25Q16BS` with 16M-bit size. The front switch, switches between the two flash chips.
+These can be programed independently by using said switch - so it is e.g. possible to run the original and new firmware in parallel.
+
+### Label specifications
+
+- **Name**: 2.5G Ethernet Switch
+- **Model**: Hi-K0402WS
+- **Ports**:
+ - 4 × RJ45: 10/100/1000/2500 Mbps
+ - 2 × SFP: 1000 / 2500 / 10000 Mbps
+
+### What works (expected from label + similar devices)
+
+- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
+- Both SFP ports supporting 1G, 2.5G and 10G modules
+- LEDs
+
+### PCB overview
+
+**Board markings**
+- Top silkscreen: PCB-KO4022W-V3.0 / DIP-KO4022WS-V3.0
+
+Top side
+
+
+
+Bottom
+
+
+
+### T2, serial console
+
+| `J2` pin | Signal |
+| -------- | ----------- |
+| 1 | 3V3 |
+| 2 | RX (Input) |
+| 3 | TX (Output) |
+| 4 | GND |
+
+
+## Power supply
+
+Input power is delivered via barell plug, `12V 1A` adapter was provided.
+Board has two supply rails. `0.95` and `3.3` volt.
+
+### `0.95` Core Voltage
+
+Voltage is made by a `Techcode TD1720` .
+
+### `3.3` Voltage
+
+Voltage is created by chip marked as `Techcode TD1720`.
+
+**There seems to have been a miscalculation when choosing the inductor and the device is ~25% more efficient with an 5V power supply.**
diff --git a/html/main.js b/html/main.js
index 9c48581..6c05550 100644
--- a/html/main.js
+++ b/html/main.js
@@ -2,7 +2,7 @@ var txG = new BigInt64Array(10);
var txB = new BigInt64Array(10);
var rxG = new BigInt64Array(10);
var rxB = new BigInt64Array(10);
-const linkS = ["Disabled", "No Link", "100M", "1000M", "500M", "10G", "2.5G", "5G"];
+const linkS = ["Disabled", "Down", "10M", "100M", "1000M", "500M", "10G", "2.5G", "5G"];
var pState = new Int8Array(10);
var pIsSFP = new Int8Array(10);
var pAdvertised = new Int8Array(10);
diff --git a/httpd/page_impl.c b/httpd/page_impl.c
index f8d810b..d89b26b 100644
--- a/httpd/page_impl.c
+++ b/httpd/page_impl.c
@@ -626,13 +626,25 @@ void send_status(void)
}
slen += strtox(outbuf + slen, ",\"link\":");
-
- if (i < 8)
- reg_read_m(RTL837X_REG_LINKS);
+
+ uint8_t b = 0;
+ // Determine link state
+ reg_read_m(RTL837X_REG_LINKS_STS);
+ if(!((sfr_data[(i / 8) + 1] >> (i % 8 ) & 1)))
+ {
+ b = 0; //link down
+ }
else
- reg_read_m(RTL837X_REG_LINKS_89);
- uint8_t b = sfr_data[3 - ((i & 7) >> 1)];
- b = (i & 1) ? b >> 4 : b & 0xf;
+ {
+ //Determine link speed
+ if (i < 8)
+ reg_read_m(RTL837X_REG_LINKS);
+ else
+ reg_read_m(RTL837X_REG_LINKS_89);
+
+ b = sfr_data[3 - ((i & 7) >> 1)];
+ b = ((i & 1) ? b >> 4 : b & 0xf) + 1;
+ }
char_to_html('0' + b);
STAT_GET(STAT_COUNTER_TX_PKTS, i);
diff --git a/machine.c b/machine.c
index a959b79..9c12312 100644
--- a/machine.c
+++ b/machine.c
@@ -2,6 +2,7 @@
#include "rtl837x_pins.h"
#include "rtl837x_leds.h"
#include "rtl837x_regs.h"
+#include "rtl837x_common.h"
#ifdef MACHINE_KP_9000_6XHML_X2
__code const struct machine machine = {
@@ -97,6 +98,40 @@ __code const struct machine machine = {
LEDS_2G5 | LEDS_LINK | LEDS_ACT },
},
};
+#elif defined MACHINE_KP_9000_9XHML_X
+__code const struct machine machine = {
+ .machine_name = "keepLink KP-9000-9XHML-X",
+ .isRTL8373 = 1,
+ .min_port = 0,
+ .max_port = 8,
+ .n_sfp = 1,
+ .log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
+ .phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
+ .is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
+ .sfp_port[0].pin_detect = GPIO38,
+ .sfp_port[0].pin_los = GPIO_NA,
+ .sfp_port[0].sds = 1,
+ .sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
+ .reset_pin = GPIO48_I2C_SCL1,
+ .high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 },
+ .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
+ .led_sets = {
+ { /* RJ45: First LED, yellow, second LED: green */
+ LEDS_2G5 | LEDS_LINK,
+ LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
+ 0,
+ 0,
+ }, { /* SFP PORT, SINGLE GREEN LED */
+ LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
+ 0,
+ 0,
+ 0,
+ }},
+ .led_mux_custom = 1,
+ .led_mux = {0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0c, 0x09, 0x0d, 0x10,
+ 0x11, 0x0e, 0x14, 0x11, 0x12, 0x15, 0x15, 0x16, 0x18, 0x19,
+ 0x1a, 0x19, 0x1d, 0x1e, 0x1c, 0x1d, 0x20, 0x21},
+};
void machine_custom_init(void) { }
@@ -265,6 +300,55 @@ __code const struct machine machine = {
void machine_custom_init(void) { }
+#elif defined MACHINE_HI_K0402WS
+__code const struct machine machine = {
+ .machine_name = "HiSource HI-K0402WS",
+ .isRTL8373 = 0,
+ .min_port = 3,
+ .max_port = 8,
+ .n_sfp = 2,
+ .log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
+ .phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
+ .is_sfp = {0, 0, 0, 1, 0, 0, 0, 0, 1},
+
+ // Left SFP port
+ .sfp_port[0].pin_detect = GPIO38,
+ .sfp_port[0].pin_los = GPIO_NA,
+ .sfp_port[0].sds = 1,
+ .sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
+
+ // Right SFP port
+ .sfp_port[1].pin_detect = GPIO37,
+ .sfp_port[1].pin_los = GPIO_NA,
+ .sfp_port[1].sds = 0,
+ .sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
+
+ .reset_pin = GPIO_NA,
+ .high_leds = { .mux = LED_28 | LED_29, .enable = LED_27 | LED_28 | LED_29 },
+ .port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
+ .led_sets = {
+ {
+ LEDS_2G5 | LEDS_LINK | LEDS_10M | LEDS_ACT,
+ LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
+ LEDS_1G | LEDS_LINK,
+ 0
+ },
+ {
+ LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK,
+ LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_ACT,
+ 0,
+ 0
+ },
+ },
+ .led_mux_custom = 1,
+ .led_mux = {
+ 0x00,0x01,0x04,0x05,0x08,0x09,0x0c,0x3f,0x0d,0x10,0x11,0x0e,0x14,0x11,0x12,0x15,0x15,0x16,0x18,0x19,0x1a,0x19,0x1d,0x1e,0x1c,0x1d,0x20,0x21
+ },
+ };
+
+void machine_custom_init(void) {
+ reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
+}
#else
#error "Please select a machine type in machine.h"
#endif
diff --git a/machine.h b/machine.h
index 4fb3cf8..06a2475 100644
--- a/machine.h
+++ b/machine.h
@@ -14,6 +14,7 @@
// #define MACHINE_TRENDNET_TEG_S562
// #define MACHINE_HG0402XG_V1_1
// #define MACHINE_SWTGW218AS
+// #define MACHINE_HI_K0402WS
// #define DEFAULT_8C_1SFP
typedef struct {
diff --git a/rtl837x_port.c b/rtl837x_port.c
index 322e60d..4e12a6d 100644
--- a/rtl837x_port.c
+++ b/rtl837x_port.c
@@ -369,15 +369,28 @@ void port_stats_print(void) __banked
}
}
- if (i < 8)
- reg_read_m(RTL837X_REG_LINKS);
+ uint8_t b = 0;
+
+ // Determine link state
+ reg_read_m(RTL837X_REG_LINKS_STS);
+ if(!((sfr_data[(i / 8) + 1] >> ( i % 8 ) & 1)))
+ {
+ b = 99;
+ }
else
- reg_read_m(RTL837X_REG_LINKS_89);
- uint8_t b = sfr_data[3 - ((i & 7) >> 1)];
- b = (i & 1) ? b >> 4 : b & 0xf;
+ {
+ if (i < 8)
+ reg_read_m(RTL837X_REG_LINKS);
+ else
+ reg_read_m(RTL837X_REG_LINKS_89);
+
+ b = sfr_data[3 - ((i & 7) >> 1)];
+ b = (i & 1) ? b >> 4 : b & 0xf;
+ }
+
switch (b) {
case 0:
- print_string("Down\t");
+ print_string("10M\t");
break;
case 1:
print_string("100M\t");
@@ -391,6 +404,9 @@ void port_stats_print(void) __banked
case 5:
print_string("2.5G\t");
break;
+ case 99:
+ print_string("Down\t");
+ break;
default:
print_string("Up\t");
break;
diff --git a/rtl837x_regs.h b/rtl837x_regs.h
index 32e7a98..41f5510 100644
--- a/rtl837x_regs.h
+++ b/rtl837x_regs.h
@@ -80,6 +80,8 @@
#define RTL837X_REG_LINKS 0x63f0
#define RTL837X_REG_LINKS_89 0x63f4
+#define RTL837X_REG_LINKS_STS 0x63E8
+
/* Each nibble encodes the link state of a port.
Port 0 appears to be the CPU port
The RTL8372 serves ports 4-7, port 3 is the RTL8221