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 | ||
|
|
6fdb19f18c | ||
|
|
70f8964918 | ||
|
|
aba58e7f99 | ||
|
|
2404e7a9b6 | ||
|
|
6a31b4a279 | ||
|
|
6cd1f683bb | ||
|
|
7e90f6a126 | ||
|
|
9bd301447b | ||
|
|
9745dfe6ae | ||
|
|
d4345c1bf8 | ||
|
|
fcaacd4429 | ||
|
|
0f63244ca1 | ||
|
|
913e9780b8 | ||
|
|
0d748fa808 | ||
|
|
bd974e0aaf | ||
|
|
56686185ce | ||
|
|
ed069b67fd | ||
|
|
b1026490a8 | ||
|
|
b096efd63a |
No files matched your search
@@ -4,6 +4,17 @@
|
||||
|
||||
## 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
|
||||
- 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,
|
||||
|
||||
@@ -103,6 +103,7 @@ SRCS += \
|
||||
rtl837x_flash.c \
|
||||
rtl837x_igmp.c \
|
||||
rtl837x_init.c \
|
||||
rtl837x_nic.c \
|
||||
rtl837x_leds.c \
|
||||
rtl837x_leds_dump.c \
|
||||
rtl837x_phy.c \
|
||||
|
||||
@@ -191,7 +191,7 @@ Go to "Firmware update" tab, select the correct file.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> 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]
|
||||
> Check one more time that your device matches the machine type before flashing.
|
||||
@@ -364,7 +364,7 @@ The following documents give further documentation on specific features of the R
|
||||
- [L2 learning](doc/l2.md)
|
||||
- [IGMP (IP-MC streaming)](doc/igmp.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)
|
||||
- [VLAN](doc/vlan.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
|
||||
// R7848-000004ff
|
||||
REG_SET(RTL837X_REG_NIC_RXBUFF_RX, 0x4ff);
|
||||
REG_SET(RTL837X_REG_NIC_RXBUFF_RX, RTL837X_NIC_RX_LAST_SLOT);
|
||||
|
||||
// R7844-000007fe
|
||||
REG_SET(RTL837X_REG_NIC_BUFFSIZE_TX, 0x7fe);
|
||||
@@ -296,6 +296,7 @@ void nic_setup(void) __banked
|
||||
|
||||
// Sequence number of TX packets
|
||||
tx_seq = 0;
|
||||
REG_SET(RTL837X_NIC_INT_MSK, NIC_INT_RXIE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -745,7 +745,7 @@ void parse_isolate(void)
|
||||
if (cmd_compare(2, "off")) {
|
||||
for (uint8_t i = machine.min_port; i <= machine.max_port; i++)
|
||||
members |= ((uint16_t)1) << i;
|
||||
members |= 0x200; // CPU-port
|
||||
members |= PMASK_CPU; // CPU-port
|
||||
port_isolate(port_configured, members);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ __xdata uip_ipaddr_t server;
|
||||
#define DHCP_END 255
|
||||
|
||||
#pragma codeseg BANK3
|
||||
#pragma constseg BANK2
|
||||
#pragma constseg BANK3
|
||||
|
||||
struct dhcp_pkt {
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
@@ -177,3 +177,20 @@ Once the board has been tested on hardware:
|
||||
`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.
|
||||
@@ -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
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
* 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
|
||||
|
||||
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
|
||||
|
||||
**Board markings**
|
||||
- Top silkscreen: PCB-KO4022W-V3.0 / DIP-KO4022WS-V3.0
|
||||
- Top silkscreen: PCB-K0402W-V3.0 / DIP-K0402WS-V3.0
|
||||
|
||||
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 |
|
||||
| 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`.
|
||||
@@ -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.
|
||||
|
||||
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.
|
||||
|
||||
### Label specifications
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
It is highly similar to SWTG024AS-V2.0, with the only difference being the GPIO configuration for the SFP port.
|
||||
|
||||
## Brands
|
||||
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
||||
|---|---|---|---|---|---|
|
||||
| Horaco | ZX-SG4T2 | | PCB-SWTG024AS-A-V2.0.1_19650 | P25D40SH | ??? |
|
||||
| GoodTop | GT-ST024M | Yes | PCB-SWTG024AS-A-V2.0.1 | 2M | ??? |
|
||||
|Brand |Type |Managed|PCB |Flash |Chip RTL|
|
||||
|---------|--------------|-------|------------------------------|----------------|--------|
|
||||
| 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
|
||||
|
||||
|
||||
@@ -5,9 +5,15 @@
|
||||
|---|---|---|---|---|---|
|
||||
| Mokerlink | ZX-SWTGW218AS | Yes| SWTG118AS-V2.0-16029 | 2MB (FM25Q16A)| 8273N + 8224N |
|
||||
| Sodola | | | | | |
|
||||
| Horaco | | | | | |
|
||||
| Horaco | HC-SWTGW218AS | Yes | SWTG118AS-V2.1 | 2MB | 8373 (non-N) |
|
||||
| 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
|
||||
|
||||
|
||||
|
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,45 +4,52 @@ The following devices have been tested and are fully working:
|
||||
| Brand | Type | Managed | PCB | Flash | Ports |
|
||||
|----------|-----------------|---------|---------------------------------------------------------------------------|-------|-------|
|
||||
| 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 |
|
||||
| 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 |
|
||||
| GoodTop | GT-ST018M | Yes | [SWTG018AS-A V2.0](devices/SWTG018AS_A_V2_0.md) | ? | 8 + 1 |
|
||||
| GoodTop | GT-ST024M | Yes | [SWTG024AS-A V2.0.1](devices/SWTG024AS-A-V2.0.1_4C_2SFP.md) | 2M | 4 + 2 |
|
||||
| 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 |
|
||||
| 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-V3.0](devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
|
||||
| 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 |
|
||||
| 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-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-4T2XT | Yes | [PCB-SL310S-4T2XT-V1.0.0-22273](devices/ZX310S-4T2XT.md) | 2M | 6 |
|
||||
| Horaco | ZX-SG4T2 | No | [SWTG024AS-A-V2.0.1_19650_4C_2SFP](devices/SWTG024AS-A-V2.0.1_4C_2SFP.md) | 0.5M | 4 + 2 |
|
||||
| Horaco | ZX-SWTG124AS | Yes | [SWTG024AS-v2.0](devices/SWTG024AS.md) | | 4 + 2 |
|
||||
| Keeplink | KP-9000-6XH-X2 / 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-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 |
|
||||
| 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 | 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| ZX-SWTGW218AS | Yes | [SWTG118AS-V2.0-16029](devices/SWTGW218AS.md) | 2M | 8 + 1 |
|
||||
| LIANGUO | ZX-SWTGW215AS | Yes | [PCB-SWTG115AS-V2.0 / PCB-SWTG115AS-V2.1](devices/SWTGW215AS.md) | 2M | 5 + 1 |
|
||||
| MokerLink| 2G040210GSM | Yes | [2M-PCB43-V1.1](devices/2M-PCB43-V1.1.md) | | 4 + 2 |
|
||||
| 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 |
|
||||
| ONT | ONT-S207CW-62TS-SE | 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 |
|
||||
| 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 |
|
||||
| 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-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 |
|
||||
| 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 |
|
||||
| Xikestore| SKS3200M-4GPY2XF| Yes | [SWTG024AS-v1.0](devices/SWTG024AS.md) | | 4 + 2 |
|
||||
| TRENDnet | TEG-S562 | No | [TEG-S563/EU H/W: V1.0R](devices/TEG-S562.md) | 2M | 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 |
|
||||
| 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 |
|
||||
| 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
|
||||
the machine target by PCB revision. The ML/non-ML or managed/unmanaged label
|
||||
|
||||
@@ -64,6 +64,12 @@ struct machine {
|
||||
uint8_t led_mux_custom;
|
||||
uint8_t led_mux[28];
|
||||
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
|
||||
|
||||
@@ -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,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"
|
||||
|
||||
__code const struct machine machine = {
|
||||
.machine_name = MACHINE_MODEL,
|
||||
.machine_name = MACHINE_MODEL,
|
||||
.isRTL8373 = 0,
|
||||
.min_port = 3,
|
||||
.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
|
||||
|
||||
@@ -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_PCB_K0402WS_V2) || \
|
||||
defined(MACHINE_PCB_K0402WS_V3) || \
|
||||
defined(MACHINE_2G5F4_10G2_V1_01) || \
|
||||
defined(MACHINE_FNS1200P)
|
||||
void machine_custom_init(void) __banked
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
// Define Port-masks for 9-port devices and 6-port devices
|
||||
#define PMASK_9 0x1ff
|
||||
#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
|
||||
#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. */
|
||||
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;
|
||||
|
||||
// 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 sfr_data[4];
|
||||
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;
|
||||
#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 uint16_t management_vlan;
|
||||
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 */
|
||||
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
|
||||
{
|
||||
if (port > 9 || type >= VLAN_INVALID) {
|
||||
if (port > CPU_PORT || type >= VLAN_INVALID) {
|
||||
print_string("Invalid port or ingress filter type\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -147,6 +147,9 @@
|
||||
*/
|
||||
#define RTL837X_REG_NIC_BUFFSIZE_TX 0x7844
|
||||
#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_TXCMD 0x7850
|
||||
#define RTL837X_REG_RX_CTRL 0x785c
|
||||
|
||||
@@ -30,7 +30,7 @@ extern __xdata struct machine_runtime machine_detected;
|
||||
|
||||
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_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 uint8_t stp_pprio[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 */
|
||||
|
||||
/* Last-heard designated info per port (from received BPDUs); consult
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include <stdint.h>
|
||||
|
||||
// #define REGDBG 1
|
||||
// #define RXTXDBG 1
|
||||
|
||||
#include "rtl837x_sfr.h"
|
||||
#include "rtl837x_regs.h"
|
||||
@@ -12,6 +11,7 @@
|
||||
#include "rtl837x_phy.h"
|
||||
#include "rtl837x_port.h"
|
||||
#include "rtl837x_trap.h"
|
||||
#include "rtl837x_nic.h"
|
||||
#include "rtl837x_stp.h"
|
||||
#include "rtl837x_lacp.h"
|
||||
#include "rtl837x_igmp.h"
|
||||
@@ -123,8 +123,8 @@ __code const uint8_t * __code const hex = "0123456789abcdef";
|
||||
__xdata uint8_t flash_buf[FLASH_BUF_SIZE];
|
||||
|
||||
// NIC buffers for packet RX/TX
|
||||
__xdata uint8_t rx_headers[16]; // Packet header(s) on RX
|
||||
__xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
|
||||
__xdata uint8_t rx_headers[16]; // RX descriptor
|
||||
__xdata uint8_t uip_buf[UIP_CONF_BUFFER_ALLOC_SIZE];
|
||||
|
||||
__xdata uint16_t rx_packet_vlan;
|
||||
__xdata uint16_t management_vlan;
|
||||
@@ -714,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
|
||||
* Bank is < 0x3f and is the MSB
|
||||
* addr gives the address in the bank
|
||||
@@ -999,8 +897,12 @@ void tcpip_output(void)
|
||||
uint16_t ring_ptr = ((uint16_t)sfr_data[2]) << 8;
|
||||
ring_ptr |= sfr_data[3];
|
||||
|
||||
// Move data over from xmem buffer to ASIC side using DMA
|
||||
nic_tx_packet(ring_ptr);
|
||||
// Move data over from xmem buffer to ASIC side using DMA. A VLAN-tagged
|
||||
// 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
|
||||
reg_read_m(RTL837X_REG_NIC_TX_CURR_PKT);
|
||||
@@ -1037,7 +939,7 @@ void handle_rx(void)
|
||||
write_char(' ');
|
||||
}
|
||||
#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);
|
||||
return;
|
||||
}
|
||||
@@ -1684,7 +1586,7 @@ void main(void)
|
||||
// Flash controller should be initialized before any code in other banks is being fetched
|
||||
// See this issue: https://github.com/logicog/RTLPlayground/issues/70
|
||||
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
|
||||
sfp_pins_last = 0x33; // signal LOS and no module inserted (for both slots, even if only 1 present)
|
||||
@@ -1805,7 +1707,6 @@ void main(void)
|
||||
lacpEnabled = 0;
|
||||
lacp_init();
|
||||
nic_setup();
|
||||
REG_SET(RTL837X_NIC_INT_MSK, NIC_INT_RXIE);
|
||||
trap_init();
|
||||
vlan_setup();
|
||||
port_l2_setup();
|
||||
|
||||
@@ -29,6 +29,7 @@ TESTS = $(BUILDDIR)/test_cmd_editor \
|
||||
$(BUILDDIR)/test_page_json \
|
||||
$(BUILDDIR)/test_httpd_tx \
|
||||
$(BUILDDIR)/test_tick_gate \
|
||||
$(BUILDDIR)/test_nic_rx \
|
||||
$(BUILDDIR)/test_lacp
|
||||
|
||||
# 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)
|
||||
$(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)
|
||||
$(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
|
||||
* 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); }
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/* ---------- platform mocks ---------- */
|
||||
|
||||
uint8_t uip_buf[UIP_CONF_BUFFER_SIZE + 2];
|
||||
uint8_t uip_buf[UIP_CONF_BUFFER_ALLOC_SIZE];
|
||||
uint16_t uip_len;
|
||||
struct uip_eth_addr uip_ethaddr = { .addr = {0x02,0x11,0x22,0x33,0x44,0x55} };
|
||||
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;
|
||||
}
|
||||
@@ -132,6 +132,10 @@ typedef unsigned short uip_stats_t;
|
||||
*/
|
||||
#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.
|
||||
*
|
||||
|
||||
@@ -136,7 +136,7 @@ static __code const uip_ipaddr_t all_zeroes_addr =
|
||||
#endif /* UIP_CONF_IPV6 */
|
||||
|
||||
#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. */
|
||||
#endif /* UIP_CONF_EXTERNAL_BUFFER */
|
||||
|
||||
|
||||
@@ -419,7 +419,7 @@
|
||||
#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.
|
||||
|
||||