Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8e437f3a4 | ||
|
|
82dfb8f789 | ||
|
|
8224b06f9e | ||
|
|
69151362a0 | ||
|
|
24e83d5b74 | ||
|
|
3d81df0cad | ||
|
|
2481810906 | ||
|
|
03311debe6 | ||
|
|
e4adec9c11 | ||
|
|
d525229b42 | ||
|
|
73b23808cf | ||
|
|
4a14f50932 | ||
|
|
1bfe632174 | ||
|
|
265a80bb25 | ||
|
|
64efd3fb9f | ||
|
|
2e6425f5e6 | ||
|
|
1856aeba28 | ||
|
|
4e4a2ea4db | ||
|
|
4ccbf51976 | ||
|
|
0df48fbb1c | ||
|
|
25040070e5 | ||
|
|
edf6351d85 | ||
|
|
c3b4cc893b | ||
|
|
b83b67d234 | ||
|
|
efd61be64e | ||
|
|
da7909f422 | ||
|
|
14b2ce1c49 | ||
|
|
84d9408151 | ||
|
|
05c0571154 | ||
|
|
8790f0dca4 | ||
|
|
98af999304 | ||
|
|
0a996fa6d0 | ||
|
|
441e575661 | ||
|
|
a27118a428 | ||
|
|
01709431dc | ||
|
|
de0d413c0c | ||
|
|
b3ac10cae7 | ||
|
|
4e00f5a592 | ||
|
|
eff3f42ae1 | ||
|
|
dda873a633 | ||
|
|
9b2bd7f1b8 | ||
|
|
2dfe531fe0 | ||
|
|
72c2625121 | ||
|
|
58fd1a3ccc | ||
|
|
4f1a2f04d8 | ||
|
|
cedc795b82 | ||
|
|
ccf541a06b | ||
|
|
d5124df89e | ||
|
|
3eacc9c8a5 | ||
|
|
735672ccf1 | ||
|
|
1ebee4d6e9 | ||
|
|
24c0a95734 | ||
|
|
f88f655f5a | ||
|
|
a6b0918885 | ||
|
|
1d6fe690a4 | ||
|
|
e67c928eb7 | ||
|
|
46f8ea8712 | ||
|
|
b0eab52a2e | ||
|
|
8ce062c349 | ||
|
|
f768220a73 | ||
|
|
eab2e26510 | ||
|
|
b0ed56d423 | ||
|
|
36a064d03d | ||
|
|
2d01b8b7d7 | ||
|
|
fa632cdc6e | ||
|
|
177fb76e1b | ||
|
|
ff57084799 | ||
|
|
2dc5520928 | ||
|
|
7c11142a04 | ||
|
|
957a5b0e23 | ||
|
|
c773230a9b | ||
|
|
4f009539b0 | ||
|
|
bb90e0c9ba | ||
|
|
0e9c997d06 | ||
|
|
5ab247e996 | ||
|
|
d80717f3f0 | ||
|
|
24069439b0 | ||
|
|
4117f549cc | ||
|
|
2e24b24426 | ||
|
|
b71239f394 | ||
|
|
6e69f5bba3 | ||
|
|
1224335b66 | ||
|
|
e5b19bc594 | ||
|
|
89fcc6836d | ||
|
|
f9d4ab0074 | ||
|
|
6f68ccef28 | ||
|
|
8e687ef28e | ||
|
|
87db2dd4b8 | ||
|
|
aac1aed4c8 | ||
|
|
f0aea3dcac | ||
|
|
f10ab30f6d | ||
|
|
de431c6d84 | ||
|
|
3cd6d60e0b | ||
|
|
67b8c718fb | ||
|
|
26547f3e01 | ||
|
|
13b75a73c9 | ||
|
|
c6fceae724 | ||
|
|
068ec4c510 | ||
|
|
3a92459190 | ||
|
|
5ffeb3d16a | ||
|
|
de705380c9 | ||
|
|
e4f3315af3 | ||
|
|
07ab04e668 | ||
|
|
c5ce24ff78 | ||
|
|
bcb237158f | ||
|
|
f103daaafa | ||
|
|
168add47a3 | ||
|
|
423886dc54 | ||
|
|
4a9137387c | ||
|
|
2fc08f40d2 | ||
|
|
4a7fd7a098 | ||
|
|
19cd1200b4 | ||
|
|
333adbaf19 | ||
|
|
8051061fd7 | ||
|
|
8ae3f5e70f | ||
|
|
9ce328d155 | ||
|
|
2e463a2f30 | ||
|
|
422dc3f24d | ||
|
|
4b01ff9f8a | ||
|
|
456a4d9d3f | ||
|
|
02e9189f5f | ||
|
|
aff7d9c098 | ||
|
|
770926abd1 | ||
|
|
13f04d8acb | ||
|
|
49284fee15 | ||
|
|
db9ce7543e | ||
|
|
7a14c2d4a5 | ||
|
|
92948079a9 | ||
|
|
e406a3e82b | ||
|
|
c43b955db0 | ||
|
|
0321763e91 | ||
|
|
4bbbcd7d04 | ||
|
|
682ed861fa | ||
|
|
3a9045b97e | ||
|
|
4b9f6c319f | ||
|
|
6e2701bc8c | ||
|
|
ac3b4b17ae | ||
|
|
f87eb70c6a | ||
|
|
214cc6b737 | ||
|
|
40177f6318 | ||
|
|
d3dda09079 | ||
|
|
277e729f2c | ||
|
|
f778b9159b | ||
|
|
b6d6d2391d | ||
|
|
2c231fdf69 | ||
|
|
689751ffe6 | ||
|
|
fa93340c24 | ||
|
|
e9523a2f67 | ||
|
|
088be074f5 | ||
|
|
340fdd97e5 | ||
|
|
09ce4b391b | ||
|
|
7e6577a811 | ||
|
|
675faf0471 | ||
|
|
175ca9464a | ||
|
|
38241f0a08 | ||
|
|
0fe323b12f | ||
|
|
94187461c6 | ||
|
|
fa0eb91586 | ||
|
|
2f872ea08e | ||
|
|
ab2d30a05b | ||
|
|
d37ce07119 | ||
|
|
4bd6ffd083 | ||
|
|
94cfec8693 | ||
|
|
a4bb3f1725 | ||
|
|
931e6da0ab | ||
|
|
88454ec7d7 | ||
|
|
f0efb84abb | ||
|
|
62d3424a92 | ||
|
|
a3860c29cb | ||
|
|
b1961c6955 | ||
|
|
bb84bdc55a | ||
|
|
9733ff61a0 | ||
|
|
1b5243714e | ||
|
|
36459fdd76 | ||
|
|
ce11790a0d | ||
|
|
55431b39f6 | ||
|
|
46e1c955ba | ||
|
|
7b728cec6f | ||
|
|
0d17dd563f | ||
|
|
d556d634ca | ||
|
|
2844a1ed6d | ||
|
|
7b5e365d5e | ||
|
|
45fb382b07 | ||
|
|
8973774594 | ||
|
|
48c5b0c9cf | ||
|
|
1557a7cf3c | ||
|
|
131bc106af | ||
|
|
19ccc4003d | ||
|
|
b5fe9f217f | ||
|
|
f65d14f452 | ||
|
|
b92fba870c | ||
|
|
4deee377a7 | ||
|
|
fe42b07e2b | ||
|
|
9984649177 | ||
|
|
7d47edb649 | ||
|
|
fdb19fe0ee | ||
|
|
b9b50f9a70 | ||
|
|
c31b67572b | ||
|
|
a4e3b4368b | ||
|
|
93003c8cb8 | ||
|
|
fd058ea74d | ||
|
|
edc469fe29 | ||
|
|
a71c5359a5 | ||
|
|
9e3863cc4e | ||
|
|
d22ec04b5b | ||
|
|
0a65536a7f | ||
|
|
0631c813e2 | ||
|
|
eaebeba528 | ||
|
|
b36fd95356 | ||
|
|
52b1d1a4ea | ||
|
|
48f28ae7ff | ||
|
|
a7fc8303e9 | ||
|
|
a62866a93a | ||
|
|
42bbed9661 | ||
|
|
3c8de6da87 | ||
|
|
3a6f62b1d5 | ||
|
|
530e2683f0 | ||
|
|
9fedc6dd3d | ||
|
|
5e23d13771 | ||
|
|
09d5857fdd | ||
|
|
be309853c9 | ||
|
|
072edb36a8 | ||
|
|
10dd330e3c | ||
|
|
c514eb8bf3 | ||
|
|
e2c4ed6be3 | ||
|
|
56ee56af2e | ||
|
|
8626b4c1d4 | ||
|
|
0cc09e4015 | ||
|
|
674dc1f35d | ||
|
|
7e6b443e07 | ||
|
|
73ec184c23 | ||
|
|
bf41fbd202 | ||
|
|
04ab442c6d | ||
|
|
c02623a610 | ||
|
|
c69bf4c5ec | ||
|
|
575274786a | ||
|
|
7f4f6dae03 | ||
|
|
4eeb12c020 | ||
|
|
7d81b15b6e | ||
|
|
d6253ddc25 | ||
|
|
8cac67cdf7 | ||
|
|
5620e950ce | ||
|
|
83491bc9e3 | ||
|
|
eb83b8be09 | ||
|
|
bece4a20a1 | ||
|
|
cdc84c75e4 | ||
|
|
6be1871bb4 | ||
|
|
4686515de3 | ||
|
|
c39cc421a7 | ||
|
|
c1df7c23d1 | ||
|
|
9bae4052a3 | ||
|
|
0d115e0e0b | ||
|
|
8e78d1e629 | ||
|
|
13cc9db1ce | ||
|
|
3dcab09047 | ||
|
|
94992562fd | ||
|
|
6150ada5f8 | ||
|
|
8116ef0a5b | ||
|
|
0cd56b1196 | ||
|
|
3b3f36256c | ||
|
|
18b28edcbb | ||
|
|
6ea9503ab2 | ||
|
|
e0df37f359 | ||
|
|
c04a5fc3a4 | ||
|
|
f0b311fc43 | ||
|
|
2f005d2993 | ||
|
|
974052877d | ||
|
|
ae77ffe495 | ||
|
|
f65416f0d1 | ||
|
|
ffde4eaf60 | ||
|
|
c05d83132b | ||
|
|
dcd3cd5a98 | ||
|
|
9f107b6e60 | ||
|
|
15b10d9ed0 | ||
|
|
abf1cd1344 | ||
|
|
b5b52776bc | ||
|
|
0486c34bfd | ||
|
|
690092d564 | ||
|
|
115ea09ebb | ||
|
|
f3e1a393b5 | ||
|
|
206c72b5ef | ||
|
|
472811cc9a | ||
|
|
80552816b9 | ||
|
|
c1caf6f569 | ||
|
|
ddad65fe90 | ||
|
|
ff7b517491 | ||
|
|
65417433eb | ||
|
|
b7621fad31 | ||
|
|
82f78cb8f2 | ||
|
|
75f2ade1a1 | ||
|
|
3e91b05a42 | ||
|
|
ec1cb4106d | ||
|
|
62c6c65f1c | ||
|
|
c691591295 | ||
|
|
434acbcc13 | ||
|
|
1aae2fac30 | ||
|
|
1f9b3df3e6 | ||
|
|
eb4bae278b | ||
|
|
7908044a44 | ||
|
|
0ec1a5e63f | ||
|
|
114af559c7 | ||
|
|
5a2c4ca029 | ||
|
|
63e367d298 | ||
|
|
5e513daf17 | ||
|
|
3ec9319d77 | ||
|
|
b42eace21d | ||
|
|
3dfd6a88c7 | ||
|
|
7fa26e0ae3 | ||
|
|
1c8cdab4bf | ||
|
|
f49ca0d6fe | ||
|
|
12fb6fd809 | ||
|
|
dad65fd550 | ||
|
|
dc82e044bc | ||
|
|
7daa9effe0 | ||
|
|
950586135a | ||
|
|
c1ad800fc5 | ||
|
|
dc4fb5becc | ||
|
|
78ecef15e9 | ||
|
|
eab927f52a | ||
|
|
02c816647c | ||
|
|
d3f1069285 | ||
|
|
98bda62181 | ||
|
|
3f65db9984 | ||
|
|
df95c544d4 | ||
|
|
7df3c87892 | ||
|
|
53f12a42c5 | ||
|
|
1b514b5ea8 | ||
|
|
dd09be9dd0 | ||
|
|
b2b7f8a0c6 | ||
|
|
5b28ddf80a | ||
|
|
624f93a28a | ||
|
|
fe3da0c7a5 | ||
|
|
412098d0ed | ||
|
|
5ecce86ef1 | ||
|
|
247b230212 | ||
|
|
c012dda029 | ||
|
|
6616a0c9ce | ||
|
|
eab8c901cf | ||
|
|
21a9fdf45a | ||
|
|
1ed12d1101 | ||
|
|
8d7faf5312 | ||
|
|
af4101f060 | ||
|
|
d6d9c368e9 | ||
|
|
36de9791be | ||
|
|
eab17f8a3f | ||
|
|
552bd1cb18 | ||
|
|
4bcbada764 | ||
|
|
9fae0f9249 | ||
|
|
774e04816e | ||
|
|
ead1c40aac | ||
|
|
6488433584 | ||
|
|
59088b4787 | ||
|
|
30547cc453 | ||
|
|
58aead38cf | ||
|
|
9c3433cf6b | ||
|
|
97d44fbf4b | ||
|
|
00ee3d1325 | ||
|
|
078a446cee | ||
|
|
efdf93a97a | ||
|
|
025e1a186b | ||
|
|
dc5cbcda16 | ||
|
|
12c15603ed | ||
|
|
3a7da77a99 | ||
|
|
13509d56e5 | ||
|
|
54b5e90976 | ||
|
|
38b8e38c04 | ||
|
|
d245249385 | ||
|
|
8b7306f995 | ||
|
|
ecac6d1934 | ||
|
|
f2966ad248 | ||
|
|
8a7b146892 | ||
|
|
0998a9dfaa | ||
|
|
aded07730e | ||
|
|
58d059384d | ||
|
|
a7692022f1 | ||
|
|
e26693826e | ||
|
|
be6bd2a5b3 | ||
|
|
6c43091b7a | ||
|
|
b57b7d1a3d | ||
|
|
fc86ea8be5 | ||
|
|
91780110f2 | ||
|
|
f0e9953081 | ||
|
|
1c9bf10b87 | ||
|
|
2e2529be27 | ||
|
|
f6348765b4 | ||
|
|
6411c5157c | ||
|
|
d06dc3e5f8 | ||
|
|
dd7f9f7c7b | ||
|
|
3b8dba6e87 | ||
|
|
a259587bf9 | ||
|
|
f23d840cee | ||
|
|
f46ef3a43c | ||
|
|
81af3a29a2 | ||
|
|
5a55524115 | ||
|
|
6b39bcc448 | ||
|
|
4c8e0ce975 | ||
|
|
71344825c7 | ||
|
|
40ce742d04 | ||
|
|
f5e4fa5134 | ||
|
|
28020e8186 | ||
|
|
cbcf67a693 | ||
|
|
d6bf46595a | ||
|
|
2499d116a3 | ||
|
|
74a1c6831a | ||
|
|
a79c483f94 | ||
|
|
75aa23468c | ||
|
|
373a21f4a1 | ||
|
|
89b4cf83ce | ||
|
|
005209f97a | ||
|
|
f0f142fbe0 | ||
|
|
daf9d8965a | ||
|
|
58b12c4aa6 | ||
|
|
4ce3e33447 | ||
|
|
ebd27e4763 | ||
|
|
e60a09fb7e | ||
|
|
828963b586 | ||
|
|
944f4ce6f0 | ||
|
|
73d9a8ccb1 | ||
|
|
3a3967960f | ||
|
|
e38abf27c9 | ||
|
|
05ded88f85 | ||
|
|
dc22c4908b | ||
|
|
c0d9bf7f0d | ||
|
|
1947356ec5 | ||
|
|
2fa4686b33 | ||
|
|
bd06f7f5e5 | ||
|
|
b6d2d7c072 | ||
|
|
3c72f0e1b6 | ||
|
|
6be5693385 | ||
|
|
8e9bb56a29 | ||
|
|
e50d3c6950 | ||
|
|
4db1ccbbd9 | ||
|
|
ccafa01c74 | ||
|
|
cb43b3cbd6 | ||
|
|
9d4e531306 | ||
|
|
7f0e7fdc82 | ||
|
|
f187261085 | ||
|
|
aba69cd640 | ||
|
|
b6dcb75130 | ||
|
|
4e04735a5f | ||
|
|
fc3c686564 | ||
|
|
e826180d06 | ||
|
|
b63117ba6c | ||
|
|
be7796a22c | ||
|
|
1bd4a8d3cc | ||
|
|
1db30f22de | ||
|
|
4c70e654d1 | ||
|
|
3c24f2bdea | ||
|
|
3e610392a9 | ||
|
|
f00dbab0c4 | ||
|
|
bc46646398 | ||
|
|
5fa6c36b73 | ||
|
|
146771f5ca | ||
|
|
bf0bea1edd | ||
|
|
907ad08830 | ||
|
|
7cf0115182 | ||
|
|
adfbead438 | ||
|
|
301774040b | ||
|
|
683037f410 | ||
|
|
57b820c4e8 | ||
|
|
75b223223c | ||
|
|
9a6e2b3e01 | ||
|
|
6e394300c8 | ||
|
|
801150431b | ||
|
|
45d0aac118 | ||
|
|
ee05cd4000 | ||
|
|
74013bb14f | ||
|
|
beb14deba5 | ||
|
|
1212def799 | ||
|
|
95b3bde822 | ||
|
|
f511453f79 | ||
|
|
8653216047 | ||
|
|
e62e0fc8bd | ||
|
|
2ff418f80f | ||
|
|
5d42e8843e | ||
|
|
3c183f73f8 | ||
|
|
3776f12f5c | ||
|
|
5ddec9710a | ||
|
|
f627559005 | ||
|
|
dca92d7f45 | ||
|
|
149dc8537f | ||
|
|
42f7b4fba1 | ||
|
|
17642699d4 | ||
|
|
724fd1e061 | ||
|
|
3eb2dfe0c9 | ||
|
|
73df006d39 | ||
|
|
175f3bb185 | ||
|
|
57061161b6 | ||
|
|
80f97a50e0 | ||
|
|
c265a20d83 | ||
|
|
4937618684 | ||
|
|
1a743b3889 | ||
|
|
425283b774 | ||
|
|
f582576b10 | ||
|
|
16b0f207ed | ||
|
|
fe2bcc7f2d | ||
|
|
a0628c7df5 | ||
|
|
cefe48fe51 | ||
|
|
e8e7fcbe7f | ||
|
|
8a28b4fc88 | ||
|
|
9a96c80af2 | ||
|
|
772e9dc526 | ||
|
|
025f72c876 | ||
|
|
62f80f0ad2 | ||
|
|
803d9c1242 | ||
|
|
ec069a5bcc | ||
|
|
81d11c246c | ||
|
|
85d1d7520a | ||
|
|
810db48a00 | ||
|
|
f9d3dec50f | ||
|
|
236eac610d | ||
|
|
9df9eece3f | ||
|
|
3cd9131795 | ||
|
|
50b68f908e | ||
|
|
f1f3d521b5 | ||
|
|
addca1cb26 | ||
|
|
cbd2a8c080 | ||
|
|
78b3971782 | ||
|
|
201c7e333d | ||
|
|
2c26a4f389 | ||
|
|
266c95e4d7 | ||
|
|
38b19820e4 | ||
|
|
988bddacf7 | ||
|
|
4264856109 | ||
|
|
35d26cb08f | ||
|
|
a9af466702 | ||
|
|
024c8cef49 | ||
|
|
64906ad135 | ||
|
|
4d7a2e28c7 | ||
|
|
a6c5f558bf | ||
|
|
5a6b854c5d | ||
|
|
d31980eb9e | ||
|
|
eb4a6ac275 | ||
|
|
1ba1224644 | ||
|
|
4a78b2dc8c | ||
|
|
0160b430f4 | ||
|
|
c72d36af36 | ||
|
|
7ebb420e7d | ||
|
|
2cf60e177b | ||
|
|
0ce5fb4af3 | ||
|
|
4b5bf09c83 | ||
|
|
be520d6716 | ||
|
|
f3c1b7f3ac | ||
|
|
7a790b32b1 | ||
|
|
293a196c91 | ||
|
|
6b4d2b9cfa | ||
|
|
3c4fb679bd | ||
|
|
f1f69e26fd | ||
|
|
b51ed71bb1 | ||
|
|
65a41eaddd | ||
|
|
5361c85d30 | ||
|
|
a31be093e7 | ||
|
|
f39eefa90c | ||
|
|
eaff9537ef | ||
|
|
2110cf128a | ||
|
|
267e371d3c | ||
|
|
9702f8e4c4 | ||
|
|
524c37d7c7 | ||
|
|
b5387016fa | ||
|
|
5c881da4fe | ||
|
|
0df699659a | ||
|
|
032305ad3a | ||
|
|
b16c7d9723 | ||
|
|
6e1f199571 | ||
|
|
5329193987 | ||
|
|
52cf759bec | ||
|
|
cbbc6160f4 | ||
|
|
a8d3b7d39a | ||
|
|
80095ba617 | ||
|
|
a3d1a35e2f | ||
|
|
8c3df643d0 | ||
|
|
37eefb4b35 | ||
|
|
3f5093f180 | ||
|
|
47b3ee60b6 | ||
|
|
59d20ed9b6 | ||
|
|
f41ed2b943 | ||
|
|
56fa96c494 | ||
|
|
6bfcbd2f9a | ||
|
|
fa7895ad62 | ||
|
|
d405dd7776 | ||
|
|
1ed8b131bc | ||
|
|
9ada6adad7 | ||
|
|
719c6db228 | ||
|
|
a96fdfe10c | ||
|
|
1d1e33f4d5 | ||
|
|
3fda9ccd86 | ||
|
|
3be6667789 | ||
|
|
5103d1c168 | ||
|
|
ce85576882 | ||
|
|
59c60504e7 | ||
|
|
a3c586ef38 | ||
|
|
8bc530d3d0 | ||
|
|
f2c6ac01d9 | ||
|
|
94d9f2c8e8 | ||
|
|
0503e7952d | ||
|
|
787d593996 | ||
|
|
db2a541e5f | ||
|
|
11be13fe53 | ||
|
|
65f8afb908 | ||
|
|
0126b159bf | ||
|
|
31024388ba | ||
|
|
9f2d6b72b7 | ||
|
|
5c5dcb5209 | ||
|
|
be6d47a3ab | ||
|
|
4ff009dbfc | ||
|
|
0998b7381f | ||
|
|
0c339e9123 | ||
|
|
75151e0b00 | ||
|
|
4c4232cc07 | ||
|
|
43845b911b | ||
|
|
0ed45e0710 | ||
|
|
5e30f8e6c0 | ||
|
|
7f3c91ac0c | ||
|
|
3853a2701d | ||
|
|
00a5f81871 | ||
|
|
53d865059d | ||
|
|
b90aedd8f2 | ||
|
|
c4928e5546 | ||
|
|
67ae4598d9 | ||
|
|
6b190eb9f3 | ||
|
|
fae16dabf5 | ||
|
|
b651890a3a | ||
|
|
caa7874bb3 | ||
|
|
53f33bd606 | ||
|
|
57e3fce95e | ||
|
|
52692d05b1 | ||
|
|
d364bd69e4 | ||
|
|
70ab7ff769 | ||
|
|
e30976be76 | ||
|
|
1a55a134c7 | ||
|
|
23f0ba995c | ||
|
|
22a09bd06a | ||
|
|
930a08ec52 | ||
|
|
1701d4dc53 | ||
|
|
1e19a9abe2 | ||
|
|
1098e73337 | ||
|
|
99b0fc4b32 | ||
|
|
10d472d8a6 | ||
|
|
6254f44001 | ||
|
|
c435838376 | ||
|
|
3f7db7e430 | ||
|
|
f98fe32d0c | ||
|
|
d2e8ee0e41 | ||
|
|
a9a455e447 | ||
|
|
3f26bf7348 | ||
|
|
ac302d4a67 | ||
|
|
409bc58e17 | ||
|
|
fbcec2cb5a | ||
|
|
ccb90ed16f | ||
|
|
4389cfcd8b | ||
|
|
5e901fb5c2 | ||
|
|
2974e4b66a | ||
|
|
108ac9b8fc | ||
|
|
de3eca26c3 | ||
|
|
8164166465 | ||
|
|
87fe1e77ae | ||
|
|
a753f6f02e | ||
|
|
c86d4b31f2 | ||
|
|
3c89b22207 | ||
|
|
bebe79c4c9 | ||
|
|
adb0b54691 | ||
|
|
b99436543a | ||
|
|
1194823cd5 | ||
|
|
94716ceb5d | ||
|
|
13120127df | ||
|
|
46037cd54d | ||
|
|
e6cd362a1e | ||
|
|
f21b3a32bd | ||
|
|
35941dd19f | ||
|
|
0f257d38df | ||
|
|
912e68d6eb | ||
|
|
c473646389 | ||
|
|
51cf40d040 | ||
|
|
3fd9cdfa7e | ||
|
|
3189820ba0 | ||
|
|
ed74ec1e97 | ||
|
|
dd95a05487 | ||
|
|
481c02c740 | ||
|
|
0a31a65477 | ||
|
|
2d176b7ccc | ||
|
|
a1fac63710 | ||
|
|
5c7f82e2fe | ||
|
|
e765d17c2b | ||
|
|
8fb9afb955 | ||
|
|
e96780fadb | ||
|
|
2221f0fa32 | ||
|
|
f86b8f32de | ||
|
|
9389db9e9b | ||
|
|
519c3a8df3 | ||
|
|
64422367d5 | ||
|
|
dc2b03e331 | ||
|
|
fcf1b3c310 | ||
|
|
1dd6156a1f | ||
|
|
e75a4c2a95 | ||
|
|
05d8c36afe | ||
|
|
b6c9eaf00f | ||
|
|
ecf5f47960 | ||
|
|
457f117216 | ||
|
|
ebf6ed7526 | ||
|
|
96f2c860fc | ||
|
|
dd52e8e85e | ||
|
|
ecf8c999b1 | ||
|
|
64a1d252cd | ||
|
|
b80d46955c | ||
|
|
0a18c64dcc | ||
|
|
b53c56e7f6 | ||
|
|
17d41b53b7 | ||
|
|
bd98cb0312 | ||
|
|
5566d71522 | ||
|
|
5e1396cc42 | ||
|
|
7fe0678c92 | ||
|
|
7ec25a39a2 | ||
|
|
98e3cde2f5 | ||
|
|
d90c02f951 | ||
|
|
bbb92c86db | ||
|
|
1635236a05 | ||
|
|
5e3a280b5c | ||
|
|
a56e2a419b | ||
|
|
9c01227572 | ||
|
|
6d37a47481 | ||
|
|
87b9e59cdb | ||
|
|
0e86b84efa | ||
|
|
bd595b7f94 | ||
|
|
06d4a3504a | ||
|
|
d68534e833 | ||
|
|
e0356bd751 | ||
|
|
4b770a8abc | ||
|
|
709436ca13 | ||
|
|
28856ef495 | ||
|
|
113bb654aa | ||
|
|
efc1883685 | ||
|
|
72921ba3be | ||
|
|
70be673fca | ||
|
|
bf5205258e | ||
|
|
98ddb0bb29 | ||
|
|
d152f89549 | ||
|
|
c61e94527e | ||
|
|
f76ccaf3d8 | ||
|
|
ebc6cd06ad | ||
|
|
017aaf71d6 | ||
|
|
4eaf16f96d | ||
|
|
718745e7b5 | ||
|
|
06ee1ce38e | ||
|
|
d3e8698e40 | ||
|
|
f122402bdd | ||
|
|
842d68af97 | ||
|
|
bfd1ce9183 | ||
|
|
4ed6575a87 | ||
|
|
1b1c656404 | ||
|
|
018eab9810 | ||
|
|
ec36658ab9 | ||
|
|
eeded0f788 | ||
|
|
7a7ffd3bf8 | ||
|
|
8f3b738e59 | ||
|
|
62065875e3 | ||
|
|
e7f70a724b | ||
|
|
d7a7bdac7e | ||
|
|
94e34a5991 | ||
|
|
b58b1dfb35 | ||
|
|
592b903305 | ||
|
|
4ca5b4e87a | ||
|
|
5a8a8ed91b | ||
|
|
ad64e450e1 | ||
|
|
cfeffc434d | ||
|
|
8670709b6e | ||
|
|
ce496ab25f | ||
|
|
964ef2da7a | ||
|
|
053dbe286e | ||
|
|
e68e5cef46 | ||
|
|
b5543b6aeb | ||
|
|
a51fcf1478 | ||
|
|
247cb4dd2f | ||
|
|
394fc99485 | ||
|
|
cf0707475d | ||
|
|
73b99b2f08 | ||
|
|
005eaa3248 | ||
|
|
98f1e9443a | ||
|
|
4c2be334d5 | ||
|
|
073cc1e4a4 | ||
|
|
ba919280ac | ||
|
|
dcc60c3824 | ||
|
|
caad366b3b | ||
|
|
ce0ee859d6 | ||
|
|
a369e46fe6 | ||
|
|
defb37c06a | ||
|
|
a5f77e4caf | ||
|
|
1311cb9ea9 | ||
|
|
7d0d8525d2 | ||
|
|
21f33abfa7 |
No files matched your search
@@ -0,0 +1,19 @@
|
||||
.git/
|
||||
.gitignore
|
||||
.gitattributes
|
||||
.github/
|
||||
output/
|
||||
installer/output/
|
||||
*.bin
|
||||
html_data.c
|
||||
html_data.h
|
||||
*.o
|
||||
*.rel
|
||||
*.lst
|
||||
*.sym
|
||||
*.asm
|
||||
*.ihx
|
||||
*.img
|
||||
*.map
|
||||
*.mem
|
||||
*.lk
|
||||
@@ -3,6 +3,7 @@ name: Build firmware
|
||||
on:
|
||||
push:
|
||||
branches: ['**']
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -16,8 +17,14 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
apt update
|
||||
apt install make gcc sdcc xxd python-is-python3 libjson-c-dev -y
|
||||
- name: Check if machine.c can be compiled for all machines
|
||||
apt install make gcc sdcc xxd python-is-python3 libjson-c-dev zlib1g-dev -y
|
||||
- name: Run the host-side unit tests
|
||||
run: make -C test
|
||||
- name: Check that every machine definition can be compiled
|
||||
run: make machine_check
|
||||
- name: Make project
|
||||
run: make MACHINE="KP_9000_6XHML_X2"
|
||||
- name: Make project (4x2/RTL8372)
|
||||
run: make CI=1 MACHINE="KP_9000_6XHML_X2"
|
||||
- name: Make project (8x1/RTL8373)
|
||||
run: make CI=1 MACHINE="KP_9000_9XHML_X_V3_1"
|
||||
- name: Make project with the health instrumentation
|
||||
run: make clean && make CI=1 MACHINE="KP_9000_6XHML_X2" HEALTH=1
|
||||
@@ -7,3 +7,7 @@ version.h
|
||||
tools/httpd_sim
|
||||
tools/injector
|
||||
tools/fileadder
|
||||
|
||||
# host-test stand-ins for the two generated headers
|
||||
!test/stub/html_data.h
|
||||
!test/stub/version.h
|
||||
@@ -0,0 +1,37 @@
|
||||
# Change Log
|
||||
|
||||
## [0.x] - 2026-xx-XX
|
||||
|
||||
## Added
|
||||
|
||||
- Web UI
|
||||
- Compress the embedded assets (minify + gzip) and switch to a single-page layout. #315
|
||||
- Replace the multi-page UI with a themed single-page app: light, dark and Selenized themes following the browser by default,
|
||||
English, Japanese and Chinese, save to flash merges the command log into the startup config and verifies the write,
|
||||
firmware images are checked in the browser before upload. #429
|
||||
|
||||
## Changed
|
||||
|
||||
## Fixed
|
||||
|
||||
- Config
|
||||
- A startup configuration line longer than the command buffer no longer stops the replay:
|
||||
the offending line is skipped and the following lines are still applied.
|
||||
- The web UI and the configuration upload now refuse a line the replay cannot take,
|
||||
instead of writing it to flash.
|
||||
|
||||
## Breaking changes
|
||||
|
||||
- Config
|
||||
- VLAN don't accept port `u`-suffix anymore.
|
||||
So `vlan 1 4u` is not valid anymore.
|
||||
Replace it with `vlan 1 4`.
|
||||
- Commands
|
||||
- port zero/`0` is treated as the `CPU_PORT`. #326
|
||||
- Many commands don't accept the CPU_PORT anymore. See #334.
|
||||
When the CPU_PORT is needed, the command/service will add the CPU_PORT automaticly.
|
||||
Only `isolate` accept the CPU_PORT as destination port.
|
||||
|
||||
## [v0.1_aplha] - 2025-11-03
|
||||
|
||||
First release.
|
||||
@@ -0,0 +1,19 @@
|
||||
FROM debian:13-slim
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
make \
|
||||
gcc \
|
||||
sdcc \
|
||||
xxd \
|
||||
python3 \
|
||||
libjson-c-dev \
|
||||
git \
|
||||
zlib1g-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# git safe.directory for mounted repos (Makefile uses git describe)
|
||||
RUN git config --global --add safe.directory /workspace
|
||||
|
||||
WORKDIR /workspace
|
||||
|
||||
CMD ["bash"]
|
||||
@@ -4,22 +4,38 @@ DEFAULT_CONFIG_LOCATION = 454656
|
||||
CONFIG_LOCATION = 458752
|
||||
HTML_LOCATION = 262144
|
||||
|
||||
ifeq ($(origin CC),default)
|
||||
CC = sdcc
|
||||
CC_FLAGS = -mmcs51 -I. -Ihttpd -Iuip
|
||||
ASM = sdas8051
|
||||
endif
|
||||
CC_FLAGS = -mmcs51 -I. -Imachine -Ihttpd -Iuip
|
||||
ASM ?= sdas8051
|
||||
AFLAGS= -plosgff
|
||||
|
||||
SUBDIRS := tools
|
||||
SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS))
|
||||
|
||||
BUILDDIR = output
|
||||
VERSION_HEADER := version.h
|
||||
|
||||
ifeq ($(MACHINE),)
|
||||
MACHINE:= $(shell grep "^\s*#define MACHINE_" machine.h | sed "s/^\s*#define MACHINE_//")
|
||||
else
|
||||
# $MACHINE selects machine/$(MACHINE).c as the board definition and is passed
|
||||
# on as -DMACHINE_$(MACHINE), which the rest of the firmware tests with
|
||||
# #if defined(MACHINE_...), and as -DMACHINE_NAME, which machine.h uses to
|
||||
# include machine/$(MACHINE).h. Both take the same value, so they cannot drift.
|
||||
ifneq ($(MACHINE),)
|
||||
CC_FLAGS += -DMACHINE_$(MACHINE)
|
||||
CC_FLAGS += -DMACHINE_NAME=$(MACHINE)
|
||||
endif
|
||||
# Health instrumentation and the "health" console command: HEALTH=1 gmake ...
|
||||
ifneq ($(HEALTH),)
|
||||
CC_FLAGS += -DHEALTH
|
||||
endif
|
||||
|
||||
ifeq ($(CI),1)
|
||||
CC_FLAGS += --Werror
|
||||
endif
|
||||
|
||||
# The board definition being built: one file per MACHINE_* symbol in machine.h.
|
||||
MACHINE_SRC = machine/$(MACHINE).c
|
||||
|
||||
BUILDDIR = output/$(MACHINE)
|
||||
VERSION_HEADER := version.h
|
||||
|
||||
GIT_VERSION := $(shell git rev-parse --short HEAD)
|
||||
ifeq ($(shell git status --porcelain --untracked-files=no),)
|
||||
@@ -30,76 +46,178 @@ endif
|
||||
VERSION_EXTENSION = v$(VERSION)-$(GIT_VERSION)
|
||||
FILENAME_EXTENSION = $(VERSION_EXTENSION)-$(MACHINE)
|
||||
|
||||
all: create_build_dir $(VERSION_HEADER) $(SUBDIRS) $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin
|
||||
# Deterministic build date: honor SOURCE_DATE_EPOCH, else the HEAD commit date,
|
||||
# else wall-clock (no-git fallback). Keeps same-commit builds byte-identical
|
||||
# (BUILD_DATE is baked into the image and covered by the trailing CRC).
|
||||
SOURCE_DATE_EPOCH ?= $(shell git show -s --format=%ct HEAD 2>/dev/null)
|
||||
ifeq ($(SOURCE_DATE_EPOCH),)
|
||||
BUILD_DATE := $(shell date +"%Y-%m-%d %H:%M:%S")
|
||||
else
|
||||
BUILD_DATE := $(shell date -u -d @$(SOURCE_DATE_EPOCH) +"%Y-%m-%d %H:%M:%S" 2>/dev/null \
|
||||
|| date -u -r $(SOURCE_DATE_EPOCH) +"%Y-%m-%d %H:%M:%S")
|
||||
endif
|
||||
|
||||
# $(MACHINE_SRC) is listed here so an unknown $MACHINE fails before anything else
|
||||
# is built, including the tools/ subdirectory.
|
||||
all: create_build_dir $(VERSION_HEADER) $(MACHINE_SRC) $(SUBDIRS) $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin
|
||||
|
||||
create_build_dir:
|
||||
mkdir -p $(BUILDDIR)
|
||||
mkdir -p $(BUILDDIR)/uip
|
||||
mkdir -p $(BUILDDIR)/httpd
|
||||
mkdir -p "$(BUILDDIR)"
|
||||
mkdir -p "$(BUILDDIR)/uip"
|
||||
mkdir -p "$(BUILDDIR)/httpd"
|
||||
mkdir -p "$(BUILDDIR)/machine"
|
||||
mkdir -p "$(BUILDDIR)/crypto"
|
||||
|
||||
# Every machine is a pair machine/<MACHINE>.c + machine/<MACHINE>.h. Selecting
|
||||
# them by name means no #if/#elif chain, so an unknown or empty $MACHINE is
|
||||
# caught here instead of by a #error further down the build.
|
||||
$(MACHINE_SRC):
|
||||
@echo "ERROR: MACHINE='$(MACHINE)' has no definition (expected $(MACHINE_SRC))." >&2
|
||||
@echo " Every machine is one file pair under machine/, named after the" >&2
|
||||
@echo " MACHINE_* symbol it defines; see machine/*.c for the full list." >&2
|
||||
@echo " Example: make MACHINE=KP_9000_6XHML_X2" >&2
|
||||
@false
|
||||
|
||||
# Keep the per-machine definition in first position to fail immediately on an
|
||||
# invalid $MACHINE value
|
||||
SRCS = \
|
||||
$(MACHINE_SRC) \
|
||||
machine_init.c \
|
||||
cmd_editor.c \
|
||||
cmd_parser.c \
|
||||
dhcp.c \
|
||||
html_data.c \
|
||||
rtlplayground.c \
|
||||
boot.c \
|
||||
sfp.c \
|
||||
dns.c \
|
||||
dns_cli.c \
|
||||
ntp.c \
|
||||
ntp_cli.c \
|
||||
syslog.c \
|
||||
udp_apps.c \
|
||||
crypto/chacha20.c
|
||||
|
||||
# RTL837x
|
||||
SRCS += \
|
||||
rtl837x_bandwidth.c \
|
||||
rtl837x_flash.c \
|
||||
rtl837x_igmp.c \
|
||||
rtl837x_init.c \
|
||||
rtl837x_leds.c \
|
||||
rtl837x_leds_dump.c \
|
||||
rtl837x_phy.c \
|
||||
rtl837x_pins.c\
|
||||
rtl837x_port.c \
|
||||
rtl837x_stp.c \
|
||||
rtl837x_lldp.c \
|
||||
rtl837x_storm.c \
|
||||
rtl837x_lacp.c \
|
||||
rtl837x_trap.c
|
||||
SRCS += \
|
||||
httpd/httpd.c \
|
||||
httpd/page_impl.c
|
||||
SRCS += \
|
||||
uip/timer.c \
|
||||
uip/uip.c \
|
||||
uip/uiplib.c \
|
||||
uip/uip_arp.c \
|
||||
uip/uip-fw.c \
|
||||
uip/uip-neighbor.c \
|
||||
uip/uip-split.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
|
||||
SRCS += rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c cmd_editor.c rtl837x_bandwidth.c rtl837x_init.c syslog.c
|
||||
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 udp_apps.c
|
||||
SRCS += httpd/httpd.c httpd/page_impl.c
|
||||
OBJS = ${SRCS:%.c=$(BUILDDIR)/%.rel}
|
||||
DEPS := ${SRCS:%.c=$(BUILDDIR)/%.d}
|
||||
HTML := $(shell find $(html) -name '*.js' -or -name '*.html' -or -name '*.svg')
|
||||
HTML := $(shell find html -name '*.js' -or -name '*.html' -or -name '*.svg' -or -name '*.css' -or -name '*.ico')
|
||||
|
||||
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
|
||||
# Minified copy of the web UI sources, used as the fileadder input.
|
||||
# The raw html/ sources stay untouched for development; the minified
|
||||
# copy is a build artifact under output/.
|
||||
HTML_MIN := output/html_min
|
||||
.PHONY: html_min
|
||||
html_min: $(HTML)
|
||||
rm -rf $(HTML_MIN)
|
||||
mkdir -p $(HTML_MIN)
|
||||
@for f in $(HTML); do python3 tools/minify.py $$f $(HTML_MIN)/$$(basename $$f) || exit 1; done
|
||||
|
||||
$(VERSION_HEADER):
|
||||
@echo "#ifndef VERSION_H" > $(VERSION_HEADER)
|
||||
@echo "#define VERSION_H" >> $(VERSION_HEADER)
|
||||
@echo "#define VERSION_SW \"$(VERSION_EXTENSION)\"" >> $(VERSION_HEADER)
|
||||
@echo "#define BUILD_DATE \"$(shell date +"%Y-%m-%d %H:%M:%S")\"" >> $(VERSION_HEADER)
|
||||
@echo "#endif" >> $(VERSION_HEADER)
|
||||
html_data.c html_data.h &: $(HTML) | tools html_min
|
||||
tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -z -d $(HTML_MIN) -p html_data
|
||||
|
||||
$(VERSION_HEADER): FORCE
|
||||
@printf '%s\n' "#ifndef VERSION_H" "#define VERSION_H" \
|
||||
"#define VERSION_SW \"$(VERSION_EXTENSION)\"" \
|
||||
"#define BUILD_DATE \"$(BUILD_DATE)\"" \
|
||||
"#endif" > $(VERSION_HEADER).tmp
|
||||
@cmp -s $(VERSION_HEADER).tmp $(VERSION_HEADER) \
|
||||
&& rm -f $(VERSION_HEADER).tmp \
|
||||
|| mv $(VERSION_HEADER).tmp $(VERSION_HEADER)
|
||||
|
||||
httpd: html_data.h
|
||||
|
||||
$(SUBDIRS):
|
||||
$(MAKE) -C $@
|
||||
|
||||
clean:
|
||||
clean: $(SUBDIRSCLEAN)
|
||||
-rm -f html_data.c html_data.h $(VERSION_HEADER)
|
||||
-if [ -d $(BUILDDIR) ]; then find $(BUILDDIR) -type f ! -name "*.bin" -delete; fi
|
||||
|
||||
distclean:
|
||||
distclean: $(SUBDIRSCLEAN)
|
||||
-rm -f html_data.c html_data.h $(VERSION_HEADER)
|
||||
-rm -rf $(BUILDDIR)
|
||||
|
||||
$(BUILDDIR)/%.rel: %.c
|
||||
$(SUBDIRSCLEAN):
|
||||
$(MAKE) -C $(@:clean=) clean
|
||||
|
||||
# Objects depend on the flags they were built with, through a stamp file that
|
||||
# is rewritten only when CC_FLAGS actually changes.
|
||||
CCFLAGS_STAMP := $(BUILDDIR)/.ccflags
|
||||
|
||||
.PHONY: FORCE
|
||||
FORCE:
|
||||
|
||||
$(CCFLAGS_STAMP): FORCE | create_build_dir
|
||||
@echo '$(CC_FLAGS)' | cmp -s - $@ 2>/dev/null || echo '$(CC_FLAGS)' > $@
|
||||
|
||||
$(BUILDDIR)/%.rel: %.c $(CCFLAGS_STAMP) | create_build_dir html_data.h
|
||||
$(CC) -MMD $(CC_FLAGS) -o $@ -c $<
|
||||
|
||||
$(BUILDDIR)/%.rel: %.asm
|
||||
$(BUILDDIR)/%.rel: %.asm $(CCFLAGS_STAMP) | create_build_dir
|
||||
${ASM} ${AFLAGS} -o $@ $<
|
||||
# mv -f $(addprefix $(basename $^), .lst .rel .sym) .
|
||||
|
||||
$(BUILDDIR)/rtlplayground.ihx: $(OBJS) $(BUILDDIR)/crtstart.rel $(BUILDDIR)/crc16.rel
|
||||
$(CC) $(CC_FLAGS) -Wl-bHOME=0x00000 -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-r -o $@ $^
|
||||
$(BUILDDIR)/rtlplayground.ihx: $(OBJS) $(BUILDDIR)/crtbank.rel $(BUILDDIR)/crc16.rel $(BUILDDIR)/crypto/chacha_8051.rel
|
||||
$(CC) $(CC_FLAGS) --xram-size 48896 -Wl-bHOME=0x00000 -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-bBANK3=0x34000 -Wl-r -o $@ $^
|
||||
|
||||
$(BUILDDIR)/rtlplayground.img: $(BUILDDIR)/rtlplayground.ihx
|
||||
objcopy --input-target=ihex -O binary $< $@
|
||||
|
||||
$(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.img
|
||||
$(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.img | tools
|
||||
if [ -e $@ ]; then rm $@; fi
|
||||
tools/$(BUILDDIR)/imagebuilder -i $^ $@
|
||||
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 $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data -b BANK1 $@
|
||||
tools/$(BUILDDIR)/crc_calculator -u $@
|
||||
ln -sf rtlplayground-$(FILENAME_EXTENSION).bin $(BUILDDIR)/rtlplayground.bin
|
||||
tools/output/imagebuilder -i $^ $@
|
||||
tools/output/fileadder -a $(DEFAULT_CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
||||
tools/output/fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
||||
tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -z -d $(HTML_MIN) -b BANK1 $@
|
||||
tools/output/crc_calculator -u $@
|
||||
ln -sf $(MACHINE)/rtlplayground-$(FILENAME_EXTENSION).bin output/rtlplayground.bin
|
||||
|
||||
.PHONY: clean all $(SUBDIRS) $(VERSION_HEADER)
|
||||
.PHONY: clean distclean all $(SUBDIRS) $(SUBDIRSCLEAN) create_build_dir
|
||||
|
||||
# Every machine/ definition is compiled, so a machine added to machine/ is
|
||||
# covered without registering it anywhere. The machine-specific defines are
|
||||
# filtered out of $(CC_FLAGS) and supplied per iteration instead, so this also
|
||||
# works as "make machine_check MACHINE=...".
|
||||
MACHINE_DEFS := $(sort $(patsubst machine/%.c,%,$(wildcard machine/*.c)))
|
||||
MACHINE_LESS_CC_FLAGS = $(filter-out -DMACHINE_%,$(CC_FLAGS))
|
||||
|
||||
.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`; \
|
||||
for MACHINE in $(MACHINE_DEFS); \
|
||||
do \
|
||||
echo "Checking $${MACHINE}"; \
|
||||
$(CC) $(CC_FLAGS) -DMACHINE_$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine.c; \
|
||||
$(CC) $(MACHINE_LESS_CC_FLAGS) -DMACHINE_$${MACHINE} -DMACHINE_NAME=$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine/$${MACHINE}.c; \
|
||||
$(CC) $(MACHINE_LESS_CC_FLAGS) -DMACHINE_$${MACHINE} -DMACHINE_NAME=$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine_init.c; \
|
||||
done
|
||||
@rm -rf $(BUILDDIR)/tmp
|
||||
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
A Playground for Firmware development for advanced user of RTL8372/RTL8373 based 2.5GBit Switches.
|
||||
|
||||
For each hardware configuration of these devices, there is usually a managed and an
|
||||
umanaged version sold, with mostly identical hardware. The aim is to provide management
|
||||
unmanaged version sold, with mostly identical hardware. The aim is to provide management
|
||||
features also for unmanaged devices with additional features such as Management VLAN,
|
||||
dhcp servers, multi-language support, IPv6 and TLS-encrypted web-pages. At present, however
|
||||
DHCP servers, multi-language support, IPv6 and TLS-encrypted web-pages. At present, however
|
||||
only the following features are provided:
|
||||
- A modern web-interface with mouse-over to display further information
|
||||
- A serial console interface to configure all features
|
||||
- IGMP to configure Multicast streaming
|
||||
- Port configuration showing detailed informtion about own and Link-partner advertised
|
||||
Speed settins and configuration of these settings on the local side
|
||||
- Port configuration showing detailed information about own and Link-partner advertised
|
||||
Speed settings and configuration of these settings on the local side
|
||||
- Per-port configuration of frame sizes (MTUs) for Jumbo-Frame support or limiting MTUs
|
||||
for particular devices
|
||||
- EEE (Energy Efficient Ethernet) can be configured per-port. Detailed information is
|
||||
@@ -25,17 +25,19 @@ only the following features are provided:
|
||||
- Firmware updates via the web
|
||||
- Installation as a firmware upgrade from the original web-interface
|
||||
|
||||
<img width="1420" height="623" alt="GUI" src="doc/images/gui.png" />
|
||||
<img width="1673" height="977" alt="GUI" src="doc/images/gui.png" />
|
||||
|
||||
While the firmware provides already considerable improvements over the original managed firmware,
|
||||
the firmware still lacks support for STP and the proprietary loop prevention
|
||||
protocols as well as DHCP. If you need these features, do not install the playground on your managed
|
||||
the firmware still lacks support for the proprietary loop prevention
|
||||
protocols as well as DHCP. Spanning Tree is available (see doc/stp.md), but is
|
||||
a simplified implementation - read that document before enabling it on a
|
||||
switch you administer over the network. If you need these features, do not install the playground on your managed
|
||||
devices. In any case, installation is strongly discouraged unless you can at least make
|
||||
a backup of the original flash content via a SOIC clamp such as also used for BIOS
|
||||
backups and can re-install that firmware in case something is wrong. For this no soldering
|
||||
skills are necessary.
|
||||
|
||||
The firmware supports all hardware featues of devices with
|
||||
The firmware supports all hardware features of devices with
|
||||
- 4 2.5GBit ports + 2 SFP+ ports
|
||||
- 5 2.5GBIT + 1 SFP+ port
|
||||
- 8 2.5GBit + 1 SFP+ port
|
||||
@@ -57,9 +59,56 @@ device simulator is provided, which runs entirely under Linux as a local webserv
|
||||
Install the following particular build requisites (Debian 12/13), note that Ubuntu 24.04
|
||||
still has an older version of sdcc, but you will need sdcc version 4.5 for the code to compile:
|
||||
```
|
||||
sudo apt install make gcc sdcc xxd python-is-python3 libjson-c-dev
|
||||
sudo apt install make gcc sdcc xxd python-is-python3 libjson-c-dev zlib1g-dev
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>If using Docker (click to expand)</summary>
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Install Docker for your platform:
|
||||
|
||||
- **Linux (Debian/Ubuntu)**: `sudo apt install docker.io` then `sudo usermod -aG docker $USER` (log out and back in)
|
||||
- **Linux (other distros)**: Follow the [Docker Engine install guide](https://docs.docker.com/engine/install/)
|
||||
- **Windows**: Install [Docker Desktop for Windows](https://docs.docker.com/desktop/setup/install/windows-install/)
|
||||
- **macOS**: Install [Docker Desktop for Mac](https://docs.docker.com/desktop/setup/install/mac-install/)
|
||||
|
||||
### Usage
|
||||
|
||||
A Dockerfile is provided for a reproducible build environment:
|
||||
|
||||
```
|
||||
docker build -t rtlplayground-dev .
|
||||
```
|
||||
|
||||
Build the firmware (replace MACHINE with your target, e.g. `DEFAULT_8C_1SFP`):
|
||||
|
||||
```
|
||||
docker run --rm -v $(pwd):/workspace rtlplayground-dev make MACHINE=DEFAULT_8C_1SFP
|
||||
```
|
||||
|
||||
The resulting `.bin` file appears in `output/` on your host.
|
||||
|
||||
Build host tools only:
|
||||
|
||||
```
|
||||
docker run --rm -v $(pwd):/workspace rtlplayground-dev make -C tools
|
||||
```
|
||||
|
||||
Run the web-interface simulator locally:
|
||||
|
||||
```
|
||||
docker run --rm -p 8080:8080 -v $(pwd):/workspace rtlplayground-dev \
|
||||
tools/output/httpd_sim /workspace/html
|
||||
```
|
||||
|
||||
Edit `machine.h` or `config.txt` on your host, then re-run `make` — the
|
||||
source directory is mounted into the container, so changes take effect
|
||||
immediately. To build for a different machine, pass `MACHINE=...`.
|
||||
|
||||
</details>
|
||||
|
||||
## (1) Compiling for direct chip flashing AND upgrading an existing RTLPlayground running device
|
||||
|
||||
Edit machine.h with an editor like vi or nano. Select the correct machine the firmware should build for.
|
||||
@@ -82,7 +131,7 @@ rtlplayground-v0.1.0-12c98ba-dirty-LIANGUO_ZX_SWTGW215AS.bin
|
||||
|
||||
> [!CAUTION]
|
||||
> This image can be flashed directly to the chip OR through the firmware update/upgrade
|
||||
> interface of RTLPlaygound interface
|
||||
> interface of RTLPlayground interface
|
||||
|
||||
## (2) Compiling for OEM running device with management options (web upgrade)
|
||||
|
||||
@@ -126,11 +175,11 @@ Header checksum is: 0x5a1
|
||||
## (3) Sandbox Usage with Ghidra (optional)
|
||||
|
||||
You can play with the image using ghidra or flash real Switch Hardware. For
|
||||
ghidra see this information about [Ghidra images](ghidra.md).
|
||||
ghidra see this information about [Ghidra images](doc/ghidra.md).
|
||||
|
||||
## (4) Installation through the Web interface (software way)
|
||||
|
||||
Managed switches (OEM firmware of RTLplaygroud firmware) can be upgraded via the web interface.
|
||||
Managed switches (OEM firmware of RTLplayground firmware) can be upgraded via the web interface.
|
||||
Unmanaged switch cannot be flashed this way (see 5).
|
||||
|
||||
Go to "Firmware update" tab, select the correct file.
|
||||
@@ -141,7 +190,7 @@ Go to "Firmware update" tab, select the correct file.
|
||||
|
||||
> [!CAUTION]
|
||||
> Check one more time that your device matches the machine type before flashing.
|
||||
> Be shure you have a backup of the original firmware before diving in RTLPlaygroung.
|
||||
> Be sure you have a backup of the original firmware before diving in RTLPlayground.
|
||||
|
||||
Finally, push the Upload File Button and you're done !
|
||||
|
||||
@@ -149,7 +198,7 @@ Finally, push the Upload File Button and you're done !
|
||||
## (5) Flashing the ROM directly (hardware way, but also only way to rescue)
|
||||
|
||||
This procedure is the only way to flash unmanaged switches, if the ROM chip is large enough.
|
||||
This is also the only way to unbrick your device if something went wroong.
|
||||
This is also the only way to unbrick your device if something went wrong.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> You need a SOIC-8 clip to flash the ROM chip directly onboard.
|
||||
@@ -169,7 +218,7 @@ This is also the only way to unbrick your device if something went wroong.
|
||||
- ERASE THE ROM (BLANK) !
|
||||
- Load the firmware into IMSProg.
|
||||
- Flash is to the ROM chip.
|
||||
- Disconect the clip from the ROM chip.
|
||||
- Disconnect the clip from the ROM chip.
|
||||
- You're done, ready for the first boot.
|
||||
|
||||
## (6) Connecting a serial interface (optional)
|
||||
@@ -184,7 +233,7 @@ When you power up the switch, the device will perform some examples and provide
|
||||
## (8) The web-interface
|
||||
|
||||
The web-interface can be reached under the [default 192.168.10.247](http://192.168.10.247) unless you
|
||||
specified an IP adress in the config.txt before compilation.
|
||||
specified an IP address in the config.txt before compilation.
|
||||
|
||||
> [!TIP]
|
||||
> The default password is `1234`.
|
||||
@@ -284,17 +333,18 @@ While in compilation part, you might write directly to config.txt file before ma
|
||||
nano config.txt
|
||||
```
|
||||
|
||||
If you want to modify settings after the flash is done, go to the Advanced Settings tab in System Settings
|
||||
If you want to modify settings after the flash is done, go to the System tab and find the Startup Configuration.
|
||||
|
||||
<img width="1085" height="646" alt="ADVANCED SETTINGS" src="doc/images/advanced_settings.png" />
|
||||
<img width="1673" height="978" alt="ADVANCED SETTINGS" src="doc/images/advanced_settings.png" />
|
||||
|
||||
```
|
||||
ip xxx.xxx.xxx.xxx = IP adress of the switch
|
||||
gw yyy.yyy.yyy.yyy = IP adress of the gateway
|
||||
ip xxx.xxx.xxx.xxx = IP address of the switch
|
||||
gw yyy.yyy.yyy.yyy = IP address of the gateway
|
||||
netmask zzz.zzz.zzz.zzz = Network mask of the switch
|
||||
port x name xxx = Name xxx the port number x
|
||||
port z 1g = Set 1g speed for port z
|
||||
igmp on/off = Turn IGMP on or off
|
||||
session xxxx = Web session timeout in seconds (default 200)
|
||||
```
|
||||
[To be continue]
|
||||
|
||||
@@ -309,5 +359,7 @@ The following documents give further documentation on specific features of the R
|
||||
- [IGMP (IP-MC streaming)](doc/igmp.md)
|
||||
- [SFP+ ports](doc/sfp.md)
|
||||
- [Trunking aka. port aggregation](doc/trunking.md)
|
||||
- [LACP (802.3ad link aggregation)](doc/lacp.md)
|
||||
- [VLAN](doc/vlan.md)
|
||||
- [Storm control](doc/storm_control.md)
|
||||
- [Modifications and Flash replacement](doc/mods.md)
|
||||
@@ -0,0 +1,479 @@
|
||||
#pragma codeseg BANK3
|
||||
#pragma constseg BANK3
|
||||
|
||||
#include <8051.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "rtl837x_sfr.h"
|
||||
#include "rtl837x_regs.h"
|
||||
#include "rtl837x_common.h"
|
||||
#include "rtl837x_flash.h"
|
||||
#include "rtl837x_pins.h"
|
||||
#include "rtl837x_phy.h"
|
||||
#include "rtl837x_port.h"
|
||||
#include "rtl837x_init.h"
|
||||
#include "machine.h"
|
||||
#include "phy.h"
|
||||
#include "boot.h"
|
||||
|
||||
extern __code const struct machine machine;
|
||||
extern __xdata struct machine_runtime machine_detected;
|
||||
extern __xdata uint8_t sfr_data[4];
|
||||
extern volatile __xdata uint32_t ticks;
|
||||
__xdata uint32_t rtl8224_release_tick;
|
||||
extern __xdata uint8_t tx_seq;
|
||||
extern __code const uint8_t * __code const hex;
|
||||
|
||||
|
||||
|
||||
void sds_config_mac(uint8_t sds, uint8_t mode) __banked
|
||||
{
|
||||
reg_read_m(RTL837X_REG_SDS_MODES);
|
||||
sfr_data[0] = 0;
|
||||
sfr_data[1] = 0;
|
||||
switch (sds) {
|
||||
case 0:
|
||||
sfr_mask_data(0, 0x1f, mode);
|
||||
break;
|
||||
case 1:
|
||||
sfr_mask_data(0, 0xe0, mode << 5);
|
||||
sfr_mask_data(1, 0x03, mode >> 3);
|
||||
break;
|
||||
case 2:
|
||||
sfr_mask_data(1, 0xfc, 0x02 << 2);
|
||||
}
|
||||
if (machine_detected.isRTL8373) // Set 3rd SERDES Mode to 0x2 for RTL8224
|
||||
sfr_mask_data(1, 0xfc, 0x02 << 2);
|
||||
else
|
||||
sfr_data[2] &= 0x03;
|
||||
reg_write_m(RTL837X_REG_SDS_MODES);
|
||||
print_string("\nRTL837X_REG_SDS_MODES: ");
|
||||
print_reg(RTL837X_REG_SDS_MODES);
|
||||
print_string("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void early_boot_handle_button(void) __banked
|
||||
{
|
||||
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
|
||||
* to connect to an SFP module or a PHY
|
||||
* Valid modes are SDS_10GR, SDS_QXGMII, SDS_HISGMII, SDS_HSG, SDS_SGMII and SDS_1000BX_FIBER
|
||||
* The SerDes ID may be 0 or 1 for RTL8272 and 0-2 for RTL8373
|
||||
* SDS_QXGMII is used for 10G Fiber, RTL8224 and RTL8261BE
|
||||
*/
|
||||
void sds_config(uint8_t sds, uint8_t mode) __banked
|
||||
{
|
||||
print_string("sds_config sds: "); print_byte(sds); print_string(", mode: "); print_byte(mode); write_char('\n');
|
||||
sds_config_mac(sds, mode);
|
||||
|
||||
if (mode == SDS_10GR || mode == SDS_QXGMII)
|
||||
sds_write_v(sds, 0x21, 0x10, 0x4480); // Q002110:6480
|
||||
else
|
||||
sds_write_v(sds, 0x21, 0x10, 0x6480); // Q002110:6480
|
||||
sds_write_v(sds, 0x21, 0x13, 0x0400); // Q002113:0400
|
||||
sds_write_v(sds, 0x21, 0x18, 0x6d02); // Q002118:6d02
|
||||
sds_write_v(sds, 0x21, 0x1b, 0x424e); // Q00211b:424e
|
||||
sds_write_v(sds, 0x21, 0x1d, 0x0002); // Q00211d:0002
|
||||
sds_write_v(sds, 0x36, 0x1c, 0x1390); // Q00361c:1390
|
||||
sds_write_v(sds, 0x36, 0x14, 0x003f); // Q003614:003f
|
||||
|
||||
uint8_t page = 0;
|
||||
uint16_t v = 0;
|
||||
|
||||
switch (mode) {
|
||||
case SDS_SGMII:
|
||||
case SDS_1000BX_FIBER:
|
||||
v = 0x0300;
|
||||
page = 0x24;
|
||||
break;
|
||||
case SDS_HISGMII:
|
||||
case SDS_HSG:
|
||||
v = 0x0200;
|
||||
page = 0x28;
|
||||
break;
|
||||
case SDS_10GR:
|
||||
case SDS_QXGMII:
|
||||
v = 0x0200;
|
||||
page = 0x2e;
|
||||
break;
|
||||
case SDS_100FX:
|
||||
v = 0x0200;
|
||||
page = 0x26;
|
||||
break;
|
||||
default:
|
||||
print_string("Error in SDS Mode\n");
|
||||
return;
|
||||
}
|
||||
sds_write_v(sds, 0x36, 0x10, v); // Q003610:0200
|
||||
|
||||
if (page == 0x2e) { // 10G Fiber / SDS_QXGMII
|
||||
sds_write_v(sds, page, 0x04, 0x0080); // Q012e04:0080
|
||||
sds_write_v(sds, page, 0x06, 0x0408); // Q012e06:0408
|
||||
sds_write_v(sds, page, 0x07, 0x020d); // Q012e07:020d
|
||||
sds_write_v(sds, page, 0x09, 0x0601); // Q012e09:0601
|
||||
sds_write_v(sds, page, 0x0b, 0x222c); // Q012e0b:222c
|
||||
sds_write_v(sds, page, 0x0c, 0xa217); // Q012e0c:a217
|
||||
sds_write_v(sds, page, 0x0d, 0xfe40); // Q012e0d:fe40
|
||||
sds_write_v(sds, page, 0x15, 0xf5c1); // Q012e15:f5c1
|
||||
} else {
|
||||
sds_write_v(sds, page, 0x04, 0x0080); // Q002804:0080
|
||||
sds_write_v(sds, page, 0x07, 0x1201); // Q002807:1201
|
||||
sds_write_v(sds, page, 0x09, 0x0601); // Q002809:0601
|
||||
sds_write_v(sds, page, 0x0b, 0x232c); // Q00280b:232c
|
||||
sds_write_v(sds, page, 0x0c, 0x9217); // Q00280c:9217
|
||||
sds_write_v(sds, page, 0x0f, 0x5b50); // Q00280f:5b50
|
||||
sds_write_v(sds, page, 0x15, 0xe7c1); // Q002815:e7f1 BUG !
|
||||
}
|
||||
|
||||
sds_write_v(sds, page, 0x16, 0x0443); // Q002816:0443 / Q012e16:0443
|
||||
sds_write_v(sds, page, 0x1d, 0xabb0); // Q00281d:abb0 / Q012e1d:abb0
|
||||
|
||||
sds_write_v(sds, 0x06, 0x12, 0x5078); // Q000612:5078
|
||||
sds_write_v(sds, 0x07, 0x06, 0x9401); // Q000706:9401
|
||||
sds_write_v(sds, 0x07, 0x08, 0x9401); // Q000708:9401
|
||||
sds_write_v(sds, 0x07, 0x0a, 0x9401); // Q00070a:9401
|
||||
sds_write_v(sds, 0x07, 0x0c, 0x9401); // Q00070c:9401
|
||||
sds_write_v(sds, 0x1f, 0x0b, 0x0003); // Q001f0b:0003
|
||||
sds_write_v(sds, 0x06, 0x03, 0xc45c); // Q000603:c45c
|
||||
|
||||
// RTL8261BE
|
||||
if (machine.n_10g && mode == SDS_QXGMII) {
|
||||
sds_write_v(sds, 0x06, 0x1f, 0x2100); // Q00061f:2100
|
||||
sds_write_v(sds, 0x07, 0x11, 0x054f); // Q000711:054f
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0030); // Q002000:0030
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0010); // Q002000:0010
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0050); // Q002000:0050
|
||||
sds_write_v(sds, 0x20, 0x00, 0x00d0); // Q002000:00d0
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0cd0); // Q002000:0cd0
|
||||
sds_write_v(sds, 0x20, 0x00, 0x04d0); // Q002000:04d0
|
||||
sds_write_v(sds, 0x20, 0x00, 0x04d0); // Q002000:04d0
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0cd0); // Q002000:0cd0
|
||||
sds_write_v(sds, 0x20, 0x00, 0x00d0); // Q002000:00d0
|
||||
sds_write_v(sds, 0x20, 0x00, 0x00d0); // Q002000:00d0
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0050); // Q002000:0050
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0010); // Q002000:0010
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0010); // Q002000:0010
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0030); // Q002000:0030
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0000); // Q002000:0000
|
||||
sds_write_v(sds, 0x1f, 0x00, 0x000b); // Q001f00:000b
|
||||
sds_write_v(sds, 0x1f, 0x00, 0x0000); // Q001f00:0000
|
||||
return;
|
||||
}
|
||||
if (mode != SDS_QXGMII)
|
||||
sds_write_v(sds, 0x06, 0x1f, 0x2100); // Q00061f:2100
|
||||
|
||||
if (mode == SDS_1000BX_FIBER) {
|
||||
sds_write_v(sds, 0x02, 0x04, 0x0020); // Q000204:0020
|
||||
sds_write_v(sds, 0x00, 0x02, 0x73d0); // Q000002:73d0
|
||||
sds_write_v(sds, 0x00, 0x04, 0x074d); // Q000004:074d
|
||||
sds_write_v(sds, 0x20, 0x04, 0x0000); // Q002000:0000
|
||||
sds_write_v(sds, 0x1f, 0x00, 0x0000); // Q001f00:0000
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void rtl8224_enable(void) __banked
|
||||
{
|
||||
// Set Pin 4 low
|
||||
reg_bit_clear(RTL837X_REG_GPIO_32_63_OUTPUT, 4);
|
||||
// Configure Pin as output
|
||||
reg_bit_set(RTL837X_REG_GPIO_32_63_DIRECTION, 4);
|
||||
delay(4);
|
||||
// Set pin 4 high
|
||||
reg_bit_set(RTL837X_REG_GPIO_32_63_OUTPUT, 4);
|
||||
rtl8224_release_tick = ticks;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void nic_setup(void) __banked
|
||||
{
|
||||
// Enable NIC
|
||||
// r6040:00000100 R6040-00001100
|
||||
reg_bit_set(RTL837X_REG_HW_CONF, 0xc);
|
||||
|
||||
// This sets the size of the RX buffer, the filling level is in 0x7874
|
||||
// R7848-000004ff
|
||||
REG_SET(RTL837X_REG_NIC_RXBUFF_RX, 0x4ff);
|
||||
|
||||
// R7844-000007fe
|
||||
REG_SET(RTL837X_REG_NIC_BUFFSIZE_TX, 0x7fe);
|
||||
|
||||
// Configure NIC RX to receive various types of packets
|
||||
// RTL837X_REG_RX_CTRL: Set bits 24-31 to 0x4, clear bits 16/17
|
||||
reg_read_m(RTL837X_REG_RX_CTRL);
|
||||
sfr_mask_data(3, 0xff, 0x04);
|
||||
sfr_mask_data(2, 0x03, 0);
|
||||
reg_write_m(RTL837X_REG_RX_CTRL);
|
||||
|
||||
// Enable NIC TX (set bit 0)
|
||||
reg_bit_set(RTL837X_REG_TX_CTRL, 0);
|
||||
|
||||
// Enable NIC RX (set bit 0)
|
||||
reg_bit_set(RTL837X_REG_RX_CTRL, 0);
|
||||
|
||||
// Drop packets with invalid CRC
|
||||
reg_bit_clear(RTL837X_REG_RX_CTRL, 2);
|
||||
|
||||
// R603c-00000200
|
||||
// CPU-port is CPU-Tag aware (bit 9)
|
||||
REG_SET(RTL837X_REG_CPU_TAG_AWARE_PMASK, 0x200);
|
||||
|
||||
// Insert CPU-tag for internally received packets (bit 0), MODE is 0, i.e. ALL packets (bits 8-9)
|
||||
reg_read_m(RTL837X_REG_CPU_TAG);
|
||||
sfr_mask_data(0, 1, 1);
|
||||
sfr_mask_data(1, 3, 0);
|
||||
reg_write_m(RTL837X_REG_CPU_TAG);
|
||||
|
||||
// Force MAC mode of the CPU port (port 9)
|
||||
// r6368:00000194 R6368-00000197
|
||||
reg_read_m(RTL837X_REG_MAC_FORCE_MODE + 9 * 4);
|
||||
sfr_mask_data(0, 0, 3); // Set bits 0, 1: Force link
|
||||
reg_write_m(RTL837X_REG_MAC_FORCE_MODE+ 9 * 4);
|
||||
|
||||
// Sequence number of TX packets
|
||||
tx_seq = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void rtl8373_revision(void) __banked
|
||||
{
|
||||
reg_read_m(RTL837X_REG_CHIP_INFO);
|
||||
sfr_mask_data(2, 0x0a, 0x0a); // Enable reading version
|
||||
reg_write_m(RTL837X_REG_CHIP_INFO);
|
||||
delay(50);
|
||||
|
||||
reg_read_m(RTL837X_REG_CHIP_INFO);
|
||||
print_string("CPU revision: "); print_byte(sfr_data[2]); print_byte(sfr_data[2]); write_char('\n');
|
||||
sfr_mask_data(2, 0x0a, 0x00); // Enable reading version
|
||||
reg_write_m(RTL837X_REG_CHIP_INFO);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The SoC manages Link-State for steering the LEDs and can set PHY-settings
|
||||
* automatically through Realtek's SMI (Simple Managagement) Interface, a
|
||||
* proprietary version of MDIO which for example allows for more PHYs on the same
|
||||
* bus.
|
||||
* Configure polling via SMI and the interface setup during boot.
|
||||
*/
|
||||
void init_smi(void) __banked
|
||||
{
|
||||
print_string("\ninit_switch called\n");
|
||||
|
||||
/* Set the SMI(i.e.I2C) type for PHY polling, 0b01 is 2.5/10G PHY. Disable (0b00) for the SFP-ports
|
||||
* which are at port 8 and additionally at port 3 for a dual SFP device
|
||||
*/
|
||||
|
||||
// Default: 0x00005555
|
||||
// Workaround for SDCC BUG 4070: SFR_DATA_U32 = 0x00005555;
|
||||
SFR_DATA_U16_UPPER = 0x0000;
|
||||
SFR_DATA_U16 = 0x5555;
|
||||
if (machine.n_10g == 2) {
|
||||
// 0x00015555, only change the bytes that differs from the default.
|
||||
SFR_DATA_16 = 0x01;
|
||||
} else if (machine.n_sfp == 2)
|
||||
// 0x00005515
|
||||
SFR_DATA_0 = 0x15;
|
||||
reg_write(RTL837X_REG_SMI_MAC_TYPE);
|
||||
|
||||
// Configure polling of all PHYs by the MAC to detect link-state changes
|
||||
// Default: 0x000000ff
|
||||
// Workaround for SDCC BUG 4070: SFR_DATA_U32 = 0x000000ff;
|
||||
SFR_DATA_U16_UPPER = 0x0000;
|
||||
SFR_DATA_U16 = 0x00ff;
|
||||
if (!machine_detected.isRTL8373) {
|
||||
if (machine.n_sfp == 2) {
|
||||
// 0x000000f0, only change the bytes that differs from the default.
|
||||
SFR_DATA_0 = 0xf0;
|
||||
} else {
|
||||
// 0x000001f8, only change the bytes that differs from the default.
|
||||
SFR_DATA_8 = 0x01;
|
||||
SFR_DATA_0 = 0xf8;
|
||||
}
|
||||
}
|
||||
reg_write(RTL837X_REG_SMI_PORT_POLLING);
|
||||
// Enable MDC
|
||||
reg_read_m(RTL837X_REG_SMI_CTRL);
|
||||
sfr_mask_data(1, 0, 0x70); // Set bits 12-14 to enable MDC for SMI0-SMI2
|
||||
reg_write_m(RTL837X_REG_SMI_CTRL);
|
||||
delay(50);
|
||||
|
||||
if (!machine_detected.isRTL8373) {
|
||||
// Change I2C addresses for SMI of the non-existent PHYs
|
||||
// r6450:000020e6 R6450-000000e6
|
||||
reg_read_m(RTL837X_REG_SMI_PORT6_9_ADDR);
|
||||
sfr_mask_data(1, 0x7c, 0);
|
||||
reg_write_m(RTL837X_REG_SMI_PORT6_9_ADDR);
|
||||
|
||||
// r644c:0a418820 R644c-0a400820
|
||||
reg_read_m(RTL837X_REG_SMI_PORT0_5_ADDR);
|
||||
sfr_mask_data(2, 0x0f, 0);
|
||||
sfr_mask_data(1, 0x80, 0);
|
||||
reg_write_m(RTL837X_REG_SMI_PORT0_5_ADDR);
|
||||
}
|
||||
|
||||
if (machine.n_10g == 2) {
|
||||
// Set address of second external PHY on port 8
|
||||
REG_SET(RTL837X_REG_SMI_PORT6_9_ADDR, 0x000040e6);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void setup_i2c(void) __banked
|
||||
{
|
||||
REG_SET(RTL837X_REG_I2C_MST_IF_CTRL, 0);
|
||||
// Configure SFP EEPROM address (0x50) as I2C device address
|
||||
// Configure SFP readings address (0x51) as I2C device address
|
||||
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16), 0x50 >> 5, (0x50 << 3) & 0xff);
|
||||
|
||||
REG_SET(RTL837X_REG_I2C_CTRL2, 0);
|
||||
|
||||
// HW Control register, enable I2C depending on PIN configuration
|
||||
reg_read_m(RTL837X_PIN_MUX_1);
|
||||
for (uint8_t sfp = 0; sfp < machine.n_sfp; sfp++) {
|
||||
uint8_t i2c = machine.sfp_port[sfp].i2c;
|
||||
uint8_t scl_bus = (i2c >> RTL837X_REG_I2C_SCL_SHIFT) & RTL837X_REG_I2C_SCL_MASK;
|
||||
uint8_t sda_bus = (i2c >> RTL837X_REG_I2C_SDA_SHIFT) & RTL837X_REG_I2C_SDA_MASK;
|
||||
print_string("Configuring I2C for SFP idx="); print_byte(sfp); print_string(" SCL="); print_byte(scl_bus); print_string(", SDA="); print_byte(sda_bus); write_char('\n');
|
||||
// `& RTL837X_REG_I2C_SCL_MASK` is needed to silens a compiler warning 110.
|
||||
switch (scl_bus & RTL837X_REG_I2C_SCL_MASK) {
|
||||
case 3:
|
||||
// Bit 5-6 0b10 -> SCL (implies enabled SDA on bus 3)
|
||||
sfr_mask_data(0, 0x60, 0x40);
|
||||
break;
|
||||
case 2:
|
||||
// Bit 15-16 0b01 -> SCL
|
||||
sfr_mask_data(1, 0x80, 0x80);
|
||||
sfr_mask_data(2, 0x01, 0x00);
|
||||
break;
|
||||
case 1:
|
||||
// Bit 11-12 0b01 -> SCL
|
||||
sfr_mask_data(1, 0x18, 0x08);
|
||||
break;
|
||||
case 0:
|
||||
// Bit 7-8 0b01 -> SCL
|
||||
sfr_mask_data(0, 0x80, 0x80);
|
||||
sfr_mask_data(1, 0x01, 0x00);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (sda_bus) {
|
||||
case 4:
|
||||
// Bit 29 0b0 -> SDA
|
||||
sfr_mask_data(3, 0x20, 0x00);
|
||||
break;
|
||||
case 3:
|
||||
// Bit 5-6 0b10 -> SDA (implies enabled SCL on bus 3)
|
||||
sfr_mask_data(0, 0x60, 0x40);
|
||||
break;
|
||||
case 2:
|
||||
// Bit 17-18 0b01 -> SDA
|
||||
sfr_mask_data(2, 0x06, 0x02);
|
||||
break;
|
||||
case 1:
|
||||
// Bit 13-14 0b01 -> SDA
|
||||
sfr_mask_data(1, 0x60, 0x20);
|
||||
break;
|
||||
case 0:
|
||||
// Bit 9-10 0b01 -> SDA
|
||||
sfr_mask_data(1, 0x06, 0x02);
|
||||
break;
|
||||
}
|
||||
}
|
||||
reg_write_m(RTL837X_PIN_MUX_1);
|
||||
}
|
||||
|
||||
|
||||
/* Give the switch a name carrying the tail of its MAC, so several of them on
|
||||
* one network are distinguishable out of the box. Called after the startup
|
||||
* config has been replayed and returns at once if that config already set a
|
||||
* name, so a configured switch does no work for it (suggested in review).
|
||||
*
|
||||
* Written without a loop on purpose. Locals - counters and pointers alike -
|
||||
* land in the 8051's internal-RAM overlay, and on an image with LACP and STP
|
||||
* both enabled that overlay is exhausted: a loop here makes the linker fail
|
||||
* with "Could not get 8 consecutive bytes in internal RAM for area OSEG".
|
||||
* Moving the code into its own function does not help; the overlay is shared
|
||||
* across the whole image. Hoisting the locals to xdata does not help either,
|
||||
* because itohex() is inline and brings its own frame. */
|
||||
void set_hostname_default(void) __banked
|
||||
{
|
||||
if (hostname[0] != NUL)
|
||||
return;
|
||||
|
||||
strcpy((__xdata uint8_t *)hostname, "RTLPlayground-");
|
||||
hostname[14] = hex[uip_ethaddr.addr[3] >> 4];
|
||||
hostname[15] = hex[uip_ethaddr.addr[3] & 0xf];
|
||||
hostname[16] = hex[uip_ethaddr.addr[4] >> 4];
|
||||
hostname[17] = hex[uip_ethaddr.addr[4] & 0xf];
|
||||
hostname[18] = hex[uip_ethaddr.addr[5] >> 4];
|
||||
hostname[19] = hex[uip_ethaddr.addr[5] & 0xf];
|
||||
hostname[20] = NUL;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef BOOT_H
|
||||
#define BOOT_H
|
||||
|
||||
void sds_config_mac(uint8_t sds, uint8_t mode) __banked;
|
||||
void sds_config(uint8_t sds, uint8_t mode) __banked;
|
||||
void early_boot_handle_button(void) __banked;
|
||||
void rtl8224_enable(void) __banked;
|
||||
void nic_setup(void) __banked;
|
||||
void rtl8373_revision(void) __banked;
|
||||
void init_smi(void) __banked;
|
||||
void setup_i2c(void) __banked;
|
||||
void set_hostname_default(void) __banked;
|
||||
|
||||
#endif
|
||||
@@ -40,21 +40,24 @@ void cmd_edit(void) __banked
|
||||
{
|
||||
while (l != sbuf_ptr) {
|
||||
if (sbuf[l] >= ' ' && sbuf[l] < 127) { // A printable character, copy to command line
|
||||
if (cmd_line_len >= CMD_BUF_SIZE)
|
||||
continue;
|
||||
write_char(sbuf[l]);
|
||||
// Shift buffer to right
|
||||
for (uint8_t i = cmd_line_len; i > cursor; i--)
|
||||
cmd_buffer[i] = cmd_buffer[i-1];
|
||||
// Insert char in comand buffer
|
||||
cmd_buffer[cursor++] = sbuf[l];
|
||||
cmd_line_len++;
|
||||
// Print rest of line
|
||||
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
||||
write_char(cmd_buffer[i]);
|
||||
// Move backwards
|
||||
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
||||
write_char('\010'); // BS works like cursor-left
|
||||
// Reserve one byte for the terminating NUL written on Enter. When the
|
||||
// line is full, drop the character but still fall through to advance the
|
||||
// serial-ring read pointer below; a 'continue' here would spin forever.
|
||||
if (cmd_line_len < CMD_BUF_SIZE - 1) {
|
||||
write_char(sbuf[l]);
|
||||
// Shift buffer to right
|
||||
for (uint8_t i = cmd_line_len; i > cursor; i--)
|
||||
cmd_buffer[i] = cmd_buffer[i-1];
|
||||
// Insert char in comand buffer
|
||||
cmd_buffer[cursor++] = sbuf[l];
|
||||
cmd_line_len++;
|
||||
// Print rest of line
|
||||
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
||||
write_char(cmd_buffer[i]);
|
||||
// Move backwards
|
||||
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
||||
write_char('\010'); // BS works like cursor-left
|
||||
}
|
||||
} else if (sbuf[l] == '\033') { // ESC-Sequence
|
||||
// Wait until we have at least 3 characters including the ESC character in the serial buffer
|
||||
if (((sbuf_ptr + SBUF_SIZE - l) & SBUF_MASK) < 3)
|
||||
@@ -190,7 +193,7 @@ void cmd_edit(void) __banked
|
||||
// Check whether return was pressed:
|
||||
if (sbuf[l] == '\n' || sbuf[l] == '\r') {
|
||||
write_char('\n');
|
||||
cmd_buffer[cmd_line_len] = '\0';
|
||||
cmd_buffer[cmd_line_len] = NUL;
|
||||
// write_char('>'); print_string_x(cmd_buffer); write_char('<');
|
||||
// If there is a command we print the prompt after execution
|
||||
// otherwise immediately because there is nothing to execute
|
||||
|
||||
@@ -6,13 +6,42 @@
|
||||
#include "rtl837x_common.h"
|
||||
|
||||
extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
||||
extern __xdata uint8_t cmd_available;
|
||||
extern __bit __at(0x03) cmd_available;
|
||||
extern __xdata uint8_t err_status;
|
||||
|
||||
/* Health instrumentation, built with HEALTH=1. Without it the hooks below
|
||||
* compile to nothing and the "health" command does not exist. */
|
||||
#ifdef HEALTH
|
||||
/* Phase ids, in main-loop order */
|
||||
#define HEALTH_PH_LINK 0
|
||||
#define HEALTH_PH_SFP 1
|
||||
#define HEALTH_PH_RX 2
|
||||
#define HEALTH_PH_TX 3
|
||||
#define HEALTH_PH_STP 4
|
||||
#define HEALTH_PH_CMD 5
|
||||
#define HEALTH_PHASES 6
|
||||
#define HEALTH_LLDP 7
|
||||
|
||||
extern __xdata uint16_t health_rx_frames;
|
||||
#define health_rx_frame() health_rx_frames++
|
||||
|
||||
void health_loop_start(void) __banked; /* once per idle() pass, resets the phase baseline */
|
||||
void health_phase(uint8_t id) __banked; /* after each phase; accounts ticks since last checkpoint */
|
||||
void health_stack_paint(void) __banked; /* paint the unused stack area once at boot */
|
||||
void health_show(void) __banked; /* "health" CLI dump */
|
||||
#else
|
||||
#define health_rx_frame()
|
||||
#define health_loop_start()
|
||||
#define health_phase(id)
|
||||
#define health_stack_paint()
|
||||
#endif
|
||||
|
||||
void cmd_tokenize(void) __banked;
|
||||
void cmd_parser(void) __banked;
|
||||
void execute_config(void) __banked;
|
||||
void execute_commands(__xdata uint8_t *p) __banked;
|
||||
void print_ip(__xdata uint8_t *ptr) __banked;
|
||||
void print_mac(__xdata uint8_t *ptr) __banked;
|
||||
void print_sw_version(void) __banked;
|
||||
void clear_command_history(void) __banked;
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
;
|
||||
.globl _crc_value
|
||||
.globl _crc16
|
||||
.globl _crc16_bank1
|
||||
.globl __sdcc_banked_ret
|
||||
.equ BANK, 0x96
|
||||
; .equ DPS, 0x86
|
||||
; Variable in XMEM holding current CRC16 value, being updated
|
||||
@@ -18,7 +20,7 @@ _crc_value::
|
||||
.area HOME (CODE)
|
||||
.area CSEG (CODE)
|
||||
; .area BANK1 (CODE)
|
||||
_crc16:
|
||||
_crc16_bank1:
|
||||
mov BANK, #1
|
||||
push dph
|
||||
push dpl
|
||||
@@ -52,6 +54,10 @@ _crc16:
|
||||
|
||||
.area BANK1 (CODE)
|
||||
|
||||
_crc16:
|
||||
lcall _crc16_bank1
|
||||
ljmp __sdcc_banked_ret
|
||||
|
||||
crc16_table_l:
|
||||
.byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41
|
||||
.byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
.area HOME (CODE)
|
||||
.area GSINIT0 (CODE)
|
||||
.area GSINIT1 (CODE)
|
||||
.area GSINIT2 (CODE)
|
||||
.area GSINIT3 (CODE)
|
||||
.area GSINIT4 (CODE)
|
||||
.area GSINIT5 (CODE)
|
||||
.area GSINIT (CODE)
|
||||
.area GSFINAL (CODE)
|
||||
.area CSEG (CODE)
|
||||
|
||||
|
||||
.area HOME (CODE)
|
||||
|
||||
__sdcc_banked_call::
|
||||
push _PSBANK
|
||||
xch a,r0
|
||||
push a
|
||||
mov a,r1
|
||||
push a
|
||||
mov a,r2
|
||||
anl a,#0x1f
|
||||
mov _PSBANK, a
|
||||
xch a, r0
|
||||
ret
|
||||
|
||||
__sdcc_banked_ret::
|
||||
pop _PSBANK
|
||||
ret
|
||||
@@ -1,17 +0,0 @@
|
||||
.area GSFINAL (CODE)
|
||||
|
||||
__sdcc_banked_call::
|
||||
push _PSBANK
|
||||
xch a,r0
|
||||
push a
|
||||
mov a,r1
|
||||
push a
|
||||
mov a,r2
|
||||
anl a,#0x1f
|
||||
mov _PSBANK, a
|
||||
xch a, r0
|
||||
ret
|
||||
|
||||
__sdcc_banked_ret::
|
||||
pop _PSBANK
|
||||
ret
|
||||
@@ -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
|
||||
@@ -0,0 +1,103 @@
|
||||
#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(0xbf00) chacha20;
|
||||
|
||||
#ifdef CHACHA20_TEST
|
||||
__xdata uint8_t plaintext[256];
|
||||
__xdata uint8_t cyphertext[256];
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
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(' ');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef CHACHA20_TEST
|
||||
// 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(' ');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,455 @@
|
||||
; ChaCha Quater-Round implementation in Assembler
|
||||
.module chacha_8051
|
||||
; Global variables:
|
||||
.globl _chacha_20
|
||||
.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
|
||||
|
||||
|
||||
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
|
||||
|
||||
; 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
|
||||
|
||||
|
||||
;
|
||||
; 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
|
||||
jnz chacha_count_done
|
||||
dec dpl
|
||||
movx a, @dptr
|
||||
inc a
|
||||
movx @dptr, a
|
||||
jnz chacha_count_done
|
||||
dec dpl
|
||||
movx a, @dptr
|
||||
inc a
|
||||
movx @dptr, a
|
||||
jnz chacha_count_done
|
||||
dec dpl
|
||||
movx a, @dptr
|
||||
inc a
|
||||
movx @dptr, a
|
||||
chacha_count_done:
|
||||
pop dph
|
||||
pop dpl
|
||||
pop acc
|
||||
ret
|
||||
@@ -41,6 +41,7 @@ __xdata uip_ipaddr_t server;
|
||||
#define DHCP_REBIND_LEN 4
|
||||
#define DHCP_CLIENT_ID 61
|
||||
#define DHCP_CLIENT_ID_LEN 7
|
||||
#define DHCP_HOSTNAME 12
|
||||
#define DHCP_REQUEST_IP 50
|
||||
#define DHCP_REQUEST_IP_LEN 4
|
||||
#define DHCP_PARAMS 55
|
||||
@@ -49,7 +50,7 @@ __xdata uip_ipaddr_t server;
|
||||
#define DHCP_PARAM_DNS 6
|
||||
#define DHCP_END 255
|
||||
|
||||
#pragma codeseg BANK2
|
||||
#pragma codeseg BANK3
|
||||
#pragma constseg BANK2
|
||||
|
||||
struct dhcp_pkt {
|
||||
@@ -93,7 +94,7 @@ void dhcp_prepare_request(void)
|
||||
DHCP_P->hw_len = 6;
|
||||
DHCP_P->hops = 0;
|
||||
|
||||
DHCP_P->tid = HTONS(dhcp_state.transaction_id);
|
||||
DHCP_P->tid = dhcp_state.transaction_id;
|
||||
DHCP_P->delay = HTONS(0);
|
||||
DHCP_P->flags = 0;
|
||||
// Clear fields client_ip to bootp_file
|
||||
@@ -116,6 +117,20 @@ void dhcp_addopt_client_id(void)
|
||||
}
|
||||
|
||||
|
||||
void dhcp_addopt_hostname(void)
|
||||
{
|
||||
uint8_t len = 0;
|
||||
while (hostname[len])
|
||||
len++;
|
||||
if (!len)
|
||||
return;
|
||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_HOSTNAME;
|
||||
DHCP_OPT[dhcp_state.opt_ptr++] = len;
|
||||
memcpy(&DHCP_OPT[dhcp_state.opt_ptr], hostname, len);
|
||||
dhcp_state.opt_ptr += len;
|
||||
}
|
||||
|
||||
|
||||
void dhcp_addopt_request_ip(void)
|
||||
{
|
||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_REQUEST_IP;
|
||||
@@ -124,7 +139,6 @@ 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[2];
|
||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[3];
|
||||
memcpy(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
|
||||
}
|
||||
|
||||
|
||||
@@ -136,13 +150,11 @@ 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[2];
|
||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[3];
|
||||
memcpy(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
|
||||
}
|
||||
|
||||
|
||||
void dhcp_send_discover(void)
|
||||
{
|
||||
print_string("dhcp_send_discover called\n");
|
||||
dhcp_prepare_request();
|
||||
|
||||
dhcp_state.opt_ptr = 0;
|
||||
@@ -152,6 +164,7 @@ void dhcp_send_discover(void)
|
||||
|
||||
dhcp_addopt_client_id();
|
||||
dhcp_addopt_request_ip();
|
||||
dhcp_addopt_hostname();
|
||||
|
||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_PARAMS;
|
||||
DHCP_OPT[dhcp_state.opt_ptr++] = 3;
|
||||
@@ -177,7 +190,6 @@ void dhcp_send_discover(void)
|
||||
|
||||
void dhcp_send_request(void)
|
||||
{
|
||||
print_string("dhcp_send_request called\n");
|
||||
dhcp_prepare_request();
|
||||
|
||||
dhcp_state.opt_ptr = 0;
|
||||
@@ -188,6 +200,7 @@ void dhcp_send_request(void)
|
||||
dhcp_addopt_client_id();
|
||||
dhcp_addopt_request_ip();
|
||||
dhcp_addopt_server_id();
|
||||
dhcp_addopt_hostname();
|
||||
|
||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_PARAMS;
|
||||
DHCP_OPT[dhcp_state.opt_ptr++] = 3;
|
||||
@@ -215,19 +228,21 @@ void ip_opt(__xdata uint8_t * ip)
|
||||
{
|
||||
dhcp_state.opt_ptr++;
|
||||
uint8_t len = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||
if (len >= 4)
|
||||
memcpy(ip, &DHCP_OPT[dhcp_state.opt_ptr], 4);
|
||||
// There may be more than one IP option, such as 2 DNS servers advertised
|
||||
dhcp_state.opt_ptr += len - 4;
|
||||
dhcp_state.opt_ptr += len;
|
||||
}
|
||||
|
||||
|
||||
void long_opt(void)
|
||||
uint8_t long_opt(void)
|
||||
{
|
||||
dhcp_state.opt_ptr++;
|
||||
dhcp_state.opt_ptr++;
|
||||
uint8_t len = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||
if (len < 4) {
|
||||
dhcp_state.opt_ptr += len;
|
||||
return 0;
|
||||
}
|
||||
long_value = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||
long_value <<= 8;
|
||||
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
||||
@@ -235,6 +250,8 @@ void long_opt(void)
|
||||
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
||||
long_value <<= 8;
|
||||
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
||||
dhcp_state.opt_ptr += len - 4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -258,16 +275,16 @@ void parse_opts(void)
|
||||
ip_opt(&dhcp_state.broadcast[0]);
|
||||
break;
|
||||
case DHCP_LEASE:
|
||||
long_opt();
|
||||
dhcp_state.lease = long_value;
|
||||
if (long_opt())
|
||||
dhcp_state.lease = long_value;
|
||||
break;
|
||||
case DHCP_REBIND:
|
||||
long_opt();
|
||||
dhcp_state.rebind = long_value;
|
||||
if (long_opt())
|
||||
dhcp_state.rebind = long_value;
|
||||
break;
|
||||
case DHCP_RENEWAL:
|
||||
long_opt();
|
||||
dhcp_state.renewal = long_value;
|
||||
if (long_opt())
|
||||
dhcp_state.renewal = long_value;
|
||||
break;
|
||||
case DHCP_END:
|
||||
break;
|
||||
@@ -283,7 +300,7 @@ void parse_opts(void)
|
||||
|
||||
void parse_dhcp(void)
|
||||
{
|
||||
if (!DHCP_P->tid == HTONS(dhcp_state.transaction_id))
|
||||
if (DHCP_P->tid != dhcp_state.transaction_id)
|
||||
return;
|
||||
if (DHCP_P->cookie[0] != 0x63 || DHCP_P->cookie[1] != 0x82 || DHCP_P->cookie[2] != 0x53 || DHCP_P->cookie[3] != 0x63)
|
||||
return;
|
||||
@@ -315,6 +332,18 @@ void parse_dhcp(void)
|
||||
uip_ipaddr(&uip_hostaddr, dhcp_state.current_ip[0], dhcp_state.current_ip[1], dhcp_state.current_ip[2], dhcp_state.current_ip[3]);
|
||||
uip_ipaddr(&uip_draddr, dhcp_state.router[0], dhcp_state.router[1], dhcp_state.router[2], dhcp_state.router[3]);
|
||||
uip_ipaddr(&uip_netmask, dhcp_state.subnet[0], dhcp_state.subnet[1], dhcp_state.subnet[2], dhcp_state.subnet[3]);
|
||||
/* T1 is optional. Without it the renewal time stays zero, which
|
||||
* makes dhcp_timer zero, and the callback then sends a REQUEST on
|
||||
* every pass through LEASING: client and server trade REQUEST and
|
||||
* ACK as fast as the round trip allows. RFC 2131 has the client
|
||||
* renew at half the lease when the server does not say, and if
|
||||
* there is no lease either, pick something rather than zero. Only
|
||||
* filled in when absent, so a server that asks for a short renewal
|
||||
* still gets it. */
|
||||
if (!dhcp_state.renewal)
|
||||
dhcp_state.renewal = dhcp_state.lease / 2;
|
||||
if (!dhcp_state.renewal)
|
||||
dhcp_state.renewal = 60;
|
||||
dhcp_state.state = DHCP_LEASING;
|
||||
dhcp_state.ticks = SYS_TICK_HZ;
|
||||
dhcp_state.dhcp_timer = dhcp_state.renewal > 0xffff ? 0xffff : dhcp_state.renewal;
|
||||
@@ -324,6 +353,12 @@ void parse_dhcp(void)
|
||||
|
||||
void dhcp_start(void) __banked
|
||||
{
|
||||
/* Starting twice would leave the first socket bound: uip_udp_new() takes
|
||||
* the next free slot while the old one keeps port 68, and dhcp_callback()
|
||||
* matches on that port rather than on the connection, so every leftover
|
||||
* runs the state machine too and the timers count down once per socket. */
|
||||
if (dhcp_state.state != DHCP_OFF)
|
||||
dhcp_stop();
|
||||
uip_ipaddr(server, 255,255,255,255);
|
||||
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;
|
||||
@@ -334,15 +369,18 @@ void dhcp_start(void) __banked
|
||||
return;
|
||||
}
|
||||
get_random_32();
|
||||
dhcp_state.transaction_id = SFR_DATA_U32;
|
||||
// Workaround SDCC bug 4070: dhcp_state.transaction_id = SFR_DATA_U32;
|
||||
__xdata uint8_t * tid = &dhcp_state.transaction_id;
|
||||
*tid++ = SFR_DATA_24;
|
||||
*tid++ = SFR_DATA_16;
|
||||
*tid++ = SFR_DATA_8;
|
||||
*tid = SFR_DATA_0;
|
||||
dhcp_state.state = DHCP_START;
|
||||
print_string("dhcp_start done\n");
|
||||
}
|
||||
|
||||
|
||||
void dhcp_stop(void) __banked
|
||||
{
|
||||
print_string("dhcp_stop called\n");
|
||||
uip_udp_remove(dhcp_state.conn);
|
||||
dhcp_state.state = DHCP_OFF;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* DNS resolver for the RTL837x platform
|
||||
* This code is in the Public Domain
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "rtl837x_common.h"
|
||||
#include "cmd_parser.h"
|
||||
#include "uip/uip.h"
|
||||
#include "dhcp.h"
|
||||
#include "dns.h"
|
||||
|
||||
#pragma codeseg BANK3
|
||||
#pragma constseg BANK3
|
||||
|
||||
#define DNS_PORT 53
|
||||
#define DNS_TRIES 6
|
||||
#define DNS_TIMEOUT (2 * SYS_TICK_HZ)
|
||||
|
||||
extern __xdata struct dhcp_state dhcp_state;
|
||||
extern volatile __xdata uint32_t ticks;
|
||||
|
||||
__xdata struct dns_state dns_state;
|
||||
__xdata uip_ipaddr_t dns_ip;
|
||||
uint8_t * __xdata dns_cand[3];
|
||||
|
||||
|
||||
static uint8_t dns_used(__xdata uint8_t *a) __reentrant
|
||||
{
|
||||
return a[0] | a[1] | a[2] | a[3];
|
||||
}
|
||||
|
||||
|
||||
static uint8_t dns_name_is_ip(void) __reentrant
|
||||
{
|
||||
__xdata char *s = dns_state.name;
|
||||
uint8_t i, n;
|
||||
uint16_t v;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
v = 0;
|
||||
n = 0;
|
||||
while (*s >= '0' && *s <= '9') {
|
||||
v = v * 10 + (*s++ - '0');
|
||||
if (++n > 3 || v > 255)
|
||||
return 0;
|
||||
}
|
||||
if (!n)
|
||||
return 0;
|
||||
dns_state.addr[i] = v;
|
||||
if (i < 3 && *s++ != '.')
|
||||
return 0;
|
||||
}
|
||||
return !*s;
|
||||
}
|
||||
|
||||
|
||||
static void dns_next(void) __reentrant
|
||||
{
|
||||
uint8_t k = 0;
|
||||
|
||||
if (dns_state.conn) {
|
||||
uip_udp_remove(dns_state.conn);
|
||||
dns_state.conn = 0;
|
||||
}
|
||||
if (dns_used(dns_state.server[0]))
|
||||
dns_cand[k++] = dns_state.server[0];
|
||||
if (dns_used(dns_state.server[1]))
|
||||
dns_cand[k++] = dns_state.server[1];
|
||||
if (dns_used(dhcp_state.dns))
|
||||
dns_cand[k++] = dhcp_state.dns;
|
||||
if (!k || dns_state.tries >= DNS_TRIES) {
|
||||
dns_state.status = DNS_FAILED;
|
||||
if (dns_state.verbose)
|
||||
print_string(k ? "DNS: no answer\n" : "DNS: no server\n");
|
||||
return;
|
||||
}
|
||||
k = dns_state.tries % k;
|
||||
uip_ipaddr(dns_ip, dns_cand[k][0], dns_cand[k][1], dns_cand[k][2], dns_cand[k][3]);
|
||||
dns_state.conn = uip_udp_new(&dns_ip, HTONS(DNS_PORT));
|
||||
if (!dns_state.conn) {
|
||||
dns_state.status = DNS_FAILED;
|
||||
print_string("DNS: no free UDP connection\n");
|
||||
return;
|
||||
}
|
||||
dns_state.send = 1;
|
||||
}
|
||||
|
||||
|
||||
static void dns_query(void) __reentrant
|
||||
{
|
||||
__xdata uint8_t *p = (__xdata uint8_t *)uip_appdata;
|
||||
__xdata char *n = dns_state.name;
|
||||
__xdata uint8_t *label;
|
||||
uint16_t len = 12;
|
||||
|
||||
dns_state.id++;
|
||||
p[0] = dns_state.id >> 8;
|
||||
p[1] = dns_state.id;
|
||||
p[2] = 0x01;
|
||||
p[3] = 0x00;
|
||||
p[4] = 0;
|
||||
p[5] = 1;
|
||||
p[6] = p[7] = p[8] = p[9] = p[10] = p[11] = 0;
|
||||
while (*n) {
|
||||
label = p + len++;
|
||||
*label = 0;
|
||||
while (*n && *n != '.') {
|
||||
p[len++] = *n++;
|
||||
(*label)++;
|
||||
}
|
||||
if (*n)
|
||||
n++;
|
||||
}
|
||||
p[len++] = 0;
|
||||
p[len++] = 0;
|
||||
p[len++] = 1;
|
||||
p[len++] = 0;
|
||||
p[len++] = 1;
|
||||
uip_udp_send(len);
|
||||
}
|
||||
|
||||
|
||||
static uint16_t dns_skip_name(__xdata uint8_t *p, uint16_t i, uint16_t len) __reentrant
|
||||
{
|
||||
while (i < len) {
|
||||
if (!p[i])
|
||||
return i + 1;
|
||||
if ((p[i] & 0xc0) == 0xc0)
|
||||
return i + 2;
|
||||
i += p[i] + 1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static void dns_answer(void) __reentrant
|
||||
{
|
||||
__xdata uint8_t *p = (__xdata uint8_t *)uip_appdata;
|
||||
uint16_t len = uip_datalen();
|
||||
uint16_t i, an;
|
||||
|
||||
if (dns_state.status != DNS_PENDING || len < 12 || !(p[2] & 0x80)
|
||||
|| p[0] != (uint8_t)(dns_state.id >> 8) || p[1] != (uint8_t)dns_state.id)
|
||||
return;
|
||||
an = ((uint16_t)p[6] << 8) | p[7];
|
||||
i = dns_skip_name(p, 12, len) + 4;
|
||||
while (!(p[3] & 0x0f) && an-- && i + 10 <= len) {
|
||||
i = dns_skip_name(p, i, len);
|
||||
if (i + 10 > len)
|
||||
break;
|
||||
if (!p[i] && p[i + 1] == 1 && !p[i + 8] && p[i + 9] == 4 && i + 14 <= len) {
|
||||
memcpy(dns_state.addr, p + i + 10, 4);
|
||||
dns_state.status = DNS_DONE;
|
||||
uip_udp_remove(dns_state.conn);
|
||||
dns_state.conn = 0;
|
||||
if (dns_state.verbose) {
|
||||
print_string("DNS: ");
|
||||
print_string_x(dns_state.name);
|
||||
print_string(" is ");
|
||||
print_ip(dns_state.addr);
|
||||
write_char('\n');
|
||||
}
|
||||
return;
|
||||
}
|
||||
i += 10 + (((uint16_t)p[i + 8] << 8) | p[i + 9]);
|
||||
}
|
||||
dns_state.tries = DNS_TRIES;
|
||||
dns_next();
|
||||
}
|
||||
|
||||
|
||||
void dns_init(void) __banked
|
||||
{
|
||||
memset(dns_state.server, 0, sizeof(dns_state.server));
|
||||
dns_state.name[0] = 0;
|
||||
dns_state.status = DNS_IDLE;
|
||||
dns_state.conn = 0;
|
||||
}
|
||||
|
||||
|
||||
void dns_lookup(void) __banked
|
||||
{
|
||||
if (dns_name_is_ip()) {
|
||||
dns_state.status = DNS_DONE;
|
||||
return;
|
||||
}
|
||||
dns_state.tries = 0;
|
||||
dns_state.status = DNS_PENDING;
|
||||
dns_next();
|
||||
}
|
||||
|
||||
|
||||
void dns_show(void) __banked
|
||||
{
|
||||
print_string("DNS servers ");
|
||||
print_ip(dns_state.server[0]);
|
||||
write_char(' ');
|
||||
print_ip(dns_state.server[1]);
|
||||
print_string(", from DHCP ");
|
||||
print_ip(dhcp_state.dns);
|
||||
write_char('\n');
|
||||
if (!dns_state.name[0])
|
||||
return;
|
||||
print_string("Last lookup ");
|
||||
print_string_x(dns_state.name);
|
||||
print_string(": ");
|
||||
if (dns_state.status == DNS_DONE)
|
||||
print_ip(dns_state.addr);
|
||||
else if (dns_state.status == DNS_PENDING)
|
||||
print_string("pending");
|
||||
else
|
||||
print_string("failed");
|
||||
write_char('\n');
|
||||
}
|
||||
|
||||
|
||||
void dns_callback(uint16_t lport) __banked __reentrant
|
||||
{
|
||||
if (!dns_state.conn || lport != dns_state.conn->lport)
|
||||
return;
|
||||
if (uip_newdata()) {
|
||||
dns_answer();
|
||||
return;
|
||||
}
|
||||
if (dns_state.status != DNS_PENDING)
|
||||
return;
|
||||
if (dns_state.send) {
|
||||
dns_state.send = 0;
|
||||
dns_state.sent = ticks;
|
||||
dns_query();
|
||||
return;
|
||||
}
|
||||
if (ticks - dns_state.sent >= DNS_TIMEOUT) {
|
||||
dns_state.tries++;
|
||||
dns_next();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef _DNS_H_
|
||||
#define _DNS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define DNS_NAME_LEN 48
|
||||
|
||||
#define DNS_IDLE 0
|
||||
#define DNS_PENDING 1
|
||||
#define DNS_DONE 2
|
||||
#define DNS_FAILED 3
|
||||
|
||||
struct uip_udp_conn;
|
||||
|
||||
struct dns_state {
|
||||
uint8_t server[2][4]; /* configured servers, 0.0.0.0 = unused */
|
||||
char name[DNS_NAME_LEN]; /* name of the current or last lookup */
|
||||
uint8_t addr[4]; /* address found by the last lookup */
|
||||
uint8_t status; /* DNS_* */
|
||||
uint8_t verbose; /* print the result of the lookup */
|
||||
uint8_t tries; /* queries sent for the current lookup */
|
||||
uint8_t send; /* a query is due on the connection */
|
||||
uint16_t id;
|
||||
uint32_t sent; /* ticks when the last query went out */
|
||||
struct uip_udp_conn *conn;
|
||||
};
|
||||
|
||||
extern __xdata struct dns_state dns_state;
|
||||
|
||||
void dns_init(void) __banked;
|
||||
void dns_lookup(void) __banked;
|
||||
void dns_show(void) __banked;
|
||||
void dns_callback(uint16_t lport) __banked __reentrant;
|
||||
void dns_parse(void) __banked __reentrant;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Command line interface of the DNS resolver for the RTL837x platform
|
||||
* This code is in the Public Domain
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "rtl837x_common.h"
|
||||
#include "cmd_parser.h"
|
||||
#include "dns.h"
|
||||
|
||||
#pragma codeseg BANK2
|
||||
#pragma constseg BANK2
|
||||
|
||||
extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
||||
extern __xdata uint8_t cmd_words_len;
|
||||
extern __xdata uint8_t cmd_words_b[15];
|
||||
extern __xdata uint8_t ip[4];
|
||||
uint8_t cmd_compare(uint8_t start, __code const uint8_t * cmd);
|
||||
uint8_t parse_ip(uint8_t idx);
|
||||
|
||||
|
||||
void dns_parse(void) __banked __reentrant
|
||||
{
|
||||
__xdata uint8_t *s;
|
||||
uint8_t n;
|
||||
|
||||
if (cmd_words_len < 2) {
|
||||
dns_show();
|
||||
return;
|
||||
}
|
||||
if (cmd_compare(1, "server") && cmd_words_len >= 3 && parse_ip(cmd_words_b[2])) {
|
||||
memcpy(dns_state.server[0], ip, 4);
|
||||
memset(dns_state.server[1], 0, 4);
|
||||
if (cmd_words_len >= 4) {
|
||||
if (!parse_ip(cmd_words_b[3]))
|
||||
goto err;
|
||||
memcpy(dns_state.server[1], ip, 4);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (cmd_compare(1, "lookup") && cmd_words_len >= 3) {
|
||||
if (dns_state.status == DNS_PENDING) {
|
||||
print_string("DNS: a lookup is already running\n");
|
||||
return;
|
||||
}
|
||||
s = &cmd_buffer[cmd_words_b[2]];
|
||||
for (n = 0; s[n] && s[n] != ' '; n++) {
|
||||
if (n == DNS_NAME_LEN - 1)
|
||||
goto err;
|
||||
dns_state.name[n] = s[n];
|
||||
}
|
||||
dns_state.name[n] = 0;
|
||||
dns_state.verbose = 1;
|
||||
dns_lookup();
|
||||
if (dns_state.status == DNS_DONE) {
|
||||
print_ip(dns_state.addr);
|
||||
write_char('\n');
|
||||
}
|
||||
return;
|
||||
}
|
||||
err:
|
||||
print_string("Error: dns [server <ip> [<ip>]|lookup <name>]\n");
|
||||
}
|
||||
@@ -64,3 +64,33 @@ Writing 0x1 to register 0x7850 will transmit the frame. The Ethernet frame
|
||||
checksum and the TCP checksum are automatically calculated (offloaded) by the
|
||||
ASIC before transmitting on the wire.
|
||||
|
||||
|
||||
## The RTL tag words
|
||||
|
||||
The frame header uses the Realtek Remote Control Protocol (RRCP) format or
|
||||
the like.
|
||||
|
||||
The `flags` word:
|
||||
|
||||
```
|
||||
bit15 EFID_EN | 14:12 EFID | 11 PRI_EN | 10:8 PRI |
|
||||
bit7 KEEP | 6 VSEL | 5 LEARN_DIS | 4:0 VIDX
|
||||
```
|
||||
|
||||
All fields are in network byte order.
|
||||
|
||||
* `EFID_EN`, `EFID`: look the destination up under this filtering ID
|
||||
instead of the port's own
|
||||
* `PRI_EN`, `PRI`: force the given priority on the frame
|
||||
* `KEEP`: keep the 802.1Q tagging of the frame exactly as injected,
|
||||
bypassing the egress tagging rules of the port
|
||||
* `VSEL`, `VIDX`: classify the frame into the VLAN at this index of the
|
||||
VLAN table
|
||||
* `LEARN_DIS`: do not learn the source address from this frame
|
||||
|
||||
The `pmask` word: bit 15 is `ALLOW`, bits 14 to 0 are a port mask.
|
||||
|
||||
* `ALLOW` clear: the mask is the egress set, the frame goes to exactly
|
||||
the ports given
|
||||
* `ALLOW` set: the ASIC looks the destination up as usual and the mask
|
||||
only limits which ports the result may use
|
||||
@@ -0,0 +1,40 @@
|
||||
### 2M-PCB23-V3.2
|
||||
|
||||
## Brands
|
||||
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
||||
|---|---|---|---|---|---|
|
||||
| keepLINK | KP-9000-9XHML-X | Yes| 2M-PCB23-V3.2 | 2M (Winbond 25Q) | |
|
||||
|
||||
The original web interface reports this board as hardware version V3.2
|
||||
(original firmware V100.9.25, January 2026).
|
||||
|
||||
## PCB
|
||||
|
||||
<img src="photos/2M-PCB23-V3.2-managed/2M-PCB23-V3.2-top.jpeg" width="300" />
|
||||
|
||||
## Compared to V3.1
|
||||
|
||||
The component placement matches [2M-PCB23-V3.1](2M-PCB23-V3_1.md): same
|
||||
positions for the flash (U8), the T7/T8/T9/T10 headers, the SFP cage and its
|
||||
LED, and the unpopulated U7/U9 footprints. Build with
|
||||
`MACHINE=KP_9000_9XHML_X_V3_2`, which uses the V3.1 machine definition and
|
||||
only differs in the reported name.
|
||||
|
||||
## Tested
|
||||
|
||||
Installed from the original firmware through its web interface with
|
||||
`installer/output/rtlplayground_oem_upgrade.bin`, then:
|
||||
|
||||
- RJ45 ports link at 2.5G; LEDs: orange at 2.5G, green below
|
||||
- SFP port: module detected with vendor/model/serial and DOM readings
|
||||
(temperature, Vcc, TX bias, TX/RX power), link up at 10G
|
||||
- factory MAC read from flash (0x1FC000)
|
||||
- reset button (GPIO48): held for more than 10 s it restores the default config
|
||||
|
||||
## Flash access
|
||||
|
||||
Reading the flash in-circuit with a SOIC-8 clip did not work: the chip ID
|
||||
comes back as `EF FF FF` (only the manufacturer byte is right) and reads
|
||||
return 0xff, the same as on a V3.1 board. The switch chip is powered through
|
||||
the clip and keeps driving the SPI lines. Make sure a way back is acceptable
|
||||
before installing, or hold the switch chip in reset while reading.
|
||||
@@ -0,0 +1,55 @@
|
||||
# 2G040210GSM
|
||||
|
||||
The following is a documentation for the managed switch marked as `2G040210GSM`
|
||||
and sold by Mokerlink.
|
||||
|
||||
### Label specifications
|
||||
|
||||
- **Name**: 4-port 2.5G Web Managed Switch
|
||||
- **Ports**:
|
||||
- 4 × RJ45: 10/100/1000/2500 Mbps
|
||||
- 2 × SFP+: 1000 / 2500 / 10000 Mbps
|
||||
- **Power**: 12V DC, 1A barrel connector
|
||||
|
||||
### What works
|
||||
The device is fully supported:
|
||||
- All 4 2.5GBASE-T RJ45 ports work at 10/100/1000/2500 Mbps
|
||||
- The SFP+ port supports 1G, 2.5G and 10G modules
|
||||
- LEDs work with the same indiciations as the OEM firmware (use KP_9000_6XHML_X2_V1_1 in machine.h if building yourself or the corresponding pre-compiled binary)
|
||||
- untested due to missing Hardware: SFP+ ports equipped with 1G or 2.5G SFPs.
|
||||
|
||||
### Hardware overview
|
||||
Front
|
||||
|
||||
<img src="photos/2M-PCB43-V1.1-managed/2M-PCB43-V1.1-front.jpeg" width="300" />
|
||||
|
||||
Label
|
||||
|
||||
<img src="photos/2M-PCB43-V1.1-managed/2M-PCB43-V1.1-label.jpeg" width="300" />
|
||||
|
||||
### PCB overview
|
||||
|
||||
**Board markings**
|
||||
- Top silkscreen: 2M-PCB43-V1.1
|
||||
|
||||
Top side
|
||||
|
||||
<img src="photos/2M-PCB43-V1.1-managed/2M-PCB43-V1.1-top.jpeg" width="300" />
|
||||
|
||||
Bottom
|
||||
|
||||
<img src="photos/2M-PCB43-V1.1-managed/2M-PCB43-V1.1-bottom.jpeg" width="300" />
|
||||
|
||||
### J1, serial console
|
||||
|
||||
| `J8` pin | Signal |
|
||||
| -------- | ----------- |
|
||||
| 1 | RX (Input) |
|
||||
| 2 | TX (Output) |
|
||||
| 3 | GND |
|
||||
| 4 | 3V3 |
|
||||
|
||||
|
||||
## Power supply
|
||||
|
||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
||||
@@ -0,0 +1,32 @@
|
||||
# MokerLink POE-2G080110GS
|
||||
|
||||
The `POE-2G080110GS` is an unmanaged 8x2.5G RJ45 and 1xSFP+ PoE switch sold by Mokerlink. There is also a `POE-2G080110GSM` managed version of the switch which may be similar but this has not been verified on actual hardware.
|
||||
|
||||
## Brands
|
||||
| Brand | Type |Managed| PCB | Flash | Chip RTL |
|
||||
|--------|------------------|-------|------------------|-----------------|---------------|
|
||||
| Mokerlink | POE-2G080110GS | No | 2M-PCB51-ML-V1.1 | 4MB (W25Q32JV) | 8373N + 8224N |
|
||||
|
||||
## Hardware overview
|
||||
Front
|
||||
|
||||
<img src="photos/POE-2G080110GS/POE-2G080110GS-front.jpg" width="300" />
|
||||
|
||||
Label
|
||||
|
||||
<img src="photos/POE-2G080110GS/POE-2G080110GS-label.jpg" width="300" />
|
||||
|
||||
The stock firmware from a POE-2G080110GS device had a sha256sum of `4c280853465eaad80e1772075c0f2d29c11fb8c561547f06353d3a5443c388e9`.
|
||||
|
||||
### PCB
|
||||
|
||||
Top silkscreen is marked `2M-PCB51-ML-V1.1`. PoE is provided by RTL8238C. Flash chip is 4 MB Winbond 25Q32JV (U8).
|
||||
|
||||
<img src="photos/POE-2G080110GS/POE-2G080110GS-pcb.jpg" width="300" />
|
||||
|
||||
> [!CAUTION]
|
||||
> This device operates on mains voltage, which can be a dangerous or potentially lethal hazard. Even after the device is unplugged, high-voltage capacitors can remain charged afterward and may still shock you. Do not attempt to open/disassemble a mains powered device unless you understand how to do so safely. Also, opening the device may void your warranty.
|
||||
|
||||
## Notes
|
||||
|
||||
The stock firmware blinks both the 2.5G and 1G LEDs on activity, despite the front of the device indicating that each LED should be independent. The `POE_2G080110GS` machine config behaves as the front of the device indicates (and what seems more logical) -- each port LED turns on and blinks independently.
|
||||
@@ -0,0 +1,70 @@
|
||||
# F7008-2.5
|
||||
|
||||
Documentation for the unmanaged 8 + 1 switch sold as `7018-2.5G` by Guangnianwei
|
||||
(光年微), board marking `F7008-2.5`, PCB `F7008-2.5GPOE-V1.2`.
|
||||
|
||||
### Brands
|
||||
|
||||
| Brand | Type | Managed | PCB | Flash | Chip RTL |
|
||||
|-------|------|---------|-----|-------|----------|
|
||||
| Guangnianwei (光年微) | 7018-2.5G | No | F7008-2.5GPOE-V1.2 | W25Q64JVSSIQ | 8373N + 8224N |
|
||||
|
||||
### What works
|
||||
|
||||
- All eight 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
||||
- SFP+ port with 1G/2.5G/10G modules
|
||||
- LEDs of the eight RJ45 ports
|
||||
|
||||
### Not verified
|
||||
|
||||
- The LED pads for the SFP+ cage are not mapped yet. The SFP+ lamps are left
|
||||
undriven, so an inserted module lights nothing.
|
||||
- The UART header footprint is present but unpopulated, and no boot log could be
|
||||
captured from it, so the baud rate is unknown. There are most likely
|
||||
unpopulated 0-Ohm resistors next to the header; bridging those should bring
|
||||
the console to life.
|
||||
|
||||
### Build target
|
||||
|
||||
```
|
||||
make MACHINE=F7008_2_5
|
||||
```
|
||||
|
||||
### LED wiring
|
||||
|
||||
Measured pad to lamp map (`led_mux` index -> lamp):
|
||||
|
||||
| Port | green lamp | yellow lamp |
|
||||
|------|-----------|-------------|
|
||||
| 1 | pad 0 | pad 1 |
|
||||
| 2 | pad 2 | pad 3 |
|
||||
| 3 | pad 4 | pad 5 |
|
||||
| 4 | pad 6 | pad 8 |
|
||||
| 5 | pad 9 | pad 10 |
|
||||
| 6 | pad 12 | pad 15 |
|
||||
| 7 | pad 18 | pad 21 |
|
||||
| 8 | pad 24 | pad 25 |
|
||||
|
||||
Pads 7, 11, 13, 14, 16, 17, 19, 20, 22, 23, 26 and 27 do not drive an RJ45 lamp.
|
||||
|
||||
The front panel is silkscreened `2.5G: Green / 10/100M: Yellow`, and the target
|
||||
follows it: the green lamp is on while the port is linked at 2.5G, the yellow
|
||||
lamp blinks while data is flowing.
|
||||
|
||||
### PCB overview
|
||||
|
||||
The board is marked `F7008-2.5GPOE-V1.2`.
|
||||
|
||||
Top side:
|
||||
|
||||
<img src="photos/F7008-2.5/PCB-top.jpg" width="600" />
|
||||
|
||||
Bottom side:
|
||||
|
||||
<img src="photos/F7008-2.5/PCB-bottom.jpg" width="600" />
|
||||
|
||||
### Hardware notes
|
||||
|
||||
- 4 x `RT4802SNE` magnetics
|
||||
- Unpopulated UART header footprint, next to the magnetics
|
||||
- Power input 12V 1A, 180 x 84 x 29 mm metal case
|
||||
@@ -0,0 +1,39 @@
|
||||
# FG-4GT-2SX_V2.0
|
||||
|
||||
Following is documentation for unmanaged switch marked as `FG-4GT-2SX_V2.0`.
|
||||
|
||||
Original software is running UART on 9600 baud rate.
|
||||
|
||||
## Brands
|
||||
|
||||
* Ruiying RY-4GT-2SX
|
||||
|
||||
<img src="photos/FG-4GT-2SX_V2.0/RY-4GT-2SX_label.jpg" width="300" />
|
||||
|
||||
## What works
|
||||
|
||||
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
||||
- Both SFP ports supporting 1G, 2.5G and 10G modules
|
||||
- LEDs
|
||||
|
||||
## PCB overview
|
||||
|
||||
**Board markings**
|
||||
|
||||
- Top silkscreen: FG-4GT-2SX_V2.0
|
||||
|
||||
Front panel
|
||||
|
||||
<img src="photos/FG-4GT-2SX_V2.0/chassis-front.jpg" width="300" />
|
||||
|
||||
Top side
|
||||
|
||||
<img src="photos/FG-4GT-2SX_V2.0/PCB-top.jpg" width="300" />
|
||||
|
||||
Bottom
|
||||
|
||||
<img src="photos/FG-4GT-2SX_V2.0/PCB-bottom.jpg" width="300" />
|
||||
|
||||
## Power supply
|
||||
|
||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
||||
@@ -0,0 +1,79 @@
|
||||
# FG-8GT-1SX
|
||||
|
||||
Following is documentation for unmanaged switch marked as `FG-8GT-1SX`.
|
||||
|
||||
Original software is running UART on 9600 baud rate.
|
||||
|
||||
Using SPI clamp in-board is the only method for initial installation.
|
||||
|
||||
### Brands
|
||||
|
||||
| Brand | Type | Managed | PCB | Flash | Chip RTL |
|
||||
|---------|------------|---------|------------|-------------|---------------|
|
||||
| Ruiying | RY-8GT-1SX | No | FG-8GT-1SX | GD25Q80ESIG | 8373N + 8224N |
|
||||
|
||||
### What works
|
||||
|
||||
- All eight 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
||||
- SFP port with 1G/2.5G/10G modules
|
||||
- LEDs
|
||||
|
||||
### PCB overview
|
||||
|
||||
**Board markings**
|
||||
|
||||
- Top silkscreen: FG-8GT-1SX
|
||||
|
||||
Top side:
|
||||
|
||||
<img src="photos/FG-8GT-1SX/PCB-top.jpg" width="600" />
|
||||
|
||||
Bottom:
|
||||
|
||||
<img src="photos/FG-8GT-1SX/PCB-bottom.jpg" width="600" />
|
||||
|
||||
### Serial console
|
||||
|
||||
The PCB has five unpopulated through-holes near the SoC, with a white rectangle surrouding them, labeled as `J18` and a triangle points to the square shaped first pin.
|
||||
|
||||
This is where the "expected" UART header should be soldered at, with redundant 3V3 VCC, but also with missing 0Ω resistors between TX/RX and SoC, so simply soldering a header would not work. One need also add the missing resistors or solder the pads together, while making sure not connecting unrelated pads.
|
||||
|
||||
Numbered from the triangle, the header pinout is:
|
||||
|
||||
| Position | Signal | GPIO | Status |
|
||||
|----------|--------|--------|-------------|
|
||||
| 1 | GND | GND | Internal |
|
||||
| 2 | TX | GPIO31 | Unconnected |
|
||||
| 3 | RX | GPIO32 | Unconnected |
|
||||
| 4 | 3V3 | - | Internal |
|
||||
| 5 | 3V3 | - | Internal |
|
||||
|
||||
There're four resistor pads near the header.
|
||||
|
||||
| Resistor ID | SoC Side | Header Side |
|
||||
|-------------|-------------|-------------|
|
||||
| R1240 | TX / GPIO31 | Pin 2 |
|
||||
| R1243 | 3V3 | - |
|
||||
| R1242 | 3V3 | Pin 3 |
|
||||
| R1241 | RX / GPIO32 | - |
|
||||
|
||||
To get TX working, solder a 0Ω resistor between the pads for R1240 or solder them together.
|
||||
|
||||
For RX However, the designer certainly made a mistake, as the SoC-side lines to the resistor expected for Rx (R1242) and 3V3 (R1241) are swapped. For RX to work, the R1241 SoC side and R1242 header side shall be connected, so either:
|
||||
|
||||
- Solder: R1241 SoC side -> R1241 header side -> R1242 header side
|
||||
- Jump wire: R1241 SoC side -> R1242 header side
|
||||
|
||||
Be sure not to bring R1242 SoC side to the connection as that would wire Rx to 3v3.
|
||||
|
||||
A complete working serial header should look like following on this PCB:
|
||||
|
||||
<img src="photos/FG-8GT-1SX/Serial.png" width="600" />
|
||||
|
||||
- **Settings**: 115200 baud / 8N1 / 3.3V TTL
|
||||
- Connect a USB-TTL adapter: adapter GND → pin 1, RX → pin 2, TX → pin 3
|
||||
|
||||
### Power supply
|
||||
|
||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
# Hasivo S1100WP-8GT-1SX-SE
|
||||
|
||||
RTL8373-based 8×2.5G PoE + 1×SFP switch.
|
||||
|
||||
### Label specifications
|
||||
|
||||
- **Manufacturer**: Hasivo
|
||||
- **Model**: S1100WP-8GT-1SX-SE
|
||||
- **Ports**:
|
||||
- 8 × RJ45: 10/100/1000/2500 Mbps with PoE
|
||||
- 1 × SFP: 1G / 2.5G / 10G
|
||||
- **Power input**: DC 52V 2.5A
|
||||
- **Stock firmware defaults**: IP 192.168.0.1, user/password `admin`/`admin`
|
||||
|
||||
### What works
|
||||
|
||||
- All eight 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps (PoE is not configurable via RTLPlayground)
|
||||
- SFP port supporting 1G, 2.5G and 10G modules
|
||||
- LEDs: green (2.5G) and amber (1G/100M/10M) per copper port; combined link/act on the SFP port
|
||||
|
||||
### Photos
|
||||
|
||||
Front panel:
|
||||
|
||||
<img src="photos/HASIVO_S1100WP-8GT-1SX-SE/front.jpg" width="600" />
|
||||
|
||||
Label:
|
||||
|
||||
<img src="photos/HASIVO_S1100WP-8GT-1SX-SE/label.jpg" width="600" />
|
||||
|
||||
### PCB overview
|
||||
|
||||
Top side:
|
||||
|
||||
<img src="photos/HASIVO_S1100WP-8GT-1SX-SE/pcb_top.jpg" width="600" />
|
||||
|
||||
Bottom side:
|
||||
|
||||
<img src="photos/HASIVO_S1100WP-8GT-1SX-SE/pcb_bottom.jpg" width="600" />
|
||||
|
||||
### Port layout
|
||||
|
||||
| Logical port | Physical port | Type |
|
||||
|--------------|---------------|--------|
|
||||
| 1-8 | 1-8 | Copper |
|
||||
| 9 | 9 | SFP |
|
||||
|
||||
### LED configuration
|
||||
|
||||
Copper ports use LED SET0, the SFP port uses LED SET1.
|
||||
|
||||
| SET | LED0 | LED2 |
|
||||
|------|-----------------------------------------------|------------------------------------------------------|
|
||||
| SET0 | Green — lights on 2.5G link with activity | Amber — lights on 1G / 100M / 10M link with activity |
|
||||
| SET1 | All speeds — lights on any link with activity | — |
|
||||
|
||||
### SFP GPIO assignments
|
||||
|
||||
| SFP (logical 9) | pin_detect (ModAbs) | pin_los | pin_tx_disable | SerDes | I2C SDA | I2C SCL |
|
||||
|-----------------|---------------------|---------|----------------|--------|-----------------|---------------------|
|
||||
| SFP | GPIO30_ACL_BIT3_EN | GPIO37 | GPIO_NA | SDS1 | GPIO39_I2C_SDA4 | GPIO40_I2C_SCL3_MDC1 |
|
||||
|
||||
### Machine configuration
|
||||
|
||||
- `reset_pin`: GPIO54_ACL_BIT2_EN
|
||||
- High LEDs (pads 27-29): mux = `LED_27 | LED_28_SYS | LED_29`, enable = `LED_28_SYS | LED_29`
|
||||
|
||||
### PoE
|
||||
|
||||
The 8 copper ports support PoE powered by a DC 52V 2.5A input. Power management is handled by two HS104PTI chipsets over I2C (GPIO47_I2C_SDA0, GPIO46_I2C_SCL0):
|
||||
|
||||
* Chip 1 (I2C address 0x1A): 2.5G Ports 1–4
|
||||
* Chip 2 (I2C address 0x2A): 2.5G Ports 5–8
|
||||
|
||||
Note: The current implementation does not yet support PoE management. Consequently, PoE currently operates in standalone mode without software control.
|
||||
@@ -1,62 +0,0 @@
|
||||
# Hisource Hi-K0402WS
|
||||
|
||||
Following is documentation for unmanaged switch marked as `Hi-K0402WS`.
|
||||
|
||||
Original software is running UART on 9600 baud rate.
|
||||
|
||||
Using SPI clamp in-board is the only method for initial installation.
|
||||
|
||||
The board has two flash chips `BY25Q16BS` with 16M-bit size. The front switch, switches between the two flash chips.
|
||||
These can be programed independently by using said switch - so it is e.g. possible to run the original and new firmware in parallel.
|
||||
|
||||
### Label specifications
|
||||
|
||||
- **Name**: 2.5G Ethernet Switch
|
||||
- **Model**: Hi-K0402WS
|
||||
- **Ports**:
|
||||
- 4 × RJ45: 10/100/1000/2500 Mbps
|
||||
- 2 × SFP: 1000 / 2500 / 10000 Mbps
|
||||
|
||||
### What works (expected from label + similar devices)
|
||||
|
||||
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
||||
- Both SFP ports supporting 1G, 2.5G and 10G modules
|
||||
- LEDs
|
||||
|
||||
### PCB overview
|
||||
|
||||
**Board markings**
|
||||
- Top silkscreen: PCB-KO4022W-V3.0 / DIP-KO4022WS-V3.0
|
||||
|
||||
Top side
|
||||
|
||||
<img src="photos/K0402W-V3.0-unmanaged\PCB-top.jpg" width="300" />
|
||||
|
||||
Bottom
|
||||
|
||||
<img src="photos/K0402W-V3.0-unmanaged\PCB-bottom.jpg" width="300" />
|
||||
|
||||
### T2, serial console
|
||||
|
||||
| `J2` pin | Signal |
|
||||
| -------- | ----------- |
|
||||
| 1 | 3V3 |
|
||||
| 2 | RX (Input) |
|
||||
| 3 | TX (Output) |
|
||||
| 4 | GND |
|
||||
|
||||
|
||||
## Power supply
|
||||
|
||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
||||
Board has two supply rails. `0.95` and `3.3` volt.
|
||||
|
||||
### `0.95` Core Voltage
|
||||
|
||||
Voltage is made by a `Techcode TD1720` .
|
||||
|
||||
### `3.3` Voltage
|
||||
|
||||
Voltage is created by chip marked as `Techcode TD1720`.
|
||||
|
||||
**There seems to have been a miscalculation when choosing the inductor and the device is ~25% more efficient with an 5V power supply.**
|
||||
@@ -0,0 +1,64 @@
|
||||
# Lianguo HYWS-SGT0108S
|
||||
|
||||
Following is documentation for unmanaged switch marked as `HYWS-SGT0108S`.
|
||||
|
||||
Original software is running UART on 9600 baud rate. Output is very minimal.
|
||||
|
||||
Using SPI clamp in-board is the only method for initial installation and update.
|
||||
|
||||
Stock flash chip is 512KB in size. Consider replacing for update through Web UI.
|
||||
|
||||
- Header for uart is clearly identified.
|
||||
- The red LED act as a powered-on LED.
|
||||
- There is no SYS LED.
|
||||
- There is a footprint for a Reset button. Unpopulated. Unclear if routed back to RTL8373.
|
||||
|
||||
### Label specifications
|
||||
|
||||
- **Name**: 2.5G Ethernet Switch 8+1
|
||||
- **Model**: HYWS-SGT0108S
|
||||
- **Ports**:
|
||||
- 8 × RJ45: 10/100/1000/2500 Mbps
|
||||
- 1 × SFP: 1000 / 2500 / 10000 Mbps
|
||||
|
||||
### What works
|
||||
|
||||
- All eight 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
||||
- SFP port supporting 1G, 2.5G and 10G modules
|
||||
- RJ45 LEDs (Blue+White)
|
||||
- SFP Single LED (Blue)
|
||||
|
||||
### Assembled unit
|
||||
|
||||
Top side
|
||||
|
||||
<img src="photos/HYWS-SGT0108S-unmanaged\Assembled-top.jpg" width="300" />
|
||||
|
||||
Front
|
||||
|
||||
<img src="photos/HYWS-SGT0108S-unmanaged\Assembled-front.jpg" width="300" />
|
||||
|
||||
Bottom
|
||||
|
||||
<img src="photos/HYWS-SGT0108S-unmanaged\Assembled-bottom.jpg" width="300" />
|
||||
|
||||
### PCB overview
|
||||
|
||||
**Board markings**
|
||||
- Top silkscreen: 2G5F_20G_V1.01 / 2023-09-28
|
||||
|
||||
Top side
|
||||
|
||||
<img src="photos/HYWS-SGT0108S-unmanaged\PCB-top.jpg" width="300" />
|
||||
|
||||
Bottom
|
||||
|
||||
<img src="photos/HYWS-SGT0108S-unmanaged\PCB-bot.jpg" width="300" />
|
||||
|
||||
Original SPI Flash Chip
|
||||
|
||||
<img src="photos/HYWS-SGT0108S-unmanaged\og_spi_flash.jpg" width="300" />
|
||||
|
||||
## Power supply
|
||||
|
||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
||||
@@ -1,17 +1,36 @@
|
||||
# Keeplink KP-9000-6XH-X2
|
||||
# Keeplink KP-9000-6XH-X2 / KP-9000-6XHML-X2
|
||||
|
||||
Following is documentation for unmanaged switch marked as `KP-9000-6XH-X2`.
|
||||
Following is documentation for switches marked as `KP-9000-6XH-X2` or
|
||||
`KP-9000-6XHML-X2`.
|
||||
|
||||
Using SPI clamp in-board is the only method for initial installation.
|
||||
|
||||
### Label specifications
|
||||
|
||||
- **Name**: 4X 2.5G RJ45 Port + 2 X 10G SFP+ Port
|
||||
- **Model**: KP-9000-6XH-X2
|
||||
- **Model**: KP-9000-6XH-X2 / KP-9000-6XHML-X2
|
||||
- **Ports**:
|
||||
- 4 × RJ45: 10/100/1000/2500 Mbps
|
||||
- 2 × SFP+: 1000 / 2500 / 10000 Mbps
|
||||
|
||||
### Machine target
|
||||
|
||||
These devices exist with different PCB revisions. Select the machine target by
|
||||
the PCB silkscreen, not by the label on the case. The `6XH` / `6XHML`
|
||||
distinction appears to be a stock firmware, SKU or label difference, not a
|
||||
reliable indicator of PCB wiring. The PCB revision defines the hardware layout.
|
||||
|
||||
| PCB silkscreen | Known labels / devices | Recommended machine target | Equivalent target | Legacy target |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `2M-PCB43-V1.1` | Mokerlink 2G040210GSM web-managed 4+2 switch | `MACHINE_KP_9000_6XHML_X2_V1_1` | `MACHINE_KP_9000_6XH_X2_V1_1` | `MACHINE_KP_9000_6XHML_X2` |
|
||||
| `2M-PCB43-V1.2` | `KP-9000-6XHML-X2` | `MACHINE_KP_9000_6XHML_X2_V1_2` | `MACHINE_KP_9000_6XH_X2_V1_2` | `MACHINE_KP_9000_6XHML_X2` |
|
||||
| `2M-PCB43-V2.1` | `KP-9000-6XH-X2`, `KP-9000-6XHML-X2` | `MACHINE_KP_9000_6XH_X2_V2_1` or `MACHINE_KP_9000_6XHML_X2_V2_1` | same V2.1 layout | `MACHINE_KP_9000_6XH_X2` |
|
||||
|
||||
The V1.1 and V1.2 boards currently use the same V1.x GPIO, SFP, port and LED
|
||||
layout. The V2.1 board uses a different V2.1 layout with custom LED muxing.
|
||||
Legacy targets are preserved for compatibility with already-tested devices, but
|
||||
new builds should prefer the explicit PCB-revision targets.
|
||||
|
||||
### What works
|
||||
|
||||
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
||||
@@ -19,7 +38,7 @@ Using SPI clamp in-board is the only method for initial installation.
|
||||
- LEDs
|
||||
- untested due to missing Hardware: SFP+ ports equipped with 1G or 2.5G SFPs.
|
||||
|
||||
### Hardware overview
|
||||
### Hardware overview: 2M-PCB43-V2.1
|
||||
|
||||
Front side:
|
||||
|
||||
@@ -44,6 +63,24 @@ Bottom
|
||||
|
||||
<img src="photos/2M-PCB43-V2.1-unmanaged/2M-PCB43-V2.1-bottom.jpg" width="600" />
|
||||
|
||||
### Hardware overview: 2M-PCB43-V1.1 / V1.2
|
||||
|
||||
The V1.1 board has been reported in the Mokerlink 2G040210GSM web-managed 4+2
|
||||
switch. The V1.2 board has been seen in managed `KP-9000-6XHML-X2` devices.
|
||||
Both use the same V1.x layout.
|
||||
|
||||
Label:
|
||||
|
||||
<img src="photos/KP-9000-6XHML-X2/label.jpg" width="600" />
|
||||
|
||||
Top side:
|
||||
|
||||
<img src="photos/KP-9000-6XHML-X2/pcb_top.jpg" width="600" />
|
||||
|
||||
Bottom:
|
||||
|
||||
<img src="photos/KP-9000-6XHML-X2/pcb_bottom.jpg" width="600" />
|
||||
|
||||
## Reset Button
|
||||
|
||||
There's an unpopulated Reset button on the front left side of the PCB.
|
||||
@@ -54,4 +91,3 @@ The front case has already the hole in the metal case, you just have to punch a
|
||||
## Power supply
|
||||
|
||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
# ONT-S207CW-62TS-SE / Binardat 2G06-04210GSM / Binardat 2G06-04210GS
|
||||
|
||||
## Overview
|
||||
|
||||
ONT-S207CW-62TS-SE, Binardat 2G06-04210GSM (managed), and Binardat 2G06-04210GS (unmanaged) are **switches with identical hardware**:
|
||||
- **CPU:** RTL8372N (confirmed via serial: "Detecting CPU: RTL8372N")
|
||||
- **Flash:** GD25Q128E (16MB)
|
||||
- **Ports:** 4x 2.5G RJ45 + 2x 10G SFP+
|
||||
- **Console:** 115200 baud (RTLPlayground firmware) / 9600 baud (stock firmware)
|
||||
|
||||
**Note:** These devices are **RTL8372N-based** with **LAN ports mounted upside-down on the PCB**, requiring a custom configuration. The `MACHINE_ONT_S207CW_62TS_SE` definition uses a **custom configuration** with:
|
||||
- Corrected port mapping (physical ports 1-4 = RJ45, 5-6 = SFP)
|
||||
- Optimized LED sets for different port wiring (RJ45 Ports 1-2 have reversed LED wiring)
|
||||
- Custom LED mux configuration
|
||||
|
||||
## Device Photos
|
||||
|
||||
### Binardat 2G06-04210GSM
|
||||
|
||||
**Front View:**
|
||||
<img src="photos/ONT-S207CW-Binardat-2G06-04210GSM/binardat-2g06-04210gsm-front.jpg" width="400" />
|
||||
|
||||
**Back View:**
|
||||
<img src="photos/ONT-S207CW-Binardat-2G06-04210GSM/binardat-2g06-04210gsm-back.jpg" width="400" />
|
||||
|
||||
**PCB View:**
|
||||
<img src="photos/ONT-S207CW-Binardat-2G06-04210GSM/binardat-2g06-04210gsm-pcb.jpg" width="400" />
|
||||
|
||||
*Photos courtesy of [andreas5232](https://github.com/andreas5232) from [emesix/ONT-S207CW-62TS-SE#1](https://github.com/emesix/ONT-S207CW-62TS-SE/issues/1)*
|
||||
|
||||
## Hardware Specification
|
||||
|
||||
| Feature | Value |
|
||||
|---|---|
|
||||
| **CPU** | RTL8372N |
|
||||
| **Flash** | GD25Q128E (16MB) |
|
||||
| **RAM** | Integrated in RTL8372N |
|
||||
| **RJ45 Ports** | 4x 2.5GBase-T (Ports 1-4) |
|
||||
| **SFP+ Ports** | 2x 10G (Ports 5-6) |
|
||||
| **Console** | UART (115200 baud for RTLPlayground, 9600 baud for stock) |
|
||||
| **Stock Web UI IP** | 192.168.2.1 |
|
||||
| **Loader Mode IP** | 192.168.10.247 |
|
||||
|
||||
## Port Layout
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │
|
||||
│ │RJ45 │ │RJ45 │ │RJ45 │ │RJ45 │ │SFP+ │ │SFP+ │ │
|
||||
│ │ 1 │ │ 2 │ │ 3 │ │ 4 │ │ 5 │ │ 6 │ │
|
||||
│ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │
|
||||
│ │
|
||||
│ [System LEDs] │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## LED Behavior
|
||||
|
||||
### RJ45 Ports (Physical 1-4)
|
||||
|
||||
| LED Color | Speed |
|
||||
|---|---|
|
||||
| **Green** | 2.5G |
|
||||
| **Orange** | 1G / 100M / 10M |
|
||||
| **Off** | No link |
|
||||
|
||||
### SFP+ Ports (Physical 5-6)
|
||||
|
||||
| LED Color | Speed |
|
||||
|---|---|
|
||||
| **Green** | 10G |
|
||||
| **Orange** | 2.5G / 1G |
|
||||
| **Off** | No link / No SFP module |
|
||||
|
||||
## Port to Logical Mapping
|
||||
|
||||
Custom mapping for ONT-S207CW-62TS-SE:
|
||||
|
||||
| Physical Port | Logical Port | Type | LED Set |
|
||||
|---|---|---|---|
|
||||
| 1 | 7 | RJ45 | 2 |
|
||||
| 2 | 6 | RJ45 | 2 |
|
||||
| 3 | 5 | RJ45 | 0 |
|
||||
| 4 | 4 | RJ45 | 0 |
|
||||
| 5 | 3 | SFP+ (SDS0) | 3 |
|
||||
| 6 | 8 | SFP+ (SDS1) | 3 |
|
||||
|
||||
**Note:** Ports 1-2 (RJ45) have reversed LED wiring and use LED-Set 2. SFP Ports 5-6 use LED-Set 3 to account for wiring differences.
|
||||
|
||||
## Flashing Instructions
|
||||
|
||||
See the [README.md](../../README.md) for general flashing instructions.
|
||||
|
||||
## Stock Firmware Information
|
||||
|
||||
| Property | Value |
|
||||
|---|---|
|
||||
| **Default IP** | 192.168.2.1 (ONT) / 192.168.10.247 (Loader Mode) |
|
||||
| **Default Login** | admin/admin (may vary by OEM) |
|
||||
| **Console Baud** | 9600 (stock) / 115200 (RTLPlayground) |
|
||||
| **CPU String** | "RTL8372N" |
|
||||
| **Loader Mode IP** | 192.168.10.247 |
|
||||
|
||||
## Configuration Details
|
||||
|
||||
- **CPU:** RTL8372N
|
||||
- **SFP:** SDS0 on logical port 3 (GPIO37), SDS1 on logical port 8 (GPIO38)
|
||||
- **Port Mapping:** Physical 1-4 → Logical 7-4, Physical 5-6 → Logical 3,8
|
||||
- **LED Wiring:** RJ45 Ports 1-2 and SFP Port 6 have reversed LED pins (orange/green swapped)
|
||||
- **LED Sets:** Set 0 for RJ45 Ports 3-4, Set 1 unused, Set 2 for RJ45 Ports 1-2, Set 3 for SFP Ports 5-6
|
||||
|
||||
## Notes
|
||||
|
||||
- ONT-S207CW-62TS-SE, Binardat 2G06-04210GSM (managed), and Binardat 2G06-04210GS (unmanaged) are **RTL8372N-based** with **LAN ports mounted upside-down on the PCB**
|
||||
- Web UI shows correct physical port order (1-2-3-4 for RJ45, 5-6 for SFP)
|
||||
- Loader Mode always remains accessible at `192.168.10.247` for recovery
|
||||
- Serial console: 9600 baud (stock) → 115200 baud (RTLPlayground)
|
||||
|
||||
## References
|
||||
|
||||
- [GitHub Issue: emesix/ONT-S207CW-62TS-SE#1](https://github.com/emesix/ONT-S207CW-62TS-SE/issues/1) - Original photos and discussion
|
||||
- [PR: logicog/RTLPlayground#465](https://github.com/logicog/RTLPlayground/pull/465) - Feedback and improvements
|
||||
@@ -0,0 +1,53 @@
|
||||
# IG108
|
||||
|
||||
Following is documentation for unmanaged switch marked as `IG108`.
|
||||
|
||||
Original software is running UART on 9600 baud rate.
|
||||
|
||||
Using SPI clamp in-board is the only method for initial installation.
|
||||
|
||||
### Brands
|
||||
|
||||
| Brand | Type | Managed | PCB | Flash | Chip RTL |
|
||||
|---------|------------|---------|------------|-------------|---------------|
|
||||
| Goalake | IG108 | No | PB-2132 | cFeon Q32A | 8373N + 8224N |
|
||||
| Netcore | GS9 | No | PB-2132 | cFeon Q32A | 8373N + 8224N |
|
||||
|
||||
### What works
|
||||
|
||||
- All eight 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
||||
- SFP port with 1G/2.5G/10G modules
|
||||
- LEDs
|
||||
|
||||
### PCB overview
|
||||
|
||||
**Board markings**
|
||||
|
||||
- Top silkscreen: PB-2132
|
||||
|
||||
Front Goalake:
|
||||
|
||||
<img src="photos/PB-2132/case.jpg" width="600" />
|
||||
|
||||
Label Goalake:
|
||||
|
||||
<img src="photos/PB-2132/label.jpg" width="600" />
|
||||
|
||||
Top side:
|
||||
|
||||
<img src="photos/PB-2132/PCB-top.jpg" width="600" />
|
||||
|
||||
Bottom:
|
||||
|
||||
<img src="photos/PB-2132/PCB-bottom.jpg" width="600" />
|
||||
|
||||
### Serial console
|
||||
|
||||
The PCB has unpopulated through-holes near the SFP Port, with description of each pin, works out of the box.
|
||||
|
||||
- **Settings**: 115200 baud / 8N1 / 3.3V TTL
|
||||
|
||||
### Power supply
|
||||
|
||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
Hisource Hi-K0402WS V2
|
||||
|
||||
RTL8372-based 4×2.5G + 2×SFP+ unmanaged switch.
|
||||
|
||||
Using SPI clamp in-board is the only method for initial installation.
|
||||
|
||||
### Label specifications
|
||||
|
||||
- **Manufacturer**: HISOURCE
|
||||
- **Model**: Hi-K0402WS V2
|
||||
- **Ports**:
|
||||
- 4 × RJ45: 10/100/1000/2500 Mbps
|
||||
- 2 × SFP+: 1G / 2.5G / 10G
|
||||
|
||||
### What works
|
||||
|
||||
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
||||
- Both SFP+ ports supporting 1G, 2.5G and 10G modules
|
||||
- LEDs: amber (2.5G) and green (1G/100M/10M) per copper port; combined link/act on SFP ports
|
||||
|
||||
### PCB overview
|
||||
|
||||
**Board markings**
|
||||
- PCB-K0402WS-V2.0
|
||||
- DIP-K0402WS-V2.0
|
||||
|
||||
**Key components**
|
||||
- U1: SPI NOR flash, 2 MiB
|
||||
- S1: unpopulated slide switch footprint (three through-holes used as serial console)
|
||||
|
||||
Front panel
|
||||
|
||||
<img src="photos/PCB-K0402WS-V2.0/chassis-front.jpg" width="400" />
|
||||
|
||||
Bottom label
|
||||
|
||||
<img src="photos/PCB-K0402WS-V2.0/chassis-bottom.jpg" width="400" />
|
||||
|
||||
Top side (PCB)
|
||||
|
||||
<img src="photos/PCB-K0402WS-V2.0/PCB-top.jpg" width="300" />
|
||||
|
||||
### Port layout
|
||||
|
||||
| Front panel position | Logical port | Physical port | Type |
|
||||
|----------------------|--------------|---------------|---------|
|
||||
| SFP left | 8 | 5 | SFP+ |
|
||||
| RJ45 1 | 4 | 1 | Copper |
|
||||
| RJ45 2 | 5 | 2 | Copper |
|
||||
| RJ45 3 | 6 | 3 | Copper |
|
||||
| RJ45 4 | 7 | 4 | Copper |
|
||||
| SFP right | 3 | 6 | SFP+ |
|
||||
|
||||
### Serial console
|
||||
|
||||
The PCB has three unpopulated through-holes intended for a slide switch, directly connected to UART0.
|
||||
Numbered from the left (SFP port side), the pinout is:
|
||||
|
||||
| Position (left→right) | Signal | GPIO |
|
||||
|-----------------------|--------|--------------------------|
|
||||
| 1 (leftmost) | RX | GPIO32\_UART0\_RX (32) |
|
||||
| 2 (middle) | GND | GND |
|
||||
| 3 (rightmost) | TX | GPIO31\_UART0\_TX (31) |
|
||||
|
||||
- **Settings**: 115200 baud / 8N1 / 3.3V TTL
|
||||
- Connect a USB-TTL adapter: adapter TX → pin 1, GND → pin 2, adapter RX → pin 3
|
||||
|
||||
### LED configuration
|
||||
|
||||
Copper ports use LED SET0, SFP ports use LED SET1.
|
||||
|
||||
| SET | LED0 | LED2 |
|
||||
|------|--------------------------------------------------|---------------------------------------------------|
|
||||
| SET0 | Amber — lights on 2.5G link | Green — lights on 1G / 100M / 10M link |
|
||||
| SET1 | All speeds — lights on any link with activity | — |
|
||||
|
||||
LED pad to physical port mapping:
|
||||
|
||||
| GPIO pads | Port |
|
||||
|-----------|-------------------------|
|
||||
| GPIO8–11 | Physical port 5 (left SFP) |
|
||||
| GPIO12–14 | Physical port 1 (RJ45 1) |
|
||||
| GPIO15–17 | Physical port 2 (RJ45 2) |
|
||||
| GPIO18–20 | Physical port 3 (RJ45 3) |
|
||||
| GPIO21–23 | Physical port 4 (RJ45 4) |
|
||||
| GPIO24–27 | Physical port 6 (right SFP) |
|
||||
|
||||
### SFP GPIO assignments
|
||||
|
||||
| SFP | pin\_detect (ModAbs) | pin\_los | SerDes | I2C SDA | I2C SCL |
|
||||
|------------------|-----------------------------|------------------------|--------|----------------------|--------------------------|
|
||||
| Left (logical 8) | GPIO30\_ACL\_BIT3\_EN | GPIO37 | SDS1 | GPIO39\_I2C\_SDA4 | GPIO40\_I2C\_SCL3\_MDC1 |
|
||||
| Right (logical 3)| GPIO50\_I2C\_SCL2\_UART1\_TX | GPIO51\_I2C\_SDA2\_UART1\_RX | SDS0 | GPIO41\_I2C\_SDA3\_MDIO1 | GPIO40\_I2C\_SCL3\_MDC1 |
|
||||
|
||||
GPIO assignments were verified by observing GPIO state changes during SFP module insertion/removal
|
||||
and cross-checked against an original firmware register dump.
|
||||
`pin_tx_disable` is GPIO\_NA on both ports (original firmware keeps all GPIOs as inputs).
|
||||
@@ -0,0 +1,79 @@
|
||||
# PCB-K0402WS-V3.0
|
||||
|
||||
Following is documentation for a variety of unmanaged switch internally marked as `PCB-K0402WS-V3.0`. They are sold under many brands.
|
||||
|
||||
Original software is running UART on 9600 baud rate.
|
||||
|
||||
Note during opening the device: there might be a hidden 5th screw on the back
|
||||
of the device just above the big label, might be covered by a QC sticker.
|
||||
|
||||
### Brands
|
||||
|
||||
* Hisource Hi-K0402WS
|
||||
|
||||
<img src="photos/PCB-K0402WS-V3.0/HiSource_HI-K0402WS.jpg" width="300" />
|
||||
|
||||
* Ztyuav Z-QWYT0402
|
||||
|
||||
<img src="photos/PCB-K0402WS-V3.0/Ztyuav_Z-QWYT0402.jpg" width="300" />
|
||||
|
||||
<img src="photos/PCB-K0402WS-V3.0/Ztyuav_Z-QWYT0402_label.jpg" width="300" />
|
||||
|
||||
* Siscolink SL-G0402F
|
||||
|
||||
<img src="photos/PCB-K0402WS-V3.0/Siscolink SL-G0402F.jpg" width="300"/>
|
||||
### Programming
|
||||
|
||||
Using SPI clamp in-board is the only method for initial installation.
|
||||
|
||||
The board has two flash chips `BY25Q16BS` with 16M-bit size. The front switch, switches between the two flash chips.
|
||||
These can be programed independently by using said switch - so it is e.g. possible to run the original and new firmware in parallel.
|
||||
The switch actually controls the HOLD line of each flash chip, and toggling the switch results in a reboot.
|
||||
|
||||
If the programming clip keeps HOLD not connected, the flashing will commence on whatever the switch selected, regardless on which chip was clipped.
|
||||
|
||||
For the initial flash (at least with flashrom), the bin file produced by the build is much smaller than the flash chip, it is suggested to pad the file to keep flashrom happy: `truncate -s 2097152 rtlplayground-*-PCB_K0402WS_V3.bin`. Note: do not then proceed to use this resulting padded file for the web flashing (as it bricks the device), use the original unpadded .bin.
|
||||
|
||||
### What works (expected from label + similar devices)
|
||||
|
||||
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
||||
- Both SFP ports supporting 1G, 2.5G and 10G modules
|
||||
- LEDs
|
||||
|
||||
### PCB overview
|
||||
|
||||
**Board markings**
|
||||
- Top silkscreen: PCB-KO4022W-V3.0 / DIP-KO4022WS-V3.0
|
||||
|
||||
Top side
|
||||
|
||||
<img src="photos/PCB-K0402WS-V3.0/PCB-top.jpg" width="300" />
|
||||
|
||||
Bottom
|
||||
|
||||
<img src="photos/PCB-K0402WS-V3.0/PCB-bottom.jpg" width="300" />
|
||||
|
||||
### T2, serial console
|
||||
|
||||
| `J2` pin | Signal |
|
||||
| -------- | ----------- |
|
||||
| 1 | 3V3 |
|
||||
| 2 | RX (Input) |
|
||||
| 3 | TX (Output) |
|
||||
| 4 | GND |
|
||||
|
||||
|
||||
## Power supply
|
||||
|
||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
||||
Board has two supply rails. `0.95` and `3.3` volt.
|
||||
|
||||
### `0.95` Core Voltage
|
||||
|
||||
Voltage is made by a `Techcode TD1720` .
|
||||
|
||||
### `3.3` Voltage
|
||||
|
||||
Voltage is created by chip marked as `Techcode TD1720`.
|
||||
|
||||
**There seems to have been a miscalculation when choosing the inductor and the device is ~25% more efficient with an 5V power supply.**
|
||||
@@ -0,0 +1,43 @@
|
||||
# Steamemo IG204-V1
|
||||
|
||||
Following is documentation for unmanaged switch marked as `IG204-V1`.
|
||||
|
||||
Using SPI clamp in-board is the only method for initial installation.
|
||||
|
||||
### Label specifications
|
||||
|
||||
- **Name**: 2.5G Ethernet Switch
|
||||
- **Model**: IG204 V1
|
||||
- **Ports**:
|
||||
- 4 × RJ45: 10/100/1000/2500 Mbps
|
||||
- 2 × SFP: 1000 / 2500 / 10000 Mbps
|
||||
|
||||
### What works (expected from label + similar devices)
|
||||
|
||||
- Four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
||||
- Two SFP ports supporting 1G, 2.5G and 10G modules
|
||||
- LEDs
|
||||
|
||||
### PCB overview
|
||||
|
||||
**Board markings**
|
||||
- Top silkscreen: PB-2131
|
||||
|
||||
|
||||
Top side
|
||||
|
||||
<img src="photos/STEAMEMO_IG204_V1/PCB-top.jpg" width="600" />
|
||||
|
||||
### Connectors
|
||||
### T7, serial console
|
||||
|
||||
| `T7` pin | Signal |
|
||||
| -------- | ----------- |
|
||||
| 1 | TX (Output) |
|
||||
| 2 | GND |
|
||||
| 3 | RX (Input) |
|
||||
| 4 | 3V3 |
|
||||
|
||||
### Power supply
|
||||
|
||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
||||
@@ -1,4 +1,11 @@
|
||||
# SWTG018AS-A V2.0
|
||||
## Brands
|
||||
| Brand | Type |Managed| PCB | Flash | Chip RTL |
|
||||
|---------|------------------|-------|------------------|-----------------|---------------|
|
||||
| Ampcom | SWTG018AS-A V2.0 | No | SWTG018AS-A V2.0 | 2MB | 8273N + 8224N |
|
||||
| Horaco | HC-SWTGW218AS-A | Yes | SWTG018AS-A V2.0 | 2MB(25Q16JVSIQ) | 8273N + 8224N |
|
||||
| GoodTop | GT-ST018M | Yes | SWTG018AS-A V2.0 | ? | 8273N + 8224N |
|
||||
|
||||
|
||||
The following is a documentation for the unmanaged switch marked as `SWTG018AS-A V2.0`.
|
||||
It is e.g. sold under the Ampcom brand, but no branh-markings are found on the device.
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
### SWTG024AS-A-V2.0.1_4C_2SFP
|
||||
It is highly similar to SWTG024AS-V2.0, with the only difference being the GPIO configuration for the SFP port.
|
||||
|
||||
## Brands
|
||||
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
||||
|---|---|---|---|---|---|
|
||||
| Horaco | ZX-SG4T2 | | PCB-SWTG024AS-A-V2.0.1_19650 | P25D40SH | ??? |
|
||||
|
||||
### Label specifications
|
||||
|
||||
- **Name**:
|
||||
- **Ports**:
|
||||
- 4 × RJ45: 10/100/1000/2500 Mbps
|
||||
- 2 × SFP+: 1000 / 2500 / 10000 Mbps
|
||||
|
||||
<img src="photos/SWTG024AS-A-V2_0_1_19650/horaco-zx-sg4t2-label.jpg" width="300" />
|
||||
|
||||
### What works
|
||||
The device is fully supported:
|
||||
- ALL 2.5GBASE-T RJ45 ports work at 10/100/1000/2500 Mbps
|
||||
- The SFP+ port supports 1G, 2.5G and 10G modules
|
||||
|
||||
### PCB overview
|
||||
|
||||
**Board markings**
|
||||
- Top silkscreen: PCB-SWTG024AS-A-V2.0.1_19650
|
||||
|
||||
Top side
|
||||
|
||||
<img src="photos/SWTG024AS-A-V2_0_1_19650/horaco-zx-sg4t2-pcb-top.jpg" width="300" />
|
||||
|
||||
Bottom
|
||||
|
||||
<img src="photos/SWTG024AS-A-V2_0_1_19650/horaco-zx-sg4t2-pcb-bottom.jpg" width="300" />
|
||||
|
||||
### J1, serial console
|
||||
|
||||
| `J1` pin | Signal |
|
||||
| -------- | ----------- |
|
||||
| 1 | 3V3 |
|
||||
| 2 | GND |
|
||||
| 3 | RX (Input) |
|
||||
| 4 | TX (Output) |
|
||||
@@ -0,0 +1,44 @@
|
||||
### SWTG024AS-A-V2.0.1_5C_1SFP
|
||||
It is highly similar to SWTG024AS-V2.0, with the only difference being the GPIO configuration for the SFP port.
|
||||
|
||||
## Brands
|
||||
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
||||
|---|---|---|---|---|---|
|
||||
| Horaco | HC-SWTGW215AS | | PCB-SWTG024AS-A-V2.0.1_19650 | W25Q16JV | 8272N |
|
||||
|
||||
### Label specifications
|
||||
|
||||
- **Name**:
|
||||
- **Ports**:
|
||||
- 5 × RJ45: 10/100/1000/2500 Mbps
|
||||
- 1 × SFP+: 1000 / 2500 / 10000 Mbps
|
||||
|
||||
<!-- <img src="" width="300" /> -->
|
||||
|
||||
### What works
|
||||
The device is fully supported:
|
||||
- ALL 2.5GBASE-T RJ45 ports work at 10/100/1000/2500 Mbps
|
||||
- The SFP+ port supports 1G, 2.5G and 10G modules
|
||||
- LEDs work with the same indiciations as the OEM firmware
|
||||
|
||||
### PCB overview
|
||||
|
||||
**Board markings**
|
||||
- Top silkscreen: PCB-SWTG024AS-A-V2.0.1_19650
|
||||
|
||||
Top side
|
||||
|
||||
<!-- <img src="" width="300" /> -->
|
||||
|
||||
Bottom
|
||||
|
||||
<!-- <img src="" width="300" /> -->
|
||||
|
||||
### J1, serial console
|
||||
|
||||
| `J1` pin | Signal |
|
||||
| -------- | ----------- |
|
||||
| 1 | 3V3 |
|
||||
| 2 | GND |
|
||||
| 3 | RX (Input) |
|
||||
| 4 | TX (Output) |
|
||||
@@ -0,0 +1,49 @@
|
||||
### SWTG024AS-V2.0
|
||||
|
||||
## Brands
|
||||
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
||||
|---|---|---|---|---|---|
|
||||
| hongyavision | LG-SG5T1 | No | PCB-SWTG024AS-V2.0_16895 | 25Q40 | 8272 |
|
||||
|
||||
### Label specifications
|
||||
|
||||
- **Name**:
|
||||
- **Ports**:
|
||||
- 5 × RJ45: 10/100/1000/2500 Mbps
|
||||
- 1 × SFP+: 1000 / 2500 / 10000 Mbps
|
||||
- **Power**: 12V DC, 1A 5525 connector
|
||||
|
||||
<img src="photos/SWTG024AS-V2.0/label.jpg" width="300" />
|
||||
|
||||
### What works
|
||||
The device is fully supported:
|
||||
- ALL 2.5GBASE-T RJ45 ports work at 10/100/1000/2500 Mbps
|
||||
- The SFP+ port supports 1G, 2.5G and 10G modules
|
||||
- LEDs work with the same indiciations as the OEM firmware
|
||||
- Online update does not work with 512KiB flash.
|
||||
### PCB overview
|
||||
|
||||
**Board markings**
|
||||
- Top silkscreen: PCB-SWTG024AS-V2.0
|
||||
|
||||
Top side
|
||||
|
||||
<img src="photos/SWTG024AS-V2.0/pcb_top.jpg" width="300" />
|
||||
|
||||
Bottom
|
||||
|
||||
<img src="photos/SWTG024AS-V2.0/pcb_bottom.jpg" width="300" />
|
||||
|
||||
### J1, serial console
|
||||
|
||||
| `J1` pin | Signal |
|
||||
| -------- | ----------- |
|
||||
| 1 | GND |
|
||||
| 2 | RX (Input) |
|
||||
| 3 | TX (Output) |
|
||||
|
||||
Note,`R52`、`R53`may not be installed.You need to bridge them using either solder or resistors.
|
||||
|
||||
## Power supply
|
||||
|
||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
||||
@@ -9,8 +9,8 @@ Also the RJ45 connectors can be all plastic/non-shielded or with metal shielding
|
||||
|Brand|Type|Managed|PCB|PCB Label|Flash|Chip RTL|
|
||||
|---|---|---|---|---|---|---|
|
||||
| LIANGUO |SWTG024AS |No| SWTG024AS-v2.0-17452 | CM-23-11-2336 023-17453| 512 KiB | 8272 |
|
||||
| Haraco |ZX-SWTG124AS | Yes | SWTG024AS-v2.0 | ??? | ??? | 8272 |
|
||||
| Xikestore |SKS3200M-4GPY2XF | Yes | SWTG024AS-v1.0 | CM-23-08-2043 023-16721 | ??? | 8272 |
|
||||
| Horaco |ZX-SWTG124AS | Yes | SWTG024AS-v2.0 | ??? | ??? | 8272 |
|
||||
| Xikestore |SKS3200M-4GPY2XF | Yes | SWTG024AS-v1.0 | CM-23-08-2043 023-16721 | 2048 KiB | 8272 |
|
||||
| Sodola | SL-SWTG124AS-D | Yes | SWTG024AS-v2.0-17452 | ??? | 2048 KiB | 8272 |
|
||||
|
||||
## PCB
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
### ZX-SWTGW215AS
|
||||
# ZX-SWTGW215AS
|
||||
|
||||
## Brands
|
||||
|
||||
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
||||
|---|---|---|---|---|---|
|
||||
| Lianguo | ZX-SWTGW215AS | Yes | PCB-SWTG115AS-V2.0 | FM25Q16A | 8272 |
|
||||
| Lianguo | ZX-SWTGW215AS | Yes | PCB-SWTG115AS-V2.0 | FM25Q16A | 8372 |
|
||||
| sold as Lianguo, actual device unbranded | ZX-SWTGW215AS | Yes | PCB-SWTG115AS-V2.1 | W25Q16JVSIQ (2MiB) | 8372 |
|
||||
|
||||
## RTLPlayground target
|
||||
|
||||
@@ -12,13 +14,23 @@ 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
|
||||
## Label (V2.0)
|
||||
|
||||
<img src="photos/ZX-SWTGW215AS/pcb_top.jpg" width="300" />
|
||||
<img src="photos/ZX-SWTGW215AS-V2.0/label.jpg" width="300" />
|
||||
|
||||
# Connectors
|
||||
## PCB (V2.0)
|
||||
|
||||
## Port overview
|
||||
<img src="photos/ZX-SWTGW215AS-V2.0/pcb_top.jpg" width="300" />
|
||||
<img src="photos/ZX-SWTGW215AS-V2.0/pcb_bottom.jpg" width="300" />
|
||||
|
||||
## PCB (V2.1)
|
||||
|
||||
<img src="photos/ZX-SWTGW215AS-V2.1/pcb-top.jpg" width="300" />
|
||||
<img src="photos/ZX-SWTGW215AS-V2.1/pcb-bottom.jpg" width="300" />
|
||||
|
||||
## Connectors
|
||||
|
||||
### Port overview
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────────────────────┐
|
||||
@@ -36,7 +48,7 @@ Port 5 RJ45 is interfaced through a RTL8221B IC.
|
||||
| RJ45 | 3, 4, 5, 6, 7 | 1-5 |
|
||||
| SFP | 8 | 6 |
|
||||
|
||||
## J4
|
||||
### J4
|
||||
|
||||
* Location: SFP connector `J4`.
|
||||
* Connected to: 10GMAC number 8, SerDes 1.
|
||||
@@ -48,10 +60,11 @@ Port 5 RJ45 is interfaced through a RTL8221B IC.
|
||||
|5| MODDEF1 – SCL | GPIO40 | I2C SCL |
|
||||
|6| MODDEF0 – PRESENT | GPIO30 | Detect |
|
||||
|8| LOS | GPIO37 | RX Loss of Signal |
|
||||
### Notes
|
||||
|
||||
#### Notes
|
||||
* Not all signals were mapped mechanically, hence they've been left out of documentation.
|
||||
|
||||
## T3, Slave Interface
|
||||
### T3, Slave Interface
|
||||
|
||||
This connector goes to U4 `I2C EEPROM` and U10 `SPI FLASH` (mappings identical to SWTG024AS).
|
||||
|
||||
@@ -65,11 +78,12 @@ For detailed Slave Interface functionality and protocol information, see [T3 doc
|
||||
|4| VCC |
|
||||
|5| 33R -> U10-P2 | SPI-DO/D1 |
|
||||
|6| U10-P1 | SPI-CS |
|
||||
### Notes
|
||||
|
||||
#### Notes
|
||||
* 1 pin is square shaped.
|
||||
|
||||
|
||||
## T5, Serial Console
|
||||
### T5, Serial Console
|
||||
|
||||
|`T5` pin|GPIO|Signal|
|
||||
|---|---|---|
|
||||
@@ -77,10 +91,11 @@ For detailed Slave Interface functionality and protocol information, see [T3 doc
|
||||
| 2 | GND | |
|
||||
| 3 | GPIO32 | U0RXD (Input) |
|
||||
| 4 | 3V3 | |
|
||||
### Notes
|
||||
|
||||
#### Notes
|
||||
* 1 pin is square shaped.
|
||||
|
||||
## T8
|
||||
### T8
|
||||
|
||||
|`T8` pin|GPIO|Signal|
|
||||
|---|---|---|
|
||||
@@ -91,18 +106,19 @@ For detailed Slave Interface functionality and protocol information, see [T3 doc
|
||||
| 5 | GPIO47 | |
|
||||
| 6 | GPIO49 | |
|
||||
|
||||
### Notes
|
||||
#### Notes
|
||||
* 1 pin is square shaped.
|
||||
* Mapping unverified but assumed the same as [LIANGUO SWTG024AS](SWTG024AS.md#t8).
|
||||
|
||||
# Reset Circuit
|
||||
## Reset Circuit
|
||||
| Function | GPIO |
|
||||
|---|---|
|
||||
| Reset button | GPIO54 |
|
||||
|
||||
### Notes
|
||||
* Circuit is active-low
|
||||
|
||||
# GPIO
|
||||
## 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.
|
||||
|
||||
@@ -141,7 +157,7 @@ Note: T3/U4/U10-related signal annotations below are copied from [LIANGUO SWTG02
|
||||
| 40000000 | GPIO30 | J4-6 | SFP DETECT | | GPIO62 | | |
|
||||
| 80000000 | GPIO31 | T5-1 | U0TXD | | GPIO63 | | |
|
||||
|
||||
# LEDs
|
||||
## LEDs
|
||||
|
||||
| NAME | GPIO | Port(s) | Function | Notes |
|
||||
| ---- | ---- | ---- | ---- | ---- |
|
||||
@@ -162,3 +178,6 @@ Note: T3/U4/U10-related signal annotations below are copied from [LIANGUO SWTG02
|
||||
|
||||
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.
|
||||
|
||||
## Flashing
|
||||
|
||||
For devices with Winbond 25Q16JVSIQ, flashing is possible for example using flashprog with device "W25Q16.V". Note that you should not overwrite the whole flash to keep device-specific data (like the MAC address at 0x1fc000). Also, creating a backup of the entire falsh before is of course a very good idea.
|
||||
@@ -6,6 +6,7 @@
|
||||
| Mokerlink | ZX-SWTGW218AS | Yes| SWTG118AS-V2.0-16029 | 2MB (FM25Q16A)| 8273N + 8224N |
|
||||
| Sodola | | | | | |
|
||||
| Horaco | | | | | |
|
||||
| XikeStor | SKS3200-8E1X | Yes | SWTG118AS-V2.1-17462 | 2MB (25Q16JVSIQ) | |
|
||||
|
||||
|
||||
## Photos
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# ZX310S-4T2XT
|
||||
|
||||
The following is a documentation for the managed switch marked as
|
||||
`ZX310S-4T2XT` and sold by Horaco.
|
||||
|
||||
The original software is running UART on 57600 baud rate 8N1.
|
||||
|
||||
CPU: RTL8372
|
||||
Flash: 2MByte Winbond W25Q16DV (U3)
|
||||
PHY 2x RTL8261BE
|
||||
|
||||
### Label specifications
|
||||
|
||||
- **Name**:
|
||||
- **Ports**:
|
||||
- 4 × RJ45: 10/100/1000/2500 Mbps
|
||||
- 2 x RJ45: 10/100/1000/2500/5000/10000 Mbps
|
||||
- **Power**: 12V DC, 2A barrel connector
|
||||
|
||||
<img src="photos/ZX310S-4T2XT/label.jpg" width="300" />
|
||||
|
||||
### What works
|
||||
The device is fully supported:
|
||||
- All 4 2.5GBASE-T RJ45 ports work at 10/100/1000/2500 Mbps, including EEE
|
||||
- The 10GBit ports works, including EEE.
|
||||
- LEDs work with the same indiciations as the OEM firmware
|
||||
|
||||
### PCB overview
|
||||
|
||||
**Board markings**
|
||||
- Top silkscreen: PCB-SL310S-4T2XT-V1.0.0-22273
|
||||
|
||||
Top side
|
||||
|
||||
<img src="photos/ZX310S-4T2XT/pcb_top.jpg" width="300" />
|
||||
|
||||
Bottom
|
||||
|
||||
<img src="photos/ZX310S-4T2XT/pcb_bottom.jpg" width="300" />
|
||||
|
||||
### J1, serial console
|
||||
|
||||
| `J1` pin | Signal |
|
||||
| -------- | ----------- |
|
||||
| 1 | TX (Output) |
|
||||
| 2 | RX (Input) |
|
||||
| 3 | GND |
|
||||
| 4 | 3V3 |
|
||||
|
||||
|
||||
## Power supply
|
||||
|
||||
Input power is delivered via barell plug, `12V 2A` adapter was provided.
|
||||
|
After Width: | Height: | Size: 480 KiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 715 KiB |
|
After Width: | Height: | Size: 615 KiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 519 KiB |
|
After Width: | Height: | Size: 529 KiB |
|
After Width: | Height: | Size: 133 KiB |
|
After Width: | Height: | Size: 207 KiB |
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 203 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 220 KiB |
|
After Width: | Height: | Size: 273 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 791 KiB |
|
After Width: | Height: | Size: 760 KiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 546 KiB |
|
After Width: | Height: | Size: 478 KiB |
|
After Width: | Height: | Size: 639 KiB |
|
After Width: | Height: | Size: 907 KiB |
|
After Width: | Height: | Size: 923 KiB |
|
After Width: | Height: | Size: 290 KiB |
|
After Width: | Height: | Size: 360 KiB |
|
After Width: | Height: | Size: 170 KiB |
|
After Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 3.5 MiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 152 KiB |
|
After Width: | Height: | Size: 242 KiB |
|
After Width: | Height: | Size: 157 KiB |
|
After Width: | Height: | Size: 934 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 455 KiB |
|
After Width: | Height: | Size: 710 KiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 3.2 MiB |
|
After Width: | Height: | Size: 9.7 MiB |
|
After Width: | Height: | Size: 36 MiB |
|
After Width: | Height: | Size: 476 KiB |