151 Commits
Author SHA1 Message Date
logicog 85244d85f9 ChaCha20 implementation for encryption
Add an implementation in 8051 assembler for the generation of a
ChaCha20 keystream and an encryption function using the keystream
in C.

A test function using the example from RFC7539 is provided in
chacha20_test.

Keys, nonce, and block counter and the pointers to the input plaintext,
its length and the output pointer are provided via a struct chacha20,
which also holds the working state of the ChaCha20 algorithm
2026-04-26 10:30:55 +02:00
logicog e280ccd2f9 Use RTL descriptor definition 2026-04-24 08:42:00 +02:00
logicog baa4e5e142 Use header structures of TX and RX, add dot1q for management VLAN TX 2026-04-22 22:36:26 +02:00
logicog b53e7e1a06 Add NOTHS macro 2026-04-22 22:36:26 +02:00
logicog 14b45735e2 Cleanup STP, use new frame descriptor definitions 2026-04-22 22:36:26 +02:00
logicog 946e80cebe Add frame descriptor structure 2026-04-22 22:36:26 +02:00
logicog e2df95ba90 Cleanup DHCP client code 2026-04-22 22:36:26 +02:00
logicog 570ee6c995 Move initialization routines to BANK2 2026-04-22 22:36:26 +02:00
logicog 01fa43510e Merge pull request #206 from vDorst/fix_cmd_parsing
Fix cmd parsing
2026-04-21 21:24:22 +02:00
René van Dorst d2e79d4d80 Fix: In commit 8cbafaa cmd_tokenize() has changed. Missed that it also used
outside cmd_parser.c.
Fix the other location and headerfile.
2026-04-21 21:17:22 +02:00
René van Dorst 016061d8db cmd: Fix 8324edc atoi_short() commit.
vlan initialization was removed while trying out an other version.
But was not restored back.
2026-04-21 21:16:03 +02:00
logicog 5035366551 Merge pull request #204 from vDorst/remove___gptrxxx_calls
Remove `__gptrput()` and `__gptrget()` calls
2026-04-21 05:38:33 +02:00
logicog 2a8f183e6a Merge pull request #203 from vDorst/refactor_cmd_parsing
Refactor cmd parsing
2026-04-19 22:51:04 +02:00
René van Dorst 18225f5d22 uip: more fix. 2026-04-19 22:18:39 +02:00
René van Dorst 224471d676 uip: move second argument to __xdata free up 4 sram bytes. 2026-04-19 22:18:39 +02:00
René van Dorst 50d06c61bc change prototype uip_udp_new(), saves 1 sram. 2026-04-19 22:18:39 +02:00
René van Dorst d5709bcaf3 fix atoi 2026-04-19 22:18:39 +02:00
René van Dorst 52d943d5e4 rtlplayground: de-__gptrput()-call in read_reg_timer() 2026-04-19 22:18:39 +02:00
René van Dorst e79e90dd35 cmd_parser: de-__gptrput()-call in vlan_ingress_mode_parse() 2026-04-19 22:18:36 +02:00
René van Dorst da768171a5 change cmd_tokenize().
Remove the return argument because `err_status` is also reflecting the result.
Fix the error message when too many arguments are found.

refactor `execute_config()`, error out when err_status is not OK.
2026-04-19 22:00:31 +02:00
René van Dorst 94bf4425ba uip: de-__gptrput()-call access to struct uip_udp_conn 2026-04-18 22:38:42 +02:00
René van Dorst 3e599f0e06 dhcp: de-__gptrput()-call in ip_opt() 2026-04-18 22:27:55 +02:00
René van Dorst 6c6d11ab33 dhcp: de-__gptrget()-call in dhcp_print_ip() 2026-04-18 22:20:46 +02:00
René van Dorst 791f68582d httpd: de-__gptrget()-call in string_to_html() 2026-04-18 22:20:46 +02:00
René van Dorst facc4afe40 uip: de-__gptrget()-call in timer_{set,reset,restart,exprired}() 2026-04-18 22:20:46 +02:00
René van Dorst 8134ca7ec7 uip: de-__gptrget()-call in uip_ipaddr_copy() 2026-04-18 22:20:46 +02:00
René van Dorst 642030c7b2 uip: de-__gptrget()-call in uip_add32() 2026-04-18 22:20:46 +02:00
René van Dorst 8324edc5f7 cmd_parser: Improve atoi_byte() and atoi_short().
Because no memory type is specified to the reference location, sdcc is
using a helper function to access the location. But sdcc is using a
register to tell the helper function which memory-type is used.
This registers must also be preseved until all access to that location is done.
2026-04-18 22:19:35 +02:00
René van Dorst f2ff7d7737 parse_ee() make use of cmd_words_len 2026-04-18 19:35:51 +02:00
René van Dorst a24b63a81f parse_mtu() make use of cmd_words_len 2026-04-18 19:35:51 +02:00
René van Dorst abe3513bc6 parse_port() make use of cmd_words_len 2026-04-18 19:35:51 +02:00
René van Dorst 49c43082a3 parse_mirror() make use of cmd_words_len, refactor small parts 2026-04-18 19:35:51 +02:00
René van Dorst f71e869b97 parse_ingress() make use of cmd_words_len, refactor small parts 2026-04-18 19:35:51 +02:00
René van Dorst 1fe236246a parse_isolate() make use of cmd_words_len 2026-04-18 19:35:51 +02:00
René van Dorst 2acf2499d1 parse_lag_hash() make use of cmd_words_len 2026-04-18 19:35:51 +02:00
René van Dorst 56e0d0a5d1 parse_lag() make use of cmd_words_len 2026-04-18 19:35:51 +02:00
René van Dorst 7380aeb10d parse_bw() make use of cmd_words_len 2026-04-18 19:35:51 +02:00
René van Dorst 0d698dc572 parse_passwd() make use of cmd_words_len, change password memcpy. 2026-04-18 19:35:51 +02:00
René van Dorst c7fb354f08 parse_sds{get,set}() and parse_phy{get,set}() make use of cmd_words_len 2026-04-18 19:35:51 +02:00
René van Dorst 2cdab5f9d9 parse_reg{set,get}() make use cmd_words_len. 2026-04-18 19:35:51 +02:00
René van Dorst 301577efc8 parse_vlan() make use of cmd_words_len. 2026-04-18 19:35:51 +02:00
René van Dorst 1156f00f95 cmd_parser() make use of cmd_words_len 2026-04-18 19:35:51 +02:00
René van Dorst 8cbafaa347 Change cmd_tokenize() it only stores valid locations and use a length field. 2026-04-18 19:35:48 +02:00
René van Dorst 80ff1b25c9 Improve: cmd_compare().
Because `cmd` is guaranteed by the compiler to be NULL-terminated, we can make use of that to ensure the loop always ends.
So we don't need to know when the next words starts.
2026-04-18 19:15:25 +02:00
René van Dorst 1a5208110c Merge pull request #195 from logicog/fix_config_reading
Fix reading configuration over flash block boundaries
2026-04-17 11:46:03 +02:00
logicog e2717ef7ca Count pages instead of bytes reading config in execute_config() 2026-04-17 11:37:15 +02:00
logicog 1769528420 Introduce global error variable, check during config execution 2026-04-16 22:01:51 +02:00
logicog 9d4c06d752 Merge pull request #200 from feelfree69/port_names
Port names
2026-04-14 18:51:43 +02:00
feelfree69 2565aeadf4 Do no show empty names in tooltips 2026-04-14 18:28:13 +02:00
logicog c3530aaafc Handle error when configuration file cmd too long 2026-04-14 18:00:29 +02:00
TylerDurden-23 6af19e1e6b Merge pull request #197 from logicog/isolation
Port Isolation CLI command
2026-04-14 08:02:16 +02:00
logicog 1683eef94b Fix bug where cmd_words[] is not properly initialized 2026-04-14 05:16:45 +02:00
logicog 036d9ca229 Add port isolation cmd 2026-04-13 20:13:28 +02:00
feelfree69 b31179acbe move extern declaration for port_names to trl837x_common.h 2026-04-13 19:14:24 +02:00
logicog b7ad67d336 Make port isolation API available 2026-04-13 18:15:01 +02:00
feelfree69 e130777b24 serial console cosmetic change 2026-04-13 14:55:50 +02:00
feelfree69 41f0dad49d Add ability to assign a name to a port 2026-04-13 14:55:10 +02:00
logicog d4d12fe3b4 Merge pull request #192 from janh/cmd-sds-phy
Add commands to read/write SerDes and PHY registers
2026-04-10 15:37:01 +02:00
logicog 4440bcc43a Fix reading configuration over flash block boundaries 2026-04-09 22:34:32 +02:00
Jan Hoffmann f6a5163f33 Add commands to access PHY registers 2026-04-06 18:25:40 +02:00
Jan Hoffmann e210f31f0e Add commands to access SerDes registers 2026-04-06 18:25:35 +02:00
Jan Hoffmann 9eecdd071a Add atoi_byte function
Similar to atoi_short, but reads into a uint8_t instead of a uint16_t.
2026-04-06 18:25:30 +02:00
René van Dorst c4368c68be Merge pull request #189 from bstreiff/pcb23_v2_2
Add support for keepLink KP-9000-9XHML-X (2M-PCB23-V2.2 version)
Rename machine keepLink KP-9000-9XHML-X (2M-PCB23-V3.1 version)
2026-04-05 14:04:10 +00:00
ranma 1b02f303b2 Merge pull request #190 from ranma/fix-bit-linking
Fix declaration of tx_buf_empty bit var

__sbit is for SFRs, for regular data __bit should be used. Otherwise the variables is not correctly declared in the BSEG section, leading to bit temporaries being allocated in the same location.

When this causes the tx_buf_empty to be overwritten to 0, then the next write_char will hang forever.

With this change the bit is properly declared in BSEG for the linker, which in my testing resolves the overlap issue:
```
;--------------------------------------------------------
; bit data
;--------------------------------------------------------
        .area BSEG    (BIT)
_tx_buf_empty::
        .ds 1
```

Only the vlan and mtu commands call atoi_short, which has a local bit _atoi_short_sloc0_1_0 which is the first bit in the BSEG, and assigning to that one corrupted the tx_buf_empty bit.
Though this is also a compiler optimization-failure, the _atoi_short_sloc0_1_0 value isn't even used after assignment, AFAICS it is a dead store.

Its from the isnumber inline:
```
[...]
;--------------------------------------------------------
; bit data
;--------------------------------------------------------
        .area BSEG    (BIT)
_atoi_short_sloc0_1_0:
        .ds 1
_parse_ip_sloc0_1_0:
        .ds 1
[...]
;       cmd_parser.c:85: l -= '0';
        mov     r3,a  
        add     a,#0xd0
;       cmd_parser.c:86: return (l <= ('9'-'0'));
        add     a,#0xff - 0x09
        cpl     c
;       cmd_parser.c:172: while (isnumber(cmd_buffer[idx])) {
        mov     _atoi_short_sloc0_1_0,c
        jnc     00103$
[...]
```
2026-04-05 11:05:10 +02:00
Tobias Diedrich fd9a7717ce Fix declaration of tx_buf_empty bit var
__sbit is for SFRs, for regular data __bit should be used.
Otherwise the variables is not correctly declared in the BSEG
section, leading to bit temporaries being allocated in the same
location.

When this causes the tx_buf_empty to be overwritten to 0, then
the next write_char will hang forever.
2026-04-04 22:02:45 +02:00
Brenda Streiff 29ce05b70e Add keepLink KP-9000-9XHML-X V2.2 version
This splits the current MACHINE_KP_9000_9XHML_X definition into "V2_2"
and "V3_1" versions for the two known versions of this hardware.

Confirmed to work:
- LED configuration matches stock firmware
- Port ordering matches label
- A SFP can be detected and EEPROM read (I don't have a fiber cable to test link)
- Reset button presses are detected
2026-04-04 11:40:03 -05:00
Brenda Streiff 97ae6bf1d3 Document the '2M-PCB23-V2.2' PCB
Sold as "keepLINK KP-9000-9XHML-X". This is different from the other, "V3.1"
version of the "keepLINK KP-9000-9XHML-X".
2026-04-04 11:40:03 -05:00
TylerDurden-23 4ccb988d70 Merge pull request #188 from UAb5eSMn/machine_check
Check if machine.c can be compiled for all machines
2026-03-31 19:36:57 +02:00
UAb5eSMn 075d7e43f7 Check if machine.c can be compiled for all machines 2026-03-30 22:28:36 +02:00
René van Dorst 97e73d95aa Merge pull request #183 from janh/fix-i2c-and-sfp-ddm
Fix I2C access and SFP diagnostic monitoring in web interface
2026-03-30 17:21:51 +00:00
René van Dorst 2eb6bac4a5 Merge pull request #186 from UAb5eSMn/machine_fix
Fix compilation issue for machine HG0402XG_V1_1
2026-03-29 18:16:17 +00:00
UAb5eSMn 7d4ccf8f23 Remove machine HORACO_ZX_SG4T2 from comment 2026-03-29 20:10:56 +02:00
UAb5eSMn c0f6b8a1a6 Fix compilation error for machine HG0402XG_V1_1 2026-03-29 20:10:56 +02:00
TylerDurden-23 f3b6c16161 Merge pull request #185 from vDorst/fix_swgt024_v2_0
Fix swgt024 v2.0
2026-03-29 18:29:18 +02:00
René van Dorst 73f92f2e12 Add SWGT024_V2_0 Unmanaged pinout and machine type. 2026-03-29 16:35:31 +02:00
René van Dorst bfab8cbba3 Rename MACHINE_SWGT024_V2_0 to MACHINE_SWGT024_V2_0_MANAGED.
So we can support other versions too.
2026-03-29 16:13:38 +02:00
René van Dorst eedb0dec01 SWGT024 v2.0: Fix LED and RESET defines for managed version
Original firmware used for RJ45:
* Amber leds only for 2.5GBit link/act.
* Green leds only for other speeds.
2026-03-29 16:13:36 +02:00
logicog 08ad843c56 Merge pull request #184 from vDorst/rename_led_28
Rename LED_28 to LED_28_SYS.
2026-03-29 07:50:27 +02:00
Jan Hoffmann 05693f5171 Also show SFP TX/RX power in dBm 2026-03-29 00:33:48 +01:00
Jan Hoffmann 6eaa1985aa Fix SFP diagnostic monitoring data in web interface
If the module is not internally calibrated, it is necessary to apply
calibration values to get meaningful results.
2026-03-29 00:33:48 +01:00
Jan Hoffmann 45ba32f65d Fix scaling for power values in SFP diagnostics 2026-03-29 00:33:48 +01:00
Jan Hoffmann 0b4f59483b Don't write SFP options value twice in status JSON 2026-03-29 00:33:48 +01:00
René van Dorst 385c850d2f add comments 2026-03-28 21:40:43 +01:00
René van Dorst cdbc48f2c2 Rename LED_28 to LED_28_SYS.
So it clear that led 28 is the SYSTEM LED.
2026-03-28 19:29:49 +01:00
Jan Hoffmann efe0c282ba Fix I2C access code
While the current implementation works for what it is actually used, it
is broken when trying to do larger transfers.

The length field in the control register has a size of 4 bits. In every
transfer, length+1 bytes are read. Thus, each transfer is limited to a
maximum of 16 bytes. Add a check for the length, and write the correct
value to the register.

Also update the loop in "sfp_send_data" to properly increment the output
register. Remove the unused special case for a length of 128 bytes.
2026-03-28 18:14:15 +01:00
René van Dorst 54fced05b0 Merge pull request #178 from bennydiamond/Support_ZX_SWTGW215AS
Add support for PCB-SWTG115AS-V2.0
2026-03-28 13:16:07 +00:00
bennydiamond b64dfd8c25 Correction on IO mappings
Add further clarification on mapping assumptions
2026-03-27 20:56:09 -04:00
bennydiamond 5f1cd4cce0 Update documentation 2026-03-27 19:34:39 -04:00
bennydiamond 7ffd0c25c2 Support for PCB-SWTG115AS-V2.0
Marketed as Lianguo ZX-SWTGW215AS
2026-03-27 19:34:39 -04:00
René van Dorst 8b4e09ad69 Merge pull request #181 from janh/improve-1g-sfp-compat
Improve compatibility with 1G SFP modules
2026-03-27 22:58:30 +00:00
René van Dorst 34d53dddf2 Merge pull request #179 from bennydiamond/Early_boot_wipe_config
Wipe config if button held at boot
2026-03-27 20:05:55 +00:00
René van Dorst ec5f655bba Merge pull request #180 from janh/k0501w-rename-version
Rename K0501W to include PCB version
2026-03-27 19:52:29 +00:00
René van Dorst 7291f38e46 Merge pull request #182 from janh/commands-newline
Make sure that the output of all commands ends with a newline
2026-03-27 19:05:29 +00:00
Jan Hoffmann c3b99fdcdf Make sure that the output of all commands ends with a newline 2026-03-27 19:36:14 +01:00
Jan Hoffmann 9f800bae01 Improve compatibility with 1G SFP modules
Some modules report a nominal signaling rate of 1200 MBd.
2026-03-27 17:56:40 +01:00
logicog df498b0879 Merge pull request #173 from diijkstra/vlan_console
Console: Add Ingress type & VLAN show table
2026-03-26 21:02:33 +01:00
Jan Hoffmann 03422463e4 Rename K0501W to include PCB version
It seems very likely that other versions are not compatible, so make it
clear by including it in the machine type and name. Also update the
documentation.
2026-03-26 19:59:06 +01:00
bennydiamond 2bfbe5358b LED pattern definition on early boot reset
LED Double blink while button is held

FAST blink for 3 seconds when config is reset
2026-03-26 12:31:20 -04:00
TylerDurden-23 3bb89bfb80 Merge pull request #177 from janh/k0501w
Add support for K0501W boards
2026-03-26 10:12:32 +01:00
bennydiamond dba3679e2f Wipe config if button held at boot
Blocking by design to prevent loading config

Button must be held between 10 and 30 seconds to trigger reset.

If held more than 30 seconds, boot normally. This is to prevent lock-up in case of weird hardware variants.
2026-03-25 23:15:04 -04:00
Jan Hoffmann f331a6129a Add support for K0501W boards
This board appears for example in the Davuaz Da-K6501W switch, and is
designed similarly to Hi-K0402WS.

However, it only has one SFP port and another 2.5G copper port using
RTL8221B 2.5G PHY instead. Also, some components on the board, like
additional LEDs, mode switch, and second flash chip are not populated.

Like earlier revisions of the K0402W(S) board, there is no UART, so
debugging is limited.

As this is an unmanaged switch, installation needs a flash programmer.
2026-03-25 19:31:14 +01:00
logicog 877e5a68fb Merge pull request #176 from janh/improve-2500m-sfp-compat
Improve compatibility with 2.5G SFP modules
2026-03-24 18:13:27 +01:00
Jan Hoffmann ed6c95e522 Improve compatibility with 2.5G SFP modules
Some modules might report a nominal bitrate of 2500 Mbd or 3200 Mbd
instead of 3100 Mbd. Accept the entire range to make them work.
2026-03-24 15:26:29 +01:00
diijkstra cb8d0e45bb Review: Move w initialization 2026-03-23 19:31:06 +01:00
TylerDurden-23 877b16e837 Merge pull request #174 from logicog/fix_vlan_display
Fix display of VLANs for ports
2026-03-22 18:20:33 +01:00
logicog fce64ac368 Fix display of VLANs for ports 2026-03-22 13:45:42 +01:00
logicog dd9e5c8ff8 Merge pull request #172 from diijkstra/trendnet
Document firmware upload via CLI
2026-03-22 05:26:45 +01:00
diijkstra f7fcf0eda7 Console: Add Ingress type & VLAN show table
Added new `vlan show` command to dump current VLAN settings.
Supports printing PVID & ingress filtering per port.

Added new `ingress [p]<mode>` command to setup ingress filtering.
Added wrappers for enabling/disabling vlan filtering. Currently
not configurable, but state in console is read via ASIC registers.

Full VLAN dump & web support of new commands will be added later.
2026-03-21 12:29:26 +01:00
diijkstra 905cf38f1f Trendnet: Another mapping fix
Physical to logical mapping was reverted for SFP ports.
2026-03-21 12:22:36 +01:00
diijkstra b0370f7bb3 Doc: Describe how to upload firmware via CLI & HTTP
Rough explanation how to upload a new firmware. Probably, we should
support basic auth on upload for easier use, but lets document
what we have.
2026-03-21 12:22:36 +01:00
logicog d21d269d49 Merge pull request #152 from mmmspatz/mspatz/fix_vlan_page
Fix "Get Configuration" on vlan.html
2026-03-19 11:36:59 +01:00
feelfree69 cb81f82cf6 Merge pull request #170 from logicog/fix_bank0
Fix missing assignment of bank when html_data.c code is generated
2026-03-19 11:23:07 +01:00
logicog 59e7a21955 Merge pull request #159 from diijkstra/web_sfp_state
Web: Add SFP state/pin status
2026-03-19 05:22:24 +01:00
logicog c530ec4ae3 Fix missing assignment of bank when html_data.c code is generated 2026-03-18 08:34:26 +01:00
TylerDurden-23 8e2b48ef25 Merge pull request #167 from logicog/browsser_trouble
Fix browser issues with Chrome and latest Firefox
2026-03-17 10:29:02 +01:00
logicog 65f094c1d1 Merge pull request #163 from feelfree69/parser_fix
fix crash
2026-03-16 17:51:24 +01:00
logicog 090283d538 Add retry mechanism for xhttp requests to make Chrome happy 2026-03-16 17:32:50 +01:00
logicog 7e3a0f5d8f Allow javascript to modify svg styles for Firefox version >140 2026-03-16 17:32:15 +01:00
feelfree69 4706f6232a simplify parsing code 2026-03-15 15:43:34 +01:00
diijkstra b47a868db3 Web: Handle missing LOS pin
When device has no LOS pin and module has no extended status, the
RX LOS value will not be shown. When both are present, the equality
check is performed. When only one is present, the present value
will be shown.

json from the switch, will still contain the field, but can be
null for when pin is not available.
2026-03-15 12:18:02 +01:00
feelfree69 454eb28bce Merge branch 'logicog:main' into parser_fix 2026-03-15 08:58:15 +01:00
logicog dc283bc724 Merge pull request #165 from feelfree69/bank0_overflow
Fail building image on BANK0 overflow
2026-03-15 07:39:38 +01:00
feelfree69 a001cd3da7 Fail also on BANK0 overflow 2026-03-14 22:15:33 +01:00
feelfree69 e92b4a2358 Don't allow partial commands 2026-03-14 19:47:56 +01:00
René van Dorst 47c5443f0e Merge pull request #164 from TylerDurden-23/fix-1gbaset-sfp
Fix 1GBase-T SFP module not working on serdes port 1.
2026-03-14 17:03:05 +00:00
chriz baa3e7edb7 Fix 1GBase-T SFP module not working on serdes port 1. 2026-03-14 16:33:54 +01:00
feelfree69 34d46aa29a fix crash 2026-03-14 13:59:14 +01:00
diijkstra 6b64534f40 WEB: Display single RX LOS
As sugested, lets display single value, and raise alarm when pin
is different than module.
2026-03-14 13:15:01 +01:00
logicog b18ed62042 Merge pull request #161 from diijkstra/backspace
Console: Handle ^H as backspace
2026-03-14 13:14:39 +01:00
diijkstra 16edc6b421 Console: Handle ^H as backspace
Currently only ASCII DEL (key code 127) is handled as backspace, but some terminal
emulators are sending ^H which is ASCII BS (key code 8). Looks like we can
safely treat both in the same matter.
2026-03-14 12:35:16 +01:00
logicog f1e5b7e31a Merge pull request #92 from vDorst/doc_gpio
doc: gpio overview and mux settings
2026-03-14 12:17:06 +01:00
diijkstra 1f6e07a1af Web: Add SFP state/pin status
The state of the SFP module is being already send in status.json,
but was not parsed via Web UI. When debuging SFP LOS/Signal detection
it is usefull to see what module is reporting back.

Extended the SFP mouse-over information with:
 - RX LOS as reported in 0x02 bit of register 238
 - External TX Disabled from 0x80 bit of register 238
 - TX fault from 0x04 of the same register
 - The last state of RX LOS pin (available also when there is no 0x40
   option on the module)

This should help identify missing/incorrect setup of TX disabled pin.
2026-03-13 23:56:43 +01:00
logicog 0952676504 Merge pull request #158 from diijkstra/trendnet
TEG-S562: Port LEDs
2026-03-13 23:46:22 +01:00
diijkstra 95cbc1a2e0 TEG-S562: Correctly assign SFP
Looks like the SFP numbers are reversed, since GPIOs were mapped
to SFP numbers, the need to be reversed too. This fixes swapped
display of SFP stats on the webpage.
2026-03-13 23:36:29 +01:00
diijkstra d5fdaf28e8 Light description for led-set
Very light description for port_led_set and led_sets, which was
helpfull when bringing up the trendnet device.
2026-03-13 21:43:22 +01:00
diijkstra 511d35f63d TEG-S562: Port LEDs
Added support for all leds on the device.

Stock port sets are slightly differently configured, where additional
LED0 on SET_0 and LED1&LED2 where configured for link/collisions/duplex.
This has not been reproduced as those lines are probably not connected
anywhere.
2026-03-13 21:40:34 +01:00
logicog 96484bc62a Merge pull request #156 from feelfree69/make-cleanup
Cleanup Makefile
2026-03-11 20:54:47 +01:00
feelfree69 765000ce4f fixed html dependencies 2026-03-11 19:08:32 +01:00
feelfree69 dc9b211924 BUILDDIR without slash 2026-03-11 19:01:21 +01:00
feelfree69 b559c3b868 avoid doubled generation of html_data.* 2026-03-11 07:34:18 +01:00
feelfree69 13fe354da7 add dependency file generation 2026-03-11 07:26:15 +01:00
feelfree69 fc4b12725c Cleanup Makefile 2026-03-10 21:57:16 +01:00
logicog 0a52386e60 Merge pull request #155 from feelfree69/fix-bank-overflow
fix bank overflow
2026-03-10 21:47:46 +01:00
feelfree69 4b167151a5 fix bank overflow 2026-03-10 21:35:25 +01:00
René van Dorst f474b5822b Merge pull request #151 from logicog/concurrency
Web request concurrency management
2026-03-10 18:49:18 +00:00
logicog fa37940075 Control xhttp concurrency 2026-03-10 06:16:18 +01:00
Mark H. Spatz 893dcd8fcf update vlan.md 2026-03-08 19:49:37 -04:00
Mark H. Spatz 16f4e2a1c6 Fix range check in vlan_get() 2026-03-08 17:52:39 -04:00
Mark H. Spatz 364d538abd Fix "VLAN ID" field max value on vlan.html 2026-03-08 17:50:54 -04:00
Mark H. Spatz 4cef63200f Fix "Get Configuration" on vlan.html
I noticed that entering some vlan config, clicking "Update/Create", then
clicking "Get Configuration" resulted in Tagged/Untagged/PVID displaying
completely wrong data. It looks like the parisng in fetchVLAN() in
vlan.js was just completely disconnected from the layout of the
registers read by vlan_get() in rtl837x_port.c. Who knows how that
happened.

1. Fix fetchVLAN() member/untag parsing: the old code read bits [9:0]
   as untagged and bits [10:19] as tagged, but the VLAN table register
   layout is members in [9:0] and untag in [19:10]. Now correctly
   derives tagged (member && !untag) and untagged (member && untag).

2. Add PVID to vlan.json response: PVID is stored per-port in separate
   PVID registers (RTL837x_PVID_BASE_REG), not in the VLAN table entry.
   The old code nonsensically tried to read it from bits [20:29] of the
   VLAN table. Add port_pvid_get() and build a pvid bitmask in
   send_vlan() so the JS can parse it correctly.

3. Remove auto-PVID logic from setC(): setC() is called by fetchVLAN()
   while it's loading existing config, and so this logic mangled the
   display of the existing config. Also, it doesn't make sense to
   auto-set the PVID for tagged members (PVID relates to untagged
   ingress.)
2026-03-07 15:18:06 -05:00
René van Dorst a0313eab87 doc: gpio overview and mux settings 2026-01-22 23:04:07 +01:00
66 changed files with 3073 additions and 1171 deletions
+2
View File
@@ -17,5 +17,7 @@ jobs:
run: | run: |
apt update apt update
apt install make gcc sdcc xxd python-is-python3 libjson-c-dev -y apt install make gcc sdcc xxd python-is-python3 libjson-c-dev -y
- name: Check if machine.c can be compiled for all machines
run: make machine_check
- name: Make project - name: Make project
run: make MACHINE="KP_9000_6XHML_X2" run: make MACHINE="KP_9000_6XHML_X2"
+44 -33
View File
@@ -9,10 +9,10 @@ CC_FLAGS = -mmcs51 -I. -Ihttpd -Iuip
ASM = sdas8051 ASM = sdas8051
AFLAGS= -plosgff AFLAGS= -plosgff
SUBDIRS := tools uip httpd SUBDIRS := tools
SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS)) SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS))
BUILDDIR = output/ BUILDDIR = output
VERSION_HEADER := version.h VERSION_HEADER := version.h
ifeq ($(MACHINE),) ifeq ($(MACHINE),)
@@ -20,18 +20,25 @@ else
CC_FLAGS += -DMACHINE_$(MACHINE) CC_FLAGS += -DMACHINE_$(MACHINE)
endif endif
all: create_build_dir $(VERSION_HEADER) $(SUBDIRS) $(BUILDDIR)rtlplayground.bin all: create_build_dir $(VERSION_HEADER) $(SUBDIRS) $(BUILDDIR)/rtlplayground.bin
create_build_dir: create_build_dir:
mkdir -p $(BUILDDIR) mkdir -p $(BUILDDIR)
mkdir -p $(BUILDDIR)/uip
mkdir -p $(BUILDDIR)/httpd
mkdir -p $(BUILDDIR)/crypto
SRCS = rtlplayground.c rtl837x_flash.c rtl837x_leds.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c \ SRCS = rtlplayground.c rtl837x_flash.c rtl837x_leds.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c
rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c cmd_editor.c rtl837x_bandwidth.c SRCS += rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c cmd_editor.c rtl837x_bandwidth.c rtl837x_init.c
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel} SRCS += uip/timer.c uip/uip.c uip/uip_arp.c uip/uiplib.c uip/uip-fw.c uip/uip-neighbor.c uip/uip-split.c
OBJS += uip/$(BUILDDIR)/timer.rel uip/$(BUILDDIR)/uip-fw.rel uip/$(BUILDDIR)/uip-split.rel uip/$(BUILDDIR)/uip.rel uip/$(BUILDDIR)/uip_arp.rel uip/$(BUILDDIR)/uiplib.rel httpd/$(BUILDDIR)/httpd.rel httpd/$(BUILDDIR)/page_impl.rel SRCS += httpd/httpd.c httpd/page_impl.c
SRCS += crypto/chacha20.c
OBJS = ${SRCS:%.c=$(BUILDDIR)/%.rel}
DEPS := ${SRCS:%.c=$(BUILDDIR)/%.d}
HTML := $(shell find $(html) -name '*.js' -or -name '*.html' -or -name '*.svg')
html_data.c html_data.h: html tools html_data.c html_data.h: $(HTML) tools/$(BUILDDIR)/fileadder
tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -d html -p html_data tools/$(BUILDDIR)/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -d html -p html_data
$(VERSION_HEADER): $(VERSION_HEADER):
@echo "#ifndef VERSION_H" > $(VERSION_HEADER) @echo "#ifndef VERSION_H" > $(VERSION_HEADER)
@@ -46,37 +53,41 @@ $(SUBDIRS):
$(MAKE) -C $@ $(MAKE) -C $@
clean: clean:
-make -C uip clean -rm -f html_data.c html_data.h $(VERSION_HEADER)
-make -C httpd clean -rm -rf $(BUILDDIR)
-rm html_data.c html_data.h $(VERSION_HEADER)
-rm -r $(BUILDDIR)
$(BUILDDIR)crtstart.rel: crtstart.asm $(BUILDDIR)/%.rel: %.asm
$(ASM) $(AFLAGS) -o $@ $<
$(BUILDDIR)crc16.rel: crc16.asm
$(ASM) $(AFLAGS) -o $@ $<
$(BUILDDIR)%.rel: %.c
$(CC) $(CC_FLAGS) -o $@ -c $<
$(BUILDDIR)%.rel: $(BUILDDIR)%.asm
${ASM} ${AFLAGS} -o $@ $< ${ASM} ${AFLAGS} -o $@ $<
# mv -f $(addprefix $(basename $^), .lst .rel .sym) .
$(BUILDDIR)rtlplayground.ihx: $(OBJS) $(BUILDDIR)crtstart.rel $(BUILDDIR)crc16.rel $(BUILDDIR)/%.rel: %.c
$(CC) -MMD $(CC_FLAGS) -o $@ -c $<
$(BUILDDIR)/rtlplayground.ihx: $(OBJS) $(BUILDDIR)/crtstart.rel $(BUILDDIR)/crc16.rel $(BUILDDIR)/crypto/chacha_8051.rel
$(CC) $(CC_FLAGS) -Wl-bHOME=0x00000 -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-r -o $@ $^ $(CC) $(CC_FLAGS) -Wl-bHOME=0x00000 -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-r -o $@ $^
$(BUILDDIR)rtlplayground.img: $(BUILDDIR)rtlplayground.ihx $(BUILDDIR)/rtlplayground.img: $(BUILDDIR)/rtlplayground.ihx
objcopy --input-target=ihex -O binary $< $@ objcopy --input-target=ihex -O binary $< $@
$(BUILDDIR)rtlplayground.bin: $(BUILDDIR)rtlplayground.img $(BUILDDIR)/rtlplayground.bin: $(BUILDDIR)/rtlplayground.img
if [ -e $@ ]; then rm $@; fi if [ -e $@ ]; then rm $@; fi
tools/$(BUILDDIR)imagebuilder -i $^ $@ tools/$(BUILDDIR)/imagebuilder -i $^ $@
tools/$(BUILDDIR)fileadder -a $(DEFAULT_CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@ tools/$(BUILDDIR)/fileadder -a $(DEFAULT_CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
tools/$(BUILDDIR)fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@ tools/$(BUILDDIR)/fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data $@ tools/$(BUILDDIR)/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data -b BANK1 $@
tools/$(BUILDDIR)crc_calculator -u $@ tools/$(BUILDDIR)/crc_calculator -u $@
.PHONY: clean all $(SUBDIRS) .PHONY: clean all $(SUBDIRS) $(VERSION_HEADER)
.PHONY:
machine_check:
@mkdir -p $(BUILDDIR)/tmp
@set -eo pipefail; \
for MACHINE in `grep -e ' MACHINE_' machine.c | sed -e 's%^.* MACHINE_%%' -e 's%[ ]*//.*$$%%' | sort -u`; \
do \
echo "Checking $${MACHINE}"; \
$(CC) $(CC_FLAGS) -DMACHINE_$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine.c; \
done
@rm -rf $(BUILDDIR)/tmp
-include $(DEPS)
+1 -1
View File
@@ -169,7 +169,7 @@ void cmd_edit(void) __banked
} else { // An unknown or not yet complete Escape sequence: wait } else { // An unknown or not yet complete Escape sequence: wait
continue; continue;
} }
} else if (sbuf[l] == 127) { // Backspace } else if (sbuf[l] == 127 || sbuf[l] == 8) { // Backspace DEL or BS/^H
if (cursor > 0) { if (cursor > 0) {
write_char('\010'); write_char('\010');
for (uint8_t i = cursor; i < cmd_line_len; i++) for (uint8_t i = cursor; i < cmd_line_len; i++)
+590 -147
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -8,7 +8,7 @@
extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE]; extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
extern __xdata uint8_t cmd_available; extern __xdata uint8_t cmd_available;
uint8_t cmd_tokenize(void) __banked; void cmd_tokenize(void) __banked;
void cmd_parser(void) __banked; void cmd_parser(void) __banked;
void execute_config(void) __banked; void execute_config(void) __banked;
void print_sw_version(void) __banked; void print_sw_version(void) __banked;
+23
View File
@@ -0,0 +1,23 @@
#ifndef _CHACHA_H_
#define _CHACHA_H_
#include <stdint.h>
struct chacha20_t {
uint8_t wstate[64]; // 64 bytes written here
uint8_t constant[16]; // 128 bit constant
uint8_t key[32]; // 256-bit secret key
uint32_t cnt; // 32-bit block counter 1, 2.. Big Endian!
uint8_t nonce[12]; // 96-bit nonce
__xdata uint8_t *plaintext;
uint16_t length;
__xdata uint8_t *cyphertext;
};
// Encrypt a plaintext with ChaCha20 as per RFC7539
void chacha20_encrypt(void);
// Test ChaCha20 using the example from RFC7539
void chacha20_test(void);
#endif
+98
View File
@@ -0,0 +1,98 @@
#include "rtl837x_common.h"
#include "chacha.h"
void chacha_20(void);
void chacha_update(void);
void chacha_count(void);
// generate a block of ChaCha20 keystream as per RFC7539
__xdata struct chacha20_t __at(0x7000) chacha20;
__xdata uint8_t plaintext[256];
__xdata uint8_t cyphertext[256];
void chacha20_print_block(void)
{
for (uint8_t i=0; i < 64; i++) {
print_byte(*(uint8_t * __xdata)(chacha20.wstate + i));
if (i%4 == 3)
write_char(' ');
}
}
void chacha20_encrypt(void)
{
__xdata uint8_t *p = chacha20.plaintext;
while (chacha20.length) {
register uint8_t i;
chacha_count();
memcpy(chacha20.wstate, chacha20.wstate + 64, 64);
#ifdef DEBUG
chacha20_print_block(); write_char('\n');
#endif
chacha_20();
chacha_update();
#ifdef DEBUG
chacha20_print_block(); write_char('\n');
#endif
for (i = 0; i < ((chacha20.length > 64) ? 64 : chacha20.length); i++)
*chacha20.cyphertext++ = *p++ ^ chacha20.wstate[i];
chacha20.length -= chacha20.length > 64 ? 64 : chacha20.length;
#ifdef DEBUG
print_string("\n round done\n");
#endif
};
}
// Test the example of RFC 7539 Section 2.4.2
void chacha20_test(void)
{
__code uint8_t chacha_c[16] =
{ 0x61, 0x70, 0x78, 0x65, 0x33, 0x20, 0x64, 0x6e,
0x79, 0x62, 0x2d, 0x32, 0x6b, 0x20, 0x65, 0x74 };
__code uint8_t key[32] =
{ 0x03, 0x02, 0x01, 0x00, 0x07, 0x06, 0x05, 0x04,
0x0b, 0x0a, 0x09, 0x08, 0x0f, 0x0e, 0x0d, 0x0c,
0x13, 0x12, 0x11, 0x10, 0x17, 0x16, 0x15, 0x14,
0x1b, 0x1a, 0x19, 0x18, 0x1f, 0x1e, 0x1d, 0x1c };
__code uint8_t nonce[12] = {
0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
__code uint8_t sunscreen[] = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for " \
"the future, sunscreen would be it.";
/*
Ciphertext Sunscreen (from RFC 7539 Section 2.4.2):
000 6e 2e 35 9a 25 68 f9 80 41 ba 07 28 dd 0d 69 81 n.5.%h..A..(..i.
016 e9 7e 7a ec 1d 43 60 c2 0a 27 af cc fd 9f ae 0b .~z..C`..'......
032 f9 1b 65 c5 52 47 33 ab 8f 59 3d ab cd 62 b3 57 ..e.RG3..Y=..b.W
048 16 39 d6 24 e6 51 52 ab 8f 53 0c 35 9f 08 61 d8 .9.$.QR..S.5..a.
064 07 ca 0d bf 50 0d 6a 61 56 a3 8e 08 8a 22 b6 5e ....P.jaV....".^
080 52 bc 51 4d 16 cc f8 06 81 8c e9 1a b7 79 37 36 R.QM.........y76
096 5a f9 0b bf 74 a3 5b e6 b4 0b 8e ed f2 78 5e 42 Z...t.[......x^B
112 87 4d
*/
strcpy(plaintext, sunscreen);
memcpyc(chacha20.constant, chacha_c, 16);
memcpyc(chacha20.key, key, 32);
chacha20.cnt = 0;
memcpyc(chacha20.nonce, nonce, 12);
chacha20.plaintext = plaintext;
chacha20.length = strlen_x(plaintext);
chacha20.cyphertext = cyphertext;
print_string("Encrypting...\n");
chacha20_encrypt();
print_string("Cypertext:\n");
uint16_t len = strlen_x(plaintext);
for (uint8_t i = 0; i < len; i++) {
print_byte(cyphertext[i]); write_char(' ');
}
}
+489
View File
@@ -0,0 +1,489 @@
; ChaCha Quater-Round implementation in Assembler
.module chacha_8051
; Global variables:
.globl _chacha_20
.globl _chacha_test_1
.globl _chacha_qr_r
.globl _chacha_update
.globl _chacha_count
;#define CHACHA_QR(A, B, C, D) { \
; A += B; D ^= A; D = ROTL32(D, 16); \
; C += D; B ^= C; B = ROTL32(B, 12); \
; A += B; D ^= A; D = ROTL32(D, 8); \
; C += D; B ^= C; B = ROTL32(B, 7); \
;}
; r0 r1 r2 r3
; CHACHA_QR( v[ 0], v[ 4], v[ 8], v[12] );
.area HOME (CODE)
store_32:
ar7 = 0x07
ar6 = 0x06
ar5 = 0x05
ar4 = 0x04
ar3 = 0x03
ar2 = 0x02
ar1 = 0x01
ar0 = 0x00
mov a, r7
movx @dptr, a
dec dpl
mov a, r6
movx @dptr, a
dec dpl
mov a, r5
movx @dptr, a
dec dpl
mov a, r4
movx @dptr, a
ret
rol_b:
clr c
mov a, r7
rlc a
mov r7, a
mov a, r6
rlc a
mov r6, a
mov a, r5
rlc a
mov r5, a
mov a, r4
rlc a
mov r4, a
clr a
addc a, r7
mov r7, a
djnz dpl, rol_b
ret
print_regs:
push a
push ar6
push ar7
push dpl
mov dpl, a
lcall _print_byte
pop dpl
pop ar7
pop ar6
pop a
chacha_plus_xor:
; Load A into registers r4-r7, A pointed to by r0
mov dptr, #_chacha20
mov dpl, r0
movx a, @dptr
mov r7, a
dec dpl
movx a, @dptr
mov r6, a
dec dpl
movx a, @dptr
mov r5, a
dec dpl
movx a, @dptr
mov r4, a
; A += B, B pointed to by r1
mov dpl, r1
movx a, @dptr
add a, r7
mov r7, a
dec dpl
movx a, @dptr
addc a, r6
mov r6, a
dec dpl
movx a, @dptr
addc a, r5
mov r5, a
dec dpl
movx a, @dptr
addc a, r4
mov r4, a
mov dpl, r0 ; Store A back
mov a, r7
movx @dptr, a
dec dpl
mov a, r6
movx @dptr, a
dec dpl
mov a, r5
movx @dptr, a
dec dpl
mov a, r4
movx @dptr, a
; D ^= A
mov dpl, r3
movx a, @dptr
xrl a, r7
mov r7, a
dec dpl
movx a, @dptr
xrl a, r6
mov r6, a
dec dpl
movx a, @dptr
xrl a, r5
mov r5, a
dec dpl
movx a, @dptr
xrl a, r4
mov r4, a
dec dpl
ret
chacha_qr:
; QR Part: A += B; D ^= A; D = ROTL32(D, 16);
acall chacha_plus_xor
; rotate left 16. D is r4, r5, r6, r7 -> r6, r7, r4, r5
mov a, r6
xch a, r4
mov r6, a
mov a, r7
xch a, r5
mov r7, a
mov dpl, r3 ; Store D
acall store_32
;QR Part: C += D; B ^= C; B = ROTL32(B, 12);
; Swap A <-> C and D <-> B
mov a, r0
xch a, r2
mov r0, a
mov a, r1
xch a, r3
mov r1, a
acall chacha_plus_xor
; rotate left 12. D is r4, r5, r6, r7 -> r5, r6, r7, r4
mov a, r4
xch a, r7
xch a, r6
xch a, r5
mov r4, a
mov dpl, #4
acall rol_b
mov dpl, r3 ; Store D (being B)
acall store_32
; Swap A <-> C and D <-> B
mov a, r0
xch a, r2
mov r0, a
mov a, r1
xch a, r3
mov r1, a
mov dpl, r1 ; Store B
acall store_32
; QR Part A += B; D ^= A; D = ROTL32(D, 8);
acall chacha_plus_xor
mov a, r4
xch a, r7
xch a, r6
xch a, r5
mov r4, a
mov dpl, r3 ; Store D
acall store_32
; QR Part
; C += D; B ^= C; B = ROTL32(B, 7);
line4:
; Swap A <-> C and D <-> B
mov a, r0
xch a, r2
mov r0, a
mov a, r1
xch a, r3
mov r1, a
acall chacha_plus_xor
; Roll left 7 bits, start by rolling 8 bits left, then roll 1 to the right
mov a, r4
xch a, r7
xch a, r6
xch a, r5
mov r4, a
clr c
mov a, r4
rrc a
mov r4, a
mov a, r5
rrc a
mov r5, a
mov a, r6
rrc a
mov r6, a
mov a, r7
rrc a
mov r7, a
clr a
rrc a
add a, r4
mov r4, a
; Swap A <-> C and D <-> B
mov a, r0
xch a, r2
mov r0, a
mov a, r1
xch a, r3
mov r1, a
mov dpl, r1 ; Store B
acall store_32
ret
_chacha_test_1:
mov r0, #3
mov r1, #7
mov r2, #11
mov r3, #15
acall line4
ret
; QUARTERROUND(2,7,8,13)
_chacha_qr_r:
mov r0, #11
mov r1, #31
mov r2, #35
mov r3, #55
acall chacha_qr
ret
;
; Implementation of 20 ChaCha Rounds (10 Double Rounds)
;
_chacha_20:
push acc
push b
push dpl
push dph
push ar7
push ar6
push ar5
push ar4
push ar3
push ar2
push ar1
push ar0
push psw
mov b, #10 ; 10 Double rounds
chacha_20_loop:
; CHACHA_QR( v[ 0], v[ 4], v[ 8], v[12] );
mov r0, #3
mov r1, #19
mov r2, #35
mov r3, #51
acall chacha_qr
; CHACHA_QR( v[ 1], v[ 5], v[ 9], v[13] ); 7 23 39 55
mov r0, #7
mov r1, #23
mov r2, #39
mov r3, #55
acall chacha_qr
; CHACHA_QR( v[ 2], v[ 6], v[10], v[14] ); 11 27 43 59
mov r0, #11
mov r1, #27
mov r2, #43
mov r3, #59
acall chacha_qr
; CHACHA_QR( v[ 3], v[ 7], v[11], v[15] ); 15 31 47 63
mov r0, #15
mov r1, #31
mov r2, #47
mov r3, #63
acall chacha_qr
; CHACHA_QR( v[ 0], v[ 5], v[10], v[15] ); 3 23 43 63
mov r0, #3
mov r1, #23
mov r2, #43
mov r3, #63
acall chacha_qr
; CHACHA_QR( v[ 1], v[ 6], v[11], v[12] ); 7 27 47 51
mov r0, #7
mov r1, #27
mov r2, #47
mov r3, #51
acall chacha_qr
; CHACHA_QR( v[ 2], v[ 7], v[ 8], v[13] ); 11 31 35 55
mov r0, #11
mov r1, #31
mov r2, #35
mov r3, #55
acall chacha_qr
; CHACHA_QR( v[ 3], v[ 4], v[ 9], v[14] ); 15 19 39 59
mov r0, #15
mov r1, #19
mov r2, #39
mov r3, #59
acall chacha_qr
djnz b, chacha_20_loop
pop psw
pop ar0
pop ar1
pop ar2
pop ar3
pop ar4
pop ar5
pop ar6
pop ar7
pop dph
pop dpl
pop b
pop acc
ret
;
; Update ChaCHa state
;
_chacha_update:
push acc
push b
push dpl
push dph
push ar4
push ar3
push ar2
push ar1
push ar0
push psw
mov dptr, #_chacha20
mov b, #16 ; 16 uint32
update_loop:
mov a, b ; multiply by 4 and subtract 1
rl a
rl a
dec a
; Load Working State variable into registers r0-r3
mov dpl, a
orl a, #64 ; Save pointer to state
mov r4, a
movx a, @dptr
mov r3, a
dec dpl
movx a, @dptr
mov r2, a
dec dpl
movx a, @dptr
mov r1, a
dec dpl
movx a, @dptr
mov r0, a
; Add to State variable
mov a, r4
mov dpl, a
movx a, @dptr
add a, r3
mov r3, a
dec dpl
movx a, @dptr
addc a, r2
mov r2, a
dec dpl
movx a, @dptr
addc a, r1
mov r1, a
dec dpl
movx a, @dptr
addc a, r0
mov r0, a
; Store back state variable in LSB, first sequence (serialized)
mov a, r4
xrl a, #64 ; Save pointer to working state
mov dpl, a
mov a, r0
movx @dptr, a
dec dpl
mov a, r1
movx @dptr, a
dec dpl
mov a, r2
movx @dptr, a
dec dpl
mov a, r3
movx @dptr, a
djnz b, update_loop
pop psw
pop ar0
pop ar1
pop ar2
pop ar3
pop ar4
pop dph
pop dpl
pop b
pop acc
ret
;
; Increase counter in state
;
_chacha_count:
push acc
push dpl
push dph
mov dptr, #_chacha20
mov dpl, #112 + 3
movx a, @dptr
inc a
movx @dptr, a
jnc chacha_count_done
dec dpl
movx a, @dptr
inc a
movx @dptr, a
jnc chacha_count_done
dec dpl
movx a, @dptr
inc a
movx @dptr, a
jnc chacha_count_done
dec dpl
movx a, @dptr
inc a
movx @dptr, a
chacha_count_done:
pop dph
pop dpl
pop acc
ret
+18 -270
View File
@@ -15,9 +15,6 @@
__xdata struct dhcp_state dhcp_state; __xdata struct dhcp_state dhcp_state;
__xdata uip_ipaddr_t server; __xdata uip_ipaddr_t server;
#define BOOTP_REQUEST 1
#define BOOTP_REPY 2
#define DHCP_HW_TYPE_ETH 1 #define DHCP_HW_TYPE_ETH 1
#define DHCP_SUBNET_MASK 1 #define DHCP_SUBNET_MASK 1
@@ -35,7 +32,6 @@ __xdata uip_ipaddr_t server;
#define DHCP_MESSAGE_DISCOVER 1 #define DHCP_MESSAGE_DISCOVER 1
#define DHCP_MESSAGE_OFFER 2 #define DHCP_MESSAGE_OFFER 2
#define DHCP_MESSAGE_REQUEST 3 #define DHCP_MESSAGE_REQUEST 3
#define DHCP_MESSAGE_NACK 4
#define DHCP_MESSAGE_ACK 5 #define DHCP_MESSAGE_ACK 5
#define DHCP_LEASE 51 #define DHCP_LEASE 51
#define DHCP_LEASE_LEN 4 #define DHCP_LEASE_LEN 4
@@ -47,23 +43,15 @@ __xdata uip_ipaddr_t server;
#define DHCP_CLIENT_ID_LEN 7 #define DHCP_CLIENT_ID_LEN 7
#define DHCP_REQUEST_IP 50 #define DHCP_REQUEST_IP 50
#define DHCP_REQUEST_IP_LEN 4 #define DHCP_REQUEST_IP_LEN 4
#define DHCP_CLIENT_NAME 12
#define DHCP_PARAMS 55 #define DHCP_PARAMS 55
#define DHCP_VENDOR_ID 60
#define DHCP_CLIENT_ID 61
#define DHCP_PARAM_SUBNET 1 #define DHCP_PARAM_SUBNET 1
#define DHCP_PARAM_ROUTER 3 #define DHCP_PARAM_ROUTER 3
#define DHCP_PARAM_DNS 6 #define DHCP_PARAM_DNS 6
#define DHCP_END 255 #define DHCP_END 255
#define LEASE_TIME 43200
#define RENEWAL_TIME 21600
#define REBIND_TIME 21600
#pragma codeseg BANK2 #pragma codeseg BANK2
#pragma constseg BANK2 #pragma constseg BANK2
struct dhcp_pkt { struct dhcp_pkt {
uint8_t type; uint8_t type;
uint8_t hw; uint8_t hw;
@@ -87,11 +75,9 @@ struct dhcp_pkt {
#define DHCP_OPT ((__xdata uint8_t *)(uip_appdata) + sizeof (struct dhcp_pkt)) #define DHCP_OPT ((__xdata uint8_t *)(uip_appdata) + sizeof (struct dhcp_pkt))
__xdata uint32_t long_value; __xdata uint32_t long_value;
__xdata struct dhcpd_cstate cstates[DHCPD_MAX_CLIENTS];
__xdata uint8_t client_idx;
__xdata uint16_t dhcpd_vlan;
void dhcp_print_ip(uint8_t *a)
void dhcp_print_ip(__xdata uint8_t *a)
{ {
itoa(a[0]); write_char('.'); itoa(a[0]); write_char('.');
itoa(a[1]); write_char('.'); itoa(a[1]); write_char('.');
@@ -100,14 +86,14 @@ void dhcp_print_ip(uint8_t *a)
} }
void dhcp_prepare_msg(void) void dhcp_prepare_request(void)
{ {
DHCP_P->type = BOOTP_REQUEST; DHCP_P->type = 1;
DHCP_P->hw = DHCP_HW_TYPE_ETH; DHCP_P->hw = DHCP_HW_TYPE_ETH;
DHCP_P->hw_len = 6; DHCP_P->hw_len = 6;
DHCP_P->hops = 0; DHCP_P->hops = 0;
DHCP_P->tid = dhcp_state.transaction_id; // In network byte order DHCP_P->tid = HTONS(dhcp_state.transaction_id);
DHCP_P->delay = HTONS(0); DHCP_P->delay = HTONS(0);
DHCP_P->flags = 0; DHCP_P->flags = 0;
// Clear fields client_ip to bootp_file // Clear fields client_ip to bootp_file
@@ -138,6 +124,7 @@ void dhcp_addopt_request_ip(void)
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[1]; DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[1];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[2]; DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[2];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[3]; DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[3];
memcpy(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
} }
@@ -149,68 +136,14 @@ void dhcp_addopt_server_id(void)
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[1]; DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[1];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[2]; DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[2];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[3]; DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[3];
} memcpy(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
void dhcp_addopt_subnet(void)
{
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_SUBNET_MASK;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_SUBNET_MASK_LEN;
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.subnet[0];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.subnet[1];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.subnet[2];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.subnet[3];
}
void dhcp_addopt_router(void)
{
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_ROUTER;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_ROUTER_LEN;
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.router[0];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.router[1];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.router[2];
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.router[3];
}
void dhcp_addopt_lease(void)
{
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_LEASE;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_LEASE_LEN;
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = LEASE_TIME >> 8;
DHCP_OPT[dhcp_state.opt_ptr++] = LEASE_TIME & 0xff;
}
void dhcp_addopt_renewal(void)
{
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_RENEWAL;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_RENEWAL_LEN;
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = RENEWAL_TIME >> 8;
DHCP_OPT[dhcp_state.opt_ptr++] = RENEWAL_TIME & 0xff;
}
void dhcp_addopt_rebind(void)
{
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_REBIND;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_REBIND_LEN;
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = REBIND_TIME >> 8;
DHCP_OPT[dhcp_state.opt_ptr++] = REBIND_TIME & 0xff;
} }
void dhcp_send_discover(void) void dhcp_send_discover(void)
{ {
print_string("dhcp_send_discover called\n"); print_string("dhcp_send_discover called\n");
dhcp_prepare_msg(); dhcp_prepare_request();
dhcp_state.opt_ptr = 0; dhcp_state.opt_ptr = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE; DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE;
@@ -245,7 +178,7 @@ void dhcp_send_discover(void)
void dhcp_send_request(void) void dhcp_send_request(void)
{ {
print_string("dhcp_send_request called\n"); print_string("dhcp_send_request called\n");
dhcp_prepare_msg(); dhcp_prepare_request();
dhcp_state.opt_ptr = 0; dhcp_state.opt_ptr = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE; DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE;
@@ -278,42 +211,7 @@ void dhcp_send_request(void)
} }
void dhcp_send_reply(uint8_t rtype) void ip_opt(__xdata uint8_t * ip)
{
print_string("dhcp_send_reply called\n");
dhcp_prepare_msg();
DHCP_P->type = BOOTP_REPY;
DHCP_P->client_addr[0] = cstates[client_idx].mac[0]; DHCP_P->client_addr[1] = cstates[client_idx].mac[1];
DHCP_P->client_addr[2] = cstates[client_idx].mac[2]; DHCP_P->client_addr[3] = cstates[client_idx].mac[3];
DHCP_P->client_addr[4] = cstates[client_idx].mac[4]; DHCP_P->client_addr[5] = cstates[client_idx].mac[5];
if (rtype != DHCP_MESSAGE_NACK) {
DHCP_P->your_ip[0] = dhcp_state.server[0];
DHCP_P->your_ip[1] = dhcp_state.server[1];
DHCP_P->your_ip[2] = dhcp_state.server[2];
DHCP_P->your_ip[3] = DHCPD_START_IP + client_idx;
}
dhcp_state.opt_ptr = 0;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE;
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_MESSAGE_TYPE_LEN;
DHCP_OPT[dhcp_state.opt_ptr++] = rtype;
if (rtype != DHCP_MESSAGE_NACK) {
dhcp_addopt_subnet();
dhcp_addopt_router();
dhcp_addopt_server_id();
dhcp_addopt_rebind();
dhcp_addopt_lease();
dhcp_addopt_renewal();
}
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_END;
uip_udp_send(sizeof(struct dhcp_pkt) + dhcp_state.opt_ptr);
}
void ip_opt(uint8_t * __xdata ip)
{ {
dhcp_state.opt_ptr++; dhcp_state.opt_ptr++;
uint8_t len = DHCP_OPT[dhcp_state.opt_ptr++]; uint8_t len = DHCP_OPT[dhcp_state.opt_ptr++];
@@ -340,22 +238,6 @@ void long_opt(void)
} }
void print_txt_opt(void)
{
dhcp_state.opt_ptr++;
for (uint8_t l = DHCP_OPT[dhcp_state.opt_ptr++]; l ; l--)
write_char(DHCP_OPT[dhcp_state.opt_ptr++]);
}
void print_eth_opt(void)
{
dhcp_state.opt_ptr++;
for (uint8_t l = DHCP_OPT[dhcp_state.opt_ptr++]; l ; l--)
print_byte(DHCP_OPT[dhcp_state.opt_ptr++]);
}
void parse_opts(void) void parse_opts(void)
{ {
while (DHCP_OPT[dhcp_state.opt_ptr] && DHCP_OPT[dhcp_state.opt_ptr] != DHCP_END) { while (DHCP_OPT[dhcp_state.opt_ptr] && DHCP_OPT[dhcp_state.opt_ptr] != DHCP_END) {
@@ -375,9 +257,6 @@ void parse_opts(void)
case DHCP_BROADCAST: case DHCP_BROADCAST:
ip_opt(&dhcp_state.broadcast[0]); ip_opt(&dhcp_state.broadcast[0]);
break; break;
case DHCP_REQUEST_IP:
ip_opt(&dhcp_state.current_ip[0]);
break;
case DHCP_LEASE: case DHCP_LEASE:
long_opt(); long_opt();
dhcp_state.lease = long_value; dhcp_state.lease = long_value;
@@ -390,27 +269,6 @@ void parse_opts(void)
long_opt(); long_opt();
dhcp_state.renewal = long_value; dhcp_state.renewal = long_value;
break; break;
case DHCP_CLIENT_NAME:
print_string("Client name: ");
print_txt_opt();
write_char('\n');
break;
case DHCP_VENDOR_ID:
print_string("Vendor ID: ");
print_txt_opt();
write_char('\n');
break;
case DHCP_CLIENT_ID:
print_string("Client ID: ");
print_eth_opt();
write_char('\n');
break;
case DHCP_PARAMS:
print_string("PARAMS request (ignored)\n");
dhcp_state.opt_ptr++;
dhcp_state.opt_ptr += DHCP_OPT[dhcp_state.opt_ptr];
dhcp_state.opt_ptr++;
break;
case DHCP_END: case DHCP_END:
break; break;
default: default:
@@ -423,39 +281,9 @@ void parse_opts(void)
} }
void find_client(void) void parse_dhcp(void)
{ {
uint8_t i; if (!DHCP_P->tid == HTONS(dhcp_state.transaction_id))
for (i = 0; i < DHCPD_MAX_CLIENTS; i++) {
if (cstates[i].mac[0] == DHCP_P->client_addr[0] && cstates[i].mac[1] == DHCP_P->client_addr[1]
&& cstates[i].mac[2] == DHCP_P->client_addr[2] && cstates[i].mac[3] == DHCP_P->client_addr[3]
&& cstates[i].mac[4] == DHCP_P->client_addr[4] && cstates[i].mac[5] == DHCP_P->client_addr[5]
)
break;
}
if (i < DHCPD_MAX_CLIENTS) {
client_idx = i;
return;
}
client_idx = 255;
}
void find_slot(void)
{
for (client_idx = 0; client_idx < DHCPD_MAX_CLIENTS; client_idx++) {
if (!cstates[client_idx].cstate)
return;
}
client_idx = 255;
return;
}
void parse_dhcp_response(void)
{
if (!DHCP_P->tid == dhcp_state.transaction_id)
return; return;
if (DHCP_P->cookie[0] != 0x63 || DHCP_P->cookie[1] != 0x82 || DHCP_P->cookie[2] != 0x53 || DHCP_P->cookie[3] != 0x63) if (DHCP_P->cookie[0] != 0x63 || DHCP_P->cookie[1] != 0x82 || DHCP_P->cookie[2] != 0x53 || DHCP_P->cookie[3] != 0x63)
return; return;
@@ -494,50 +322,13 @@ void parse_dhcp_response(void)
} }
void parse_dhcp_request(void)
{
print_string("parse_dhcp_request called\n");
if (DHCP_P->cookie[0] != 0x63 || DHCP_P->cookie[1] != 0x82 || DHCP_P->cookie[2] != 0x53 || DHCP_P->cookie[3] != 0x63)
return;
dhcp_state.opt_ptr = 0;
if (DHCP_OPT[dhcp_state.opt_ptr++] != DHCP_MESSAGE_TYPE || DHCP_OPT[dhcp_state.opt_ptr++] != DHCP_MESSAGE_TYPE_LEN)
return;
if (DHCP_OPT[dhcp_state.opt_ptr] == DHCP_MESSAGE_DISCOVER) {
dhcp_state.opt_ptr++;
find_client();
if (client_idx == 255)
find_slot();
// If there is no empty slot, we play possum and do not answer to the request
if (client_idx == 255)
return;
cstates[client_idx].cstate = CSTATE_OFFERED;
cstates[client_idx].mac[0] = DHCP_P->client_addr[0]; cstates[client_idx].mac[1] = DHCP_P->client_addr[1];
cstates[client_idx].mac[2] = DHCP_P->client_addr[2]; cstates[client_idx].mac[3] = DHCP_P->client_addr[3];
cstates[client_idx].mac[4] = DHCP_P->client_addr[4]; cstates[client_idx].mac[5] = DHCP_P->client_addr[5];
dhcp_state.transaction_id = DHCP_P->tid;
parse_opts();
dhcp_send_reply(DHCP_MESSAGE_OFFER);
} else if (DHCP_OPT[dhcp_state.opt_ptr++] == DHCP_MESSAGE_REQUEST) {
find_client();
if (client_idx == 255) {
dhcp_send_reply(DHCP_MESSAGE_NACK);
return;
}
parse_opts();
dhcp_send_reply(DHCP_MESSAGE_ACK);
}
}
void dhcp_start(void) __banked void dhcp_start(void) __banked
{ {
uip_ipaddr(server, 255,255,255,255); uip_ipaddr(server, 255,255,255,255);
dhcp_state.conn = uip_udp_new(&server, HTONS(DHCP_SERVER_PORT)); dhcp_state.conn = uip_udp_new(&server, HTONS(DHCPC_SERVER_PORT));
dhcp_state.current_ip[0] = dhcp_state.current_ip[1] = dhcp_state.current_ip[2] = dhcp_state.current_ip[3] = 0; dhcp_state.current_ip[0] = dhcp_state.current_ip[1] = dhcp_state.current_ip[2] = dhcp_state.current_ip[3] = 0;
if(dhcp_state.conn) { if(dhcp_state.conn) {
uip_udp_bind(dhcp_state.conn, HTONS(DHCP_CLIENT_PORT)); uip_udp_bind(dhcp_state.conn, HTONS(DHCPC_CLIENT_PORT));
} else { } else {
print_string("dhcp_start failed to set up socket\n"); print_string("dhcp_start failed to set up socket\n");
return; return;
@@ -549,43 +340,6 @@ void dhcp_start(void) __banked
} }
void dhcpd_start(void) __banked
{
memset(&cstates[0], 0, sizeof (struct dhcpd_cstate) * DHCPD_MAX_CLIENTS);
dhcp_state.conn = uip_udp_new(0, 0);
if(dhcp_state.conn) {
uip_udp_bind(dhcp_state.conn, HTONS(DHCP_SERVER_PORT));
} else {
print_string("dhcpd_start failed to set up socket\n");
return;
}
if (!dhcpd_vlan)
print_string("dhcpd: enabling for all VLANs\n");
else
print_string("dhcpd: enabling for VLAN "); print_short(dhcpd_vlan); write_char('\n');
dhcp_state.state = DHCP_SERVER;
dhcp_state.server[1] = uip_hostaddr[0] >> 8; dhcp_state.server[0] = uip_hostaddr[0] & 0xff;
dhcp_state.server[3] = uip_hostaddr[1] >> 8; dhcp_state.server[2] = uip_hostaddr[1] & 0xff;
dhcp_state.router[1] = uip_draddr[0] >> 8; dhcp_state.router[0] = uip_draddr[0] & 0xff;
dhcp_state.router[3] = uip_draddr[1] >> 8; dhcp_state.router[2] = uip_draddr[1] & 0xff;
dhcp_state.subnet[1] = uip_netmask[0] >> 8; dhcp_state.subnet[0] = uip_netmask[0] & 0xff;
dhcp_state.subnet[3] = uip_netmask[1] >> 8; dhcp_state.subnet[2] = uip_netmask[1] & 0xff;
dhcp_state.broadcast[0] = dhcp_state.router[0]; dhcp_state.broadcast[1] = dhcp_state.router[1];
dhcp_state.broadcast[2] = dhcp_state.router[2]; dhcp_state.broadcast[3] = 0xff;
for (uint8_t i = 0; i < DHCPD_MAX_CLIENTS; i++) {
cstates[i].cstate = CSTATE_NONE;
}
// TODO: DNS, correct broadcast address
print_string("dhcpd_start done\n");
}
void dhcp_stop(void) __banked void dhcp_stop(void) __banked
{ {
print_string("dhcp_stop called\n"); print_string("dhcp_stop called\n");
@@ -593,13 +347,6 @@ void dhcp_stop(void) __banked
dhcp_state.state = DHCP_OFF; dhcp_state.state = DHCP_OFF;
} }
void dhcpd_stop(void) __banked
{
print_string("dhcpd_stop called\n");
uip_udp_remove(dhcp_state.conn);
dhcp_state.state = DHCP_OFF;
}
void dhcp_callback(void) __banked void dhcp_callback(void) __banked
{ {
@@ -608,10 +355,8 @@ void dhcp_callback(void) __banked
if (uip_closed()) { if (uip_closed()) {
print_string("Closed\n"); print_string("Closed\n");
return; return;
} else if (dhcp_state.state == DHCP_SERVER && uip_newdata()) {
parse_dhcp_request();
} else if (uip_newdata()) { } else if (uip_newdata()) {
parse_dhcp_response(); parse_dhcp();
} else { } else {
if (dhcp_state.state == DHCP_START) { if (dhcp_state.state == DHCP_START) {
dhcp_send_discover(); dhcp_send_discover();
@@ -634,4 +379,7 @@ void dhcp_callback(void) __banked
} }
} }
} }
// By default we do not send anything out
uip_len = 0;
} }
+5 -22
View File
@@ -3,27 +3,22 @@
#include "uipopt.h" #include "uipopt.h"
#include <stdint.h> #include <stdint.h>
#define DHCPD_MAX_CLIENTS 20
#define DHCPD_START_IP 100
#define DHCP_SERVER_PORT 67 #define DHCPC_SERVER_PORT 67
#define DHCP_CLIENT_PORT 68 #define DHCPC_CLIENT_PORT 68
#define DHCP_OFF 0 #define DHCP_OFF 0
#define DHCP_START 1 #define DHCP_START 1
#define DHCP_DISCOVER_SENT 2 #define DHCP_DISCOVER_SENT 2
#define DHCP_REQUEST_SENT 3 #define DHCP_REQUEST_SENT 3
#define DHCP_LEASING 4 #define DHCP_LEASING 4
#define DHCP_SERVER 5
#define CSTATE_NONE 0
#define CSTATE_OFFERED 1
#define CSTATE_LEASED 2
void dhcp_start(void) __banked; void dhcp_start(void) __banked;
void dhcp_stop(void) __banked; void dhcp_stop(void) __banked;
// void dhcp_periodic(void) __banked;
void dhcp_callback(void) __banked; void dhcp_callback(void) __banked;
struct dhcp_state { struct dhcp_state {
uint8_t state; uint8_t state;
uint32_t transaction_id; uint32_t transaction_id;
@@ -40,21 +35,9 @@ struct dhcp_state {
uint32_t rebind; uint32_t rebind;
uint32_t renewal; uint32_t renewal;
struct uip_udp_conn *conn; __xdata struct uip_udp_conn *conn;
}; };
struct dhcpd_cstate {
uint8_t cstate;
uint16_t timer;
uint32_t transaction_id;
uint8_t mac[6];
uint8_t ip[4];
};
void dhcpd_start(void) __banked;
void dhcpd_stop(void) __banked;
typedef struct dhcp_state uip_udp_appstate_t; typedef struct dhcp_state uip_udp_appstate_t;
/* Finally we define the application function to be called by uIP. */ /* Finally we define the application function to be called by uIP. */
+32
View File
@@ -0,0 +1,32 @@
# Automation
## Upload
You can automate upload of the firmware via WEB with curl:
1. Authorize with /login endpoint and save cookie:
```bash
curl -c cookies.txt http://${SWITCH_IP}/login -d pwd=${PASSWORD} -i
```
This will save session cookie in cookies.txt
2. Send the firmware via form:
```bash
curl -b cookies.txt http://${SWITCH_IP}/upload -F "uploadedfile=@${FIRMWARE_FILE_PATH}" -i
```
You can expect that server will close connection, without responding to request.
Wait for SWITCH_IP to be responding again.
## Port status
In similar way to upload, you can fetch the json status of the ports.
1. Get the session cookie as for upload.
2. Hit the `/status.json` with cookie:
```bash
curl -b cookies.txt http://${SWITCH_IP}/status.json
```
+177
View File
@@ -0,0 +1,177 @@
### 2M-PCB23-V2.2
## Brands
| Brand | Type | Managed | PCB | Flash | Chip RTL |
|----------|-----------------|---------|---------------|-------|-------------|
| keepLINK | KP-9000-9XHML-X | Yes | 2M-PCB23-V2.2 | 2M | 8373 + 8224 |
## PCB
<img src="photos/2M-PCB23-V2.2-managed/2M-PCB23-V2.2-top.jpg" width="300" />
## Port overview
```
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ┌──────────┐ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ SFP(J13) │ │
│ │ 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
### J13, SFP connector
| SFP Pin | Signal | GPIO | Notes |
| ------- | ----------------- | ------ | ------------------------------ |
| 2 | TX_FAULT | ?? | |
| 3 | TX_DISABLE | ?? | |
| 4 | MODDEF2 SDA | GPIO39 | |
| 5 | MODDEF1 SCL | GPIO40 | |
| 6 | MODDEF0 PRESENT | GPIO30 | "OE Exist" reported by `fiber` |
| 7 | RATE SEL | ?? | |
| 8 | LOS | GPIO37 | "OE LOS" reported by `fiber` |
| 9 | TO? | ?? | |
### T5, serial console
| pin | GPIO | Signal |
| --- | ------ | -------------- |
| 1 | GPIO32 | U0RXD (Input) |
| 2 | GND | Ground |
| 3 | GPIO31 | U0TXD (Output) |
### S1, unknown connector
| pin | GPIO | Signal |
| --- | -------- | -------------- |
| 1 | ??? | |
| x | | |
| 3 | ??? | |
| 4 | ??? | |
| 5 | ??? | |
Potentially slave interface or SMI.
### U7, flash memory
Flash chip is FM25Q16A.
### Reset button
GPIO54
## Register values
As probed with `regget` on stock firmware "V1.6".
### Model
| Name | Addr | Value |
| ------------------------- | ------ | ---------- |
| MODEL_NAME_INFO | 0x0004 | 0x83730000 |
| CHIP_MODE_INFO | 0x0008 | 0x00008000 |
| CHIP_INFO | 0x000C | 0x00300000 |
### GPIO
| Name | Addr | Value |
| ------------------------- | ------ | ---------- |
| GPIO_OUT0 | 0x003c | 0x10000000 |
| GPIO_OUT1 | 0x0040 | 0x00000010 |
| GPIO_OE0 | 0x004c | 0x10000000 |
| GPIO_OE1 | 0x0050 | 0x00000010 |
| BOND_INFO | 0x7f60 | 0x00000fff |
| STRAP_INFO | 0x7f64 | 0x0002f515 |
| IO_DRVING_0 | 0x7f68 | 0x00000000 |
| IO_DRVING_1 | 0x7f6c | 0x00000000 |
| IO_DRVING_2 | 0x7f70 | 0x00000000 |
| IO_SLEW_0 | 0x7f74 | 0x00000000 |
| IO_SLEW_1 | 0x7f78 | 0x00000000 |
| IO_SLEW_2 | 0x7f7c | 0x00000000 |
| IO_SMT_EN_0 | 0x7f80 | 0xffffffff |
| IO_SMT_EN_1 | 0x7f84 | 0xffffffff |
| IO_SMT_EN_2 | 0x7f88 | 0x0003ffff |
| IO_MUX_SEL_0 | 0x7f8c | 0x28000000 |
| IO_MUX_SEL_1 | 0x7f90 | 0x40000041 |
| IO_MUX_SEL_2 | 0x7f94 | 0x00000000 |
### LED
| Name | Addr | Value |
| ------------------------- | ------ | ---------- |
| LED_GLB_CTRL | 0x6520 | 0x0023e0f0 |
| LED3_0_SET3_2_CTRL1 | 0x6524 | 0xff001400 |
| LED3_0_SET1_0_CTRL1 | 0x6528 | 0x000f0000 |
| LED3_2_SET3_CTRL0 | 0x652c | 0x007f013f |
| LED1_0_SET3_CTRL0 | 0x6530 | 0x02000400 |
| LED3_2_SET2_CTRL0 | 0x6534 | 0x01400141 |
| LED1_0_SET2_CTRL0 | 0x6538 | 0x01440170 |
| LED3_2_SET1_CTRL0 | 0x653c | 0x18000041 |
| LED1_0_SET1_CTRL0 | 0x6540 | 0x0044017f |
| LED3_2_SET0_CTRL0 | 0x6544 | 0x00000044 |
| LED1_0_SET0_CTRL0 | 0x6548 | 0x00410175 |
| LED_PORT_SET_SEL_CTRL | 0x654c | 0x00010000 |
| SW_LED_LOAD | 0x6550 | 0x00000000 |
| LED_PORT_SW_EN_CTRL[0..7] | 0x6554 | 0x00000000 |
| LED_PORT_SW_EN_CTRL[8] | 0x6558 | 0x00000000 |
| LED_PORT_SW_CTRL[0] | 0x655c | 0x00000000 |
| LED_PORT_SW_CTRL[1] | 0x6560 | 0x00000000 |
| LED_PORT_SW_CTRL[2] | 0x6564 | 0x00000000 |
| LED_PORT_SW_CTRL[3] | 0x6568 | 0x00000000 |
| LED_PORT_SW_CTRL[4] | 0x656c | 0x00000000 |
| LED_PORT_SW_CTRL[5] | 0x6570 | 0x00000000 |
| LED_PORT_SW_CTRL[6] | 0x6574 | 0x00000000 |
| LED_PORT_SW_CTRL[7] | 0x6578 | 0x00000000 |
| LED_PORT_SW_CTRL[8] | 0x657c | 0x00000000 |
| LED_LOAD_LV1_10G | 0x6580 | 0x000fa000 |
| LED_LOAD_LV2_10G | 0x6584 | 0x00271000 |
| LED_LOAD_LV3_10G | 0x6588 | 0x004e2000 |
| LED_LOAD_LV1_5G | 0x658c | 0x000fa000 |
| LED_LOAD_LV2_5G | 0x6590 | 0x00271000 |
| LED_LOAD_LV3_5G | 0x6594 | 0x004e2000 |
| LED_LOAD_LV1_2P5G | 0x6598 | 0x000fa000 |
| LED_LOAD_LV2_2P5G | 0x659c | 0x00271000 |
| LED_LOAD_LV3_2P5G | 0x65a0 | 0x004e2000 |
| LED_LOAD_LV1_1G | 0x65a4 | 0x000fa000 |
| LED_LOAD_LV2_1G | 0x65a8 | 0x00271000 |
| LED_LOAD_LV3_1G | 0x65ac | 0x004e2000 |
| LED_LOAD_LV1_500M | 0x65b0 | 0x0007d000 |
| LED_LOAD_LV2_500M | 0x65b4 | 0x00138800 |
| LED_LOAD_LV3_500M | 0x65b8 | 0x00271000 |
| LED_LOAD_LV1_100M | 0x65bc | 0x00019000 |
| LED_LOAD_LV2_100M | 0x65c0 | 0x0003e800 |
| LED_LOAD_LV3_100M | 0x65c4 | 0x0007d000 |
| LED_LOAD_LV1_10M | 0x65c8 | 0x00002800 |
| LED_LOAD_LV2_10M | 0x65cc | 0x00006400 |
| LED_LOAD_LV3_10M | 0x65d0 | 0x0000c800 |
| LED_P_LOAD_CTRL | 0x65d4 | 0x00000000 |
| LED_GLB_ACTIVE | 0x65d8 | 0x3ffbedff |
| LED_GLB_IO_EN | 0x65dc | 0x77ffffff |
| LED_GLB_MUX_1 | 0c65e0 | 0x05102040 |
| LED_GLB_MUX_2 | 0x65e4 | 0x0c289206 |
| LED_GLB_MUX_3 | 0x65e8 | 0x1245038d |
| LED_GLB_MUX_4 | 0x65ec | 0x19616554 |
| LED_GLB_MUX_5 | 0x65f0 | 0x2079d71a |
| LED_GLB_MUX_6 | 0x65f4 | 0x000238a1 |
| LED_RLDP_CTRL_1 | 0x65f8 | 0x00000019 |
| LED_RLDP_CTRL_2 | 0x65fc | 0xffffffff |
| LED_RLDP_CTRL_3 | 0x6600 | 0x00006600 |
| LED_DUMY_0_ADDR | 0x6604 | 0x00000000 |
| LED_DUMY_1_ADDR | 0x6608 | 0x00000000 |
# LEDs
| Name | Components | Controlled by |
| ----------------------------- | --------------------------- | -------------------------- |
| RJ45 Right Green ("LINK/ACT") | | RJ45 LED0 |
| RJ45 Left Orange ("2.5G") | | RJ45 LED1 |
| RJ45 Left Green ("1G") | | RJ45 LED2 |
| "P" (PWR) | Top LED in "LED6" stack | probably pulled from Vcc |
| SFP Link ("9") | Bottom LED in "LED6" stack | SFP LED0 |
| ?? | D23 | SFP LED1 |
| ?? | D22 | SFP LED2 |
+23
View File
@@ -0,0 +1,23 @@
# K0501W V2.0
This board appears for example in the Davuaz Da-K6501W switch.
The general design of the board is similar to Hi-K0402WS V3.0.
However, there are several differences:
- One SFP port is replaced by a RTL8221B 2.5G PHY
- Only one LED is populated for the SFP port
- No mode switch and only one flash chip
- Older design using RTL8372 instead of RTL8372N (which also means different GPIO and LED configuration)
- Like earlier versions of the K0402W(S) board, there is no UART
All ports and LEDs are supported.
Installation is possible using a flash programmer.
The BoyaMicro 25Q16BSSIG flash chip is supported by flashprog with chip name "B.25D16AS/BY25Q16BS/BY25Q16ES".
## PCB pictures
The board is marked `PCB-K0501W-V2.0 DIP-K0501WS-V2.0`.
<img src="photos/K0501W_V2_0/pcb-top.jpg" width="300" />
<img src="photos/K0501W_V2_0/pcb-bottom.jpg" width="300" />
+164
View File
@@ -0,0 +1,164 @@
### ZX-SWTGW215AS
## Brands
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|---|---|---|---|---|---|
| Lianguo | ZX-SWTGW215AS | Yes | PCB-SWTG115AS-V2.0 | FM25Q16A | 8272 |
## RTLPlayground target
Use machine target `MACHINE_LIANGUO_ZX_SWTGW215AS` for this device.
Physical hardware verification: 5x RJ45 ports + 1x SFP port.
Port 5 RJ45 is interfaced through a RTL8221B IC.
## PCB
<img src="photos/ZX-SWTGW215AS/pcb_top.jpg" width="300" />
# Connectors
## Port overview
```
┌──────────────────────────────────────────────────────────────────────────────────┐
│ ┌──────────┐ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ SFP (J4) │ │
│ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ PORT 6 │ │
│ │ PORT 1 │ │ PORT 2 │ │ PORT 3 │ │ PORT 4 │ │ PORT 5 │ │ LOG 8 │ │
│ O │ LOG 4 │ │ LOG 5 │ │ LOG 6 │ │ LOG 7 │ │ LOG 3 │ │ SerDes 1 │ │
│ RST └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘ │
└──────────────────────────────────────────────────────────────────────────────────┘
```
| Type | RTLPlayground logical ports | Physical index |
|---|---|---|
| RJ45 | 3, 4, 5, 6, 7 | 1-5 |
| SFP | 8 | 6 |
## J4
* Location: SFP connector `J4`.
* Connected to: 10GMAC number 8, SerDes 1.
|`J4` SFP PINs | Signal | GPIO | Notes |
|---|---|---|---|
|3| TX_DISABLE | GPIO_NA | Not connected |
|4| MODDEF2 SDA | GPIO39 | I2C SDA |
|5| MODDEF1 SCL | GPIO40 | I2C SCL |
|6| MODDEF0 PRESENT | GPIO30 | Detect |
|8| LOS | GPIO37 | RX Loss of Signal |
### Notes
* Not all signals were mapped mechanically, hence they've been left out of documentation.
## T3, Slave Interface
This connector goes to U4 `I2C EEPROM` and U10 `SPI FLASH` (mappings identical to SWTG024AS).
For detailed Slave Interface functionality and protocol information, see [T3 documentation in SWTG024AS.md](SWTG024AS.md#t3-slave-interface).
|`T3` pin|what|Signal|
|---|---|---|
|1| U4-P6, 33R U10-P6 | I2C-SCL, SPI-CLK, Slave SCK/SCL/MDC/EE_SCL |
|2| GND | --- |
|3| U4-P5, U10-P5 | I2C-SDA, SPI-DI/DO, Slave SDI/SDA/MDIO/EE_SDA |
|4| VCC |
|5| 33R -> U10-P2 | SPI-DO/D1 |
|6| U10-P1 | SPI-CS |
### Notes
* 1 pin is square shaped.
## T5, Serial Console
|`T5` pin|GPIO|Signal|
|---|---|---|
| 1 | GPIO31 | U0TXD (Output) |
| 2 | GND | |
| 3 | GPIO32 | U0RXD (Input) |
| 4 | 3V3 | |
### Notes
* 1 pin is square shaped.
## T8
|`T8` pin|GPIO|Signal|
|---|---|---|
| 1 | GPIO46 | |
| 2 | GND | |
| 3 | GPIO48 | |
| 4 | 3V3 | |
| 5 | GPIO47 | |
| 6 | GPIO49 | |
### Notes
* 1 pin is square shaped.
* Mapping unverified but assumed the same as [LIANGUO SWTG024AS](SWTG024AS.md#t8).
# Reset Circuit
| Function | GPIO |
|---|---|
| Reset button | GPIO54 |
### Notes
* Circuit is active-low
# GPIO
Note: T3/U4/U10-related signal annotations below are copied from [LIANGUO SWTG024AS T3 section](SWTG024AS.md#t3-slave-interface) as well as T8 port from [LIANGUO SWTG024AS T8 section](SWTG024AS.md#t8). They should be treated as assumed identical for ZX-SWTGW215AS as it has not been 100% confirmed true at the moment.
| HEX VAL. | GPIO | Component / Purpose | Notes | | GPIO | Component / Purpose | Notes |
| -------- | ------ | ---- | ---- | ---- | ---- | ---- | ---- |
| 00000001 | GPIO00 | | | | GPIO32 | T5-3 | U0RXD |
| 00000002 | GPIO01 | | | | GPIO33 | | |
| 00000004 | GPIO02 | | | | GPIO34 | | |
| 00000008 | GPIO03 | | | | GPIO35 | | |
| 00000010 | GPIO04 | | | | GPIO36 | | |
| 00000020 | GPIO05 | | | | GPIO37 | J4-8 | SFP LOS |
| 00000040 | GPIO06 | | | | GPIO38 | | |
| 00000080 | GPIO07 | | | | GPIO39 | J4-4 | SFP I2C SDA |
| 00000100 | GPIO08 | | | | GPIO40 | J4-5 | SFP I2C SCL |
| 00000200 | GPIO09 | | | | GPIO41 | | |
| 00000400 | GPIO10 | | | | GPIO42 | U10-P6, U4-P6, T3-1 | SPI FLASH CLK / I2C-SCL (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
| 00000800 | GPIO11 | | | | GPIO43 | U10-P5, U4-P5, T3-3 | SPI FLASH DI/IO0 / I2C-SDA (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
| 00001000 | GPIO12 | | | | GPIO44 | U10-P2, T3-5 | SPI FLASH DO/IO1 (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
| 00002000 | GPIO13 | PORT1 LED GREEN | | | GPIO45 | U10-P1, T3-6 | SPI FLASH CS (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
| 00004000 | GPIO14 | PORT1 LED ORANGE | | | GPIO46 | T8-1 | (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
| 00008000 | GPIO15 | | | | GPIO47 | T8-5 | (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
| 00010000 | GPIO16 | PORT2 LED GREEN | | | GPIO48 | T8-3 | (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
| 00020000 | GPIO17 | PORT2 LED ORANGE | | | GPIO49 | T8-6 | (from [LIANGUO SWTG024AS](SWTG024AS.md#gpio)) |
| 00040000 | GPIO18 | PORT3 LED GREEN | | | GPIO50 | | |
| 00080000 | GPIO19 | PORT3 LED ORANGE | | | GPIO51 | | |
| 00100000 | GPIO20 | PORT4 LED GREEN | | | GPIO52 | | |
| 00200000 | GPIO21 | PORT4 LED ORANGE | | | GPIO53 | | |
| 00400000 | GPIO22 | PORT5 LED GREEN | | | GPIO54 | Reset Button | GPIO54_ACL_BIT2_EN |
| 00800000 | GPIO23 | PORT5 LED ORANGE | | | GPIO55 | | |
| 01000000 | GPIO24 | SFP LED GREEN | J4 | | GPIO56 | | |
| 02000000 | GPIO25 | | | | GPIO57 | | |
| 04000000 | GPIO26 | | | | GPIO58 | | |
| 08000000 | GPIO27 | | | | GPIO59 | | |
| 10000000 | GPIO28 | LED-SYSTEM | | | GPIO60 | | |
| 20000000 | GPIO29 | | | | GPIO61 | | |
| 40000000 | GPIO30 | J4-6 | SFP DETECT | | GPIO62 | | |
| 80000000 | GPIO31 | T5-1 | U0TXD | | GPIO63 | | |
# LEDs
| NAME | GPIO | Port(s) | Function | Notes |
| ---- | ---- | ---- | ---- | ---- |
| PORT1 LED GREEN | GPIO13 |5| Activity | LEDS_2G5, LEDS_LINK, LEDS_ACT |
| PORT1 LED ORANGE | GPIO14 | 5 | Speed | LEDS_1G, LEDS_100M, LEDS_10M, LEDS_LINK, LEDS_ACT |
| PORT2 LED GREEN | GPIO16 | 4 | Activity | LEDS_2G5, LEDS_LINK, LEDS_ACT |
| PORT2 LED ORANGE | GPIO17 | 4 | Speed | LEDS_1G, LEDS_100M, LEDS_10M, LEDS_LINK, LEDS_ACT |
| PORT3 LED GREEN | GPIO18 | 3 | Activity | LEDS_2G5, LEDS_LINK, LEDS_ACT |
| PORT3 LED ORANGE | GPIO19 | 3 | Speed | LEDS_1G, LEDS_100M, LEDS_10M, LEDS_LINK, LEDS_ACT |
| PORT4 LED GREEN | GPIO20 | 2 | Activity | LEDS_2G5, LEDS_LINK, LEDS_ACT |
| PORT4 LED ORANGE | GPIO21 | 2 | Speed | LEDS_1G, LEDS_100M, LEDS_10M, LEDS_LINK, LEDS_ACT |
| PORT5 LED GREEN | GPIO22 | 1 | Activity | LEDS_2G5, LEDS_LINK, LEDS_ACT |
| PORT5 LED ORANGE | GPIO23 | 1 | Speed | LEDS_1G, LEDS_100M, LEDS_10M, LEDS_LINK, LEDS_ACT |
| SFP LED GREEN | GPIO24 | 6 (SFP J4) | Multi-speed | LEDS_10G, LEDS_5G, LEDS_2G5, LEDS_1G, LEDS_100M, LEDS_LINK, LEDS_ACT |
| LED-SYSTEM | GPIO28 | --- | System status | --- |
## Notes
While [SWTG024AS.md](SWTG024AS.md) can be used as a general reference for hardware concepts and interface specifications, this device should not be assumed to be identical beside the difference implicitely highlighted below. Not all information has been validated for compatibility with the SWTG215AS. Consult the SWTG024AS documentation with caution and verify any critical details against this device's.
+12 -13
View File
@@ -14,10 +14,11 @@ The memory chip is `Winbond W25Q16JV` with 16M-bit size.
1. 2.5G ports on all advertised speeds. 1. 2.5G ports on all advertised speeds.
2. SFP+ communication. 2. SFP+ communication.
3. Serial, Web UI. 3. Serial, Web UI.
4. All LEDs
## Known issues ## Known issues
1. LEDs are not initialized properly. None.
## PCB ## PCB
@@ -38,10 +39,10 @@ Bottom
``` ```
┌─────────────────────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────────────────────┐
│ ┌──────────┐ ┌──────────┐ │ │ ┌──────────┐ ┌──────────┐ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ SFP │ │ SFP │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ SFP 2 │ │ SFP 1 │ │
│ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ PORT 5 │ │ PORT 6 │ │ │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ RJ45 │ │ PORT 5 │ │ PORT 6 │ │
│ │ PORT 1 │ │ PORT 2 │ │ PORT 3 │ │ PORT 4 │ │ MAC ? │ │ MAC ? │ │ │ │ PORT 1 │ │ PORT 2 │ │ PORT 3 │ │ PORT 4 │ │ MAC 8 │ │ MAC 3 │ │
│ │ MAC 4 │ │ MAC 5 │ │ MAC 6 │ │ MAC 7 │ │ SerDes ? │ │ SerDes ? │ │ │ │ MAC 4 │ │ MAC 5 │ │ MAC 6 │ │ MAC 7 │ │ SerDes 0 │ │ SerDes 1 │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘ └──────────┘ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────────────────────────────┘
``` ```
@@ -105,9 +106,9 @@ GPIO mapping unknown.
| 00000002 | GPIO01 | | GPIO33 | | | 00000002 | GPIO01 | | GPIO33 | |
| 00000004 | GPIO02 | | GPIO34 | Random changes | | 00000004 | GPIO02 | | GPIO34 | Random changes |
| 00000008 | GPIO03 | | GPIO35 | | | 00000008 | GPIO03 | | GPIO35 | |
| 00000010 | GPIO04 | | GPIO36 | SFP1 Present | | 00000010 | GPIO04 | | GPIO36 | SFP2 Present |
| 00000020 | GPIO05 | | GPIO37 | SFP1 RX Los | | 00000020 | GPIO05 | | GPIO37 | SFP2 RX Los |
| 00000040 | GPIO06 | | GPIO38 | SFP2 Present | | 00000040 | GPIO06 | | GPIO38 | SFP1 Present |
| 00000080 | GPIO07 | | GPIO39 | | | 00000080 | GPIO07 | | GPIO39 | |
| 00000100 | GPIO08 | | GPIO40 | | | 00000100 | GPIO08 | | GPIO40 | |
| 00000200 | GPIO09 | | GPIO41 | | | 00000200 | GPIO09 | | GPIO41 | |
@@ -119,11 +120,11 @@ GPIO mapping unknown.
| 00008000 | GPIO15 | PORT2 Link | GPIO47 | SFP1 I2C SDA | | 00008000 | GPIO15 | PORT2 Link | GPIO47 | SFP1 I2C SDA |
| 00010000 | GPIO16 | PORT2-LED-GREEN | GPIO48 | SFP2 I2C CLK | | 00010000 | GPIO16 | PORT2-LED-GREEN | GPIO48 | SFP2 I2C CLK |
| 00020000 | GPIO17 | PORT2-LED-AMBER | GPIO49 | SFP2 I2C SDA | | 00020000 | GPIO17 | PORT2-LED-AMBER | GPIO49 | SFP2 I2C SDA |
| 00040000 | GPIO18 | PORT3 Link | GPIO50 | SFP2 Rx LOS | | 00040000 | GPIO18 | PORT3 Link | GPIO50 | SFP1 Rx LOS |
| 00080000 | GPIO19 | PORT3-LED-GREEN | GPIO51 | SFP1 TX Disable | | 00080000 | GPIO19 | PORT3-LED-GREEN | GPIO51 | SFP2 TX Disable |
| 00100000 | GPIO20 | PORT4-LED-AMBER | GPIO52 | | | 00100000 | GPIO20 | PORT4-LED-AMBER | GPIO52 | |
| 00200000 | GPIO21 | PORT4 Link | GPIO53 | | | 00200000 | GPIO21 | PORT4 Link | GPIO53 | |
| 00400000 | GPIO22 | PORT4-LED-GREEN | GPIO54 | SFP2 TX Disable | | 00400000 | GPIO22 | PORT4-LED-GREEN | GPIO54 | SFP1 TX Disable |
| 00800000 | GPIO23 | PORT4-LED-AMBER | GPIO55 | | | 00800000 | GPIO23 | PORT4-LED-AMBER | GPIO55 | |
| 01000000 | GPIO24 | | GPIO56 | | | 01000000 | GPIO24 | | GPIO56 | |
| 02000000 | GPIO25 | | GPIO57 | | | 02000000 | GPIO25 | | GPIO57 | |
@@ -136,8 +137,6 @@ GPIO mapping unknown.
## LEDs ## LEDs
Leds are not yet working as in stock firmware. This will be handled later.
Ports 1-4 are amber for 100M/1G links, Green for 2.5G. Ports 1-4 are amber for 100M/1G links, Green for 2.5G.
Port 5-6 are green for 10G/1G link. Both should flash on activity. Port 5-6 are green for 10G/1G link. Both should flash on activity.
@@ -166,7 +165,7 @@ Voltage is made by a `APW8713` (U3).
### `3.3` Voltage ### `3.3` Voltage
Voltage is crated regulated by chip marke as `GoIAT` (U2). Voltage is crated regulated by chip marked as `GoIAT` (U2).
## SFP SPI ## SFP SPI
Binary file not shown.

After

Width:  |  Height:  |  Size: 560 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

+98
View File
@@ -0,0 +1,98 @@
# GPIO Pin, Function and MUX registers.
These functions should bevalid for `RTL8372`, `RTL8372N`, `RTL8373`, and `RTL8373N`.
`N`-version doesn't seems to have all the GPIO pins available on the outside of the package.
| GPIO | Function | TYPE | MUX REG, BIT | (RTL8372) PIN# | (RTL8372N) PIN# |
| ----- | ---- | ---- | ---- | ---- | ---- |
| GPIO0 | LED0 | I/OPU | IO_MUX_SEL_0, BIT 0 | G1 | 12 |
| GPIO1 | LED1 | I/OPU | IO_MUX_SEL_0, BIT 1 | G2 | 15 |
| GPIO2 | LED2 | I/OPU | IO_MUX_SEL_0, BIT 2 | G3 | 14 |
| GPIO3 | LED3 | I/OPU | IO_MUX_SEL_0, BIT 3 | H1 | 16 |
| GPIO4 | LED4 | I/OPU | IO_MUX_SEL_0, BIT 4 | H2 | 18 |
| GPIO5 | LED5 | I/OPU | IO_MUX_SEL_0, BIT 5 | H3 | 20 |
| GPIO6 | LED6 | I/OPU | IO_MUX_SEL_0, BIT 6 | J1 | 22 |
| GPIO7 | LED7 | I/OPU | IO_MUX_SEL_0, BIT 7 | J2 | NoPin? |
| GPIO8 | LED8 | I/OPU | IO_MUX_SEL_0, BIT 8 | J3 | 24 |
| GPIO9 | LED9 | I/OPD | IO_MUX_SEL_0, BIT 9 | L1 | 23 |
| GPIO10 | LED10 | I/OPU | IO_MUX_SEL_0, BIT 10 | L2 | 26 |
| GPIO11 | LED11 | I/OPU | IO_MUX_SEL_0, BIT 11 | L3 | NoPin? |
| GPIO12 | LED12 | I/OPD | IO_MUX_SEL_0, BIT 12 | M1 | 28 |
| GPIO13 | LED13 | I/OPU | IO_MUX_SEL_0, BIT 13 | M2 | NoPin? |
| GPIO14 | LED14 | I/OPU | IO_MUX_SEL_0, BIT 14 | M3 | NoPin? |
| GPIO15 | LED15 | I/OPU | IO_MUX_SEL_0, BIT 15 | N1 | 25 |
| GPIO16 | LED16 | I/OPU | IO_MUX_SEL_0, BIT 16 | N2 | NoPin? |
| GPIO17 | LED17 | I/OPU | IO_MUX_SEL_0, BIT 17 | N3 | NoPin? |
| GPIO18 | LED18 | I/OPD | IO_MUX_SEL_0, BIT 18 | P1 | 30 |
| GPIO19 | LED19 | I/OPU | IO_MUX_SEL_0, BIT 19 | P2 | NoPin? |
| GPIO20 | LED20 | I/OPU | IO_MUX_SEL_0, BIT 20 | P3 | NoPin? |
| GPIO21 | LED21 | I/OPU | IO_MUX_SEL_0, BIT 21 | R1 | 27 |
| GPIO22 | LED22 | I/OPU | IO_MUX_SEL_0, BIT 22 | R2 | NoPin? |
| GPIO23 | LED23 | I/OPU | IO_MUX_SEL_0, BIT 23 | R3 | NoPin? |
| GPIO24 | LED24 | I/OPU | IO_MUX_SEL_0, BIT 24 | N19 | 88 |
| GPIO25 | LED25 | I/OPU | IO_MUX_SEL_0, BIT 25 | P19 | 86 |
| GPIO26 | LED26 | I/OPU | IO_MUX_SEL_0, BIT 26 | P18 | 84 |
| GPIO27 | LED27 | I/OPU | IO_MUX_SEL_0, BIT 27 | R19 | 82 |
| GPIO28 | SYS_LED | I/OPU | IO_MUX_SEL_0, BIT 28 | F1 | 13 |
| GPIO29 | GLB_RLDP_LED_EN | | IO_MUX_SEL_0, BIT 29 | | NoPin? |
| GPIO30 | ACL_BIT3_EN | | IO_MUX_SEL_2, BIT 3 | F3 | 11 |
| GPIO31 | UART TX (OUTPUT) | | IO_MUX_SEL_1, BIT 0 | L20 | 90 |
| GPIO32 | UART TX (INPUT) | | IO_MUX_SEL_1, BIT 1 | L21 | |
| GPIO33 | GPIO_INT | | IO_MUX_SEL_1, BIT 2 | | |
| GPIO34 | MDC0 | | IO_MUX_SEL_1, BIT 3 | | |
| GPIO35 | MDIO0 | | IO_MUX_SEL_1, BIT 4 | | |
| GPIO36 | PWM_OUT | | IO_MUX_SEL_1, BIT 30 | B13 | |
| GPIO37 | --- | | | L18 | |
| GPIO38 | --- | | | K19 | |
| GPIO39 | MSDA4 | | IO_MUX_SEL_1, BIT 29 | K20 | 95 |
| GPIO40 | MDC1/SCL3 | | IO_MUX_SEL_1, BIT 5 & 6 | J29 | |
| GPIO41 | MDIO1/MSDA3 | | IO_MUX_SEL_1, BIT 5 & 6 | J19 | |
| GPIO42 | SPI-MEMORY | | RTL8373_INI_MODE_ADDR, BIT 0 & 1 | D1 | |
| GPIO43 | SPI-MEMORY | | RTL8373_INI_MODE_ADDR, BIT 0 & 1 | E1 | |
| GPIO44 | SPI-MEMORY | | RTL8373_INI_MODE_ADDR, BIT 0 & 1 | D2 | |
| GPIO45 | SPI-MEMORY | | RTL8373_INI_MODE_ADDR, BIT 0 & 1 | E2 | |
| GPIO46 | MSCK0 | | IO_MUX_SEL_1, BIT 7 & 8 | A2 | |
| GPIO47 | MSDA0 | | IO_MUX_SEL_1, BIT 9 & 10 | B2 | |
| GPIO48 | MSCK1 | | IO_MUX_SEL_1, BIT 11 & 12 | A1 | |
| GPIO49 | MSDA1 | | IO_MUX_SEL_1, BIT 13 & 14 | B1 | |
| GPIO50 | MSCL2/U1TXD | | IO_MUX_SEL_1, BIT 15 & 16 | C1 | |
| GPIO51 | MSDA2/U1RXD | | IO_MUX_SEL_1, BIT 17 & 18 | C2 | |
| GPIO52 | ACL_BIT0_EN | | IO_MUX_SEL_2, BIT 0 | | |
| GPIO53 | ACL_BIT1_EN | | IO_MUX_SEL_2, BIT 1 | | |
| GPIO54 | ACL_BIT2_EN | | IO_MUX_SEL_2, BIT 2 | E5 | |
| GPIO55 | PTP_CLK125M_IN | | IO_MUX_SEL_1, BIT 19 | | |
| GPIO56 | PTP_CLK_OUT | | IO_MUX_SEL_1, BIT 20 | | |
| GPIO57 | PTP_TOD_OUT | | IO_MUX_SEL_1, BIT 21 | | |
| GPIO58 | PTP_PPS_OUT | | IO_MUX_SEL_1, BIT 22 | | |
| GPIO59 | PTP_TOD_IN | | IO_MUX_SEL_1, BIT 23 | | |
| GPIO60 | PTP_PPS_IN | | IO_MUX_SEL_1, BIT 24 | | |
| GPIO61 | SYNCELOCK0 | | IO_MUX_SEL_1, BIT 27 | | |
| GPIO62 | SYNCELOCK1 | | IO_MUX_SEL_1, BIT 28 | | |
| GPIO63 | GPIO_MDIO0 | | IO_MUX_SEL_1, BIT 4 | | |
## I2C
| I2C | Function |Type | (RTL8372) PIN# | (RTL8372N) PIN# |
| ---- | ---- | ---- | ---- | ---- |
| GPIO47 | SDA0 | I/OPU | | B1 | 142 |
| GPIO49 | SDA1 | I/OPU | | B2 | 144 |
| GPIO51 | SDA2 | I/OPU | | C2 | ??? |
| GPIO41 | SDA3 | I/OPU | | J20 | 98 |
| GPIO39 | SDA4 | I/OPU | | K20 | 95 |
| GPIO46 | SCL0 | I/OPU | | A2 | 138 |
| GPIO48 | SCL1 | I/OPU | | A1 | 140 |
| GPIO50 | SCL2 | I/OPU | | C1 | ??? |
| GPIO40? | SCL3 | OPU | | J20 | |
# Other funcitons
| Function | Type | (RTL8372) PIN# | (RTL8372N) PIN# |
| ---- | ---- | ---- | ---- |
| nRESET | | A6 | 131 |
| PTP_SYNC | | B10 | 130 |
| INT | OPU | B6 | 132 |
+2
View File
@@ -41,6 +41,8 @@ This list is incomplete.
| Winbond | W25Q32FV | | Winbond | W25Q32FV |
| Winbond | W25Q32JV | | Winbond | W25Q32JV |
| Winbond | W25Q16JL | | Winbond | W25Q16JL |
| Winbond | W25Q16DV |
| Winbond | W25Q80DV |
| Fundan | FM25Q16A | | Fundan | FM25Q16A |
*NOTE*: Part numbers are incomplete. Part numbers may contain additional information such as package, temperature specifications, and even the number of devices on a reel. So always check the datasheet so that you have the right orderable partnumber. *NOTE*: Part numbers are incomplete. Part numbers may contain additional information such as package, temperature specifications, and even the number of devices on a reel. So always check the datasheet so that you have the right orderable partnumber.
+28 -7
View File
@@ -33,15 +33,23 @@ An entry is deleted by adding an invalid entry (00 instead of 0x02 in
RTL837x_TBL_DATA_IN_A). RTL837x_TBL_DATA_IN_A).
A port is assigned a PVID by setting the PVID-bits of the corresponding A port is assigned a PVID by setting the PVID-bits of the corresponding
register of the port. 2 ports share a register. One port uses the higher register of the port. 2 ports share a register. An odd port uses bits [23:12],
16 bits, the other (even ports) use the lower. The base register is an even port uses bits [11:0]. The base register is
RTL837x_PVID_BASE_REG (0x4e1c) and the registers go to 0x4e2c so that also RTL837x_PVID_BASE_REG (0x4e1c) and the registers go to 0x4e2c so that also
the CPU-Port may have a PVID. the CPU-Port may have a PVID.
Register RTL837x_REG_INGRESS (0x4e10) allows to define the iingress rules of Register RTL837x_REG_INGRESS (0x4e10) allows to define the ingress rules of
a port. 2 bits define a rule and bits 0-19 are being used. A value of 00 a port. 2 bits define a rule and bits 0-19 are being used. A value of 00
defines no filtering, 01 (0x01) allows only tagged packets, while 10 (0x02) defines no filtering, 01 (0x01) allows only tagged packets, while 10 (0x02)
allows only untagged packets to enter a port. The default PVID is 1. allows only untagged packets to enter a port.
Register RTL837X_VLAN_PORT_IGR_FLTR (0x4e18) enables or disables ingres VLAN
filtering, each bit corresponds to given port (port0 -> bit0, port9 -> bit9).
When enabled, incomming package's vlan tag is checked against VLAN membership
on given port. When package contains VLAN not in member list, package is dropped.
The default PVID on all port is 1, ingress VLAN filtering is enabled and all types of
frames are accepted on input on all ports.
By default, the ports transmit Ethernet frames with Realtek's proprietary By default, the ports transmit Ethernet frames with Realtek's proprietary
tag format. By setting bit 6 (0x40) of the respective port configuration tag format. By setting bit 6 (0x40) of the respective port configuration
@@ -51,7 +59,9 @@ registers 0x1238, 0x1338, ...
The code currently provides the following functions: The code currently provides the following functions:
``` ```
void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked; void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked;
void vlan_create(uint16_t vlan, uint16_t members, uint16_t tagged) __banked; uint16_t port_pvid_get(uint8_t port) __banked;
void vlan_create(void) __banked; // reads from global vlan_settings
int8_t vlan_get(register uint16_t vlan) __banked; // returns data in sfr_data
void vlan_delete(uint16_t vlan) __banked; void vlan_delete(uint16_t vlan) __banked;
``` ```
@@ -66,9 +76,20 @@ vlan <VLAN-ID> p[t/u]...
vlan <VLAN-ID> d vlan <VLAN-ID> d
deletes the VLAN deletes the VLAN
vlan show
Dumps the current ingress vlan settings.
pvid <port> <VLAN-ID> pvid <port> <VLAN-ID>
assigns PVID to a port. ports are numbered as on the casing assigns PVID to a port. ports are numbered as on the casing
ingress <port> [tagged|untagged|all] ingress [p]<t|u|a>...
Allows ingress only for the named packages at the given port Allows ingress packages on port `p` only when `t`agged, `u`ntagged or `a`ny.
Multiple ports can be given at once as in vlan. When `p` is missing, all ports
are assigned the same mode. CPU port can not be changed.
Use `vlan show` to see current configuration.
Example:
`ingress 1t 2a` -> Set port 1 as tagged input only, set port 2 accepting any frames.
`ingress a` -> Set all ports to accept both tagged and untagged frames (default behaviour).
``` ```
+6 -4
View File
@@ -3,7 +3,6 @@ function createBW() {
var tbl = document.getElementById('bwtable'); var tbl = document.getElementById('bwtable');
const limit = '<input type="checkbox" id="limit_port" onchange="exec();">' const limit = '<input type="checkbox" id="limit_port" onchange="exec();">'
if (tbl.rows.length <= 2 && numPorts) { if (tbl.rows.length <= 2 && numPorts) {
clearInterval(createBWInterval);
console.log("CREATING TABLE ", tbl.rows.length); console.log("CREATING TABLE ", tbl.rows.length);
for (let i = 2; i < 2 + numPorts; i++) { for (let i = 2; i < 2 + numPorts; i++) {
const tr = tbl.insertRow(); const tr = tbl.insertRow();
@@ -94,6 +93,7 @@ async function applyBandwidth(i) {
function getBW() { function getBW() {
var xhttp = new XMLHttpRequest(); var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() { xhttp.onreadystatechange = function() {
console.log("IN getBW ");
if (this.readyState == 4 && this.status == 200) { if (this.readyState == 4 && this.status == 200) {
const s = JSON.parse(xhttp.responseText); const s = JSON.parse(xhttp.responseText);
console.log("BW: ", JSON.stringify(s)); console.log("BW: ", JSON.stringify(s));
@@ -126,11 +126,13 @@ function getBW() {
} }
}; };
xhttp.open("GET", "/bandwidth.json", true); xhttp.open("GET", "/bandwidth.json", true);
xhttp.timeout = 1500; xhttp.send(); xhttp.timeout = 1500; sendXHTTP(xhttp);
} }
window.addEventListener("load", function() { window.addEventListener("load", function() {
update( () => {
createBW();
getBW(); getBW();
const iCount = setInterval(getBW, 2000); const interval = setInterval(update, 2000);
});
}); });
const createBWInterval = setInterval(createBW, 1010);
+5 -3
View File
@@ -1,7 +1,6 @@
function createEEE() { function createEEE() {
var tbl = document.getElementById('eeetable'); var tbl = document.getElementById('eeetable');
if (tbl.rows.length <= 2 && numPorts) { if (tbl.rows.length <= 2 && numPorts) {
clearInterval(createEEEInterval);
console.log("CREATING TABLE ", tbl.rows.length); console.log("CREATING TABLE ", tbl.rows.length);
for (let i = 2; i < 2 + numPorts; i++) { for (let i = 2; i < 2 + numPorts; i++) {
console.log("Table row: " + i + "pState: " + pState[i-2]); console.log("Table row: " + i + "pState: " + pState[i-2]);
@@ -40,11 +39,14 @@ function getEEE() {
} }
}; };
xhttp.open("GET", "/eee.json", true); xhttp.open("GET", "/eee.json", true);
xhttp.timeout = 1500; xhttp.send(); xhttp.timeout = 1500; sendXHTTP(xhttp);
} }
window.addEventListener("load", function() { window.addEventListener("load", function() {
update( () => {
createEEE();
getEEE(); getEEE();
const interval = setInterval(update, 2000);
const iCount = setInterval(getEEE, 2000); const iCount = setInterval(getEEE, 2000);
}); });
const createEEEInterval = setInterval(createEEE, 1000); });
+7
View File
@@ -2,6 +2,13 @@
<html> <html>
<script src="/main.js"></script> <script src="/main.js"></script>
<script src="/main_info.js"></script> <script src="/main_info.js"></script>
<script>
window.addEventListener("load", function() {
update( () => {
const interval = setInterval(update, 2000);
});
});
</script>
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="style.css">
<title>FreeSwitchOS Main Page</title> <title>FreeSwitchOS Main Page</title>
</head> </head>
+5 -1
View File
@@ -130,10 +130,14 @@ function getL2() {
} }
}; };
xhttp.open("GET", "/l2.json?idx=" + l2CurrentEntry, true); xhttp.open("GET", "/l2.json?idx=" + l2CurrentEntry, true);
xhttp.timeout = 1500; xhttp.send(); xhttp.timeout = 1500; sendXHTTP(xhttp);
} }
window.addEventListener("load", function() { window.addEventListener("load", function() {
update( () => {
getL2();
const interval = setInterval(update, 2000);
l2GetInterval = setInterval(getL2, 1000); l2GetInterval = setInterval(getL2, 1000);
});;
}); });
+8 -5
View File
@@ -3,7 +3,6 @@ var lagInterval = Number();
function lagForm() { function lagForm() {
if (!numPorts) if (!numPorts)
return; return;
clearInterval(lagInterval);
for (let j=0; j < 4; j++) { for (let j=0; j < 4; j++) {
var lag = "mLAG" + j var lag = "mLAG" + j
console.log("Adding LAG " + lag) console.log("Adding LAG " + lag)
@@ -35,9 +34,6 @@ function setL(p, c){
console.log("LAG setting: ", p, " to ", c); console.log("LAG setting: ", p, " to ", c);
document.getElementById(p).checked=c; document.getElementById(p).checked=c;
} }
window.addEventListener("load", function() {
lagInterval = setInterval(lagForm, 200);
});
function fetchLag() { function fetchLag() {
var xhttp = new XMLHttpRequest(); var xhttp = new XMLHttpRequest();
@@ -58,7 +54,7 @@ function fetchLag() {
} }
}; };
xhttp.open("GET", `/lag.json`, true); xhttp.open("GET", `/lag.json`, true);
xhttp.send(); sendXHTTP(xhttp);
} }
async function lagSub(l) { async function lagSub(l) {
var cmd = "lag " + l; var cmd = "lag " + l;
@@ -76,3 +72,10 @@ async function lagSub(l) {
console.error(`Error: ${err}`); console.error(`Error: ${err}`);
} }
} }
window.addEventListener("load", function() {
update( () => {
lagForm();
const interval = setInterval(update, 2000);
});
});
+186 -19
View File
@@ -9,6 +9,9 @@ var pAdvertised = new Int8Array(10);
var numPorts = 0; var numPorts = 0;
var logToPhysPort = new Int8Array(10); var logToPhysPort = new Int8Array(10);
var physToLogPort = new Int8Array(10); var physToLogPort = new Int8Array(10);
var portNames = new Array(10);
var currentRequests = [];
var currentCallback;
function drawPorts() { function drawPorts() {
var f = document.getElementById('ports'); var f = document.getElementById('ports');
console.log("DRAWING PORTS: ", numPorts); console.log("DRAWING PORTS: ", numPorts);
@@ -38,9 +41,86 @@ function drawPorts() {
} }
} }
function update() { function parseUint16(val) {
return parseInt(val, 16) & 0xffff;
}
function parseInt16(val) {
let valInt = parseInt(val, 16);
let num = valInt & 0x7fff;
if (valInt & 0x8000) {
return num - 0x8000;
}
return num;
}
function applyCalibrationSlopeOffset(val, cal) {
if (typeof cal !== 'string') {
return val;
}
if (cal.startsWith("0x")) {
cal = cal.substring(2);
}
if (cal.length != 8) {
return val;
}
let slope = parseUint16(cal.substring(0, 4)) / 256;
let offset = parseInt16(cal.substring(4, 8));
return slope * val + offset;
}
function applyRxPowerCalibration(val, cal) {
if (typeof cal !== 'string') {
return val;
}
if (cal.startsWith("0x")) {
cal = cal.substring(2);
}
if (cal.length != 40) {
return val;
}
let bytes = cal.match(/.{1,2}/g).map(function (x) { return parseInt(x, 16); });
let view = new DataView(new Uint8Array(bytes).buffer);
return view.getFloat32(0) * Math.pow(val, 4)
+ view.getFloat32(4) * Math.pow(val, 3)
+ view.getFloat32(8) * Math.pow(val, 2)
+ view.getFloat32(12) * val
+ view.getFloat32(16);
}
function decodeSfpTemp(val, cal) {
let temp = parseInt16(val);
return applyCalibrationSlopeOffset(temp, cal) / 256;
}
function decodeSfpVcc(val, cal) {
let vcc = parseUint16(val);
return applyCalibrationSlopeOffset(vcc, cal) / 10000;
}
function decodeSfpTxBias(val, cal) {
let bias = parseUint16(val);
return applyCalibrationSlopeOffset(bias, cal) / 500;
}
function decodeSfpTxPower(val, cal) {
let txPower = parseUint16(val);
return applyCalibrationSlopeOffset(txPower, cal) / 10000;
}
function decodeSfpRxPower(val, cal) {
let rxPower = parseUint16(val);
return applyRxPowerCalibration(rxPower, cal) / 10000;
}
function convertPowerTodBm(val) {
return 10 * Math.log10(val);
}
function update(callback) {
var xhttp = new XMLHttpRequest(); var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() { xhttp.onreadystatechange = function() {
console.log("IN UPDATE ");
if (this.readyState == 4 && this.status == 401) if (this.readyState == 4 && this.status == 401)
document.location = "/login.html" document.location = "/login.html"
if (this.readyState == 4 && this.status == 200) { if (this.readyState == 4 && this.status == 200) {
@@ -57,6 +137,7 @@ function update() {
let n = p.portNum; let n = p.portNum;
logToPhysPort[p.logPort] = n; logToPhysPort[p.logPort] = n;
physToLogPort[n-1] = p.logPort; physToLogPort[n-1] = p.logPort;
portNames[p.logPort] = p.name;
let pid = "port" + n; let pid = "port" + n;
let ttid = "tt_" + n; let ttid = "tt_" + n;
n--; n--;
@@ -67,12 +148,19 @@ function update() {
continue; continue;
var bgs = psvg.contentDocument.getElementsByClassName("bg"); var bgs = psvg.contentDocument.getElementsByClassName("bg");
var leds = psvg.contentDocument.getElementsByClassName("led"); var leds = psvg.contentDocument.getElementsByClassName("led");
if (leds[0] == null || leds[0].style == null)
continue;
const portName = p.name || portNames[p.logPort] || '';
var iHTML = "<table border=\"0\" class=\"tt_table\">";
if (portName) iHTML += "<tr><td align=\"left\">Name</td><td>:</td><td>" + portName + "</td></tr>";
if (p.enabled == 0) { if (p.enabled == 0) {
pState[n] = -1; pState[n] = -1;
bgs[0].style.fill = "red"; bgs[0].style.fill = "red";
leds[0].style.fill = "black"; leds[1].style.fill = "black"; leds[0].style.fill = "black"; leds[1].style.fill = "black";
psvg.style.opacity = 0.4; psvg.style.opacity = 0.4;
tt.innerHTML = "Not enabled."; iHTML += "<tr><td align=\"left\">Status</td><td>:</td><td>Not enabled.</td></tr>";
iHTML += "</table>";
tt.innerHTML = iHTML;
} else { } else {
psvg.style.opacity = 1.0; psvg.style.opacity = 1.0;
pState[n] = p.link; pState[n] = p.link;
@@ -84,34 +172,113 @@ function update() {
leds[0].style.fill = "black"; leds[1].style.fill = "black"; leds[0].style.fill = "black"; leds[1].style.fill = "black";
psvg.style.opacity = 0.4 psvg.style.opacity = 0.4
} }
var iHTML = "<table border=\"0\" class=\"tt_table\">";
iHTML += "<tr><td align=\"left\">Link speed</td><td>:</td><td>" + linkS[p.link + 1] + "</td></tr>"; iHTML += "<tr><td align=\"left\">Link speed</td><td>:</td><td>" + linkS[p.link + 1] + "</td></tr>";
if (p.isSFP) { if (p.isSFP) {
pAdvertised[n] = 0; pAdvertised[n] = 0;
const hasExtendedStatus = p.sfp_options & 0x40;
iHTML += "<tr><td>Vendor</td><td>:</td><td>" + p.sfp_vendor + "</td></tr>"; iHTML += "<tr><td>Vendor</td><td>:</td><td>" + p.sfp_vendor + "</td></tr>";
iHTML += "<tr><td>Model</td><td>:</td><td>" + p.sfp_model + "</td></tr>"; iHTML += "<tr><td>Model</td><td>:</td><td>" + p.sfp_model + "</td></tr>";
iHTML += "<tr><td>Serial</td><td>:</td><td>" + p.sfp_serial + "</td></tr>"; iHTML += "<tr><td>Serial</td><td>:</td><td>" + p.sfp_serial + "</td></tr>";
if (p.sfp_options & 0x40) { if (hasExtendedStatus) {
iHTML += "<tr><td>Temp</td><td>:</td><td>" + (Number(p.sfp_temp) >> 8) + "." + ((Number(p.sfp_temp) & 0xff)/256.0 * 100).toFixed(0) + "&#8239;&#8451;</td></tr>"; let txPower = decodeSfpTxPower(p.sfp_txpower, p.sfp_txpower_cal);
iHTML += "<tr><td>Vcc</td><td>:</td><td>" + (Number(p.sfp_vcc) / 10000.0).toFixed(2) + "&#8239;V</td></tr>"; let txPowerdBm = convertPowerTodBm(txPower);
iHTML += "<tr><td>TX-Bias</td><td>:</td><td>" + (Number(p.sfp_txbias) / 500.0).toFixed(1) + "&#8239;mA</td></tr>"; let rxPower = decodeSfpRxPower(p.sfp_rxpower, p.sfp_rxpower_cal);
iHTML += "<tr><td>TX-Power</td><td>:</td><td>" + (Number(p.sfp_txpower) / 10.0).toFixed(0) + "&#8239;mW</td></tr>"; let rxPowerdBm = convertPowerTodBm(rxPower);
iHTML += "<tr><td>RX-Power</td><td>:</td><td>" + (Number(p.sfp_rxpower) / 10.0).toFixed(0) + "&#8239;mW</td></tr>"; iHTML += "<tr><td>Temp</td><td>:</td><td>" + decodeSfpTemp(p.sfp_temp, p.sfp_temp_cal).toFixed(2) + "&#8239;&#8451;</td></tr>";
iHTML += "<tr><td>Vcc</td><td>:</td><td>" + decodeSfpVcc(p.sfp_vcc, p.sfp_vcc_cal).toFixed(2) + "&#8239;V</td></tr>";
iHTML += "<tr><td>TX-Fault</td><td>:</td><td>" + (Boolean(Number(p.sfp_state) & 0x4)) + "</td></tr>";
iHTML += "<tr><td>TX-Disabled</td><td>:</td><td>" + (Boolean(Number(p.sfp_state) & 0x80)) + "</td></tr>";
iHTML += "<tr><td>TX-Bias</td><td>:</td><td>" + decodeSfpTxBias(p.sfp_txbias, p.sfp_txbias_cal).toFixed(1) + "&#8239;mA</td></tr>";
iHTML += "<tr><td>TX-Power</td><td>:</td><td>" + txPower.toFixed(3) + "&#8239;mW / " + txPowerdBm.toFixed(2) + "&#8239;dBm</td></tr>";
iHTML += "<tr><td>RX-Power</td><td>:</td><td>" + rxPower.toFixed(3) + "&#8239;mW / " + rxPowerdBm.toFixed(2) + "&#8239;dBm</td></tr>";
}
// Not all devices & modules have LOS pin...
const rx_los_pin = p.sfp_los !== null ? Boolean(Number(p.sfp_los)) : null;
const rx_los_module = hasExtendedStatus ? Boolean(Number(p.sfp_state) & 0x2) : null;
if (rx_los_module !== null || rx_los_pin !== null) {
iHTML += `<tr><td>RX-LOS</td><td>:</td><td>${rxLosHTML(rx_los_pin, rx_los_module)}</td></tr>`;
} }
} else { } else {
pAdvertised[n] = parseInt(p.adv, 2); pAdvertised[n] = parseInt(p.adv, 2);
} };
iHTML += "</table>"; iHTML += "</table>";
tt.innerHTML = iHTML; tt.innerHTML = iHTML;
} }}
} if (callback)
} callback();
}; }};
xhttp.open("GET", "/status.json", true); xhttp.open("GET", "/status.json", true);
xhttp.timeout = 5000; xhttp.send(); xhttp.timeout = 5000;
sendXHTTP(xhttp);
}
function rxLosHTML(pinStatus, moduleStatus) {
if (moduleStatus !== null && pinStatus !== null && moduleStatus !== pinStatus) {
return `pin=${pinStatus}<br/>mod=${moduleStatus}<br/>❗❗❗❗`;
}
// Returns first non null value
return moduleStatus ?? pinStatus;
}
function callbackXHTTP()
{
x = currentRequests.shift();
x.onreadystatechange = currentCallback;
x.onreadystatechange();
if (currentRequests.length === 0)
return;
x = currentRequests[0];
currentCallback = x.onreadystatechange;
x.onreadystatechange = callbackXHTTP;
var retries = 10;
while (retries) {
try {
setTimeout(() => {
x.send();
console.log("B1");
}, 20);
} catch (error) {
retries--;
setTimeout(() => {
console.log(`Retry ${retries}/${maxRetries} failed: ${error.message}`);
}, 200);
if (retries < 1) {
throw error;
}
}
console.log("B2");
return;
}
}
function sendXHTTP(x)
{
console.log("sendXHTTP ", x);
if (currentRequests.length === 0) {
currentRequests.push(x);
currentCallback = x.onreadystatechange;
x.onreadystatechange = callbackXHTTP;
var retries = 10;
while (retries) {
try {
x.send();
console.log("A1");
} catch (error) {
retries--;
setTimeout(() => {
console.log(`Retry ${retries}/${maxRetries} failed: ${error.message}`);
}, 200);
if (retries < 1) {
throw error;
}
}
console.log("A2");
return;
}
console.log("A3");
return;
}
currentRequests.push(x);
} }
window.addEventListener("load", function() {
update();
const interval = setInterval(update, 2000);
});
+8 -5
View File
@@ -4,7 +4,6 @@ const mirrors = ["mPortsTX", "mPortsRX"];
function mirrorForm() { function mirrorForm() {
if (!numPorts) if (!numPorts)
return; return;
clearInterval(mirrorInterval);
for (let j=0; j < mirrors.length; j++) { for (let j=0; j < mirrors.length; j++) {
console.log("Adding Mirror " + j) console.log("Adding Mirror " + j)
var m = document.getElementById(mirrors[j]); var m = document.getElementById(mirrors[j]);
@@ -34,9 +33,6 @@ function mirrorForm() {
function setM(p, c){ function setM(p, c){
document.getElementById(p).checked=c; document.getElementById(p).checked=c;
} }
window.addEventListener("load", function() {
mirrorInterval = setInterval(mirrorForm, 200);
});
function fetchMirror() { function fetchMirror() {
var xhttp = new XMLHttpRequest(); var xhttp = new XMLHttpRequest();
@@ -57,5 +53,12 @@ function fetchMirror() {
} }
}; };
xhttp.open("GET", `/mirror.json`, true); xhttp.open("GET", `/mirror.json`, true);
xhttp.send(); sendXHTTP(xhttp);
} }
window.addEventListener("load", function() {
update( () => {
mirrorForm();
const interval = setInterval(update, 2000);
});
});
+1 -1
View File
@@ -11,7 +11,7 @@
<h1>Port Configuration</h1> <h1>Port Configuration</h1>
<form id="vform" action="/vlan.html"> <form id="vform" action="/vlan.html">
<table id="speedtable"> <table id="speedtable">
<tr> <th>Port</th> <th>Current Link Speed</th><th>Set Speed</th><th>Disabled</th><th>Apply</th></tr> <tr> <th>Port</th> <th>Name</th> <th>Current Link Speed</th><th>Set Speed</th><th>Disabled</th><th>Apply</th></tr>
</table> </table>
<h2 style="margin-top:3em">Configure Maximum Frame Size (MTU) forwarded at Port</h2> <h2 style="margin-top:3em">Configure Maximum Frame Size (MTU) forwarded at Port</h2>
<table id="mtutable" style="margin-top:1em"> <table id="mtutable" style="margin-top:1em">
+10 -7
View File
@@ -3,7 +3,6 @@ var clicked = new Int8Array(10);
function createPortTable() { function createPortTable() {
var tbl = document.getElementById('speedtable'); var tbl = document.getElementById('speedtable');
if (tbl.rows.length <= 2 && numPorts) { if (tbl.rows.length <= 2 && numPorts) {
clearInterval(pTableInterval);
const sSelect = '<select name="speed_sel" id="speed_sel">' const sSelect = '<select name="speed_sel" id="speed_sel">'
+ '<option value="auto">Auto</option>' + '<option value="auto">Auto</option>'
+ '<option value="2g5">2500MBit/Full</option>' + '<option value="2g5">2500MBit/Full</option>'
@@ -20,6 +19,8 @@ function createPortTable() {
console.log("Table row: " + i + "pState: " + pState[i-2]); console.log("Table row: " + i + "pState: " + pState[i-2]);
const tr = tbl.insertRow(); const tr = tbl.insertRow();
let td = tr.insertCell(); td.appendChild(document.createTextNode(`Port ${i}`)); let td = tr.insertCell(); td.appendChild(document.createTextNode(`Port ${i}`));
let portName = portNames[physToLogPort[i-1]] || '';
td = tr.insertCell(); td.appendChild(document.createTextNode(portName));
td = tr.insertCell(); td.innerHTML = linkS[pState[i] + 1]; td = tr.insertCell(); td.innerHTML = linkS[pState[i] + 1];
td = tr.insertCell(); td.innerHTML = sSelect.replaceAll("speed_sel", "speed_sel_" + i); td = tr.insertCell(); td.innerHTML = sSelect.replaceAll("speed_sel", "speed_sel_" + i);
td = tr.insertCell(); td.innerHTML = dSwitch.replaceAll("disable_port", "disable_port_" + i) td = tr.insertCell(); td.innerHTML = dSwitch.replaceAll("disable_port", "disable_port_" + i)
@@ -67,7 +68,7 @@ function updatePortTable() {
for (let i = 1; i <= numPorts ; i++) { for (let i = 1; i <= numPorts ; i++) {
if (pIsSFP[i-1]) if (pIsSFP[i-1])
continue; continue;
tbl.rows[i].cells[1].innerHTML = `${linkS[pState[i-1]+1]}`; tbl.rows[i].cells[2].innerHTML = `${linkS[pState[i-1]+1]}`;
if (!clicked[i] && pState[i - 1] < 0) { if (!clicked[i] && pState[i - 1] < 0) {
document.getElementById('speed_sel_' + i).disabled = true; document.getElementById('speed_sel_' + i).disabled = true;
document.getElementById('disable_port_' + i).checked = true; document.getElementById('disable_port_' + i).checked = true;
@@ -130,17 +131,19 @@ function getMTUs() {
if (!mtu) if (!mtu)
continue; continue;
mtu.value = mtus[n]; mtu.value = mtus[n];
clearInterval(pMTUInterval);
} }
} }
}; };
xhttp.open("GET", "/mtu.json", true); xhttp.open("GET", "/mtu.json", true);
xhttp.timeout = 1500; xhttp.send(); xhttp.timeout = 1500; sendXHTTP(xhttp);
} }
window.addEventListener("load", function() { window.addEventListener("load", function() {
update( () => {
createPortTable();
updatePortTable();
getMTUs()
const interval = setInterval(update, 2000);
const updatePortTableInterval = setInterval(updatePortTable, 1000); const updatePortTableInterval = setInterval(updatePortTable, 1000);
}); });
});
const pTableInterval = setInterval(createPortTable, 1000);
const pMTUInterval = setInterval(getMTUs, 1200);
+1 -1
View File
@@ -38,7 +38,7 @@
</div> </div>
<h1>Port Statistics</h1> <h1>Port Statistics</h1>
<table id="statstable"> <table id="statstable">
<tr> <th>Port</th> <th>link</th> <th>TX Good</th> <th>TX Bad</th> <th>RX Good</th> <th>RX Bad</th> <th> All Counters </th></tr> <tr> <th>Port</th> <th>Name</th> <th>link</th> <th>TX Good</th> <th>TX Bad</th> <th>RX Good</th> <th>RX Bad</th> <th> All Counters </th></tr>
<script src="/stat.js"></script> <script src="/stat.js"></script>
</table> </table>
</div> </div>
+17 -8
View File
@@ -151,7 +151,7 @@ function getCounters(port) {
} }
}; };
xhttp.open("GET", "/counters.json?port=" + port, true); xhttp.open("GET", "/counters.json?port=" + port, true);
xhttp.timeout = 1500; xhttp.send(); xhttp.timeout = 1500; sendXHTTP(xhttp);
} }
@@ -162,17 +162,19 @@ function fillStats() {
if (tbl.rows.length > 1) { if (tbl.rows.length > 1) {
for (let i = 0; i < numPorts; i++) { for (let i = 0; i < numPorts; i++) {
console.log("Table Update row: " + i + " state " + pState[i] + " is " + linkS[pState[i] +1]); console.log("Table Update row: " + i + " state " + pState[i] + " is " + linkS[pState[i] +1]);
tbl.rows[i+1].cells[1].innerHTML = `${linkS[pState[i]+1]}`; tbl.rows[i+1].cells[2].innerHTML = `${linkS[pState[i]+1]}`;
tbl.rows[i+1].cells[2].innerHTML = `${txG[i]} pkts`; tbl.rows[i+1].cells[3].innerHTML = `${txG[i]} pkts`;
tbl.rows[i+1].cells[3].innerHTML = `${txB[i]} pkts`; tbl.rows[i+1].cells[4].innerHTML = `${txB[i]} pkts`;
tbl.rows[i+1].cells[4].innerHTML = `${rxG[i]} pkts`; tbl.rows[i+1].cells[5].innerHTML = `${rxG[i]} pkts`;
tbl.rows[i+1].cells[5].innerHTML = `${rxB[i]} pkts`; tbl.rows[i+1].cells[6].innerHTML = `${rxB[i]} pkts`;
} }
} else { } else {
for (let i = 0; i < numPorts; i++) { for (let i = 0; i < numPorts; i++) {
console.log("Table row: " + i); console.log("Table row: " + i);
const tr = tbl.insertRow(); const tr = tbl.insertRow();
let td = tr.insertCell(); td.appendChild(document.createTextNode(`Port ${i+1}`)); let td = tr.insertCell(); td.appendChild(document.createTextNode(`Port ${i+1}`));
let portName = portNames[physToLogPort[i]] || '';
td = tr.insertCell(); td.appendChild(document.createTextNode(portName));
td = tr.insertCell(); td.appendChild(document.createTextNode(`${linkS[pState[i]+1]}`)); td = tr.insertCell(); td.appendChild(document.createTextNode(`${linkS[pState[i]+1]}`));
td = tr.insertCell(); td.appendChild(document.createTextNode(`${txG[i]} pkts`)); td = tr.insertCell(); td.appendChild(document.createTextNode(`${txG[i]} pkts`));
td = tr.insertCell();td.appendChild(document.createTextNode(`${txB[i]} pkts`)); td = tr.insertCell();td.appendChild(document.createTextNode(`${txB[i]} pkts`));
@@ -184,8 +186,6 @@ function fillStats() {
} }
} }
const stat = setInterval(fillStats, 1000);
const popup = document.getElementById('popup'); const popup = document.getElementById('popup');
const closePopup = document.getElementById('closePopup'); const closePopup = document.getElementById('closePopup');
closePopup.addEventListener('click', () => { closePopup.addEventListener('click', () => {
@@ -196,3 +196,12 @@ window.addEventListener('click', (event) => {
popup.style.display = 'none'; popup.style.display = 'none';
} }
}); });
window.addEventListener("load", function() {
update( () => {
update();
fillStats();
const stat = setInterval(fillStats, 1000);
const interval = setInterval(update, 2000);
});
});
-13
View File
@@ -23,7 +23,6 @@
<div id="system-tab" class="tab-content active"> <div id="system-tab" class="tab-content active">
<h1>System Settings</h1> <h1>System Settings</h1>
<label class="dhcpon">DHCP client endabled: <input id="dhcp" type="checkbox" onchange="dhcpClicked(this)"></label><br/><br/>
<div class="row"> <div class="row">
<div class="lcol"> <label for="ip">IP address:</label></div> <div class="lcol"> <label for="ip">IP address:</label></div>
<div class="rcol"> <input id="ip" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div> <div class="rcol"> <input id="ip" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
@@ -56,18 +55,6 @@
<br/> <br/>
<input style="width:40%;" class="action" id="switch_reset" onclick="resetSwitch();" type="button" value="Reset Switch"> <input style="width:40%;" class="action" id="switch_reset" onclick="resetSwitch();" type="button" value="Reset Switch">
</div> </div>
<div class="row">
<div class="lcol"> <label for="gw">Gateway:</label></div>
<div class="rcol"><input id="gw" class="ip" type="text" minlength="7" maxlength="15" size="15"/></div>
</div><br/>
When updating the above settings, remember to point your browser to the new IP afterwards:<br/>
<input style="width:40%;" class="action" id="ip_sub" onclick="ipSub();" type="button" value="Update Settings"><br/>
<br/><br/>
<label class="dhcpdon">Enable DHCP Server: <input id="dhcpd" type="checkbox"></label><br/><br/>
<label class="dhcpdvlan">Limit DHCP Server to VLAN (0: serve all VLANs): <input type="number" min="0" max="2047" value="0" id="dhcpd_vid" name="dhcpd_vid"></label><br/>
<input style="width:40%;" class="action" id="dhcpd_sub" onclick="dhcpdSub();" type="button" value="Change DHCPD State"><br/><br/><br/>
Save all current settings to Flash:<br/>
<input style="width:40%;" class="action" id="flash_sub" onclick="flashSave();" type="button" value="Save Settings to Flash">
</div> </div>
<script src="/config.js"></script> <script src="/config.js"></script>
+1 -49
View File
@@ -8,20 +8,6 @@ function checkIp(ip) {
} }
async function ipSub() { async function ipSub() {
if (document.getElementById('dhcp').checked) {
var cmd = "ip dhcp";
try {
const response = await fetch('/cmd', {
method: 'POST',
body: cmd
});
console.log('Completed!', response);
systemInterval = setInterval(fetchIP, 10000);
} catch(err) {
console.error(`Error: ${err}`);
}
return;
}
for (let i=0;i<3;i++) { for (let i=0;i<3;i++) {
if (!checkIp(document.getElementById(ips[i]).value)) if (!checkIp(document.getElementById(ips[i]).value))
return; return;
@@ -40,39 +26,7 @@ async function ipSub() {
} }
} }
} }
async function dhcpdSub() {
var dhcpd_cmd = "dhcpd off";
if (document.getElementById('dhcpd').checked) {
dhcpd_cmd = "dhcpd on";
var v=document.getElementById('dhcpd_vid').value
if (v && v!= 0)
dhcpd_cmd = dhcpd_cmd + " " + v;
}
try {
console.log("Sending: ", dhcpd_cmd);
const response = await fetch('/cmd', {
method: 'POST',
body: dhcpd_cmd
});
console.log('Completed!', response);
} catch(err) {
console.error(`Error: ${err}`);
}
}
function dhcpClicked(e)
{
console.log("dhcpClicked called");
if (e.checked) {
for (let i=0; i<3;i++)
document.getElementById(ips[i]).disabled = true;
document.getElementById('dhcpd').disabled = true;
} else {
console.log("dhcpClicked off");
for (let i=0; i<3;i++)
document.getElementById(ips[i]).disabled = false;
document.getElementById('dhcpd').disabled = false;
}
}
async function sendConfig(c) { async function sendConfig(c) {
const form = new FormData(); const form = new FormData();
form.append("MAX_FILE_SIZE", "4096"); form.append("MAX_FILE_SIZE", "4096");
@@ -144,8 +98,6 @@ function fetchIP() {
document.getElementById("ip").value=s.ip_address; document.getElementById("ip").value=s.ip_address;
document.getElementById("netmask").value=s.ip_netmask; document.getElementById("netmask").value=s.ip_netmask;
document.getElementById("gw").value=s.ip_gateway; document.getElementById("gw").value=s.ip_gateway;
document.getElementById('dhcp').checked = s.dhcp_client;
document.getElementById('dhcpd').checked = s.dhcp_server;
clearInterval(systemInterval); clearInterval(systemInterval);
// Fetch and populate the config textbox // Fetch and populate the config textbox
fetchConfig().then((configText) => { fetchConfig().then((configText) => {
+1 -1
View File
@@ -12,7 +12,7 @@
<form id="vform" action="/vlan.html"> <form id="vform" action="/vlan.html">
<div> <div>
<label for="vid">VLAN ID:</label> <label for="vid">VLAN ID:</label>
<input type="number" min="1" max="2047" id="vid" name="vid"> <input type="number" min="1" max="4094" id="vid" name="vid">
<button type="button" style="margin: 0 0 0 24px" onclick="fetchVLAN();">Get Configuration</button> <button type="button" style="margin: 0 0 0 24px" onclick="fetchVLAN();">Get Configuration</button>
</div> </div>
<br/><br/> <br/><br/>
+19 -15
View File
@@ -3,7 +3,6 @@ var vlanInterval = Number();
function vlanForm() { function vlanForm() {
if (!numPorts) if (!numPorts)
return; return;
clearInterval(vlanInterval);
var t = document.getElementById('tPorts'); var t = document.getElementById('tPorts');
var u = document.getElementById('uPorts'); var u = document.getElementById('uPorts');
var p = document.getElementById('pPorts'); var p = document.getElementById('pPorts');
@@ -39,11 +38,6 @@ function vlanForm() {
function setC(t, p, c){ function setC(t, p, c){
document.getElementById(t+'port'+p).checked=c; document.getElementById(t+'port'+p).checked=c;
// When a tagged port is checked, automatically select the PVID port as well
const tportElem = document.getElementById('tport'+p);
if (tportElem && tportElem.checked) {
document.getElementById('pport'+p).checked=true;
}
} }
function utClicked(t){ function utClicked(t){
@@ -58,10 +52,6 @@ function pvClicked(p){
} }
} }
window.addEventListener("load", function() {
vlanInterval = setInterval(vlanForm, 100);
});
function fetchVLAN() { function fetchVLAN() {
var xhttp = new XMLHttpRequest(); var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() { xhttp.onreadystatechange = function() {
@@ -70,10 +60,17 @@ function fetchVLAN() {
console.log("VLAN: ", JSON.stringify(s)); console.log("VLAN: ", JSON.stringify(s));
m = parseInt(s.members, 16); m = parseInt(s.members, 16);
document.getElementById('vname').value = s.name; document.getElementById('vname').value = s.name;
for (let i = 1; i <= numPorts; i++) { var members = m & 0x3FF;
setC('t', i, (m>>(10+i-1))&1); var untag = (m >> 10) & 0x3FF;
setC('u', i, (m>>(i-1))&1); var pvid = parseInt(s.pvid, 16);
setC('p', i, (m>>(20+i-1))&1); console.log("PVID: ", pvid);
for (let p = 1; p <= numPorts; p++) {
var bit = physToLogPort[p-1];
var isMember = (members >> bit) & 1;
var isUntag = (untag >> bit) & 1;
setC('t', p, isMember && !isUntag);
setC('u', p, isMember && isUntag);
setC('p', p, (pvid >> bit) & 1);
} }
} }
}; };
@@ -83,5 +80,12 @@ function fetchVLAN() {
return; return;
} }
xhttp.open("GET", `/vlan.json?vid=${v}`, true); xhttp.open("GET", `/vlan.json?vid=${v}`, true);
xhttp.send(); sendXHTTP(xhttp);
} }
window.addEventListener("load", function() {
update( () => {
vlanForm();
const interval = setInterval(update, 2000);
});
});
-26
View File
@@ -1,26 +0,0 @@
CC = sdcc
CC_FLAGS = -mmcs51 -I. -I.. -I../uip
ASM = sdas8051
AFLAGS= -plosgff
BUILDDIR = output/
SRCS = httpd.c page_impl.c
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel}
all: create_build_dir $(OBJS)
create_build_dir:
mkdir -p $(BUILDDIR)
$(BUILDDIR)%.asm: %.c
$(CC) $(CC_FLAGS) -o $@ -c -S $<
$(BUILDDIR)%.rel: $(BUILDDIR)%.asm
${ASM} ${AFLAGS} -o $@ $^
clean:
rm -r $(BUILDDIR)
.PHONY: all clean
+1 -1
View File
@@ -630,7 +630,7 @@ void httpd_appcall(void)
slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nContent-Type: "); slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nContent-Type: ");
slen += strtox(outbuf + slen, mime_strings[f_data[entry].mime]); slen += strtox(outbuf + slen, mime_strings[f_data[entry].mime]);
slen += strtox(outbuf + slen, "; charset=UTF-8\r\nCache-Control: max-age=60, must-revalidate\r\nAccess-Control-Allow-Origin: *\r\n\r\n"); slen += strtox(outbuf + slen, "; charset=UTF-8\r\nCache-Control: max-age=60, must-revalidate\r\nAccess-Control-Allow-Origin: *\r\nContent-Security-Policy: style-src 'self' 'unsafe-inline'\r\n\r\n");
len_left = f_data[entry].len; len_left = f_data[entry].len;
if (len_left > (TCP_OUTBUF_SIZE - slen)) { if (len_left > (TCP_OUTBUF_SIZE - slen)) {
+41 -19
View File
@@ -9,7 +9,6 @@
#include "uip.h" #include "uip.h"
#include "html_data.h" #include "html_data.h"
#include <stdint.h> #include <stdint.h>
#include "dhcp.h"
#include "phy.h" #include "phy.h"
#include "version.h" #include "version.h"
#include "machine.h" #include "machine.h"
@@ -46,8 +45,6 @@ extern __xdata char sfp_module_model[2][17];
extern __xdata char sfp_module_serial[2][17]; extern __xdata char sfp_module_serial[2][17];
extern __xdata uint8_t sfp_options[2]; extern __xdata uint8_t sfp_options[2];
extern __xdata struct dhcp_state dhcp_state;
__code uint8_t * __code HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n"; __code uint8_t * __code HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n";
__code uint8_t * __code HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n"; __code uint8_t * __code HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
@@ -100,7 +97,7 @@ void itoa_html(uint8_t v)
char_to_html('0' + (v % 10)); char_to_html('0' + (v % 10));
} }
void string_to_html(register char *s) void string_to_html(__code char *s)
{ {
while (*s) char_to_html(*s++); while (*s) char_to_html(*s++);
} }
@@ -178,11 +175,15 @@ void send_sfp_info(uint8_t sfp)
void sfp_send_data(uint8_t slot, uint8_t reg, uint8_t len) void sfp_send_data(uint8_t slot, uint8_t reg, uint8_t len)
{ {
// maximum supported transfer size is 16 bytes
if (len > 16)
return;
if (reg & 0x80) { // Configure SFP readings address (0x51) as I2C device address if (reg & 0x80) { // Configure SFP readings address (0x51) as I2C device address
reg &= 0x7f; reg &= 0x7f;
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | len & 0xf, 0x51 >> 5, (0x51 << 3) & 0xff); REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | (len - 1) & 0xf, 0x51 >> 5, (0x51 << 3) & 0xff);
} else { } else {
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | len & 0xf, 0x50 >> 5, (0x50 << 3) & 0xff); REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | (len - 1) & 0xf, 0x50 >> 5, (0x50 << 3) & 0xff);
} }
reg_read_m(RTL837X_REG_I2C_CTRL); reg_read_m(RTL837X_REG_I2C_CTRL);
@@ -199,12 +200,9 @@ void sfp_send_data(uint8_t slot, uint8_t reg, uint8_t len)
reg_read_m(RTL837X_REG_I2C_CTRL); reg_read_m(RTL837X_REG_I2C_CTRL);
} while (sfr_data[3] & 0x1); } while (sfr_data[3] & 0x1);
for (uint8_t i = 0; i < len & 0xf; i++) { for (uint8_t i = 0; i < len; i++) {
if (!(i & 0x3)) if (!(i & 0x3))
reg_read_m(RTL837X_REG_I2C_OUT + (i >> 2)); reg_read_m(RTL837X_REG_I2C_OUT + i);
if (len & 0x80)
char_to_html(sfr_data[3 - (i & 0x3)]);
else
byte_to_html(sfr_data[3 - (i & 0x3)]); byte_to_html(sfr_data[3 - (i & 0x3)]);
} }
} }
@@ -253,12 +251,6 @@ void send_basic_info(void)
send_sfp_info(1); send_sfp_info(1);
char_to_html('"'); char_to_html('"');
} }
if (dhcp_state.state != DHCP_OFF && dhcp_state.state != DHCP_SERVER)
slen += strtox(outbuf + slen, ",\"dhcp_client\":1,\"dhcp_server\":0");
else if (dhcp_state.state == DHCP_SERVER)
slen += strtox(outbuf + slen, ",\"dhcp_client\":0,\"dhcp_server\":1");
else
slen += strtox(outbuf + slen, ",\"dhcp_client\":0,\"dhcp_server\":0");
char_to_html('}'); char_to_html('}');
} }
@@ -279,6 +271,14 @@ void send_vlan(uint16_t vlan)
while(vlan_names[n] && vlan_names[n] != ' ') while(vlan_names[n] && vlan_names[n] != ' ')
char_to_html(vlan_names[n++]); char_to_html(vlan_names[n++]);
} }
slen += strtox(outbuf + slen, "\",\"pvid\":\"0x");
uint16_t pvid_mask = 0;
for (uint8_t i = machine.min_port; i <= machine.max_port; i++) {
if (port_pvid_get(i) == vlan)
pvid_mask |= (1 << i);
}
byte_to_html(pvid_mask >> 8);
byte_to_html(pvid_mask);
slen += strtox(outbuf + slen, "\"}"); slen += strtox(outbuf + slen, "\"}");
} }
@@ -633,6 +633,11 @@ void send_status(void)
itoa_html(machine.log_to_phys_port[i]); itoa_html(machine.log_to_phys_port[i]);
slen += strtox(outbuf + slen, ",\"logPort\":"); slen += strtox(outbuf + slen, ",\"logPort\":");
itoa_html(i); itoa_html(i);
slen += strtox(outbuf + slen, ",\"name\":\"");
for (uint8_t j = 0; j < PORT_NAME_SIZE && port_names[i][j]; j++) {
char_to_html(port_names[i][j]);
}
slen += strtox(outbuf + slen, "\"");
if (machine.is_sfp[i]) { if (machine.is_sfp[i]) {
slen += strtox(outbuf + slen, ",\"isSFP\":1,\"enabled\":"); slen += strtox(outbuf + slen, ",\"isSFP\":1,\"enabled\":");
@@ -641,7 +646,6 @@ void send_status(void)
slen += strtox(outbuf + slen,",\"sfp_options\":\"0x"); slen += strtox(outbuf + slen,",\"sfp_options\":\"0x");
byte_to_html(sfp_options[machine.is_sfp[i]-1]); byte_to_html(sfp_options[machine.is_sfp[i]-1]);
if (sfp_options[machine.is_sfp[i]-1] & 0x40) { if (sfp_options[machine.is_sfp[i]-1] & 0x40) {
sfp_send_data(machine.is_sfp[i] - 1, 92, 1);
slen += strtox(outbuf + slen,"\",\"sfp_temp\":\"0x"); slen += strtox(outbuf + slen,"\",\"sfp_temp\":\"0x");
sfp_send_data(machine.is_sfp[i] - 1, 224, 2); sfp_send_data(machine.is_sfp[i] - 1, 224, 2);
slen += strtox(outbuf + slen,"\",\"sfp_vcc\":\"0x"); slen += strtox(outbuf + slen,"\",\"sfp_vcc\":\"0x");
@@ -652,6 +656,19 @@ void send_status(void)
sfp_send_data(machine.is_sfp[i] - 1, 230, 2); sfp_send_data(machine.is_sfp[i] - 1, 230, 2);
slen += strtox(outbuf + slen,"\",\"sfp_rxpower\":\"0x"); slen += strtox(outbuf + slen,"\",\"sfp_rxpower\":\"0x");
sfp_send_data(machine.is_sfp[i] - 1, 232, 2); sfp_send_data(machine.is_sfp[i] - 1, 232, 2);
if (sfp_options[machine.is_sfp[i]-1] & 0x10) {
slen += strtox(outbuf + slen,"\",\"sfp_temp_cal\":\"0x");
sfp_send_data(machine.is_sfp[i] - 1, 212, 4);
slen += strtox(outbuf + slen,"\",\"sfp_vcc_cal\":\"0x");
sfp_send_data(machine.is_sfp[i] - 1, 216, 4);
slen += strtox(outbuf + slen,"\",\"sfp_txbias_cal\":\"0x");
sfp_send_data(machine.is_sfp[i] - 1, 204, 4);
slen += strtox(outbuf + slen,"\",\"sfp_txpower_cal\":\"0x");
sfp_send_data(machine.is_sfp[i] - 1, 208, 4);
slen += strtox(outbuf + slen,"\",\"sfp_rxpower_cal\":\"0x");
sfp_send_data(machine.is_sfp[i] - 1, 184, 16);
sfp_send_data(machine.is_sfp[i] - 1, 200, 4);
}
slen += strtox(outbuf + slen,"\",\"sfp_state\":\"0x"); slen += strtox(outbuf + slen,"\",\"sfp_state\":\"0x");
sfp_send_data(machine.is_sfp[i] - 1, 238, 1); sfp_send_data(machine.is_sfp[i] - 1, 238, 1);
} }
@@ -664,7 +681,12 @@ void send_status(void)
slen += strtox(outbuf + slen,"\",\"sfp_serial\":\""); slen += strtox(outbuf + slen,"\",\"sfp_serial\":\"");
for (register uint8_t s = 0; s < 16; s++) for (register uint8_t s = 0; s < 16; s++)
outbuf[slen++] = sfp_module_serial[machine.is_sfp[i]-1][s]; outbuf[slen++] = sfp_module_serial[machine.is_sfp[i]-1][s];
char_to_html('"'); slen += strtox(outbuf + slen,"\",\"sfp_los\":");
if (machine.sfp_port[machine.is_sfp[i]-1].pin_los == GPIO_NA) {
slen += strtox(outbuf + slen,"null");
} else {
bool_to_html(sfp_pins_last & (0x2 << (((machine.is_sfp[i]-1) << 2))));
}
} else { } else {
bool_to_html(0); bool_to_html(0);
} }
+211 -32
View File
@@ -27,7 +27,7 @@ __code const struct machine machine = {
.sfp_port[1].sds = 1, .sfp_port[1].sds = 1,
.sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, .sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.reset_pin = GPIO54_ACL_BIT2_EN, .reset_pin = GPIO54_ACL_BIT2_EN,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 }, .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}, .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
/* Conditions for LED on: /* Conditions for LED on:
* dual led orange: ledset_0 & ledset_2 * dual led orange: ledset_0 & ledset_2
@@ -89,7 +89,7 @@ __code const struct machine machine = {
.sfp_port[0].sds = 1, .sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, .sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.reset_pin = GPIO_NA, .reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 }, .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}, .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, .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_2G5 | LEDS_LINK,
@@ -100,9 +100,62 @@ __code const struct machine machine = {
void machine_custom_init(void) { } void machine_custom_init(void) { }
#elif defined MACHINE_KP_9000_9XHML_X #elif defined MACHINE_KP_9000_9XHML_X_V2_2
__code const struct machine machine = { __code const struct machine machine = {
.machine_name = "keepLink KP-9000-9XHML-X", .machine_name = "keepLink KP-9000-9XHML-X V2.2",
.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 = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.reset_pin = GPIO54_ACL_BIT2_EN,
.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 = {
{ /* Set 0 for RJ45 connectors */
/* LED0: Right Green */
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
/* LED1: Left Orange */
LEDS_2G5 | LEDS_LINK,
/* LED2: Left Green */
LEDS_1G | LEDS_LINK,
/* LED3: None */
0,
}, { /* Set 1 for SFP port */
/* LED0: Single Green "9" LED */
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,
/* LED1: D23 LED on PCB */
LEDS_1G | LEDS_LINK,
/* LED2: D22 LED on PCB */
LEDS_2G5 | LEDS_LINK,
/* LED3: Unused */
LEDS_COL | LEDS_DUPLEX,
}, { /* Set 2: Unused, but set to same things as stock firmware for consistency */
LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
LEDS_1G | LEDS_LINK | LEDS_ACT,
LEDS_2G5 | LEDS_LINK | LEDS_ACT | LEDS_5G,
LEDS_10G | LEDS_ACT | LEDS_LINK,
}, { /* Set 3: Unused, but set to same things as stock firmware for consistency */
LEDS_TX,
LEDS_RX,
LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5,
},
},
};
void machine_custom_init(void) { }
#elif defined MACHINE_KP_9000_9XHML_X_V3_1
__code const struct machine machine = {
.machine_name = "keepLink KP-9000-9XHML-X V3.1",
.isRTL8373 = 1, .isRTL8373 = 1,
.min_port = 0, .min_port = 0,
.max_port = 8, .max_port = 8,
@@ -115,7 +168,7 @@ __code const struct machine machine = {
.sfp_port[0].sds = 1, .sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, .sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.reset_pin = GPIO48_I2C_SCL1, .reset_pin = GPIO48_I2C_SCL1,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 }, .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}, .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
.led_sets = { .led_sets = {
{ /* RJ45: First LED, yellow, second LED: green */ { /* RJ45: First LED, yellow, second LED: green */
@@ -137,9 +190,48 @@ __code const struct machine machine = {
void machine_custom_init(void) { } void machine_custom_init(void) { }
#elif defined MACHINE_SWGT024_V2_0 #elif defined MACHINE_SWGT024_V2_0_MANAGED
__code const struct machine machine = { __code const struct machine machine = {
.machine_name = "SWGT024 V2.0", .machine_name = "SWGT024 V2.0 Managed",
.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 = GPIO_NA,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 39 */
// Right SFP port (J2)
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
.sfp_port[1].pin_los = GPIO_NA,
.sfp_port[1].pin_tx_disable = GPIO_NA,
.sfp_port[1].sds = 0,
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 40 */
.reset_pin = GPIO54_ACL_BIT2_EN,
.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 = {
{
/* Green LED */
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
0,
/* Amber LED */
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
0
},
},
};
void machine_custom_init(void) { }
#elif defined MACHINE_SWGT024_V2_0_UNMANAGED
__code const struct machine machine = {
.machine_name = "SWGT024 V2.0 Unmanaged",
.isRTL8373 = 0, .isRTL8373 = 0,
.min_port = 3, .min_port = 3,
.max_port = 8, .max_port = 8,
@@ -159,18 +251,18 @@ __code const struct machine machine = {
.sfp_port[1].pin_tx_disable = GPIO_NA, .sfp_port[1].pin_tx_disable = GPIO_NA,
.sfp_port[1].sds = 0, .sfp_port[1].sds = 0,
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 40 */ .sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 40 */
.reset_pin = GPIO36_PWM_OUT, .reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 }, .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}, .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
/* Conditions for LED on: .led_sets = {
* dual led orange: ledset_0 & ledset_2 {
* dual led green: ledset_2 & !ledset_0 /* Green LED */
* single right led green: ledset_0 & !ledset_1 LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G,
*/ 0,
.led_sets = { { LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G, /* Amber LED */
LEDS_2G5 | LEDS_LINK | LEDS_10G, LEDS_2G5 | LEDS_LINK | LEDS_ACT,
LEDS_1G | LEDS_LINK, 0
0 }, },
}, },
}; };
@@ -192,7 +284,7 @@ __code const struct machine machine = {
.sfp_port[0].sds = 1, .sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, .sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.reset_pin = GPIO_NA, .reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 }, .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}, .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
.led_sets = { .led_sets = {
{ /* RJ45: First LED, yellow, second LED: green */ { /* RJ45: First LED, yellow, second LED: green */
@@ -231,12 +323,12 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = 10, .sfp_port[0].pin_los = 10,
.sfp_port[0].pin_tx_disable = 0xFF, .sfp_port[0].pin_tx_disable = 0xFF,
.sfp_port[0].sds = 1, .sfp_port[0].sds = 1,
.sfp_port[0].i2c_bus ={ .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, .sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[1].pin_detect = 30, .sfp_port[1].pin_detect = 30,
.sfp_port[1].pin_los = 51, .sfp_port[1].pin_los = 51,
.sfp_port[1].pin_tx_disable = 0xFF, .sfp_port[1].pin_tx_disable = 0xFF,
.sfp_port[1].sds = 0, .sfp_port[1].sds = 0,
.sfp_port[1].i2c_bus = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, .sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.reset_pin = GPIO_NA, .reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 , .enable = LED_27 | LED_29 }, .high_leds = { .mux = LED_27 , .enable = LED_27 | LED_29 },
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1}, .port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
@@ -274,7 +366,7 @@ __code const struct machine machine = {
.sfp_port[0].sds = 1, .sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, .sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.reset_pin = GPIO54_ACL_BIT2_EN, .reset_pin = GPIO54_ACL_BIT2_EN,
.high_leds = { .mux = LED_27 | LED_28 | LED_29, .enable = LED_28 | LED_29 }, .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}, .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
.led_sets = { { LEDS_2G5 | LEDS_LINK | LEDS_ACT, // Green LED (right) .led_sets = { { LEDS_2G5 | LEDS_LINK | LEDS_ACT, // Green LED (right)
0, // unused 0, // unused
@@ -289,6 +381,39 @@ __code const struct machine machine = {
}, },
}; };
void machine_custom_init(void) { }
#elif defined MACHINE_LIANGUO_ZX_SWTGW215AS // Has PCB branded PCB-SWTG115AS-V2.0 but is labeled and reports as a ZX-SWTGW215AS, seems to be identical to the "real" ZX-SWTGW215AS except for the LEDs
__code const struct machine machine = {
.machine_name = "Lianguo ZX-SWTGW215AS",
.isRTL8373 = 0,
.min_port = 3,
.max_port = 8,
.n_sfp = 1,
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
.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 = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.reset_pin = GPIO54_ACL_BIT2_EN,
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
.led_sets = { { LEDS_2G5 | LEDS_LINK | LEDS_ACT, // Green LED (right)
0, // unused
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // Amber LED (left)
0
}, // unused
{ LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT, // SFP LED
0, // unused
0, // unused
0
}, // unused },
},
.led_mux_custom = 0,
};
void machine_custom_init(void) { } void machine_custom_init(void) { }
#elif defined MACHINE_DEFAULT_8C_1SFP #elif defined MACHINE_DEFAULT_8C_1SFP
@@ -307,7 +432,7 @@ __code const struct machine machine = {
.sfp_port[0].sds = 1, .sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, .sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.reset_pin = GPIO_NA, .reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 }, .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}, .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, .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_2G5 | LEDS_LINK,
@@ -326,19 +451,35 @@ __code const struct machine machine = {
.max_port = 8, .max_port = 8,
.n_sfp = 2, .n_sfp = 2,
.log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5}, .log_to_phys_port = {0, 0, 0, 6, 1, 2, 3, 4, 5},
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0}, .phys_to_log_port = {4, 5, 6, 7, 8, 3, 0, 0, 0},
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1}, .is_sfp = {0, 0, 0, 1, 0, 0, 0, 0, 2},
.sfp_port[0].pin_detect = GPIO36_PWM_OUT, .sfp_port[0].pin_detect = GPIO38,
.sfp_port[0].pin_los = GPIO37, .sfp_port[0].pin_los = GPIO50_I2C_SCL2_UART1_TX,
.sfp_port[0].pin_tx_disable = GPIO51_I2C_SDA2_UART1_RX, .sfp_port[0].pin_tx_disable = GPIO54_ACL_BIT2_EN,
.sfp_port[0].sds = 0, .sfp_port[0].sds = 0,
.sfp_port[0].i2c = { .sda = GPIO47_I2C_SDA0, .scl = GPIO46_I2C_SCL0 }, .sfp_port[0].i2c = { .sda = GPIO47_I2C_SDA0, .scl = GPIO46_I2C_SCL0 },
.sfp_port[1].pin_detect = GPIO38, .sfp_port[1].pin_detect = GPIO36_PWM_OUT,
.sfp_port[1].pin_los = GPIO50_I2C_SCL2_UART1_TX, .sfp_port[1].pin_los = GPIO37,
.sfp_port[1].pin_tx_disable = GPIO54_ACL_BIT2_EN, .sfp_port[1].pin_tx_disable = GPIO51_I2C_SDA2_UART1_RX,
.sfp_port[1].sds = 1, .sfp_port[1].sds = 1,
.sfp_port[1].i2c = { .sda = GPIO49_I2C_SDA1, .scl = GPIO48_I2C_SCL1 }, .sfp_port[1].i2c = { .sda = GPIO49_I2C_SDA1, .scl = GPIO48_I2C_SCL1 },
.reset_pin = GPIO_NA, .reset_pin = GPIO_NA,
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
.led_sets = {
{
0, // Unused
LEDS_2G5 | LEDS_LINK | LEDS_ACT, // Green
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, // Amber
0 // Unused
},
{
0, // Unused
0, // Unused
LEDS_10G | LEDS_1G | LEDS_LINK | LEDS_ACT, // Green
0, // Unused
},
},
}; };
void machine_custom_init(void) { } void machine_custom_init(void) { }
@@ -367,7 +508,7 @@ __code const struct machine machine = {
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, .sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
.reset_pin = GPIO_NA, .reset_pin = GPIO_NA,
.high_leds = { .mux = LED_28 | LED_29, .enable = LED_27 | LED_28 | LED_29 }, .high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1}, .port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
.led_sets = { .led_sets = {
{ {
@@ -392,6 +533,44 @@ __code const struct machine machine = {
void machine_custom_init(void) { void machine_custom_init(void) {
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6); reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
} }
#elif defined MACHINE_K0501W_V2_0
__code const struct machine machine = {
.machine_name = "K0501W V2.0",
.isRTL8373 = 0,
.min_port = 3,
.max_port = 8,
.n_sfp = 1,
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
.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 = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.reset_pin = GPIO_NA,
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
.led_sets = {
{
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
0,
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
0
},
{
LEDS_10G | LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
0,
0,
0
},
},
};
void machine_custom_init(void) { }
#else #else
#error "Please select a machine type in machine.h" #error "Please select a machine type in machine.h"
#endif #endif
+16 -5
View File
@@ -6,17 +6,20 @@
/* /*
* Select your machine type below * Select your machine type below
*/ */
// #define MACHINE_KP_9000_6XHML_X2 #define MACHINE_KP_9000_6XHML_X2
// #define MACHINE_KP_9000_6XH_X // #define MACHINE_KP_9000_6XH_X
// #define MACHINE_KP_9000_9XH_X_EU // #define MACHINE_KP_9000_9XH_X_EU
// #define MACHINE_KP_9000_9XHML_X // #define MACHINE_KP_9000_9XHML_X_V2_2
// #define MACHINE_SWGT024_V2_0 // #define MACHINE_KP_9000_9XHML_X_V3_1
// #define MACHINE_HORACO_ZX_SG4T2 // #define MACHINE_SWGT024_V2_0_MANAGED
// #define MACHINE_SWGT024_V2_0_UNMANAGED
// #define MACHINE_TRENDNET_TEG_S562 // #define MACHINE_TRENDNET_TEG_S562
// #define MACHINE_HG0402XG_V1_1 // #define MACHINE_HG0402XG_V1_1
// #define MACHINE_SWTG018AS_A_V_2_0 // #define MACHINE_SWTG018AS_A_V_2_0
// #define MACHINE_SWTGW218AS // #define MACHINE_SWTGW218AS
// #define MACHINE_HI_K0402WS // #define MACHINE_HI_K0402WS
// #define MACHINE_K0501W_V2_0
// #define MACHINE_LIANGUO_ZX_SWTGW215AS
// #define MACHINE_DEFAULT_8C_1SFP // #define MACHINE_DEFAULT_8C_1SFP
typedef struct { typedef struct {
@@ -27,7 +30,8 @@ typedef struct {
#define LED_27 1 #define LED_27 1
#define LED_28 2 // SYSTEM LED
#define LED_28_SYS 2
#define LED_29 4 #define LED_29 4
struct high_leds { struct high_leds {
@@ -49,7 +53,9 @@ struct sfp_port
typedef struct machine { typedef struct machine {
char machine_name[30]; char machine_name[30];
uint8_t isRTL8373; uint8_t isRTL8373;
// Lowest logical port number
uint8_t min_port; uint8_t min_port;
// Highest logical port number
uint8_t max_port; uint8_t max_port;
uint8_t n_sfp; uint8_t n_sfp;
uint8_t log_to_phys_port[9]; uint8_t log_to_phys_port[9];
@@ -59,7 +65,12 @@ typedef struct machine {
struct sfp_port sfp_port[2]; struct sfp_port sfp_port[2];
uint8_t reset_pin; uint8_t reset_pin;
struct high_leds high_leds; struct high_leds high_leds;
// Defines which led-set (0-3) will be used for given logical port
// led-set is physical group of LEDs that can be configured to show different port status combinations (see port_led_set below)
uint8_t port_led_set[9]; uint8_t port_led_set[9];
// Defines led-set configuration, applied to all ports using particular led-set
// Each led-set can have 4 different hardware LED configurations. Which one should be used, depends how LED is wired on the board
// See stock RTL837X_REG_LED3_2_SETx and RTL837X_REG_LED1_0_SETx registers for reference configuration
uint32_t led_sets[4][4]; uint32_t led_sets[4][4];
uint8_t led_mux_custom; uint8_t led_mux_custom;
uint8_t led_mux[28]; uint8_t led_mux[28];
+21 -7
View File
@@ -36,12 +36,20 @@ extern __xdata uint8_t sbuf[SBUF_SIZE];
// Size of the TCP Output buffer // Size of the TCP Output buffer
#define TCP_OUTBUF_SIZE 2500 #define TCP_OUTBUF_SIZE 2500
// Size of the port name, including the terminating null byte
#define PORT_NAME_SIZE 32
// Size of the memory area dedicated to VLAN-names // Size of the memory area dedicated to VLAN-names
#define VLAN_NAMES_SIZE 1024 #define VLAN_NAMES_SIZE 1024
// Size of the flash buffer used for writing to flash, must be a multiple of the flash page size (0x100) // Size of the flash buffer used for writing to flash, must be a multiple of the flash page size (0x100)
#define FLASH_BUF_SIZE 512 #define FLASH_BUF_SIZE 512
// Errors for commands
#define ERR_OK 0
#define ERR_TOO_MANY_ARGUMENTS 1
#define ERR_CMD_TOO_LONG 2
// For RX data, a propriatary RTL FRAME is inserted. Instead of 0x0800 for IPv4, // For RX data, a propriatary RTL FRAME is inserted. Instead of 0x0800 for IPv4,
// the RTL_FRAME_TAG_ID is used as part of an 8-byte tag. When VLAN is activated, // the RTL_FRAME_TAG_ID is used as part of an 8-byte tag. When VLAN is activated,
// the VLAN tag is inserted after the RTL tag // the VLAN tag is inserted after the RTL tag
@@ -62,10 +70,11 @@ struct vlan_tag {
#define RTL_TAG_SIZE (sizeof (struct rtl_tag)) #define RTL_TAG_SIZE (sizeof (struct rtl_tag))
#define VLAN_TAG_SIZE (sizeof (struct vlan_tag)) #define VLAN_TAG_SIZE (sizeof (struct vlan_tag))
#define RTL_FRAME_TAG_ID 0x8899 #define RTL_FRAME_TAG_ID 0x8899
#define RTL_FRAME_TAG_VERSION 0x04
// For RX and TX, an 8 byte header describing the frame to be moved to the Asic // For TX, an 8 byte (plus 4 byte padding when when VLAN is enabled)
// and received from the Asic is used // header describing the frame to be moved to the Asic is used
#define RTL_FRAME_HEADER_SIZE 8 #define RTL_FRAME_DESC_SIZE 12
// This is the standard size of an Ethernet frame header // This is the standard size of an Ethernet frame header
#define ETHER_HEADER_SIZE 14 #define ETHER_HEADER_SIZE 14
@@ -95,10 +104,10 @@ struct flash_region_t {
uint16_t len; uint16_t len;
}; };
extern __xdata char port_names[9][PORT_NAME_SIZE];
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2]; extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
extern __xdata struct uip_eth_addr uip_ethaddr; extern __xdata struct uip_eth_addr uip_ethaddr;
extern __xdata uint16_t rx_packet_vlan;
extern __xdata uint16_t dhcpd_vlan;
// Headers for calls in the common code area (HOME/BANK0) // Headers for calls in the common code area (HOME/BANK0)
void print_string(__code char *p); void print_string(__code char *p);
@@ -117,6 +126,8 @@ void reg_read(uint16_t reg_addr);
void reg_read_m(uint16_t reg_addr); void reg_read_m(uint16_t reg_addr);
void reg_write(uint16_t reg_addr); void reg_write(uint16_t reg_addr);
void reg_write_m(uint16_t reg_addr); void reg_write_m(uint16_t reg_addr);
void sds_read(uint8_t sds_id, uint8_t page, uint8_t reg);
void sds_write_v(uint8_t sds_id, uint8_t page, uint8_t reg, uint16_t v);
void delay(uint16_t t); void delay(uint16_t t);
void sleep(uint16_t t); void sleep(uint16_t t);
void write_char(char c); void write_char(char c);
@@ -138,9 +149,12 @@ uint16_t strcpy(register __xdata uint8_t *dst, register const char *s);
void tcpip_output(void); void tcpip_output(void);
uint8_t read_flash(uint8_t bank, __code uint8_t *addr); uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
void get_random_32(void); void get_random_32(void);
void read_reg_timer(uint32_t * tmr); void read_reg_timer(__xdata uint32_t * tmr);
void sfp_print_info(uint8_t sfp); void sfp_print_info(uint8_t sfp);
bool gpio_pin_test(uint8_t pin); bool gpio_pin_test(uint8_t pin);
void set_sys_led_state(uint8_t state); void set_sys_led_state(uint8_t state);
void sds_read(uint8_t sds_id, uint8_t page, uint8_t reg);
void sds_write_v(uint8_t sds_id, uint8_t page, uint8_t reg, uint16_t v);
void sds_config_mac(uint8_t sds, uint8_t mode);
void sds_config(uint8_t sds, uint8_t mode);
#endif #endif
+247
View File
@@ -0,0 +1,247 @@
#include <stdint.h>
#include "rtl837x_common.h"
#include "rtl837x_sfr.h"
#include "rtl837x_regs.h"
#include "rtl837x_port.h"
#include "rtl837x_phy.h"
#include "phy.h"
#include "machine.h"
extern __xdata uint8_t sfr_data[4];
extern __code struct machine machine;
extern __xdata struct machine_runtime machine_detected;
#pragma codeseg BANK2
#pragma constseg BANK2
/*
* Configure the PHY-Side of the SDS-SDS link between SoC and PHY
*/
void static sds_init(void)
{
/*
p001e.000d:9535 R02f8-00009535 R02f4-0000953a P000001.1e00000d:953a
p001e.000d:953a p001e.000d:953a R02f8-0000953a R02f4-00009530 P000001.1e00000d:9530
RTL8373:
p001e.000d:0010 R02f8-00000010 R02f4-0000001a P000001.1e00000d:b7fe
p001e.000d:0010 p001e.000d:0010 R02f8-00000010 R02f4-00000010 P000001.1e00000d:b7fe
*/
phy_read(0, PHY_MMD30, 0xd);
uint16_t pval = SFR_DATA_U16;
// PHY Initialization:
REG_WRITE(0x2f8, 0, 0, pval >> 8, pval);
delay(20);
pval &= 0xfff0;
pval |= 0x0a;
REG_WRITE(0x2f4, 0, 0, pval >> 8, pval);
delay(10);
phy_write_mask(0x1, PHY_MMD30, 0xd, pval);
phy_read(0, PHY_MMD30, 0xd);
pval = SFR_DATA_U16;
REG_WRITE(0x2f8, 0, 0, pval >> 8, pval);
pval &= 0xfff0;
REG_WRITE(0x2f4, 0, 0, pval >> 8, pval);
phy_write_mask(0x1, PHY_MMD30, 0xd, pval);
if (machine_detected.isN) {
uint16_t pval;
print_string(" N-settings");
// Serdes 0 RX PN swap for 64B/66B
sds_read(1, 6, 2);
pval = SFR_DATA_U16;
sds_write_v(1, 6, 2, pval | 0x2000);
// Serdes 1 RX PN swap for 8B/10B
sds_read(1, 0, 0);
pval = SFR_DATA_U16;
sds_write_v(1, 0, 0, pval | 0x200);
// Serdes 0 RX PN swap for 64B/66B
sds_read(0, 6, 2);
pval = SFR_DATA_U16;
sds_write_v(0, 6, 2, pval | 0x2000);
if (machine_detected.isRTL8373) {
// RTL8224: Serdes 0 RX PN swap for 64B/66B
// We assume that RTL8373N always paired with RTL8224N.
// This sds register value is 0x0000 at reset.
// So only write to it.
RTL8224_SDS_WRITE(0, 6, 2, 0x2000);
} else {
// Serdes 0 RX PN swap for 8B/10B
sds_read(0, 0, 0);
pval = SFR_DATA_U16;
sds_write_v(0, 0, 0, pval | 0x200);
}
}
}
void rtl8373_init(void) __banked
{
print_string("\nrtl8373_init called\n");
// r65d8:3ffbedff R65d8-3ffbedff
reg_bit_set(0x65d8, 0x1d);
sds_init();
// Disable all SERDES for configuration
REG_SET(RTL837X_REG_SDS_MODES, 0x000037ff);
// q000601:c800 Q000601:c804 q000601:c804 Q000601:c800
sds_read(0, 0x06, 0x01);
uint16_t pval = SFR_DATA_U16;
sds_write_v(0, 0x06, 0x01, pval | 0x04);
delay(50);
sds_read(0, 0x06, 0x01);
pval = SFR_DATA_U16;
sds_write_v(0, 0x06, 0x01, pval & 0xfffb);
phy_config_8224();
sds_config_mac(1, SDS_OFF); // Off for now until SFP+ port used
sds_config_mac(2, SDS_SGMII); // For RTL8224
sds_config(0, SDS_QXGMII);
// SDS 1 setup
// q012100:4902 Q012100:4906 q013605:0000 Q013605:4000 Q011f02:001f q011f15:0086
sds_write_v(1, 0x21, 0x00, 0x4906);
sds_write_v(1, 0x36, 0x05, 0x4000);
sds_write_v(1, 0x1f, 0x02, 0x001f);
sds_read(1, 0x1f, 0x15);
pval = SFR_DATA_U16;
// r0a90:000000f3 R0a90-000000fc
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
sfr_mask_data(0, 0x0f,0x0c);
reg_write_m(RTL837X_CFG_PHY_MDI_REVERSE);
if (machine_detected.isN) {
print_string(" TX_POLARITY_SWAP\n");
// FOR N-Version: #TX_POLARITY_SWAP
reg_read_m(RTL837X_CFG_PHY_TX_POLARITY_SWAP);
sfr_data[2] = 0x59;
sfr_data[3] = 0x6a;
reg_write_m(RTL837X_CFG_PHY_TX_POLARITY_SWAP);
}
rtl8224_phy_enable();
// Disable PHYs for configuration
phy_write_mask(0xff,PHY_MMD31,0xa610,0x2858);
// Set bits 0x13 and 0x14 of 0x5fd4
// r5fd4:0002914a R5fd4-001a914a
reg_bit_set(0x5fd4, 0x13);
reg_bit_set(0x5fd4, 0x14);
// Configure ports
uint16_t reg = 0x1238; // Port base register for the bits we set
for (char i = 0; i < 9; i++) {
// Bit 7 (0x40) enables replacement of the RTL-VLAN tag with an 802.1Q VLAN tag
REG_SET(reg, 0xe77);
reg += 0x100;
}
// r0b7c:000000d8 R0b7c-000000f8 r6040:00000030 R6040-00000031
reg_bit_set(0xb7c, 5);
// R7124-00001050 R7128-00001050 R712c-00001050 R7130-00001050 R7134-00001050 R7138-00001050
// R713c-00001050 R7140-00001050 R7144-00001050 R7148-00001050
REG_SET(0x7124, 0x1050); REG_SET(0x7128, 0x1050); REG_SET(0x712c, 0x1050);
REG_SET(0x7130, 0x1050); REG_SET(0x7134, 0x1050); REG_SET(0x7138, 0x1050);
REG_SET(0x713c, 0x1050); REG_SET(0x7140, 0x1050); REG_SET(0x7144, 0x1050);
REG_SET(0x7148, 0x1050);
reg_bit_set(RTL837X_REG_HW_CONF, 0);
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
// TODO: patch the PHYs
// Re-enable PHY after configuration
phy_write_mask(0xff,PHY_MMD31,0xa610,0x2058);
// Enables MAC access
// Set bits 0xc-0x14 of 0x632c to 0x1f8, see rtl8372_init
// r632c:00000540 R632c-001f8540 // RTL8373: 001ff540
reg_read_m(0x632c);
sfr_mask_data(1, 0x70, 0xf0); // The ports of the RTL8824
sfr_mask_data(2, 0x10, 0x1f);
reg_write_m(0x632c);
print_string("\nrtl8373_init done\n");
}
void rtl8372_init(void) __banked
{
print_string("\nrtl8372_init called\n");
sds_init();
phy_config(8); // PHY configuration: External 8221B?
phy_config(3); // PHY configuration: all internal PHYs?
// Set the MAC SerDes Modes Bits 0-4: SDS 0 = 0x2 (0x2), Bits 5-9: SDS 1: 1f (off)
// r7b20:00000bff R7b20-00000bff r7b20:00000bff R7b20-00000bff r7b20:00000bff R7b20-000003ff r7b20:000003ff R7b20-000003e2 r7b20:000003e2 R7b20-000003e2
reg_read_m(RTL837X_REG_SDS_MODES);
sfr_mask_data(1, 0, 0x03);
sfr_mask_data(0, 0, 0xe2);
reg_write_m(RTL837X_REG_SDS_MODES);
// r0a90:000000f3 R0a90-000000fc
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
sfr_mask_data(0, 0x0f, 0x0c);
reg_write_m(RTL837X_CFG_PHY_MDI_REVERSE);
// Disable PHYs for configuration
phy_write_mask(0xf0,PHY_MMD31,0xa610,0x2858);
// Set bits 0x13 and 0x14 of 0x5fd4
// r5fd4:0002914a R5fd4-001a914a
reg_bit_set(0x5fd4, 0x13);
reg_bit_set(0x5fd4, 0x14);
// Configure ports 3-8:
//
// r1538:00000e33 R1538-00000e37 r1538:00000e37 R1538-00000e37 r1538:00000e37 R1538-00000f37
// [...]
///
uint16_t reg = 0x1238 + 0x300; // Port base register for the bits we set
for (char i = machine.min_port; i <= machine.max_port; i++) {
// Bit 7 (0x40) enables replacement of the RTL-VLAN tag with an 802.1Q VLAN tag
REG_SET(reg, 0xe77);
reg += 0x100;
}
// r0b7c:000000d8 R0b7c-000000f8 r6040:00000030 R6040-00000031
reg_bit_set(0xb7c, 5);
reg_bit_set(RTL837X_REG_HW_CONF, 0);
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
// TODO: patch the PHYs
// Re-enable PHY after configuration
phy_write_mask(0xf0,PHY_MMD31,0xa610,0x2058);
// Enables MAC access
// Set bits 0xc-0x14 of 0x632c to 0x1f8, see rtl8372_init
// r632c:00000540 R632c-001f8540 // RTL8373: 001ff540
reg_read_m(0x632c);
sfr_mask_data(1, 0x70, 0x80);
sfr_mask_data(2, 0x10, 0x1f);
reg_write_m(0x632c);
print_string("\nrtl8372_init done\n");
}
+7
View File
@@ -0,0 +1,7 @@
#ifndef _RTL837X_INIT_H_
#define _RTL837X_INIT_H_
void rtl8372_init(void) __banked;
void rtl8373_init(void) __banked;
#endif
+4 -2
View File
@@ -190,7 +190,8 @@ void leds_setup(void) __banked
else else
reg_bit_clear(RTL837X_PIN_MUX_0, 27); reg_bit_clear(RTL837X_PIN_MUX_0, 27);
if (machine.high_leds.mux & LED_28) // SYSTEM LED
if (machine.high_leds.mux & LED_28_SYS)
reg_bit_set(RTL837X_PIN_MUX_0, 28); reg_bit_set(RTL837X_PIN_MUX_0, 28);
else else
reg_bit_clear(RTL837X_PIN_MUX_0, 28); reg_bit_clear(RTL837X_PIN_MUX_0, 28);
@@ -205,7 +206,8 @@ void leds_setup(void) __banked
else else
reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 27); reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 27);
if (machine.high_leds.enable & LED_28) // SYSTEM LED
if (machine.high_leds.enable & LED_28_SYS)
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 28); reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 28);
else else
reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 28); reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 28);
+4 -1
View File
@@ -367,12 +367,15 @@ void phy_show(uint8_t port) __banked
print_string("5G"); print_string("5G");
break; break;
default: default:
print_string("10M"); print_string("Down");
} }
if ( (((v & 0x0600) >> 7) | ((v & 0x0030) >> 4)) <= 6) { // Link is up
if (v & 0x8) if (v & 0x8)
print_string(" full duplex"); print_string(" full duplex");
else else
print_string(" half duplex"); print_string(" half duplex");
}
phy_read(port, PHY_MMD_AN, PHY_ANEG_CTRL); phy_read(port, PHY_MMD_AN, PHY_ANEG_CTRL);
v = SFR_DATA_U16; v = SFR_DATA_U16;
+123 -11
View File
@@ -35,6 +35,7 @@ void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata u
print_string("\nport_mirror_set called \n"); print_string("\nport_mirror_set called \n");
print_string("Mirroring port: "); print_byte(port); print_string(" with rx-mask: "); print_string("Mirroring port: "); print_byte(port); print_string(" with rx-mask: ");
print_short(rx_pmask); print_string(", tx mask: "); print_short(tx_pmask); print_short(rx_pmask); print_string(", tx mask: "); print_short(tx_pmask);
write_char('\n');
REG_WRITE(RTL837x_MIRROR_CONF, rx_pmask >> 8, rx_pmask, tx_pmask >> 8, tx_pmask); REG_WRITE(RTL837x_MIRROR_CONF, rx_pmask >> 8, rx_pmask, tx_pmask >> 8, tx_pmask);
REG_WRITE(RTL837x_MIRROR_CTRL, 0, 0, 0, (port << 1) | 0x1); REG_WRITE(RTL837x_MIRROR_CTRL, 0, 0, 0, (port << 1) | 0x1);
@@ -48,17 +49,39 @@ void port_mirror_del(void) __banked
} }
void port_ingress_filter(__xdata uint8_t port, __xdata uint8_t type) __banked bool port_ingress_filter(__xdata uint8_t port, __xdata vlan_ingress_mode_t type) __banked
{ {
if (type & 0x1) if (port > 9 || type >= VLAN_INVALID) {
print_string("Invalid port or ingress filter type\n");
return false;
}
if (type & 0x1) {
reg_bit_set(RTL837x_REG_INGRESS, port << 1); reg_bit_set(RTL837x_REG_INGRESS, port << 1);
else } else {
reg_bit_clear(RTL837x_REG_INGRESS, port << 1); reg_bit_clear(RTL837x_REG_INGRESS, port << 1);
if (type & 0x2) }
if (type & 0x2) {
reg_bit_set(RTL837x_REG_INGRESS, (port << 1) + 1); reg_bit_set(RTL837x_REG_INGRESS, (port << 1) + 1);
else } else {
reg_bit_clear(RTL837x_REG_INGRESS, (port << 1) + 1); reg_bit_clear(RTL837x_REG_INGRESS, (port << 1) + 1);
} }
return true;
}
vlan_ingress_mode_t port_ingress_filter_get(__xdata uint8_t port) __banked
{
reg_read_m(RTL837x_REG_INGRESS);
if (port > 9) {
return VLAN_INVALID;
}
// Each port is represented by 2 bits in the ingress register, starting from bit 0 for port 0
const uint8_t sfr_index = 3 - (port / 4);
const uint8_t shift = (port % 4) << 1;
return (vlan_ingress_mode_t)((sfr_data[sfr_index] >> shift) & 0x03);
}
/* /*
@@ -78,6 +101,17 @@ void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked
} }
} }
uint16_t port_pvid_get(uint8_t port) __banked
{
uint16_t reg = RTL837x_PVID_BASE_REG + ((port >> 1) << 2);
reg_read_m(reg);
if (port & 0x1) {
return (sfr_data[1] << 4) | (sfr_data[2] >> 4);
} else {
return ((sfr_data[2] & 0x0f) << 8) | sfr_data[3];
}
}
void vlan_delete(uint16_t vlan) __banked void vlan_delete(uint16_t vlan) __banked
{ {
@@ -93,7 +127,7 @@ void vlan_delete(uint16_t vlan) __banked
*/ */
int8_t vlan_get(register uint16_t vlan) __banked int8_t vlan_get(register uint16_t vlan) __banked
{ {
if (vlan >= 0x3ff) // VLAN 4095 is special if (vlan >= 0xfff) // VLAN 4095 is special
return -1; return -1;
REG_WRITE(RTL837X_TBL_CTRL, vlan >> 8, vlan, TBL_VLAN, TBL_EXECUTE); REG_WRITE(RTL837X_TBL_CTRL, vlan >> 8, vlan, TBL_VLAN, TBL_EXECUTE);
@@ -199,7 +233,8 @@ void vlan_setup(void) __banked
// EGRESS filtering for port: removal of additional VLAN tag (mode 0x3 for each port) // EGRESS filtering for port: removal of additional VLAN tag (mode 0x3 for each port)
reg_bit_clear(RTL837X_VLAN_PORT_EGR_TAG, i << 1); reg_bit_clear(RTL837X_VLAN_PORT_EGR_TAG, i << 1);
reg_bit_clear(RTL837X_VLAN_PORT_EGR_TAG, (i << 1) + 1); reg_bit_clear(RTL837X_VLAN_PORT_EGR_TAG, (i << 1) + 1);
reg_bit_set(RTL837X_VLAN_PORT_IGR_FLTR, i); // Enable INGRESS filtering for port: discard packets not belonging to member VLAN on that port
port_ingress_vlan_filter_set(i, true);
#ifdef DEBUG #ifdef DEBUG
print_string("\n"); print_string("\n");
@@ -224,6 +259,7 @@ void vlan_setup(void) __banked
#ifdef DEBUG #ifdef DEBUG
print_string("\nvlan_setup, REG 0x6738: "); print_reg(0x6738); print_string("\nvlan_setup, REG 0x6738: "); print_reg(0x6738);
print_string("\nvlan_setup, REG 0x4e10: "); print_reg(0x4e10);
print_string("\nvlan_setup, REG 0x4e18: "); print_reg(0x4e18); print_string("\nvlan_setup, REG 0x4e18: "); print_reg(0x4e18);
print_string("\nvlan_setup, REG 0x4e14: "); print_reg(0x4e14); print_string("\nvlan_setup, REG 0x4e14: "); print_reg(0x4e14);
print_string("\nvlan_setup, REG 0x4e30: "); print_reg(0x4e30); print_string("\nvlan_setup, REG 0x4e30: "); print_reg(0x4e30);
@@ -427,14 +463,14 @@ void port_stats_print(void) __banked
} }
void port_isolate(register uint8_t port, __xdata uint16_t pmask) void port_isolate(register uint8_t port, __xdata uint16_t pmask) __banked
{ {
if (port <= machine.max_port) if (port <= machine.max_port)
REG_SET(RTL837X_PORT_ISOLATION_BASE + (port << 2), pmask); REG_SET(RTL837X_PORT_ISOLATION_BASE + (port << 2), pmask);
} }
uint16_t port_isolation_get(register uint8_t port) uint16_t port_isolation_get(register uint8_t port) __banked
{ {
if (port > machine.max_port) if (port > machine.max_port)
return 0; return 0;
@@ -605,8 +641,9 @@ void port_rldp_on(__xdata uint16_t p_ms)
void port_lag_members_set(__xdata uint8_t lag, __xdata uint16_t members) __banked void port_lag_members_set(__xdata uint8_t lag, __xdata uint16_t members) __banked
{ {
print_string("port_lag_members_set, lag: "); print_byte(lag); print_string(", members: "); print_short(members); print_string("port_lag_members_set, lag: "); print_byte(lag); print_string(", members: "); print_short(members);
write_char('\n');
if (lag > 3) if (lag > 3)
print_string("Link aggregation group must be 0-3!"); print_string("Link aggregation group must be 0-3!\n");
reg_read_m(RTL837X_TRK_HASH_CTRL_BASE + (lag << 2)); reg_read_m(RTL837X_TRK_HASH_CTRL_BASE + (lag << 2));
if (!(sfr_data[0] | sfr_data [1] | sfr_data [2] | sfr_data [3])) if (!(sfr_data[0] | sfr_data [1] | sfr_data [2] | sfr_data [3]))
REG_SET(RTL837X_TRK_HASH_CTRL_BASE, LAG_HASH_DEFAULT); REG_SET(RTL837X_TRK_HASH_CTRL_BASE, LAG_HASH_DEFAULT);
@@ -621,7 +658,82 @@ void port_lag_members_set(__xdata uint8_t lag, __xdata uint16_t members) __banke
void port_lag_hash_set(__xdata uint8_t lag, __xdata uint8_t hash_bits) __banked void port_lag_hash_set(__xdata uint8_t lag, __xdata uint8_t hash_bits) __banked
{ {
print_string("port_lag_hash_set, lag: "); print_byte(lag); print_string(", hash: "); print_byte(hash_bits); print_string("port_lag_hash_set, lag: "); print_byte(lag); print_string(", hash: "); print_byte(hash_bits);
write_char('\n');
if (lag > 3) if (lag > 3)
print_string("Link aggregation group must be 0-3!"); print_string("Link aggregation group must be 0-3!\n");
REG_WRITE(RTL837X_TRK_HASH_CTRL_BASE + (lag << 2), 0, 0, 0, hash_bits); REG_WRITE(RTL837X_TRK_HASH_CTRL_BASE + (lag << 2), 0, 0, 0, hash_bits);
} }
void print_port_ingress_filter_mode(vlan_ingress_mode_t mode) __banked
{
switch (mode) {
case VLAN_UNTAGGED:
print_string("Untag.");
break;
case VLAN_TAGGED:
print_string("Tagged");
break;
case VLAN_ALL:
print_string("Any");
break;
default:
print_string("!!err!!");
}
}
static void print_phys_port(uint8_t port) __banked
{
if (port >= machine.min_port && port <= machine.max_port)
write_char(machine.log_to_phys_port[port] + '0');
else if (port == 9)
write_char('9');
else
write_char('?');
}
void print_vlan_ingress_port(uint8_t log_port) __banked
{
print_phys_port(log_port);write_char('\t');
print_short(port_pvid_get(log_port));write_char('\t');
print_port_ingress_filter_mode(port_ingress_filter_get(log_port));write_char('\t');
port_ingress_vlan_filter_get(log_port) ? print_string("Enabled") : print_string("Disabled");
write_char('\n');
}
/*
* Dumps the VLAN ingress configuration
*/
void vlan_dump(void) __banked
{
print_string("Ingress VLAN configuration:\n");
print_string("Port\tPVID\tType\tFiltering\n");
for (uint8_t port = machine.min_port; port <= machine.max_port; port++) {
print_vlan_ingress_port(port);
}
print_vlan_ingress_port(9);
write_char('\n');
print_string("Type - Which frame types are allowed: untagged, tagged or any\n");
print_string("Filtering - Whether packets not belonging to member VLANs on that port are dropped\n");
print_string("PVID - Assumed VLAN for untagged packets\n");
}
/** Set the ingress VLAN filtering */
bool port_ingress_vlan_filter_set(__xdata uint8_t port, __xdata bool enabled) __banked
{
if (port < machine.min_port || port > machine.max_port && port != 9) {
return false;
}
reg_bit_set(RTL837X_VLAN_PORT_IGR_FLTR, port);
return true;
}
/** Get the ingress VLAN filtering status */
bool port_ingress_vlan_filter_get(__xdata uint8_t port) __banked
{
if (port < machine.min_port || port > machine.max_port && port != 9) {
return false;
}
return reg_bit_test(RTL837X_VLAN_PORT_IGR_FLTR, port);
}
+23 -1
View File
@@ -2,6 +2,7 @@
#define _RTL837X_PORT_H_ #define _RTL837X_PORT_H_
#include <stdint.h> #include <stdint.h>
#include "rtl837x_regs.h"
#define STAT_COUNTER_TX_PKTS 46 #define STAT_COUNTER_TX_PKTS 46
#define STAT_COUNTER_RX_PKTS 47 #define STAT_COUNTER_RX_PKTS 47
@@ -13,6 +14,19 @@
reg_read_m(RTL837X_STAT_GET); \ reg_read_m(RTL837X_STAT_GET); \
} while (sfr_data[3] & 0x1); } while (sfr_data[3] & 0x1);
// Possible values for ingress filter type
typedef enum {
VLAN_ALL = INGR_ALLOW_ALL,
VLAN_TAGGED = INGR_ALLOW_TAGGED,
VLAN_UNTAGGED = INGR_ALLOW_UNTAGGED,
VLAN_INVALID = 3
} vlan_ingress_mode_e;
// Since we lack a way to force enum to be 1 byte,
// This is a typedef for the VLAN ingress filter type
// which holds vlan_ingress_mode_e values
typedef uint8_t vlan_ingress_mode_t;
struct vlan_settings { struct vlan_settings {
uint16_t vlan; uint16_t vlan;
uint16_t members; uint16_t members;
@@ -28,11 +42,13 @@ int8_t vlan_get(register uint16_t vlan) __banked;
__xdata uint16_t vlan_name(register uint16_t vlan) __banked; __xdata uint16_t vlan_name(register uint16_t vlan) __banked;
void vlan_setup(void) __banked; void vlan_setup(void) __banked;
void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked; void port_pvid_set(uint8_t port, __xdata uint16_t pvid) __banked;
uint16_t port_pvid_get(uint8_t port) __banked;
void vlan_create(void) __banked; void vlan_create(void) __banked;
void vlan_delete(uint16_t vlan) __banked; void vlan_delete(uint16_t vlan) __banked;
void vlan_dump(void) __banked;
void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked; void port_mirror_set(register uint8_t port, __xdata uint16_t rx_pmask, __xdata uint16_t tx_pmask) __banked;
void port_mirror_del(void) __banked; void port_mirror_del(void) __banked;
void port_ingress_filter(__xdata uint8_t port, __xdata uint8_t type) __banked; bool port_ingress_filter(__xdata uint8_t port, __xdata vlan_ingress_mode_t type) __banked;
void port_l2_setup(void) __banked; void port_l2_setup(void) __banked;
void port_lag_members_set(__xdata uint8_t lag, __xdata uint16_t members) __banked; void port_lag_members_set(__xdata uint8_t lag, __xdata uint16_t members) __banked;
void port_lag_hash_set(__xdata uint8_t lag, __xdata uint8_t hash) __banked; void port_lag_hash_set(__xdata uint8_t lag, __xdata uint8_t hash) __banked;
@@ -42,4 +58,10 @@ void port_eee_status_all(void) __banked;
void port_eee_enable(__xdata uint8_t port, __xdata uint8_t speed) __banked; void port_eee_enable(__xdata uint8_t port, __xdata uint8_t speed) __banked;
void port_eee_disable(uint8_t port) __banked; void port_eee_disable(uint8_t port) __banked;
void port_eee_status(uint8_t port) __banked; void port_eee_status(uint8_t port) __banked;
void print_port_ingress_filter_mode(vlan_ingress_mode_t mode) __banked;
bool port_ingress_vlan_filter_set(__xdata uint8_t port, __xdata bool enabled) __banked;
bool port_ingress_vlan_filter_get(__xdata uint8_t port) __banked;
void port_isolate(register uint8_t port, __xdata uint16_t pmask) __banked;
uint16_t port_isolation_get(register uint8_t port) __banked;
#endif #endif
+4 -4
View File
@@ -62,7 +62,7 @@ struct stp_pkt_in {
uint8_t stp_addr[6]; uint8_t stp_addr[6];
uint8_t src_addr[6]; uint8_t src_addr[6];
struct rtl_tag rtl_tag; struct rtl_tag rtl_tag;
uint8_t vtag[4]; struct vlan_tag vlan_tag;
uint16_t msg_len; uint16_t msg_len;
uint8_t dsap; uint8_t dsap;
uint8_t ssap; uint8_t ssap;
@@ -82,7 +82,7 @@ struct stp_pkt_in {
uint16_t fwd_delay; uint16_t fwd_delay;
}; };
#define STP_O ((__xdata struct stp_pkt *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE]) #define STP_O ((__xdata struct stp_pkt *)&uip_buf[RTL_FRAME_DESC_SIZE])
#define STP_I ((__xdata struct stp_pkt_in *)&uip_buf[0]) #define STP_I ((__xdata struct stp_pkt_in *)&uip_buf[0])
#define FLAG_PROPOSAL 0x02 #define FLAG_PROPOSAL 0x02
@@ -149,8 +149,8 @@ void stp_cnf_send(uint8_t port)
STP_O->stp_addr[0] = 0x01; STP_O->stp_addr[1] = 0x80; STP_O->stp_addr[2] = 0xc2; STP_O->stp_addr[0] = 0x01; STP_O->stp_addr[1] = 0x80; STP_O->stp_addr[2] = 0xc2;
STP_O->stp_addr[3] = STP_O->stp_addr[4] = STP_O->stp_addr[5] = 0x00; STP_O->stp_addr[3] = STP_O->stp_addr[4] = STP_O->stp_addr[5] = 0x00;
STP_O->rtl_tag.tag = HTONS(0x8899); STP_O->rtl_tag.tag = HTONS(RTL_FRAME_TAG_ID);
STP_O->rtl_tag.version = 0x04; STP_O->rtl_tag.version = RTL_FRAME_TAG_VERSION;
STP_O->rtl_tag.reason = 0x00; STP_O->rtl_tag.reason = 0x00;
STP_O->rtl_tag.flags = 0x0020; // Disable L2 learning STP_O->rtl_tag.flags = 0x0020; // Disable L2 learning
STP_O->rtl_tag.pmask = HTONS(((uint16_t)1) << port); STP_O->rtl_tag.pmask = HTONS(((uint16_t)1) << port);
+173 -270
View File
@@ -15,6 +15,7 @@
#include "rtl837x_igmp.h" #include "rtl837x_igmp.h"
#include "rtl837x_leds.h" #include "rtl837x_leds.h"
#include "rtl837x_bandwidth.h" #include "rtl837x_bandwidth.h"
#include "rtl837x_init.h"
#include "dhcp.h" #include "dhcp.h"
#include "cmd_parser.h" #include "cmd_parser.h"
#include "cmd_editor.h" #include "cmd_editor.h"
@@ -23,13 +24,17 @@
#include "uip/uip_arp.h" #include "uip/uip_arp.h"
#include "machine.h" #include "machine.h"
#include "phy.h" #include "phy.h"
#include "crypto/chacha.h"
extern __code const struct machine machine; extern __code const struct machine machine;
extern __xdata uint32_t flash_size; extern __xdata uint32_t flash_size;
extern __xdata uint8_t err_status;
extern __xdata uint16_t crc_value; extern __xdata uint16_t crc_value;
__xdata struct machine_runtime machine_detected; __xdata struct machine_runtime machine_detected;
void crc16(__xdata uint8_t *v) __naked; void crc16(__xdata uint8_t *v) __naked;
void flash_default_config(void);
void early_boot_handle_button(void);
// See setup_serial_timer1() for valid baudrate settings! // See setup_serial_timer1() for valid baudrate settings!
#define SERIAL_BAUD_RATE 115200 #define SERIAL_BAUD_RATE 115200
@@ -95,6 +100,7 @@ extern __xdata struct dhcp_state dhcp_state;
__xdata volatile uint8_t sbuf_ptr; __xdata volatile uint8_t sbuf_ptr;
__xdata uint8_t sbuf[SBUF_SIZE]; __xdata uint8_t sbuf[SBUF_SIZE];
// Registry data in sfr is in *big endian* order, so sfr_data[0] is the MSB and sfr_data[3] the LSB
__xdata uint8_t sfr_data[4]; __xdata uint8_t sfr_data[4];
extern __xdata uint8_t gpio_last_value[8]; extern __xdata uint8_t gpio_last_value[8];
@@ -124,6 +130,9 @@ __code uint16_t bit_mask[16] = {
__xdata uint8_t linkbits_last[4]; __xdata uint8_t linkbits_last[4];
__xdata uint8_t linkbits_last_p89; __xdata uint8_t linkbits_last_p89;
// Last known state of the SFP detection/Loss of Signal pins
// SFP1 b0 = 1 => module missing, b1 = 1 => LOS;
// SFP2 b4 = 1 => module missing, b5 = 1 => LOS;
__xdata uint8_t sfp_pins_last; __xdata uint8_t sfp_pins_last;
__xdata char sfp_module_vendor[2][17]; __xdata char sfp_module_vendor[2][17];
__xdata char sfp_module_model[2][17]; __xdata char sfp_module_model[2][17];
@@ -131,10 +140,51 @@ __xdata char sfp_module_serial[2][17];
__xdata uint8_t sfp_options[2]; __xdata uint8_t sfp_options[2];
__xdata bool button_last; __xdata bool button_last;
__xdata uint8_t button_sec_counter_last; __xdata uint8_t button_sec_counter_last;
__sbit tx_buf_empty; volatile __bit tx_buf_empty;
struct eth_in {
struct uip_eth_addr dst;
struct uip_eth_addr src;
struct rtl_tag rtl_tag;
struct vlan_tag vlan_tag;
u16_t ether_type;
};
// Dot 1Q tag size is the size of tpid + tci
#define DOT_1Q_TAG_SIZE 4
struct q_frame {
uint8_t tx_seq;
uint8_t chksum_flags; // 0x7 enables Checksums for frame header, L2 and L3
uint8_t reserved_1 [2];
uint16_t len; // Length is Little Endian
uint8_t reserved_2 [2];
struct uip_eth_addr dst;
struct uip_eth_addr src;
uint16_t tpid;
uint16_t tci;
};
struct nonq_frame {
uint8_t padding[DOT_1Q_TAG_SIZE];
uint8_t tx_seq;
uint8_t chksum_flags; // 0x7 enables Checksums for frame header, L2 and L3
uint8_t reserved_1 [2];
uint16_t len; // Length is Little Endian
uint8_t reserved_2 [2];
struct uip_eth_addr dst;
struct uip_eth_addr src;
};
#define ETH_IN ((__xdata struct eth_in *)&uip_buf[0])
#define ETHERTYPE_OFFSET (12 + VLAN_TAG_SIZE + RTL_TAG_SIZE) #define ETHERTYPE_OFFSET (12 + VLAN_TAG_SIZE + RTL_TAG_SIZE)
// The output frame structure with initial frame descriptor including padding
#define FRAME ((__xdata struct nonq_frame *)&uip_buf[0])
// The output frame structure with 802.1Q field and the padding moved before the buffer-start
#define FRAME_Q ((__xdata struct q_frame *)&uip_buf[0])
void isr_timer0(void) __interrupt(1) void isr_timer0(void) __interrupt(1)
{ {
} }
@@ -459,7 +509,7 @@ void reg_bit_clear(uint16_t reg_addr, char bit)
/* /*
* This sets a bit in the 32bit wide switch register reg_addr * This tests a bit in the 32bit wide switch register reg_addr
*/ */
uint8_t reg_bit_test(uint16_t reg_addr, char bit) uint8_t reg_bit_test(uint16_t reg_addr, char bit)
{ {
@@ -551,15 +601,38 @@ void nic_rx_packet(register uint16_t buffer, register uint16_t ring_ptr)
*/ */
void nic_tx_packet(uint16_t ring_ptr) void nic_tx_packet(uint16_t ring_ptr)
{ {
// uint16_t buffer = (uint16_t) tx_buf; uint16_t len;
uint16_t buffer = (uint16_t) uip_buf + VLAN_TAG_SIZE;
SFR_NIC_DATA_U16LE = buffer; /* If we have a management VLAN, we have inserted a dot1Q-tag into the frame and
* the frame starts at the beginning of uip_buf with the RTL TX descriptor,
* otherwise the frame is a normal Ethernet frame which starts with
* an RTL TX descriptor being padded at the beginning, in the second case
* we need to skip the padding for the sending of the frame.
*/
if (management_vlan) {
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 <<= 3;
ring_ptr |= 0x8000; ring_ptr |= 0x8000;
SFR_NIC_RING_U16LE = ring_ptr; SFR_NIC_RING_U16LE = ring_ptr;
uint16_t len = (((uint16_t)uip_buf[VLAN_TAG_SIZE + 5]) << 8) | uip_buf[VLAN_TAG_SIZE + 4];
len += 0xf; len += 0xf;
len >>= 3; len >>= 3;
SFR_NIC_CTRL = len; SFR_NIC_CTRL = len;
@@ -682,7 +755,7 @@ void cpy_4(__xdata uint8_t dest[], __xdata uint8_t source[])
} }
void read_reg_timer(uint32_t * tmr) void read_reg_timer(__xdata uint32_t * tmr)
{ {
uint8_t * val = (uint8_t *)tmr; uint8_t * val = (uint8_t *)tmr;
SFR_REG_ADDR_U16 = RTL837X_REG_SEC_COUNTER; SFR_REG_ADDR_U16 = RTL837X_REG_SEC_COUNTER;
@@ -731,6 +804,64 @@ void delay(uint16_t t)
PCON |= 1; PCON |= 1;
} }
void early_boot_handle_button(void)
{
if (machine.reset_pin == GPIO_NA)
return;
gpio_input_setup(machine.reset_pin);
// Debounce after init
delay(100);
// If the button is not already held at boot, continue normally.
if (gpio_pin_test(machine.reset_pin))
return;
set_sys_led_state(SYS_LED_FAST);
print_string("\n[Reset button held at boot]\n");
if (gpio_pin_test(machine.reset_pin))
return;
const __xdata uint32_t min_hold_ticks = 10UL * SYS_TICK_HZ;
const __xdata uint32_t max_hold_ticks = 30UL * SYS_TICK_HZ;
const __xdata uint32_t blink_ticks = SYS_TICK_HZ / 10; // 100 ms
const __xdata uint32_t pause_ticks = SYS_TICK_HZ / 2; // 500 ms
__xdata uint32_t start_ticks = ticks;
__xdata uint32_t last_blink_step = start_ticks;
__xdata uint8_t blink_step = 0;
set_sys_led_state(SYS_LED_ON);
while (!gpio_pin_test(machine.reset_pin)) {
__xdata uint32_t held_ticks = ticks - start_ticks;
if (held_ticks > max_hold_ticks) {
print_string("[Button held >30s at boot; continuing normal boot]\n");
return;
}
// Double blink pattern while button is held:
// ON (100ms), OFF (100ms), ON (100ms), OFF (500ms)
__xdata uint32_t step_ticks = (blink_step == 3) ? pause_ticks : blink_ticks;
if ((ticks - last_blink_step) >= step_ticks) {
blink_step = (blink_step + 1) & 0x3;
set_sys_led_state((blink_step == 0 || blink_step == 2) ? SYS_LED_ON : SYS_LED_OFF);
last_blink_step = ticks;
}
PCON |= 1;
}
set_sys_led_state(SYS_LED_ON);
if ((ticks - start_ticks) >= min_hold_ticks) {
print_string("[Button held 10s-30s at boot; restoring default config]\n");
set_sys_led_state(SYS_LED_FAST);
flash_default_config();
delay(3UL * SYS_TICK_HZ);
}
}
/* /*
* Configure the SerDes of the SoC for a particular mode * Configure the SerDes of the SoC for a particular mode
@@ -811,7 +942,7 @@ void sds_config(uint8_t sds, uint8_t mode)
if (mode != SDS_QXGMII) if (mode != SDS_QXGMII)
sds_write_v(sds, 0x06, 0x1f, 0x2100); // Q00061f:2100 sds_write_v(sds, 0x06, 0x1f, 0x2100); // Q00061f:2100
if (sds == 0 && mode == SDS_1000BX_FIBER) { if (mode == SDS_1000BX_FIBER) {
sds_write_v(sds, 0x02, 0x04, 0x0020); // Q000204:0020 sds_write_v(sds, 0x02, 0x04, 0x0020); // Q000204:0020
sds_write_v(sds, 0x00, 0x02, 0x73d0); // Q000002:73d0 sds_write_v(sds, 0x00, 0x02, 0x73d0); // Q000002:73d0
sds_write_v(sds, 0x00, 0x04, 0x074d); // Q000004:074d sds_write_v(sds, 0x00, 0x04, 0x074d); // Q000004:074d
@@ -828,9 +959,9 @@ uint8_t sfp_read_reg(uint8_t slot, uint8_t reg)
{ {
if (reg & 0x80) { // Configure SFP readings address (0x51) as I2C device address if (reg & 0x80) { // Configure SFP readings address (0x51) as I2C device address
reg &= 0x7f; reg &= 0x7f;
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 1, 0x51 >> 5, (0x51 << 3) & 0xff); REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 0, 0x51 >> 5, (0x51 << 3) & 0xff);
} else { } else {
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 1, 0x50 >> 5, (0x50 << 3) & 0xff); REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 0, 0x50 >> 5, (0x50 << 3) & 0xff);
} }
reg_read_m(RTL837X_REG_I2C_CTRL); reg_read_m(RTL837X_REG_I2C_CTRL);
@@ -859,26 +990,27 @@ uint8_t sfp_read_reg(uint8_t slot, uint8_t reg)
void tcpip_output(void) void tcpip_output(void)
{ {
// Add TX-TAG // Add TX-TAG
uip_buf[VLAN_TAG_SIZE] = tx_seq++; FRAME->tx_seq = tx_seq++;
uip_buf[VLAN_TAG_SIZE + 1] = 0x07; // Enable all checksums FRAME->chksum_flags = 0x07; // Enable all checksums
uip_buf[VLAN_TAG_SIZE + 5] = uip_len >> 8; FRAME->reserved_1[0] = 0x00; FRAME->reserved_1[1] = 0x00;
uip_buf[VLAN_TAG_SIZE + 4] = uip_len; FRAME->len = uip_len;
uip_buf[VLAN_TAG_SIZE + 2] = uip_buf[VLAN_TAG_SIZE + 3] = 0; FRAME->reserved_2[0] = 0x00; FRAME->reserved_2[1] = 0x00;
uip_buf[VLAN_TAG_SIZE + 6] = uip_buf[VLAN_TAG_SIZE + 7] = 0;
// For the management VLAN we insert an 802.1Q VLAN tag
if (management_vlan) {
// Shift the ethernet header before the HW type including the rtl_frame_desc to the beginning of uip_buf
// to allow space to insert the dot 1Q tag
for (uint8_t i = 0; i < sizeof(struct q_frame) - DOT_1Q_TAG_SIZE; i++)
uip_buf[i] = uip_buf[i + DOT_1Q_TAG_SIZE];
FRAME_Q->len += DOT_1Q_TAG_SIZE;
FRAME_Q->tpid = HTONS(0x8100); // Change ether-type to Dot1Q
FRAME_Q->tci = HTONS(management_vlan);
}
reg_read_m(RTL837X_REG_CPU_TX_CURR_PKT); reg_read_m(RTL837X_REG_CPU_TX_CURR_PKT);
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];
#ifdef RXTXDBG
print_string("TX: \n");
for (uint8_t i = 0; i < 120; i++) {
print_byte(uip_buf[i]);
write_char(' ');
}
write_char('\n');
#endif
// Move data over from xmem buffer to ASIC side using DMA // Move data over from xmem buffer to ASIC side using DMA
nic_tx_packet(ring_ptr); nic_tx_packet(ring_ptr);
@@ -922,14 +1054,13 @@ void handle_rx(void)
REG_SET(RTL837X_REG_NIC_RXCMD, 1); REG_SET(RTL837X_REG_NIC_RXCMD, 1);
uip_len = (((uint16_t)rx_headers[5]) << 8) | rx_headers[4]; uip_len = (((uint16_t)rx_headers[5]) << 8) | rx_headers[4];
// Retrieve VLAN from VLAN-tag rx_packet_vlan = NTOHS(ETH_IN->vlan_tag.vlan) & 0x0fff;
rx_packet_vlan = uip_buf[2 * sizeof (struct uip_eth_addr) + RTL_TAG_SIZE + 2] & 0xf;
rx_packet_vlan <<= 8;
rx_packet_vlan |= uip_buf[2 * sizeof (struct uip_eth_addr) + RTL_TAG_SIZE + 3];
#ifdef RXTXDBG #ifdef RXTXDBG
print_string(" RX-VLAN: "); print_short(rx_packet_vlan); write_char('\n'); print_string(" RX-VLAN: "); print_short(rx_packet_vlan); write_char('\n');
print_string(" RX dst: "); print_byte(uip_buf[0]); print_byte(uip_buf[1]); print_byte(uip_buf[2]); print_string(" RX dst: "); print_byte(uip_buf[0]); print_byte(uip_buf[1]); print_byte(uip_buf[2]);
print_byte(uip_buf[3]); print_byte(uip_buf[4]); print_byte(uip_buf[5]); write_char('\n'); print_byte(uip_buf[3]); print_byte(uip_buf[4]); print_byte(uip_buf[5]); write_char('\n');
print_string(" MGMT-VLAN: "); print_short(management_vlan); write_char('\n');
#endif #endif
if (stpEnabled && uip_buf[0] == 0x01 && uip_buf[1] == 0x80 && uip_buf[2] == 0xc2 // STP packet? if (stpEnabled && uip_buf[0] == 0x01 && uip_buf[1] == 0x80 && uip_buf[2] == 0xc2 // STP packet?
&& uip_buf[3] == 0x00 && uip_buf[4] == 0x00 && uip_buf[5] == 0x00) { && uip_buf[3] == 0x00 && uip_buf[4] == 0x00 && uip_buf[5] == 0x00) {
@@ -944,17 +1075,18 @@ void handle_rx(void)
if (uip_len) { if (uip_len) {
tcpip_output(); tcpip_output();
} }
} else if (uip_buf[ETHERTYPE_OFFSET] == 0x08 && uip_buf[ETHERTYPE_OFFSET + 1] == 0x06) { // ARP? } else if (ETH_IN->ether_type == HTONS(0x0806)) { // ARP
uip_arp_arpin(); uip_arp_arpin();
if (uip_len) { if (uip_len) {
tcpip_output(); tcpip_output();
} }
} else if (uip_buf[ETHERTYPE_OFFSET] == 0x08 && uip_buf[ETHERTYPE_OFFSET + 1] == 0x00) { // IP packet? } else if (ETH_IN->ether_type == HTONS(0x0800)) { // IPv4
if (!management_vlan || management_vlan == rx_packet_vlan) { if (!management_vlan || management_vlan == rx_packet_vlan) {
uip_arp_ipin(); // Learn MAC addresses in TCP packets uip_arp_ipin(); // Learn MAC addresses in TCP packets
uip_input(); uip_input();
if (uip_len) { if (uip_len) {
uip_arp_out(); // Add ethernet frame // Add ethernet frame
uip_arp_out();
tcpip_output(); tcpip_output();
} }
} }
@@ -991,9 +1123,9 @@ void handle_tx(void)
static inline uint8_t sfp_rate_to_sds_config(register uint8_t rate) static inline uint8_t sfp_rate_to_sds_config(register uint8_t rate)
{ {
if (rate == 0xd) if (rate == 0xc || rate == 0xd)
return SDS_1000BX_FIBER; return SDS_1000BX_FIBER;
if (rate == 0x1f) // Ethernet 2.5 GBit if (rate >= 0x19 && rate <= 0x20) // Ethernet 2.5 GBit
return SDS_HSG; return SDS_HSG;
if (rate > 0x65 && rate < 0x70) if (rate > 0x65 && rate < 0x70)
return SDS_10GR; return SDS_10GR;
@@ -1242,7 +1374,8 @@ void idle(void)
// Check whether a command is waiting in the cmd_buffer and execute // Check whether a command is waiting in the cmd_buffer and execute
if (cmd_available) { if (cmd_available) {
cmd_available = 0; cmd_available = 0;
if (!cmd_tokenize()) cmd_tokenize();
if (err_status == ERR_OK)
cmd_parser(); cmd_parser();
print_string("\n> "); print_string("\n> ");
} }
@@ -1470,78 +1603,6 @@ void nic_setup(void)
} }
/*
* Configure the PHY-Side of the SDS-SDS link between SoC and PHY
*/
void sds_init(void)
{
/*
p001e.000d:9535 R02f8-00009535 R02f4-0000953a P000001.1e00000d:953a
p001e.000d:953a p001e.000d:953a R02f8-0000953a R02f4-00009530 P000001.1e00000d:9530
RTL8373:
p001e.000d:0010 R02f8-00000010 R02f4-0000001a P000001.1e00000d:b7fe
p001e.000d:0010 p001e.000d:0010 R02f8-00000010 R02f4-00000010 P000001.1e00000d:b7fe
*/
phy_read(0, PHY_MMD30, 0xd);
uint16_t pval = SFR_DATA_U16;
// PHY Initialization:
REG_WRITE(0x2f8, 0, 0, pval >> 8, pval);
delay(20);
pval &= 0xfff0;
pval |= 0x0a;
REG_WRITE(0x2f4, 0, 0, pval >> 8, pval);
delay(10);
phy_write_mask(0x1, PHY_MMD30, 0xd, pval);
phy_read(0, PHY_MMD30, 0xd);
pval = SFR_DATA_U16;
REG_WRITE(0x2f8, 0, 0, pval >> 8, pval);
pval &= 0xfff0;
REG_WRITE(0x2f4, 0, 0, pval >> 8, pval);
phy_write_mask(0x1, PHY_MMD30, 0xd, pval);
if (machine_detected.isN) {
uint16_t pval;
print_string(" N-settings");
// Serdes 0 RX PN swap for 64B/66B
sds_read(1, 6, 2);
pval = SFR_DATA_U16;
sds_write_v(1, 6, 2, pval | 0x2000);
// Serdes 1 RX PN swap for 8B/10B
sds_read(1, 0, 0);
pval = SFR_DATA_U16;
sds_write_v(1, 0, 0, pval | 0x200);
// Serdes 0 RX PN swap for 64B/66B
sds_read(0, 6, 2);
pval = SFR_DATA_U16;
sds_write_v(0, 6, 2, pval | 0x2000);
if (machine_detected.isRTL8373) {
// RTL8224: Serdes 0 RX PN swap for 64B/66B
// We assume that RTL8373N always paired with RTL8224N.
// This sds register value is 0x0000 at reset.
// So only write to it.
RTL8224_SDS_WRITE(0, 6, 2, 0x2000);
} else {
// Serdes 0 RX PN swap for 8B/10B
sds_read(0, 0, 0);
pval = SFR_DATA_U16;
sds_write_v(0, 0, 0, pval | 0x200);
}
}
}
void set_sys_led_state(uint8_t state) void set_sys_led_state(uint8_t state)
{ {
reg_read_m(RTL837X_REG_LED_MODE); reg_read_m(RTL837X_REG_LED_MODE);
@@ -1563,167 +1624,6 @@ void rtl8373_revision(void)
} }
void rtl8373_init(void)
{
print_string("\nrtl8373_init called\n");
// r65d8:3ffbedff R65d8-3ffbedff
reg_bit_set(0x65d8, 0x1d);
sds_init();
// Disable all SERDES for configuration
REG_SET(RTL837X_REG_SDS_MODES, 0x000037ff);
// q000601:c800 Q000601:c804 q000601:c804 Q000601:c800
sds_read(0, 0x06, 0x01);
uint16_t pval = SFR_DATA_U16;
sds_write_v(0, 0x06, 0x01, pval | 0x04);
delay(50);
sds_read(0, 0x06, 0x01);
pval = SFR_DATA_U16;
sds_write_v(0, 0x06, 0x01, pval & 0xfffb);
phy_config_8224();
sds_config_mac(1, SDS_OFF); // Off for now until SFP+ port used
sds_config_mac(2, SDS_SGMII); // For RTL8224
sds_config(0, SDS_QXGMII);
// SDS 1 setup
// q012100:4902 Q012100:4906 q013605:0000 Q013605:4000 Q011f02:001f q011f15:0086
sds_write_v(1, 0x21, 0x00, 0x4906);
sds_write_v(1, 0x36, 0x05, 0x4000);
sds_write_v(1, 0x1f, 0x02, 0x001f);
sds_read(1, 0x1f, 0x15);
pval = SFR_DATA_U16;
// r0a90:000000f3 R0a90-000000fc
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
sfr_mask_data(0, 0x0f,0x0c);
reg_write_m(RTL837X_CFG_PHY_MDI_REVERSE);
if (machine_detected.isN) {
print_string(" TX_POLARITY_SWAP\n");
// FOR N-Version: #TX_POLARITY_SWAP
reg_read_m(RTL837X_CFG_PHY_TX_POLARITY_SWAP);
sfr_data[2] = 0x59;
sfr_data[3] = 0x6a;
reg_write_m(RTL837X_CFG_PHY_TX_POLARITY_SWAP);
}
rtl8224_phy_enable();
// Disable PHYs for configuration
phy_write_mask(0xff,PHY_MMD31,0xa610,0x2858);
// Set bits 0x13 and 0x14 of 0x5fd4
// r5fd4:0002914a R5fd4-001a914a
reg_bit_set(0x5fd4, 0x13);
reg_bit_set(0x5fd4, 0x14);
// Configure ports
uint16_t reg = 0x1238; // Port base register for the bits we set
for (char i = 0; i < 9; i++) {
// Bit 7 (0x40) enables replacement of the RTL-VLAN tag with an 802.1Q VLAN tag
REG_SET(reg, 0xe77);
reg += 0x100;
}
// r0b7c:000000d8 R0b7c-000000f8 r6040:00000030 R6040-00000031
reg_bit_set(0xb7c, 5);
// R7124-00001050 R7128-00001050 R712c-00001050 R7130-00001050 R7134-00001050 R7138-00001050
// R713c-00001050 R7140-00001050 R7144-00001050 R7148-00001050
REG_SET(0x7124, 0x1050); REG_SET(0x7128, 0x1050); REG_SET(0x712c, 0x1050);
REG_SET(0x7130, 0x1050); REG_SET(0x7134, 0x1050); REG_SET(0x7138, 0x1050);
REG_SET(0x713c, 0x1050); REG_SET(0x7140, 0x1050); REG_SET(0x7144, 0x1050);
REG_SET(0x7148, 0x1050);
reg_bit_set(RTL837X_REG_HW_CONF, 0);
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
// TODO: patch the PHYs
// Re-enable PHY after configuration
phy_write_mask(0xff,PHY_MMD31,0xa610,0x2058);
// Enables MAC access
// Set bits 0xc-0x14 of 0x632c to 0x1f8, see rtl8372_init
// r632c:00000540 R632c-001f8540 // RTL8373: 001ff540
reg_read_m(0x632c);
sfr_mask_data(1, 0x70, 0xf0); // The ports of the RTL8824
sfr_mask_data(2, 0x10, 0x1f);
reg_write_m(0x632c);
print_string("\nrtl8373_init done\n");
}
void rtl8372_init(void)
{
print_string("\nrtl8372_init called\n");
sds_init();
phy_config(8); // PHY configuration: External 8221B?
phy_config(3); // PHY configuration: all internal PHYs?
// Set the MAC SerDes Modes Bits 0-4: SDS 0 = 0x2 (0x2), Bits 5-9: SDS 1: 1f (off)
// r7b20:00000bff R7b20-00000bff r7b20:00000bff R7b20-00000bff r7b20:00000bff R7b20-000003ff r7b20:000003ff R7b20-000003e2 r7b20:000003e2 R7b20-000003e2
reg_read_m(RTL837X_REG_SDS_MODES);
sfr_mask_data(1, 0, 0x03);
sfr_mask_data(0, 0, 0xe2);
reg_write_m(RTL837X_REG_SDS_MODES);
// r0a90:000000f3 R0a90-000000fc
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
sfr_mask_data(0, 0x0f, 0x0c);
reg_write_m(RTL837X_CFG_PHY_MDI_REVERSE);
// Disable PHYs for configuration
phy_write_mask(0xf0,PHY_MMD31,0xa610,0x2858);
// Set bits 0x13 and 0x14 of 0x5fd4
// r5fd4:0002914a R5fd4-001a914a
reg_bit_set(0x5fd4, 0x13);
reg_bit_set(0x5fd4, 0x14);
// Configure ports 3-8:
//
// r1538:00000e33 R1538-00000e37 r1538:00000e37 R1538-00000e37 r1538:00000e37 R1538-00000f37
// [...]
///
uint16_t reg = 0x1238 + 0x300; // Port base register for the bits we set
for (char i = machine.min_port; i <= machine.max_port; i++) {
// Bit 7 (0x40) enables replacement of the RTL-VLAN tag with an 802.1Q VLAN tag
REG_SET(reg, 0xe77);
reg += 0x100;
}
// r0b7c:000000d8 R0b7c-000000f8 r6040:00000030 R6040-00000031
reg_bit_set(0xb7c, 5);
reg_bit_set(RTL837X_REG_HW_CONF, 0);
// enable EEE for all ports at 2.5G and 10G, but don't reset the PHYs
port_eee_enable_all(EEE_2G5 | EEE_NORESET);
// TODO: patch the PHYs
// Re-enable PHY after configuration
phy_write_mask(0xf0,PHY_MMD31,0xa610,0x2058);
// Enables MAC access
// Set bits 0xc-0x14 of 0x632c to 0x1f8, see rtl8372_init
// r632c:00000540 R632c-001f8540 // RTL8373: 001ff540
reg_read_m(0x632c);
sfr_mask_data(1, 0x70, 0x80);
sfr_mask_data(2, 0x10, 0x1f);
reg_write_m(0x632c);
print_string("\nrtl8372_init done\n");
}
/* /*
* The SoC manages Link-State for steering the LEDs and can set PHY-settings * The SoC manages Link-State for steering the LEDs and can set PHY-settings
* automatically through Realtek's SMI (Simple Managagement) Interface, a * automatically through Realtek's SMI (Simple Managagement) Interface, a
@@ -1909,7 +1809,7 @@ void check_and_flash_update_image(void)
__xdata uint16_t i = 0; __xdata uint16_t i = 0;
__xdata uint16_t j = 0; __xdata uint16_t j = 0;
__xdata uint8_t * __xdata bptr; __xdata uint8_t * __xdata bptr;
print_string("found update image! Checking integrity"); print_string("found update image!\nChecking integrity");
flash_init(0); // Re-initialize flash for non-DIO operation, otherwise flashing will fail flash_init(0); // Re-initialize flash for non-DIO operation, otherwise flashing will fail
set_sys_led_state(SYS_LED_FAST); set_sys_led_state(SYS_LED_FAST);
crc_value = 0x0000; crc_value = 0x0000;
@@ -2113,7 +2013,7 @@ void main(void)
uip_arp_init(); uip_arp_init();
httpd_init(); httpd_init();
management_vlan = 0; // Disabled management_vlan = 1; // Default management VLAN is 1
setup_i2c(); setup_i2c();
setup_sfp_gpio(); setup_sfp_gpio();
@@ -2129,6 +2029,8 @@ void main(void)
// p031f.a610:2058 p041f.a610:2058 p051f.a610:2058 r4f3c:00000000 p061f.a610:2058 p071f.a610:2058 // p031f.a610:2058 p041f.a610:2058 p051f.a610:2058 r4f3c:00000000 p061f.a610:2058 p071f.a610:2058
port_stats_print(); port_stats_print();
early_boot_handle_button();
execute_config(); execute_config();
print_string("\n> "); print_string("\n> ");
idle_ready = 1; idle_ready = 1;
@@ -2136,6 +2038,7 @@ void main(void)
set_sys_led_state(SYS_LED_ON); set_sys_led_state(SYS_LED_ON);
cmd_editor_init(); cmd_editor_init();
while (1) { while (1) {
cmd_edit(); cmd_edit();
idle(); // Enter Idle mode until interrupt occurs idle(); // Enter Idle mode until interrupt occurs
+9 -9
View File
@@ -1,27 +1,27 @@
CC = gcc CC = gcc
CCFLAGS = -Wall -o CCFLAGS = -Wall -o
BUILDDIR = output/ BUILDDIR = output
all: create_build_dir $(BUILDDIR)injector $(BUILDDIR)fileadder $(BUILDDIR)httpd_sim\ all: create_build_dir $(BUILDDIR)/injector $(BUILDDIR)/fileadder $(BUILDDIR)/httpd_sim\
$(BUILDDIR)crc_calculator $(BUILDDIR)imagebuilder $(BUILDDIR)/crc_calculator $(BUILDDIR)/imagebuilder
create_build_dir: create_build_dir:
mkdir -p $(BUILDDIR) mkdir -p $(BUILDDIR)
clean: clean:
rm -r $(BUILDDIR) rm -rf $(BUILDDIR)
$(BUILDDIR)injector: injector.c $(BUILDDIR)/injector: injector.c
gcc $^ $(CCFLAGS) $@ gcc $^ $(CCFLAGS) $@
$(BUILDDIR)fileadder: fileadder.c $(BUILDDIR)/fileadder: fileadder.c
gcc $^ $(CCFLAGS) $@ gcc $^ $(CCFLAGS) $@
$(BUILDDIR)crc_calculator: crc_calculator.c $(BUILDDIR)/crc_calculator: crc_calculator.c
gcc $^ $(CCFLAGS) $@ gcc $^ $(CCFLAGS) $@
$(BUILDDIR)httpd_sim: httpd_sim.c httpd_sim.h $(BUILDDIR)/httpd_sim: httpd_sim.c httpd_sim.h
gcc $< $(CCFLAGS) $@ -I/usr/include/json-c -ljson-c gcc $< $(CCFLAGS) $@ -I/usr/include/json-c -ljson-c
$(BUILDDIR)imagebuilder: imagebuilder.c $(BUILDDIR)/imagebuilder: imagebuilder.c
gcc $^ $(CCFLAGS) $@ gcc $^ $(CCFLAGS) $@
+1 -2
View File
@@ -121,8 +121,7 @@ void send_basic_info(int socket)
{ {
char *response = "HTTP/1.1 200 OK\r\n" char *response = "HTTP/1.1 200 OK\r\n"
"Content-Type: application/json; charset=UTF-8\r\n\r\n" "Content-Type: application/json; charset=UTF-8\r\n\r\n"
"{\"ip_address\":\"192.168.10.247\",\"ip_gateway\":\"192.168.2.22\",\"ip_netmask\":\"255.255.255.0\",\"mac_address\":\"1c:2a:a3:23:00:02\",\"sw_ver\":\"" VERSION_SW "\",\"hw_ver\":\"SWGT024-V2.0\"" "{\"ip_address\":\"192.168.10.247\",\"ip_gateway\":\"192.168.2.22\",\"ip_netmask\":\"255.255.255.0\",\"mac_address\":\"1c:2a:a3:23:00:02\",\"sw_ver\":\"" VERSION_SW "\",\"hw_ver\":\"SWGT024-V2.0\"}";
",\"dhcp_client\":1,\"dhcp_server\":0}";
write(socket, response, strlen(response)); write(socket, response, strlen(response));
} }
+5 -5
View File
@@ -91,7 +91,7 @@ int main(int argc, char **argv)
} }
int nbanks = (filesize - BANK0_SIZE) / BANK_STRIDE; int nbanks = (filesize - BANK0_SIZE) / BANK_STRIDE;
printf("Input file contains %d banks\n", nbanks); printf("Input file contains %d banks\n", nbanks+1);
/* Verify the size of banks in input file: /* Verify the size of banks in input file:
* Bank 0: 0x00002 - 0x04000 <- 0x00000 - 0x03ffe * Bank 0: 0x00002 - 0x04000 <- 0x00000 - 0x03ffe
@@ -112,15 +112,15 @@ int main(int argc, char **argv)
} }
for (int b = BANK0_SIZE; b < BANK_STRIDE + BANK0_SIZE; b ++) { for (int b = BANK0_SIZE; b < BANK_STRIDE + BANK0_SIZE; b ++) {
if (buffer[b]) { if (buffer[b]) {
printf("WARNING: Bank 0: code segment too large at 0x%x!\n", b); printf("Error: Bank 0: code segment too large at 0x%x!\n", b);
break; return 5;
} }
} }
for (int bank = 1; bank <= nbanks; bank++) { for (int bank = 1; bank <= nbanks; bank++) {
for (int b = (bank + 1) * BANK_STRIDE; b < (bank + 1) * BANK_STRIDE + BANK0_SIZE; b ++) { for (int b = (bank + 1) * BANK_STRIDE; b < (bank + 1) * BANK_STRIDE + BANK0_SIZE; b ++) {
if (buffer[b]) { if (buffer[b]) {
printf("WARNING: Bank %d: code segment too large at 0x%x!\n", bank, b); printf("Error: Bank %d: code segment too large at 0x%x!\n", bank, b);
break; return 5;
} }
} }
} }
-26
View File
@@ -1,26 +0,0 @@
CC = sdcc
CC_FLAGS = -mmcs51 -I. -I.. -I../httpd
ASM = sdas8051
AFLAGS= -plosgff
BUILDDIR = output/
SRCS = timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-split.c
OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel}
all: create_build_dir $(OBJS)
create_build_dir:
mkdir -p $(BUILDDIR)
$(BUILDDIR)%.rel: %.c
$(CC) $(CC_FLAGS) -o $@ -c $<
$(BUILDDIR)%.rel: $(BUILDDIR)%.asm
${ASM} ${AFLAGS} $^
clean:
rm -r $(BUILDDIR)
.PHONY: all clean
+4 -4
View File
@@ -64,7 +64,7 @@
* *
*/ */
void void
timer_set(struct timer *t, clock_time_t interval) timer_set(__xdata struct timer *t, clock_time_t interval)
{ {
t->interval = interval; t->interval = interval;
t->start = clock_time(); t->start = clock_time();
@@ -84,7 +84,7 @@ timer_set(struct timer *t, clock_time_t interval)
* \sa timer_restart() * \sa timer_restart()
*/ */
void void
timer_reset(struct timer *t) timer_reset(__xdata struct timer *t)
{ {
t->start += t->interval; t->start += t->interval;
} }
@@ -104,7 +104,7 @@ timer_reset(struct timer *t)
* \sa timer_reset() * \sa timer_reset()
*/ */
void void
timer_restart(struct timer *t) timer_restart(__xdata struct timer *t)
{ {
t->start = clock_time(); t->start = clock_time();
} }
@@ -121,7 +121,7 @@ timer_restart(struct timer *t)
* *
*/ */
int int
timer_expired(struct timer *t) timer_expired(__xdata struct timer *t)
{ {
return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval; return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval;
} }
+4 -4
View File
@@ -76,10 +76,10 @@ struct timer {
clock_time_t interval; clock_time_t interval;
}; };
void timer_set(struct timer *t, clock_time_t interval); void timer_set(__xdata struct timer *t, clock_time_t interval);
void timer_reset(struct timer *t); void timer_reset(__xdata struct timer *t);
void timer_restart(struct timer *t); void timer_restart(__xdata struct timer *t);
int timer_expired(struct timer *t); int timer_expired(__xdata struct timer *t);
#endif /* __TIMER_H__ */ #endif /* __TIMER_H__ */
+6 -10
View File
@@ -241,7 +241,7 @@ __xdata struct uip_stats uip_stat;
#if ! UIP_ARCH_ADD32 #if ! UIP_ARCH_ADD32
void void
uip_add32(u8_t *op32, u16_t op16) uip_add32(u8_t __xdata * op32, u16_t op16)
{ {
uip_acc32[3] = op32[3] + (op16 & 0xff); uip_acc32[3] = op32[3] + (op16 & 0xff);
uip_acc32[2] = op32[2] + (op16 >> 8); uip_acc32[2] = op32[2] + (op16 >> 8);
@@ -465,8 +465,8 @@ uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banke
#endif /* UIP_ACTIVE_OPEN */ #endif /* UIP_ACTIVE_OPEN */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#if UIP_UDP #if UIP_UDP
struct uip_udp_conn * __xdata struct uip_udp_conn *
uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked uip_udp_new(__xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banked
{ {
__xdata struct uip_udp_conn *conn; __xdata struct uip_udp_conn *conn;
@@ -919,7 +919,7 @@ uip_process(u8_t flag) __banked
/* Check if we have a DHCP packet, otherwise check if the packet is destined for our IP address. */ /* Check if we have a DHCP packet, otherwise check if the packet is destined for our IP address. */
#if !UIP_CONF_IPV6 #if !UIP_CONF_IPV6
if(!(BUF->proto == UIP_PROTO_UDP && (UDPBUF->destport == HTONS(DHCP_CLIENT_PORT) || UDPBUF->destport == HTONS(DHCP_SERVER_PORT)) )) { if(!(BUF->proto == UIP_PROTO_UDP && UDPBUF->destport == HTONS(DHCPC_CLIENT_PORT))) {
if(!uip_ipaddr_cmpx(BUF->destipaddr, uip_hostaddr)) { if(!uip_ipaddr_cmpx(BUF->destipaddr, uip_hostaddr)) {
UIP_STAT(++uip_stat.ip.drop); UIP_STAT(++uip_stat.ip.drop);
goto drop; goto drop;
@@ -938,11 +938,7 @@ uip_process(u8_t flag) __banked
} }
#endif /* UIP_CONF_IPV6 */ #endif /* UIP_CONF_IPV6 */
} }
// If we serve only the designated DHCPD-VLAN, we drop the packet if not in that VLAN
if(BUF->proto == UIP_PROTO_UDP && dhcpd_vlan && UDPBUF->destport == HTONS(DHCP_SERVER_PORT) && dhcpd_vlan != rx_packet_vlan) {
UIP_STAT(++uip_stat.ip.drop);
goto drop;
}
#if !UIP_CONF_IPV6 #if !UIP_CONF_IPV6
// if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header // if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
// checksum. */ // checksum. */
@@ -1905,7 +1901,7 @@ htons(u16_t val)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
uip_send(register __xdata const void *data, register uint16_t len) __banked uip_send(__xdata const void *data, __xdata uint16_t len) __banked
{ {
if(len > 0) { if(len > 0) {
uip_slen = len; uip_slen = len;
+9 -7
View File
@@ -495,7 +495,7 @@ void uip_unlisten(u16_t port) __banked;
* or NULL if no connection could be allocated. * or NULL if no connection could be allocated.
* *
*/ */
__xdata struct uip_conn *uip_connect(register __xdata uip_ipaddr_t *ripaddr, __xdata u16_t port) __banked; __xdata struct uip_conn *uip_connect(__xdata uip_ipaddr_t *ripaddr, __xdata u16_t port) __banked;
@@ -535,7 +535,7 @@ __xdata struct uip_conn *uip_connect(register __xdata uip_ipaddr_t *ripaddr, __x
* *
* \hideinitializer * \hideinitializer
*/ */
void uip_send(register __xdata const void *data, register uint16_t len) __banked; void uip_send(__xdata const void *data, __xdata uint16_t len) __banked;
/** /**
* The length of any incoming data that is currently avaliable (if avaliable) * The length of any incoming data that is currently avaliable (if avaliable)
@@ -763,7 +763,7 @@ void uip_send(register __xdata const void *data, register uint16_t len) __banked
* \return The uip_udp_conn structure for the new connection or NULL * \return The uip_udp_conn structure for the new connection or NULL
* if no connection could be allocated. * if no connection could be allocated.
*/ */
struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked; __xdata struct uip_udp_conn *uip_udp_new(__xdata uip_ipaddr_t *ripaddr, __xdata u16_t rport) __banked;
/** /**
* Removed a UDP connection. * Removed a UDP connection.
@@ -880,8 +880,8 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked;
*/ */
#if !UIP_CONF_IPV6 #if !UIP_CONF_IPV6
#define uip_ipaddr_copy(dest, src) do { \ #define uip_ipaddr_copy(dest, src) do { \
((u16_t *)dest)[0] = ((u16_t *)src)[0]; \ ((__xdata u16_t *)dest)[0] = ((__xdata u16_t *)src)[0]; \
((u16_t *)dest)[1] = ((u16_t *)src)[1]; \ ((__xdata u16_t *)dest)[1] = ((__xdata u16_t *)src)[1]; \
} while(0) } while(0)
#else /* !UIP_CONF_IPV6 */ #else /* !UIP_CONF_IPV6 */
#define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t)) #define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t))
@@ -908,8 +908,8 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked;
* \hideinitializer * \hideinitializer
*/ */
#if !UIP_CONF_IPV6 #if !UIP_CONF_IPV6
#define uip_ipaddr_cmp(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \ #define uip_ipaddr_cmp(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__xdata u16_t *)addr2)[0] && \
((__xdata u16_t *)addr1)[1] == ((u16_t *)addr2)[1]) ((__xdata u16_t *)addr1)[1] == ((__xdata u16_t *)addr2)[1])
#define uip_ipaddr_cmpx(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__xdata u16_t *)addr2)[0] && \ #define uip_ipaddr_cmpx(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__xdata u16_t *)addr2)[0] && \
((__xdata u16_t *)addr1)[1] == ((__xdata u16_t *)addr2)[1]) ((__xdata u16_t *)addr1)[1] == ((__xdata u16_t *)addr2)[1])
#define uip_ipaddr_cmpc(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__code u16_t *)addr2)[0] && \ #define uip_ipaddr_cmpc(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__code u16_t *)addr2)[0] && \
@@ -1070,8 +1070,10 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) __banked;
#ifndef HTONS #ifndef HTONS
# if UIP_BYTE_ORDER == UIP_BIG_ENDIAN # if UIP_BYTE_ORDER == UIP_BIG_ENDIAN
# define HTONS(n) (n) # define HTONS(n) (n)
# define NTOHS(n) (n)
# else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ # else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
# define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8)) # define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))
# define NTOHS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))
# endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ # endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
#else #else
#error "HTONS already defined!" #error "HTONS already defined!"
+1 -1
View File
@@ -81,7 +81,7 @@
* *
* \param op16 A 16-bit integer in host byte order. * \param op16 A 16-bit integer in host byte order.
*/ */
void uip_add32(u8_t *op32, u16_t op16); void uip_add32(__xdata u8_t * op32, u16_t op16);
/** /**
* Calculate the Internet checksum over a buffer. * Calculate the Internet checksum over a buffer.
+20 -41
View File
@@ -68,7 +68,8 @@
struct arp_hdr_i { struct arp_hdr_i {
struct uip_eth_hdr ethhdr; struct uip_eth_hdr ethhdr;
uint8_t rtl_tag[RTL_TAG_SIZE + VLAN_TAG_SIZE]; struct rtl_tag rtl_tag;
struct vlan_tag vlan_tag;
u16_t hwtype; u16_t hwtype;
u16_t protocol; u16_t protocol;
u8_t hwlen; u8_t hwlen;
@@ -93,7 +94,7 @@ struct arp_hdr_o {
u16_t dipaddr[2]; u16_t dipaddr[2];
}; };
struct ethip_hdr_o { struct ethip_hdr {
struct uip_eth_hdr ethhdr; struct uip_eth_hdr ethhdr;
/* IP header. */ /* IP header. */
u8_t vhl, u8_t vhl,
@@ -106,24 +107,6 @@ struct ethip_hdr_o {
u16_t ipchksum; u16_t ipchksum;
u16_t srcipaddr[2], u16_t srcipaddr[2],
destipaddr[2]; destipaddr[2];
u16_t sport, dport;
};
struct ethip_hdr_i {
struct uip_eth_hdr ethhdr;
struct rtl_tag rtl_tag;
/* IP header. */
u8_t vhl,
tos,
len[2],
ipid[2],
ipoffset[2],
ttl,
proto;
u16_t ipchksum;
u16_t srcipaddr[2],
destipaddr[2];
u16_t sport, dport;
}; };
#define ARP_REQUEST 1 #define ARP_REQUEST 1
@@ -149,9 +132,8 @@ static __xdata u8_t arptime;
static __xdata u8_t tmpage; static __xdata u8_t tmpage;
#define BUF ((__xdata struct arp_hdr_i *)&uip_buf[0]) #define BUF ((__xdata struct arp_hdr_i *)&uip_buf[0])
#define BUF_O ((__xdata struct arp_hdr_o *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE]) #define BUF_O ((__xdata struct arp_hdr_o *)&uip_buf[RTL_FRAME_DESC_SIZE])
#define IPBUF_I ((__xdata struct ethip_hdr_i *)&uip_buf[0]) #define IPBUF ((__xdata struct ethip_hdr *)&uip_buf[RTL_FRAME_DESC_SIZE])
#define IPBUF_O ((__xdata struct ethip_hdr_o *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE])
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/** /**
* Initialize the ARP module. * Initialize the ARP module.
@@ -257,26 +239,27 @@ uip_arp_update(__xdata u16_t *ipaddr, __xdata struct uip_eth_addr *ethaddr)
* variable uip_len. * variable uip_len.
*/ */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
#if 0
void void
uip_arp_ipin(void) __banked uip_arp_ipin(void)
{ {
uip_len -= sizeof(struct uip_eth_hdr); uip_len -= sizeof(struct uip_eth_hdr);
/* Only insert/update an entry if the source IP address of the /* Only insert/update an entry if the source IP address of the
incoming IP packet comes from a host on the local network. */ incoming IP packet comes from a host on the local network. */
if((IPBUF_I->srcipaddr[0] & uip_netmask[0]) != if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
(uip_hostaddr[0] & uip_netmask[0])) { (uip_hostaddr[0] & uip_netmask[0])) {
return; return;
} }
if((IPBUF_I->srcipaddr[1] & uip_netmask[1]) != if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
(uip_hostaddr[1] & uip_netmask[1])) { (uip_hostaddr[1] & uip_netmask[1])) {
return; return;
} }
uip_arp_update(IPBUF_I->srcipaddr, &(IPBUF_I->ethhdr.src)); uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
return; return;
} }
#endif /* 0 */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/** /**
* ARP processing for incoming ARP packets. * ARP processing for incoming ARP packets.
@@ -320,7 +303,8 @@ uip_arp_arpin(void) __banked
with this host in the future. */ with this host in the future. */
uip_arp_update(BUF->sipaddr, &BUF->shwaddr); uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
BUF_O->opcode = HTONS(ARP_REPLY); /* The reply opcode is 2. */
BUF_O->opcode = HTONS(2);
memcpy(BUF_O->dhwaddr.addr, BUF->shwaddr.addr, 6); memcpy(BUF_O->dhwaddr.addr, BUF->shwaddr.addr, 6);
memcpy(BUF_O->shwaddr.addr, uip_ethaddr.addr, 6); memcpy(BUF_O->shwaddr.addr, uip_ethaddr.addr, 6);
@@ -388,24 +372,19 @@ uip_arp_out(void) __banked
If not ARP table entry is found, we overwrite the original IP If not ARP table entry is found, we overwrite the original IP
packet with an ARP request for the IP address. */ packet with an ARP request for the IP address. */
if (IPBUF_O->sport == 0x4300 && !IPBUF_O->destipaddr[0] && !IPBUF_O->destipaddr[1]) {
IPBUF_O->destipaddr[0] = 0xffff;
IPBUF_O->destipaddr[1] = 0xffff;
IPBUF_O->dport = 0x4400;
}
/* First check if destination is a local broadcast. */ /* First check if destination is a local broadcast. */
if(uip_ipaddr_cmpc(IPBUF_O->destipaddr, broadcast_ipaddr)) { if(uip_ipaddr_cmpc(IPBUF->destipaddr, broadcast_ipaddr)) {
memcpyc(IPBUF_O->ethhdr.dest.addr, broadcast_ethaddr.addr, 6); memcpyc(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
} else { } else {
/* Check if the destination address is on the local network. */ /* Check if the destination address is on the local network. */
if(!uip_ipaddr_maskcmp(IPBUF_O->destipaddr, uip_hostaddr, uip_netmask)) { if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
/* Destination address was not on the local network, so we need to /* Destination address was not on the local network, so we need to
use the default router's IP address instead of the destination use the default router's IP address instead of the destination
address when determining the MAC address. */ address when determining the MAC address. */
uip_ipaddr_copy(ipaddr, uip_draddr); uip_ipaddr_copy(ipaddr, uip_draddr);
} else { } else {
/* Else, we use the destination IP address. */ /* Else, we use the destination IP address. */
uip_ipaddr_copy(ipaddr, IPBUF_O->destipaddr); uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
} }
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
@@ -440,11 +419,11 @@ uip_arp_out(void) __banked
} }
/* Build an ethernet header. */ /* Build an ethernet header. */
memcpy(IPBUF_O->ethhdr.dest.addr, tabptr->ethaddr.addr, 6); memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
} }
memcpy(IPBUF_O->ethhdr.src.addr, uip_ethaddr.addr, 6); memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
IPBUF_O->ethhdr.type = HTONS(UIP_ETHTYPE_IP); IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
uip_len += sizeof(struct uip_eth_hdr); uip_len += sizeof(struct uip_eth_hdr);
} }
+2 -2
View File
@@ -78,8 +78,8 @@ void uip_arp_init(void) __banked;
inserts a new mapping if none exists. The function assumes that an inserts a new mapping if none exists. The function assumes that an
IP packet with an Ethernet header is present in the uip_buf buffer IP packet with an Ethernet header is present in the uip_buf buffer
and that the length of the packet is in the uip_len variable. */ and that the length of the packet is in the uip_len variable. */
void uip_arp_ipin(void) __banked; /*void uip_arp_ipin(void);*/
// #define uip_arp_ipin() #define uip_arp_ipin()
/* The uip_arp_arpin() should be called when an ARP packet is received /* The uip_arp_arpin() should be called when an ARP packet is received
by the Ethernet driver. This function also assumes that the by the Ethernet driver. This function also assumes that the
+1 -1
View File
@@ -447,7 +447,7 @@ void uip_log(char *msg);
#ifdef UIP_CONF_LLH_LEN #ifdef UIP_CONF_LLH_LEN
#define UIP_LLH_LEN UIP_CONF_LLH_LEN #define UIP_LLH_LEN UIP_CONF_LLH_LEN
#else /* UIP_CONF_LLH_LEN */ #else /* UIP_CONF_LLH_LEN */
#define UIP_LLH_LEN ETHER_HEADER_SIZE + RTL_TAG_SIZE + VLAN_TAG_SIZE #define UIP_LLH_LEN ETHER_HEADER_SIZE + RTL_FRAME_DESC_SIZE
#endif /* UIP_CONF_LLH_LEN */ #endif /* UIP_CONF_LLH_LEN */
/** @} */ /** @} */