Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e39d81992 | ||
|
|
7621045de1 | ||
|
|
36a064d03d | ||
|
|
2d01b8b7d7 | ||
|
|
ff57084799 | ||
|
|
2dc5520928 | ||
|
|
7c11142a04 | ||
|
|
957a5b0e23 | ||
|
|
c773230a9b | ||
|
|
0e9c997d06 | ||
|
|
5ab247e996 | ||
|
|
d80717f3f0 | ||
|
|
2e24b24426 | ||
|
|
b71239f394 | ||
|
|
6e69f5bba3 | ||
|
|
1224335b66 | ||
|
|
e5b19bc594 | ||
|
|
89fcc6836d | ||
|
|
f9d4ab0074 | ||
|
|
6f68ccef28 | ||
|
|
8e687ef28e | ||
|
|
87db2dd4b8 | ||
|
|
aac1aed4c8 | ||
|
|
f0aea3dcac | ||
|
|
f10ab30f6d | ||
|
|
de431c6d84 | ||
|
|
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 | ||
|
|
1b5243714e | ||
|
|
ce11790a0d | ||
|
|
55431b39f6 | ||
|
|
46e1c955ba | ||
|
|
7b728cec6f | ||
|
|
0d17dd563f | ||
|
|
d556d634ca | ||
|
|
2844a1ed6d | ||
|
|
7b5e365d5e | ||
|
|
45fb382b07 | ||
|
|
8973774594 | ||
|
|
48c5b0c9cf | ||
|
|
1557a7cf3c | ||
|
|
131bc106af | ||
|
|
19ccc4003d | ||
|
|
b5fe9f217f | ||
|
|
f65d14f452 | ||
|
|
b92fba870c | ||
|
|
4deee377a7 | ||
|
|
fe42b07e2b | ||
|
|
9984649177 | ||
|
|
7d47edb649 | ||
|
|
fdb19fe0ee | ||
|
|
b9b50f9a70 | ||
|
|
c31b67572b | ||
|
|
93003c8cb8 | ||
|
|
fd058ea74d | ||
|
|
edc469fe29 | ||
|
|
a71c5359a5 | ||
|
|
9e3863cc4e | ||
|
|
d22ec04b5b | ||
|
|
0a65536a7f | ||
|
|
0631c813e2 | ||
|
|
eaebeba528 | ||
|
|
b36fd95356 | ||
|
|
52b1d1a4ea | ||
|
|
48f28ae7ff | ||
|
|
a7fc8303e9 | ||
|
|
a62866a93a | ||
|
|
42bbed9661 | ||
|
|
3c8de6da87 | ||
|
|
3a6f62b1d5 | ||
|
|
530e2683f0 | ||
|
|
9fedc6dd3d | ||
|
|
5e23d13771 | ||
|
|
09d5857fdd | ||
|
|
be309853c9 | ||
|
|
072edb36a8 | ||
|
|
10dd330e3c | ||
|
|
e2c4ed6be3 | ||
|
|
56ee56af2e | ||
|
|
8626b4c1d4 | ||
|
|
0cc09e4015 | ||
|
|
674dc1f35d | ||
|
|
7e6b443e07 | ||
|
|
73ec184c23 | ||
|
|
bf41fbd202 | ||
|
|
04ab442c6d | ||
|
|
c02623a610 | ||
|
|
c69bf4c5ec | ||
|
|
7f4f6dae03 | ||
|
|
4eeb12c020 | ||
|
|
7d81b15b6e | ||
|
|
d6253ddc25 | ||
|
|
8cac67cdf7 | ||
|
|
5620e950ce | ||
|
|
83491bc9e3 | ||
|
|
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 | ||
|
|
e7f70a724b | ||
|
|
d7a7bdac7e | ||
|
|
592b903305 |
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:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ['**']
|
branches: ['**']
|
||||||
|
pull_request:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -16,8 +17,14 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
apt update
|
apt update
|
||||||
apt install make gcc sdcc xxd python-is-python3 libjson-c-dev -y
|
apt install make gcc sdcc xxd python-is-python3 libjson-c-dev zlib1g-dev -y
|
||||||
|
- name: Run the host-side unit tests
|
||||||
|
run: make -C test
|
||||||
- name: Check if machine.c can be compiled for all machines
|
- name: Check if machine.c can be compiled for all machines
|
||||||
run: make machine_check
|
run: make machine_check
|
||||||
- name: Make project
|
- name: Make project (4x2/RTL8372)
|
||||||
run: make MACHINE="KP_9000_6XHML_X2"
|
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/httpd_sim
|
||||||
tools/injector
|
tools/injector
|
||||||
tools/fileadder
|
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,9 +4,11 @@ DEFAULT_CONFIG_LOCATION = 454656
|
|||||||
CONFIG_LOCATION = 458752
|
CONFIG_LOCATION = 458752
|
||||||
HTML_LOCATION = 262144
|
HTML_LOCATION = 262144
|
||||||
|
|
||||||
|
ifeq ($(origin CC),default)
|
||||||
CC = sdcc
|
CC = sdcc
|
||||||
|
endif
|
||||||
CC_FLAGS = -mmcs51 -I. -Ihttpd -Iuip
|
CC_FLAGS = -mmcs51 -I. -Ihttpd -Iuip
|
||||||
ASM = sdas8051
|
ASM ?= sdas8051
|
||||||
AFLAGS= -plosgff
|
AFLAGS= -plosgff
|
||||||
|
|
||||||
SUBDIRS := tools
|
SUBDIRS := tools
|
||||||
@@ -17,6 +19,14 @@ ifeq ($(MACHINE),)
|
|||||||
else
|
else
|
||||||
CC_FLAGS += -DMACHINE_$(MACHINE)
|
CC_FLAGS += -DMACHINE_$(MACHINE)
|
||||||
endif
|
endif
|
||||||
|
# Health instrumentation and the "health" console command: HEALTH=1 gmake ...
|
||||||
|
ifneq ($(HEALTH),)
|
||||||
|
CC_FLAGS += -DHEALTH
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CI),1)
|
||||||
|
CC_FLAGS += --Werror
|
||||||
|
endif
|
||||||
|
|
||||||
BUILDDIR = output/$(MACHINE)
|
BUILDDIR = output/$(MACHINE)
|
||||||
VERSION_HEADER := version.h
|
VERSION_HEADER := version.h
|
||||||
@@ -30,76 +40,149 @@ endif
|
|||||||
VERSION_EXTENSION = v$(VERSION)-$(GIT_VERSION)
|
VERSION_EXTENSION = v$(VERSION)-$(GIT_VERSION)
|
||||||
FILENAME_EXTENSION = $(VERSION_EXTENSION)-$(MACHINE)
|
FILENAME_EXTENSION = $(VERSION_EXTENSION)-$(MACHINE)
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
all: create_build_dir $(VERSION_HEADER) $(SUBDIRS) $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin
|
all: create_build_dir $(VERSION_HEADER) $(SUBDIRS) $(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin
|
||||||
|
|
||||||
create_build_dir:
|
create_build_dir:
|
||||||
mkdir -p $(BUILDDIR)
|
mkdir -p "$(BUILDDIR)"
|
||||||
mkdir -p $(BUILDDIR)/uip
|
mkdir -p "$(BUILDDIR)/uip"
|
||||||
mkdir -p $(BUILDDIR)/httpd
|
mkdir -p "$(BUILDDIR)/httpd"
|
||||||
|
mkdir -p "$(BUILDDIR)/crypto"
|
||||||
|
|
||||||
|
# Keep machine.c in first position to fail immediately on invalid $MACHINE value
|
||||||
|
SRCS = \
|
||||||
|
machine.c \
|
||||||
|
machine_init.c \
|
||||||
|
cmd_editor.c \
|
||||||
|
cmd_parser.c \
|
||||||
|
dhcp.c \
|
||||||
|
html_data.c \
|
||||||
|
rtlplayground.c \
|
||||||
|
boot.c \
|
||||||
|
sfp.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_phy.c \
|
||||||
|
rtl837x_pins.c\
|
||||||
|
rtl837x_port.c \
|
||||||
|
rtl837x_stp.c \
|
||||||
|
rtl837x_storm.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}
|
OBJS = ${SRCS:%.c=$(BUILDDIR)/%.rel}
|
||||||
DEPS := ${SRCS:%.c=$(BUILDDIR)/%.d}
|
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/output/fileadder
|
# Minified copy of the web UI sources, used as the fileadder input.
|
||||||
tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -d html -p html_data
|
# 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):
|
html_data.c html_data.h &: $(HTML) | tools html_min
|
||||||
@echo "#ifndef VERSION_H" > $(VERSION_HEADER)
|
tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -z -d $(HTML_MIN) -p html_data
|
||||||
@echo "#define VERSION_H" >> $(VERSION_HEADER)
|
|
||||||
@echo "#define VERSION_SW \"$(VERSION_EXTENSION)\"" >> $(VERSION_HEADER)
|
$(VERSION_HEADER): FORCE
|
||||||
@echo "#define BUILD_DATE \"$(shell date +"%Y-%m-%d %H:%M:%S")\"" >> $(VERSION_HEADER)
|
@printf '%s\n' "#ifndef VERSION_H" "#define VERSION_H" \
|
||||||
@echo "#endif" >> $(VERSION_HEADER)
|
"#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
|
httpd: html_data.h
|
||||||
|
|
||||||
$(SUBDIRS):
|
$(SUBDIRS):
|
||||||
$(MAKE) -C $@
|
$(MAKE) -C $@
|
||||||
|
|
||||||
clean:
|
clean: $(SUBDIRSCLEAN)
|
||||||
-rm -f html_data.c html_data.h $(VERSION_HEADER)
|
-rm -f html_data.c html_data.h $(VERSION_HEADER)
|
||||||
-if [ -d $(BUILDDIR) ]; then find $(BUILDDIR) -type f ! -name "*.bin" -delete; fi
|
-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 -f html_data.c html_data.h $(VERSION_HEADER)
|
||||||
-rm -rf $(BUILDDIR)
|
-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 $<
|
$(CC) -MMD $(CC_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
$(BUILDDIR)/%.rel: %.asm
|
$(BUILDDIR)/%.rel: %.asm $(CCFLAGS_STAMP) | create_build_dir
|
||||||
${ASM} ${AFLAGS} -o $@ $<
|
${ASM} ${AFLAGS} -o $@ $<
|
||||||
# mv -f $(addprefix $(basename $^), .lst .rel .sym) .
|
# mv -f $(addprefix $(basename $^), .lst .rel .sym) .
|
||||||
|
|
||||||
$(BUILDDIR)/rtlplayground.ihx: $(OBJS) $(BUILDDIR)/crtstart.rel $(BUILDDIR)/crc16.rel
|
$(BUILDDIR)/rtlplayground.ihx: $(OBJS) $(BUILDDIR)/crtbank.rel $(BUILDDIR)/crc16.rel $(BUILDDIR)/crypto/chacha_8051.rel
|
||||||
$(CC) $(CC_FLAGS) -Wl-bHOME=0x00000 -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-r -o $@ $^
|
$(CC) $(CC_FLAGS) --xram-size 48896 -Wl-bHOME=0x00000 -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-bBANK3=0x34000 -Wl-r -o $@ $^
|
||||||
|
|
||||||
$(BUILDDIR)/rtlplayground.img: $(BUILDDIR)/rtlplayground.ihx
|
$(BUILDDIR)/rtlplayground.img: $(BUILDDIR)/rtlplayground.ihx
|
||||||
objcopy --input-target=ihex -O binary $< $@
|
objcopy --input-target=ihex -O binary $< $@
|
||||||
|
|
||||||
$(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.img
|
$(BUILDDIR)/rtlplayground-$(FILENAME_EXTENSION).bin: $(BUILDDIR)/rtlplayground.img | tools
|
||||||
if [ -e $@ ]; then rm $@; fi
|
if [ -e $@ ]; then rm $@; fi
|
||||||
tools/output/imagebuilder -i $^ $@
|
tools/output/imagebuilder -i $^ $@
|
||||||
tools/output/fileadder -a $(DEFAULT_CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
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 $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@
|
||||||
tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data -b BANK1 $@
|
tools/output/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -z -d $(HTML_MIN) -b BANK1 $@
|
||||||
tools/output/crc_calculator -u $@
|
tools/output/crc_calculator -u $@
|
||||||
ln -sf $(MACHINE)/rtlplayground-$(FILENAME_EXTENSION).bin output/rtlplayground.bin
|
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
|
||||||
|
|
||||||
.PHONY:
|
.PHONY:
|
||||||
machine_check:
|
machine_check:
|
||||||
@mkdir -p $(BUILDDIR)/tmp
|
@mkdir -p $(BUILDDIR)/tmp
|
||||||
@set -eo pipefail; \
|
@set -eo pipefail; \
|
||||||
for MACHINE in `grep -e ' MACHINE_' machine.c | sed -e 's%^.* MACHINE_%%' -e 's%[ ]*//.*$$%%' | sort -u`; \
|
for MACHINE in `grep -E '^[[:space:]]*(//[[:space:]]*)?#define MACHINE_' machine.h | sed -E 's%^[[:space:]]*(//[[:space:]]*)?#define MACHINE_%%' | awk '{print $$1}' | sort -u`; \
|
||||||
do \
|
do \
|
||||||
echo "Checking $${MACHINE}"; \
|
echo "Checking $${MACHINE}"; \
|
||||||
$(CC) $(CC_FLAGS) -DMACHINE_$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine.c; \
|
$(CC) $(CC_FLAGS) -DMACHINE_$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine.c; \
|
||||||
|
$(CC) $(CC_FLAGS) -DMACHINE_$${MACHINE} -MMD -o $(BUILDDIR)/tmp/machine_check -c machine_init.c; \
|
||||||
done
|
done
|
||||||
@rm -rf $(BUILDDIR)/tmp
|
@rm -rf $(BUILDDIR)/tmp
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,15 @@
|
|||||||
A Playground for Firmware development for advanced user of RTL8372/RTL8373 based 2.5GBit Switches.
|
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
|
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,
|
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:
|
only the following features are provided:
|
||||||
- A modern web-interface with mouse-over to display further information
|
- A modern web-interface with mouse-over to display further information
|
||||||
- A serial console interface to configure all features
|
- A serial console interface to configure all features
|
||||||
- IGMP to configure Multicast streaming
|
- IGMP to configure Multicast streaming
|
||||||
- Port configuration showing detailed informtion about own and Link-partner advertised
|
- Port configuration showing detailed information about own and Link-partner advertised
|
||||||
Speed settins and configuration of these settings on the local side
|
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
|
- Per-port configuration of frame sizes (MTUs) for Jumbo-Frame support or limiting MTUs
|
||||||
for particular devices
|
for particular devices
|
||||||
- EEE (Energy Efficient Ethernet) can be configured per-port. Detailed information is
|
- 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
|
- Firmware updates via the web
|
||||||
- Installation as a firmware upgrade from the original web-interface
|
- 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,
|
While the firmware provides already considerable improvements over the original managed firmware,
|
||||||
the firmware still lacks support for STP and the proprietary loop prevention
|
the firmware still lacks support for the proprietary loop prevention
|
||||||
protocols as well as DHCP. If you need these features, do not install the playground on your managed
|
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
|
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
|
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
|
backups and can re-install that firmware in case something is wrong. For this no soldering
|
||||||
skills are necessary.
|
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
|
- 4 2.5GBit ports + 2 SFP+ ports
|
||||||
- 5 2.5GBIT + 1 SFP+ port
|
- 5 2.5GBIT + 1 SFP+ port
|
||||||
- 8 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
|
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:
|
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
|
## (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.
|
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]
|
> [!CAUTION]
|
||||||
> This image can be flashed directly to the chip OR through the firmware update/upgrade
|
> 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)
|
## (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)
|
## (3) Sandbox Usage with Ghidra (optional)
|
||||||
|
|
||||||
You can play with the image using ghidra or flash real Switch Hardware. For
|
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)
|
## (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).
|
Unmanaged switch cannot be flashed this way (see 5).
|
||||||
|
|
||||||
Go to "Firmware update" tab, select the correct file.
|
Go to "Firmware update" tab, select the correct file.
|
||||||
@@ -141,7 +190,7 @@ Go to "Firmware update" tab, select the correct file.
|
|||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> Check one more time that your device matches the machine type before flashing.
|
> Check one more time that your device matches the machine type before flashing.
|
||||||
> 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 !
|
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)
|
## (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 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]
|
> [!IMPORTANT]
|
||||||
> You need a SOIC-8 clip to flash the ROM chip directly onboard.
|
> 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) !
|
- ERASE THE ROM (BLANK) !
|
||||||
- Load the firmware into IMSProg.
|
- Load the firmware into IMSProg.
|
||||||
- Flash is to the ROM chip.
|
- 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.
|
- You're done, ready for the first boot.
|
||||||
|
|
||||||
## (6) Connecting a serial interface (optional)
|
## (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
|
## (8) The web-interface
|
||||||
|
|
||||||
The web-interface can be reached under the [default 192.168.10.247](http://192.168.10.247) unless you
|
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]
|
> [!TIP]
|
||||||
> The default password is `1234`.
|
> 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
|
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
|
ip xxx.xxx.xxx.xxx = IP address of the switch
|
||||||
gw yyy.yyy.yyy.yyy = IP adress of the gateway
|
gw yyy.yyy.yyy.yyy = IP address of the gateway
|
||||||
netmask zzz.zzz.zzz.zzz = Network mask of the switch
|
netmask zzz.zzz.zzz.zzz = Network mask of the switch
|
||||||
port x name xxx = Name xxx the port number x
|
port x name xxx = Name xxx the port number x
|
||||||
port z 1g = Set 1g speed for port z
|
port z 1g = Set 1g speed for port z
|
||||||
igmp on/off = Turn IGMP on or off
|
igmp on/off = Turn IGMP on or off
|
||||||
|
session xxxx = Web session timeout in seconds (default 200)
|
||||||
```
|
```
|
||||||
[To be continue]
|
[To be continue]
|
||||||
|
|
||||||
@@ -310,4 +360,5 @@ The following documents give further documentation on specific features of the R
|
|||||||
- [SFP+ ports](doc/sfp.md)
|
- [SFP+ ports](doc/sfp.md)
|
||||||
- [Trunking aka. port aggregation](doc/trunking.md)
|
- [Trunking aka. port aggregation](doc/trunking.md)
|
||||||
- [VLAN](doc/vlan.md)
|
- [VLAN](doc/vlan.md)
|
||||||
|
- [Storm control](doc/storm_control.md)
|
||||||
- [Modifications and Flash replacement](doc/mods.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,8 +40,10 @@ void cmd_edit(void) __banked
|
|||||||
{
|
{
|
||||||
while (l != sbuf_ptr) {
|
while (l != sbuf_ptr) {
|
||||||
if (sbuf[l] >= ' ' && sbuf[l] < 127) { // A printable character, copy to command line
|
if (sbuf[l] >= ' ' && sbuf[l] < 127) { // A printable character, copy to command line
|
||||||
if (cmd_line_len >= CMD_BUF_SIZE)
|
// Reserve one byte for the terminating NUL written on Enter. When the
|
||||||
continue;
|
// 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]);
|
write_char(sbuf[l]);
|
||||||
// Shift buffer to right
|
// Shift buffer to right
|
||||||
for (uint8_t i = cmd_line_len; i > cursor; i--)
|
for (uint8_t i = cmd_line_len; i > cursor; i--)
|
||||||
@@ -55,6 +57,7 @@ void cmd_edit(void) __banked
|
|||||||
// Move backwards
|
// Move backwards
|
||||||
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
for (uint8_t i = cursor; i < cmd_line_len; i++)
|
||||||
write_char('\010'); // BS works like cursor-left
|
write_char('\010'); // BS works like cursor-left
|
||||||
|
}
|
||||||
} else if (sbuf[l] == '\033') { // ESC-Sequence
|
} else if (sbuf[l] == '\033') { // ESC-Sequence
|
||||||
// Wait until we have at least 3 characters including the ESC character in the serial buffer
|
// 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)
|
if (((sbuf_ptr + SBUF_SIZE - l) & SBUF_MASK) < 3)
|
||||||
@@ -190,7 +193,7 @@ void cmd_edit(void) __banked
|
|||||||
// Check whether return was pressed:
|
// Check whether return was pressed:
|
||||||
if (sbuf[l] == '\n' || sbuf[l] == '\r') {
|
if (sbuf[l] == '\n' || sbuf[l] == '\r') {
|
||||||
write_char('\n');
|
write_char('\n');
|
||||||
cmd_buffer[cmd_line_len] = '\0';
|
cmd_buffer[cmd_line_len] = NUL;
|
||||||
// write_char('>'); print_string_x(cmd_buffer); write_char('<');
|
// write_char('>'); print_string_x(cmd_buffer); write_char('<');
|
||||||
// If there is a command we print the prompt after execution
|
// If there is a command we print the prompt after execution
|
||||||
// otherwise immediately because there is nothing to execute
|
// otherwise immediately because there is nothing to execute
|
||||||
|
|||||||
@@ -6,13 +6,41 @@
|
|||||||
#include "rtl837x_common.h"
|
#include "rtl837x_common.h"
|
||||||
|
|
||||||
extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
|
||||||
extern __xdata uint8_t cmd_available;
|
extern __bit __at(0x03) cmd_available;
|
||||||
extern __xdata uint8_t err_status;
|
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
|
||||||
|
|
||||||
|
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_tokenize(void) __banked;
|
||||||
void cmd_parser(void) __banked;
|
void cmd_parser(void) __banked;
|
||||||
void execute_config(void) __banked;
|
void execute_config(void) __banked;
|
||||||
void execute_commands(__xdata uint8_t *p) __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 print_sw_version(void) __banked;
|
||||||
void clear_command_history(void) __banked;
|
void clear_command_history(void) __banked;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
;
|
;
|
||||||
.globl _crc_value
|
.globl _crc_value
|
||||||
.globl _crc16
|
.globl _crc16
|
||||||
|
.globl _crc16_bank1
|
||||||
|
.globl __sdcc_banked_ret
|
||||||
.equ BANK, 0x96
|
.equ BANK, 0x96
|
||||||
; .equ DPS, 0x86
|
; .equ DPS, 0x86
|
||||||
; Variable in XMEM holding current CRC16 value, being updated
|
; Variable in XMEM holding current CRC16 value, being updated
|
||||||
@@ -18,7 +20,7 @@ _crc_value::
|
|||||||
.area HOME (CODE)
|
.area HOME (CODE)
|
||||||
.area CSEG (CODE)
|
.area CSEG (CODE)
|
||||||
; .area BANK1 (CODE)
|
; .area BANK1 (CODE)
|
||||||
_crc16:
|
_crc16_bank1:
|
||||||
mov BANK, #1
|
mov BANK, #1
|
||||||
push dph
|
push dph
|
||||||
push dpl
|
push dpl
|
||||||
@@ -52,6 +54,10 @@ _crc16:
|
|||||||
|
|
||||||
.area BANK1 (CODE)
|
.area BANK1 (CODE)
|
||||||
|
|
||||||
|
_crc16:
|
||||||
|
lcall _crc16_bank1
|
||||||
|
ljmp __sdcc_banked_ret
|
||||||
|
|
||||||
crc16_table_l:
|
crc16_table_l:
|
||||||
.byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41
|
.byte #0x00, #0xc1, #0x81, #0x40, #0x01, #0xc0, #0x80, #0x41
|
||||||
.byte #0x01, #0xc0, #0x80, #0x41, #0x00, #0xc1, #0x81, #0x40
|
.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,98 @@
|
|||||||
|
#include "rtl837x_common.h"
|
||||||
|
#include "chacha.h"
|
||||||
|
|
||||||
|
void chacha_20(void);
|
||||||
|
void chacha_update(void);
|
||||||
|
void chacha_count(void);
|
||||||
|
|
||||||
|
// generate a block of ChaCha20 keystream as per RFC7539
|
||||||
|
|
||||||
|
|
||||||
|
__xdata struct chacha20_t __at(0xbf00) chacha20;
|
||||||
|
__xdata uint8_t plaintext[256];
|
||||||
|
__xdata uint8_t cyphertext[256];
|
||||||
|
|
||||||
|
void chacha20_print_block(void)
|
||||||
|
{
|
||||||
|
for (uint8_t i=0; i < 64; i++) {
|
||||||
|
print_byte(*(uint8_t * __xdata)(chacha20.wstate + i));
|
||||||
|
if (i%4 == 3)
|
||||||
|
write_char(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void chacha20_encrypt(void)
|
||||||
|
{
|
||||||
|
__xdata uint8_t *p = chacha20.plaintext;
|
||||||
|
|
||||||
|
while (chacha20.length) {
|
||||||
|
register uint8_t i;
|
||||||
|
chacha_count();
|
||||||
|
memcpy(chacha20.wstate, chacha20.wstate + 64, 64);
|
||||||
|
#ifdef DEBUG
|
||||||
|
chacha20_print_block(); write_char('\n');
|
||||||
|
#endif
|
||||||
|
chacha_20();
|
||||||
|
chacha_update();
|
||||||
|
#ifdef DEBUG
|
||||||
|
chacha20_print_block(); write_char('\n');
|
||||||
|
#endif
|
||||||
|
for (i = 0; i < ((chacha20.length > 64) ? 64 : chacha20.length); i++)
|
||||||
|
*chacha20.cyphertext++ = *p++ ^ chacha20.wstate[i];
|
||||||
|
chacha20.length -= chacha20.length > 64 ? 64 : chacha20.length;
|
||||||
|
#ifdef DEBUG
|
||||||
|
print_string("\n round done\n");
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Test the example of RFC 7539 Section 2.4.2
|
||||||
|
void chacha20_test(void)
|
||||||
|
{
|
||||||
|
__code uint8_t chacha_c[16] =
|
||||||
|
{ 0x61, 0x70, 0x78, 0x65, 0x33, 0x20, 0x64, 0x6e,
|
||||||
|
0x79, 0x62, 0x2d, 0x32, 0x6b, 0x20, 0x65, 0x74 };
|
||||||
|
|
||||||
|
__code uint8_t key[32] =
|
||||||
|
{ 0x03, 0x02, 0x01, 0x00, 0x07, 0x06, 0x05, 0x04,
|
||||||
|
0x0b, 0x0a, 0x09, 0x08, 0x0f, 0x0e, 0x0d, 0x0c,
|
||||||
|
0x13, 0x12, 0x11, 0x10, 0x17, 0x16, 0x15, 0x14,
|
||||||
|
0x1b, 0x1a, 0x19, 0x18, 0x1f, 0x1e, 0x1d, 0x1c };
|
||||||
|
|
||||||
|
__code uint8_t nonce[12] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
|
__code uint8_t sunscreen[] = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for " \
|
||||||
|
"the future, sunscreen would be it.";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ciphertext Sunscreen (from RFC 7539 Section 2.4.2):
|
||||||
|
000 6e 2e 35 9a 25 68 f9 80 41 ba 07 28 dd 0d 69 81 n.5.%h..A..(..i.
|
||||||
|
016 e9 7e 7a ec 1d 43 60 c2 0a 27 af cc fd 9f ae 0b .~z..C`..'......
|
||||||
|
032 f9 1b 65 c5 52 47 33 ab 8f 59 3d ab cd 62 b3 57 ..e.RG3..Y=..b.W
|
||||||
|
048 16 39 d6 24 e6 51 52 ab 8f 53 0c 35 9f 08 61 d8 .9.$.QR..S.5..a.
|
||||||
|
064 07 ca 0d bf 50 0d 6a 61 56 a3 8e 08 8a 22 b6 5e ....P.jaV....".^
|
||||||
|
080 52 bc 51 4d 16 cc f8 06 81 8c e9 1a b7 79 37 36 R.QM.........y76
|
||||||
|
096 5a f9 0b bf 74 a3 5b e6 b4 0b 8e ed f2 78 5e 42 Z...t.[......x^B
|
||||||
|
112 87 4d
|
||||||
|
*/
|
||||||
|
strcpy(plaintext, sunscreen);
|
||||||
|
memcpyc(chacha20.constant, chacha_c, 16);
|
||||||
|
memcpyc(chacha20.key, key, 32);
|
||||||
|
chacha20.cnt = 0;
|
||||||
|
memcpyc(chacha20.nonce, nonce, 12);
|
||||||
|
chacha20.plaintext = plaintext;
|
||||||
|
chacha20.length = strlen_x(plaintext);
|
||||||
|
chacha20.cyphertext = cyphertext;
|
||||||
|
|
||||||
|
print_string("Encrypting...\n");
|
||||||
|
chacha20_encrypt();
|
||||||
|
print_string("Cypertext:\n");
|
||||||
|
uint16_t len = strlen_x(plaintext);
|
||||||
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
|
print_byte(cyphertext[i]); write_char(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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_REBIND_LEN 4
|
||||||
#define DHCP_CLIENT_ID 61
|
#define DHCP_CLIENT_ID 61
|
||||||
#define DHCP_CLIENT_ID_LEN 7
|
#define DHCP_CLIENT_ID_LEN 7
|
||||||
|
#define DHCP_HOSTNAME 12
|
||||||
#define DHCP_REQUEST_IP 50
|
#define DHCP_REQUEST_IP 50
|
||||||
#define DHCP_REQUEST_IP_LEN 4
|
#define DHCP_REQUEST_IP_LEN 4
|
||||||
#define DHCP_PARAMS 55
|
#define DHCP_PARAMS 55
|
||||||
@@ -49,7 +50,7 @@ __xdata uip_ipaddr_t server;
|
|||||||
#define DHCP_PARAM_DNS 6
|
#define DHCP_PARAM_DNS 6
|
||||||
#define DHCP_END 255
|
#define DHCP_END 255
|
||||||
|
|
||||||
#pragma codeseg BANK2
|
#pragma codeseg BANK3
|
||||||
#pragma constseg BANK2
|
#pragma constseg BANK2
|
||||||
|
|
||||||
struct dhcp_pkt {
|
struct dhcp_pkt {
|
||||||
@@ -93,7 +94,7 @@ void dhcp_prepare_request(void)
|
|||||||
DHCP_P->hw_len = 6;
|
DHCP_P->hw_len = 6;
|
||||||
DHCP_P->hops = 0;
|
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->delay = HTONS(0);
|
||||||
DHCP_P->flags = 0;
|
DHCP_P->flags = 0;
|
||||||
// Clear fields client_ip to bootp_file
|
// Clear fields client_ip to bootp_file
|
||||||
@@ -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)
|
void dhcp_addopt_request_ip(void)
|
||||||
{
|
{
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_REQUEST_IP;
|
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[1];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[2];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[2];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[3];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.current_ip[3];
|
||||||
memcpy(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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[1];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[2];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[2];
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[3];
|
DHCP_OPT[dhcp_state.opt_ptr++] = dhcp_state.server[3];
|
||||||
memcpy(&DHCP_OPT[dhcp_state.opt_ptr], uip_ethaddr.addr, 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dhcp_send_discover(void)
|
void dhcp_send_discover(void)
|
||||||
{
|
{
|
||||||
print_string("dhcp_send_discover called\n");
|
|
||||||
dhcp_prepare_request();
|
dhcp_prepare_request();
|
||||||
|
|
||||||
dhcp_state.opt_ptr = 0;
|
dhcp_state.opt_ptr = 0;
|
||||||
@@ -152,6 +164,7 @@ void dhcp_send_discover(void)
|
|||||||
|
|
||||||
dhcp_addopt_client_id();
|
dhcp_addopt_client_id();
|
||||||
dhcp_addopt_request_ip();
|
dhcp_addopt_request_ip();
|
||||||
|
dhcp_addopt_hostname();
|
||||||
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_PARAMS;
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_PARAMS;
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = 3;
|
DHCP_OPT[dhcp_state.opt_ptr++] = 3;
|
||||||
@@ -177,7 +190,6 @@ void dhcp_send_discover(void)
|
|||||||
|
|
||||||
void dhcp_send_request(void)
|
void dhcp_send_request(void)
|
||||||
{
|
{
|
||||||
print_string("dhcp_send_request called\n");
|
|
||||||
dhcp_prepare_request();
|
dhcp_prepare_request();
|
||||||
|
|
||||||
dhcp_state.opt_ptr = 0;
|
dhcp_state.opt_ptr = 0;
|
||||||
@@ -188,6 +200,7 @@ void dhcp_send_request(void)
|
|||||||
dhcp_addopt_client_id();
|
dhcp_addopt_client_id();
|
||||||
dhcp_addopt_request_ip();
|
dhcp_addopt_request_ip();
|
||||||
dhcp_addopt_server_id();
|
dhcp_addopt_server_id();
|
||||||
|
dhcp_addopt_hostname();
|
||||||
|
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_PARAMS;
|
DHCP_OPT[dhcp_state.opt_ptr++] = DHCP_PARAMS;
|
||||||
DHCP_OPT[dhcp_state.opt_ptr++] = 3;
|
DHCP_OPT[dhcp_state.opt_ptr++] = 3;
|
||||||
@@ -215,19 +228,21 @@ void ip_opt(__xdata uint8_t * ip)
|
|||||||
{
|
{
|
||||||
dhcp_state.opt_ptr++;
|
dhcp_state.opt_ptr++;
|
||||||
uint8_t len = DHCP_OPT[dhcp_state.opt_ptr++];
|
uint8_t len = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
if (len >= 4)
|
||||||
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
memcpy(ip, &DHCP_OPT[dhcp_state.opt_ptr], 4);
|
||||||
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
|
||||||
*ip++ = DHCP_OPT[dhcp_state.opt_ptr++];
|
|
||||||
// There may be more than one IP option, such as 2 DNS servers advertised
|
// 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++;
|
||||||
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 = DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
long_value <<= 8;
|
long_value <<= 8;
|
||||||
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
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 |= DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
long_value <<= 8;
|
long_value <<= 8;
|
||||||
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
long_value |= DHCP_OPT[dhcp_state.opt_ptr++];
|
||||||
|
dhcp_state.opt_ptr += len - 4;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -258,15 +275,15 @@ void parse_opts(void)
|
|||||||
ip_opt(&dhcp_state.broadcast[0]);
|
ip_opt(&dhcp_state.broadcast[0]);
|
||||||
break;
|
break;
|
||||||
case DHCP_LEASE:
|
case DHCP_LEASE:
|
||||||
long_opt();
|
if (long_opt())
|
||||||
dhcp_state.lease = long_value;
|
dhcp_state.lease = long_value;
|
||||||
break;
|
break;
|
||||||
case DHCP_REBIND:
|
case DHCP_REBIND:
|
||||||
long_opt();
|
if (long_opt())
|
||||||
dhcp_state.rebind = long_value;
|
dhcp_state.rebind = long_value;
|
||||||
break;
|
break;
|
||||||
case DHCP_RENEWAL:
|
case DHCP_RENEWAL:
|
||||||
long_opt();
|
if (long_opt())
|
||||||
dhcp_state.renewal = long_value;
|
dhcp_state.renewal = long_value;
|
||||||
break;
|
break;
|
||||||
case DHCP_END:
|
case DHCP_END:
|
||||||
@@ -283,7 +300,7 @@ void parse_opts(void)
|
|||||||
|
|
||||||
void parse_dhcp(void)
|
void parse_dhcp(void)
|
||||||
{
|
{
|
||||||
if (!DHCP_P->tid == HTONS(dhcp_state.transaction_id))
|
if (DHCP_P->tid != dhcp_state.transaction_id)
|
||||||
return;
|
return;
|
||||||
if (DHCP_P->cookie[0] != 0x63 || DHCP_P->cookie[1] != 0x82 || DHCP_P->cookie[2] != 0x53 || DHCP_P->cookie[3] != 0x63)
|
if (DHCP_P->cookie[0] != 0x63 || DHCP_P->cookie[1] != 0x82 || DHCP_P->cookie[2] != 0x53 || DHCP_P->cookie[3] != 0x63)
|
||||||
return;
|
return;
|
||||||
@@ -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_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_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]);
|
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.state = DHCP_LEASING;
|
||||||
dhcp_state.ticks = SYS_TICK_HZ;
|
dhcp_state.ticks = SYS_TICK_HZ;
|
||||||
dhcp_state.dhcp_timer = dhcp_state.renewal > 0xffff ? 0xffff : dhcp_state.renewal;
|
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
|
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);
|
uip_ipaddr(server, 255,255,255,255);
|
||||||
dhcp_state.conn = uip_udp_new(&server, HTONS(DHCPC_SERVER_PORT));
|
dhcp_state.conn = uip_udp_new(&server, HTONS(DHCPC_SERVER_PORT));
|
||||||
dhcp_state.current_ip[0] = dhcp_state.current_ip[1] = dhcp_state.current_ip[2] = dhcp_state.current_ip[3] = 0;
|
dhcp_state.current_ip[0] = dhcp_state.current_ip[1] = dhcp_state.current_ip[2] = dhcp_state.current_ip[3] = 0;
|
||||||
@@ -334,15 +369,18 @@ void dhcp_start(void) __banked
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
get_random_32();
|
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;
|
dhcp_state.state = DHCP_START;
|
||||||
print_string("dhcp_start done\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dhcp_stop(void) __banked
|
void dhcp_stop(void) __banked
|
||||||
{
|
{
|
||||||
print_string("dhcp_stop called\n");
|
|
||||||
uip_udp_remove(dhcp_state.conn);
|
uip_udp_remove(dhcp_state.conn);
|
||||||
dhcp_state.state = DHCP_OFF;
|
dhcp_state.state = DHCP_OFF;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
checksum and the TCP checksum are automatically calculated (offloaded) by the
|
||||||
ASIC before transmitting on the wire.
|
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.
|
||||||
@@ -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.
|
Using SPI clamp in-board is the only method for initial installation.
|
||||||
|
|
||||||
### Label specifications
|
### Label specifications
|
||||||
|
|
||||||
- **Name**: 4X 2.5G RJ45 Port + 2 X 10G SFP+ Port
|
- **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**:
|
- **Ports**:
|
||||||
- 4 × RJ45: 10/100/1000/2500 Mbps
|
- 4 × RJ45: 10/100/1000/2500 Mbps
|
||||||
- 2 × SFP+: 1000 / 2500 / 10000 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
|
### What works
|
||||||
|
|
||||||
- All four 2.5GBASE-T RJ45 ports at 10/100/1000/2500 Mbps
|
- 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
|
- LEDs
|
||||||
- untested due to missing Hardware: SFP+ ports equipped with 1G or 2.5G SFPs.
|
- untested due to missing Hardware: SFP+ ports equipped with 1G or 2.5G SFPs.
|
||||||
|
|
||||||
### Hardware overview
|
### Hardware overview: 2M-PCB43-V2.1
|
||||||
|
|
||||||
Front side:
|
Front side:
|
||||||
|
|
||||||
@@ -44,6 +63,24 @@ Bottom
|
|||||||
|
|
||||||
<img src="photos/2M-PCB43-V2.1-unmanaged/2M-PCB43-V2.1-bottom.jpg" width="600" />
|
<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
|
## Reset Button
|
||||||
|
|
||||||
There's an unpopulated Reset button on the front left side of the PCB.
|
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
|
## Power supply
|
||||||
|
|
||||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
||||||
|
|
||||||
@@ -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).
|
||||||
@@ -19,6 +19,9 @@ of the device just above the big label, might be covered by a QC sticker.
|
|||||||
|
|
||||||
<img src="photos/PCB-K0402WS-V3.0/Ztyuav_Z-QWYT0402_label.jpg" width="300" />
|
<img src="photos/PCB-K0402WS-V3.0/Ztyuav_Z-QWYT0402_label.jpg" width="300" />
|
||||||
|
|
||||||
|
* Siscolink SL-G0402F
|
||||||
|
|
||||||
|
<img src="photos/PCB-K0402WS-V3.0/Siscolink SL-G0402F.jpg" width="300"/>
|
||||||
### Programming
|
### Programming
|
||||||
|
|
||||||
Using SPI clamp in-board is the only method for initial installation.
|
Using SPI clamp in-board is the only method for initial installation.
|
||||||
|
|||||||
@@ -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
|
# 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`.
|
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.
|
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|
|
|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 |
|
| LIANGUO |SWTG024AS |No| SWTG024AS-v2.0-17452 | CM-23-11-2336 023-17453| 512 KiB | 8272 |
|
||||||
| Haraco |ZX-SWTG124AS | Yes | SWTG024AS-v2.0 | ??? | ??? | 8272 |
|
| Horaco |ZX-SWTG124AS | Yes | SWTG024AS-v2.0 | ??? | ??? | 8272 |
|
||||||
| Xikestore |SKS3200M-4GPY2XF | Yes | SWTG024AS-v1.0 | CM-23-08-2043 023-16721 | ??? | 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 |
|
| Sodola | SL-SWTG124AS-D | Yes | SWTG024AS-v2.0-17452 | ??? | 2048 KiB | 8272 |
|
||||||
|
|
||||||
## PCB
|
## PCB
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
### ZX-SWTGW215AS
|
# ZX-SWTGW215AS
|
||||||
|
|
||||||
## Brands
|
## Brands
|
||||||
|
|
||||||
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
|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
|
## 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.
|
Physical hardware verification: 5x RJ45 ports + 1x SFP port.
|
||||||
Port 5 RJ45 is interfaced through a RTL8221B IC.
|
Port 5 RJ45 is interfaced through a RTL8221B IC.
|
||||||
|
|
||||||
## 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 |
|
| RJ45 | 3, 4, 5, 6, 7 | 1-5 |
|
||||||
| SFP | 8 | 6 |
|
| SFP | 8 | 6 |
|
||||||
|
|
||||||
## J4
|
### J4
|
||||||
|
|
||||||
* Location: SFP connector `J4`.
|
* Location: SFP connector `J4`.
|
||||||
* Connected to: 10GMAC number 8, SerDes 1.
|
* 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 |
|
|5| MODDEF1 – SCL | GPIO40 | I2C SCL |
|
||||||
|6| MODDEF0 – PRESENT | GPIO30 | Detect |
|
|6| MODDEF0 – PRESENT | GPIO30 | Detect |
|
||||||
|8| LOS | GPIO37 | RX Loss of Signal |
|
|8| LOS | GPIO37 | RX Loss of Signal |
|
||||||
### Notes
|
|
||||||
|
#### Notes
|
||||||
* Not all signals were mapped mechanically, hence they've been left out of documentation.
|
* 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).
|
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 |
|
|4| VCC |
|
||||||
|5| 33R -> U10-P2 | SPI-DO/D1 |
|
|5| 33R -> U10-P2 | SPI-DO/D1 |
|
||||||
|6| U10-P1 | SPI-CS |
|
|6| U10-P1 | SPI-CS |
|
||||||
### Notes
|
|
||||||
|
#### Notes
|
||||||
* 1 pin is square shaped.
|
* 1 pin is square shaped.
|
||||||
|
|
||||||
|
|
||||||
## T5, Serial Console
|
### T5, Serial Console
|
||||||
|
|
||||||
|`T5` pin|GPIO|Signal|
|
|`T5` pin|GPIO|Signal|
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
@@ -77,10 +91,11 @@ For detailed Slave Interface functionality and protocol information, see [T3 doc
|
|||||||
| 2 | GND | |
|
| 2 | GND | |
|
||||||
| 3 | GPIO32 | U0RXD (Input) |
|
| 3 | GPIO32 | U0RXD (Input) |
|
||||||
| 4 | 3V3 | |
|
| 4 | 3V3 | |
|
||||||
### Notes
|
|
||||||
|
#### Notes
|
||||||
* 1 pin is square shaped.
|
* 1 pin is square shaped.
|
||||||
|
|
||||||
## T8
|
### T8
|
||||||
|
|
||||||
|`T8` pin|GPIO|Signal|
|
|`T8` pin|GPIO|Signal|
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
@@ -91,18 +106,19 @@ For detailed Slave Interface functionality and protocol information, see [T3 doc
|
|||||||
| 5 | GPIO47 | |
|
| 5 | GPIO47 | |
|
||||||
| 6 | GPIO49 | |
|
| 6 | GPIO49 | |
|
||||||
|
|
||||||
### Notes
|
#### Notes
|
||||||
* 1 pin is square shaped.
|
* 1 pin is square shaped.
|
||||||
* Mapping unverified but assumed the same as [LIANGUO SWTG024AS](SWTG024AS.md#t8).
|
* Mapping unverified but assumed the same as [LIANGUO SWTG024AS](SWTG024AS.md#t8).
|
||||||
|
|
||||||
# Reset Circuit
|
## Reset Circuit
|
||||||
| Function | GPIO |
|
| Function | GPIO |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Reset button | GPIO54 |
|
| Reset button | GPIO54 |
|
||||||
|
|
||||||
### Notes
|
### Notes
|
||||||
* Circuit is active-low
|
* 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.
|
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 | | |
|
| 40000000 | GPIO30 | J4-6 | SFP DETECT | | GPIO62 | | |
|
||||||
| 80000000 | GPIO31 | T5-1 | U0TXD | | GPIO63 | | |
|
| 80000000 | GPIO31 | T5-1 | U0TXD | | GPIO63 | | |
|
||||||
|
|
||||||
# LEDs
|
## LEDs
|
||||||
|
|
||||||
| NAME | GPIO | Port(s) | Function | Notes |
|
| 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.
|
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 |
|
| Mokerlink | ZX-SWTGW218AS | Yes| SWTG118AS-V2.0-16029 | 2MB (FM25Q16A)| 8273N + 8224N |
|
||||||
| Sodola | | | | | |
|
| Sodola | | | | | |
|
||||||
| Horaco | | | | | |
|
| Horaco | | | | | |
|
||||||
|
| XikeStor | SKS3200-8E1X | Yes | SWTG118AS-V2.1-17462 | 2MB (25Q16JVSIQ) | |
|
||||||
|
|
||||||
|
|
||||||
## Photos
|
## 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: 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: 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 |
|
After Width: | Height: | Size: 657 KiB |
|
After Width: | Height: | Size: 2.2 MiB |
|
After Width: | Height: | Size: 2.5 MiB |
|
After Width: | Height: | Size: 2.7 MiB |
@@ -0,0 +1,79 @@
|
|||||||
|
# The health command
|
||||||
|
|
||||||
|
`health` prints a one-page snapshot of the firmware's vital signs on the
|
||||||
|
serial console. It exists for the situations where the switch misbehaves and
|
||||||
|
every probe from the network measures the network instead of the device: the
|
||||||
|
dump is taken from inside, costs one command, and works while HTTP does not.
|
||||||
|
|
||||||
|
```
|
||||||
|
> health
|
||||||
|
up 0000001f ticks 0x00001f4c loops 0x000016da rx 0x024e
|
||||||
|
link max 01 slow 0x0000
|
||||||
|
sfp max 74 slow 0x0001
|
||||||
|
rx max 00 slow 0x0000
|
||||||
|
tx max 00 slow 0x0000
|
||||||
|
stp max 04 slow 0x0001
|
||||||
|
cmd max 02 slow 0x0001
|
||||||
|
sp 80 untouched 62
|
||||||
|
tcp st 00 tmr 00 rtx 00 rto 00 len 0x0000 mss 0x05b4
|
||||||
|
lport 0x0000 rport 0x0000 rip 0x0000 0x0000
|
||||||
|
httpd left 0x0000 entry 00 stp 01 mvlan 0x0002
|
||||||
|
```
|
||||||
|
|
||||||
|
The instrumentation is not part of a default build. It costs about 1.1 kB
|
||||||
|
of bank 2, a few bytes of xdata and seven banked calls per main-loop pass,
|
||||||
|
which is nothing a user needs unless they are chasing a problem, so it is
|
||||||
|
switched on at build time:
|
||||||
|
|
||||||
|
```
|
||||||
|
make MACHINE=SWTGW218AS HEALTH=1
|
||||||
|
```
|
||||||
|
|
||||||
|
Without it the hooks compile to nothing and `health` is not a command.
|
||||||
|
|
||||||
|
All figures are raw hex. The counters are cumulative: take two dumps a known
|
||||||
|
time apart and the differences give the rates.
|
||||||
|
|
||||||
|
## The first line
|
||||||
|
|
||||||
|
`up` is the seconds counter, `ticks` the system tick (200 per second),
|
||||||
|
`loops` the number of main-loop passes and `rx` the frames handle_rx has
|
||||||
|
taken off the NIC. A healthy loop completes one pass per tick, so the
|
||||||
|
difference in `loops` tracks the difference in `ticks`; a loop that falls
|
||||||
|
behind is being held up by one of the phases below. The `rx` rate separates
|
||||||
|
a flooded CPU port from a stalled loop, which look identical from outside.
|
||||||
|
|
||||||
|
## Phases
|
||||||
|
|
||||||
|
Each line is one section of the main loop: the link poll, SFP handling,
|
||||||
|
frame reception, TCP transmission, the STP timers and the command dispatch.
|
||||||
|
`max` is the worst time that section has taken, in ticks of 5 ms; `slow`
|
||||||
|
counts the passes that took two ticks or more. A misbehaving subsystem
|
||||||
|
names itself here, which is the difference between knowing that the loop is
|
||||||
|
slow and knowing why.
|
||||||
|
|
||||||
|
A dump of its own output takes the console some milliseconds, so running
|
||||||
|
`health` repeatedly increments the `cmd` counters by itself. That is the
|
||||||
|
instrument observing itself, not a fault.
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
|
||||||
|
At boot the free stack area is painted with a pattern. `sp` is the live
|
||||||
|
stack pointer; `untouched` counts the painted bytes still intact at the top,
|
||||||
|
which is the closest thing to a high-water mark this hardware offers. A
|
||||||
|
shrinking `untouched` across dumps means something is reaching deeper than
|
||||||
|
anything before it.
|
||||||
|
|
||||||
|
## The TCP slot
|
||||||
|
|
||||||
|
The connection table is printed whole, one slot per pair of lines: TCP
|
||||||
|
state (3 is ESTABLISHED, 0 closed), retransmission timer and counter, bytes
|
||||||
|
in flight, negotiated MSS, then the ports and the peer address. With a
|
||||||
|
single slot serving the entire web interface, one glance answers the
|
||||||
|
question every management outage starts with: who is holding it. A slot
|
||||||
|
showing state 3 with nothing in flight and a peer that no longer answers is
|
||||||
|
a connection whose owner went away.
|
||||||
|
|
||||||
|
`httpd left` and `entry` describe the file transfer the web server believes
|
||||||
|
it is in the middle of, and the trailing flags show whether STP is running
|
||||||
|
and which VLAN carries management.
|
||||||
@@ -69,7 +69,7 @@ The code currently provides the following functions:
|
|||||||
void igmp_setup(void) __banked;
|
void igmp_setup(void) __banked;
|
||||||
void igmp_enable(void) __banked;
|
void igmp_enable(void) __banked;
|
||||||
void igmp_router_port_set(uint16_t pmask) __banked;
|
void igmp_router_port_set(uint16_t pmask) __banked;
|
||||||
void igmp_packet_handler(void) __banked;
|
uint8_t igmp_packet_handler(void) __banked;
|
||||||
void igmp_show(void) __banked;
|
void igmp_show(void) __banked;
|
||||||
```c
|
```c
|
||||||
`igmp_setup()` is called at boot-time and configures flooding of all IP-MC packets by
|
`igmp_setup()` is called at boot-time and configures flooding of all IP-MC packets by
|
||||||
@@ -80,7 +80,11 @@ of IP-MC packets to be limited to only subscribed ports.
|
|||||||
|
|
||||||
`igmp_router_port_set()`configures forwarding ports for IGMP messages.
|
`igmp_router_port_set()`configures forwarding ports for IGMP messages.
|
||||||
|
|
||||||
`igmp_packet_handler()` implements handling of trapped IGMP packets by the CPU.
|
`igmp_packet_handler()` implements handling of trapped IGMP packets by the CPU. It is called
|
||||||
|
for frames to 01:00:5e:xx:xx:xx and returns 0 when the frame is not a trapped IGMP packet,
|
||||||
|
so that it is passed on to the IP stack. IGMPv1/v2 reports (0x12, 0x16) join the group given
|
||||||
|
in the IGMP header, IGMPv2 leaves (0x17) leave it, IGMPv3 reports use the first group record
|
||||||
|
(type 4 joins, type 3 leaves). Trapped IGMP frames arrive without a VLAN tag.
|
||||||
|
|
||||||
`igmp_show()` prints out the IGMP configuration on the CLI.
|
`igmp_show()` prints out the IGMP configuration on the CLI.
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 120 KiB |
@@ -65,3 +65,36 @@ ASIC and flushing the table in order to quickly forget the learned entries.
|
|||||||
3c:18:a0:7e:11:00 0x0001 learned 5
|
3c:18:a0:7e:11:00 0x0001 learned 5
|
||||||
1c:2a:a3:23:00:02 0x0001 learned 7
|
1c:2a:a3:23:00:02 0x0001 learned 7
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Static multicast entries
|
||||||
|
|
||||||
|
Slow-protocol frames such as LACPDUs and STP BPDUs have to reach the CPU
|
||||||
|
without being flooded to the other ports. No bridge relays these frames:
|
||||||
|
their addresses are in the set that 802.1D-2004 clause 7.12.6 forbids a
|
||||||
|
bridge to forward, and what travels the network is the information, with
|
||||||
|
every bridge regenerating BPDUs of its own on its designated ports. The reserved-multicast *trap* action
|
||||||
|
cannot do that on this hardware, because its destination is an external CPU
|
||||||
|
attached to a physical port, which these boards do not populate. The protocol
|
||||||
|
modules therefore leave the reserved-multicast action at *forward* and constrain
|
||||||
|
the egress with a static L2 multicast entry instead: the lookup hits the entry's
|
||||||
|
own port mask rather than the VLAN flood mask. Verified on a SWTGW218AS both
|
||||||
|
ways, with the CPU bit cleared, where delivery stops, and with the CPU bit alone,
|
||||||
|
where nothing egresses.
|
||||||
|
|
||||||
|
`port_l2mc_set()` writes one such entry. The SMI layout is the L2 multicast
|
||||||
|
variant of the table entry:
|
||||||
|
|
||||||
|
```
|
||||||
|
DATA_IN_A = MAC bytes 5..2 -> c2 00 00 <mac_last>
|
||||||
|
DATA_IN_B = MAC[1..0] | vid<<16 | IVL<<29 | pmask[1:0]<<30
|
||||||
|
DATA_IN_C = pmask[9:2]
|
||||||
|
```
|
||||||
|
|
||||||
|
Lookups are IVL, so an entry made for VID 0 is never matched and a caller adds
|
||||||
|
one entry per PVID in use. The write goes through the table access register
|
||||||
|
with the table selector set to the L2 lookup table, `TBL_L2_UNICAST` in the
|
||||||
|
code, a name that despite appearances covers the multicast entries as well.
|
||||||
|
The hardware hashes MAC and VID to pick the bucket slot by itself.
|
||||||
|
Writing the same MAC and VID again replaces the entry rather than adding a
|
||||||
|
second one, so a caller can retarget the mask at will, for instance back to all
|
||||||
|
ports to restore flooding.
|
||||||
@@ -48,9 +48,11 @@ void port_lag_hash_set(__xdata uint8_t lag, __xdata uint8_t hash_bits) __banked;
|
|||||||
## LAG configuration on the Serial Console
|
## LAG configuration on the Serial Console
|
||||||
For testing the following commands are provided on the serial console:
|
For testing the following commands are provided on the serial console:
|
||||||
```
|
```
|
||||||
> lag <LAG-ID> [p1] [p2]...
|
> lag <LAG-ID> <p1> [p2]...
|
||||||
Create or set a LAG. Trunk-ID is 1 or 2. Ports are physical ports
|
Create or set a LAG. LAG-ID is 1 to 4. Ports are physical ports.
|
||||||
If only the LAG-ID is given but no members, the LAG is deleted
|
|
||||||
|
> lag <LAG-ID> d
|
||||||
|
Delete the LAG.
|
||||||
|
|
||||||
> lag show
|
> lag show
|
||||||
Shows information on all 4 lags
|
Shows information on all 4 lags
|
||||||
@@ -92,7 +94,7 @@ The following shows the network configuration
|
|||||||
On _both_ switches create a LAG with ports 1 and 2 inside and the default hash algorithm which takes
|
On _both_ switches create a LAG with ports 1 and 2 inside and the default hash algorithm which takes
|
||||||
source and destination ports into account, e.g. just use the default:
|
source and destination ports into account, e.g. just use the default:
|
||||||
```
|
```
|
||||||
> lag 0 1 2
|
> lag 1 1 2
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -37,12 +37,13 @@ This list is incomplete.
|
|||||||
| Brand | Partnumber |
|
| Brand | Partnumber |
|
||||||
| ---------- |----------- |
|
| ---------- |----------- |
|
||||||
| GigaDevice | GD25Q32E |
|
| GigaDevice | GD25Q32E |
|
||||||
|
| Fundan | FM25Q16A |
|
||||||
|
| Puya | P25D40SH |
|
||||||
| Winbond | W25Q16JV |
|
| Winbond | W25Q16JV |
|
||||||
| Winbond | W25Q32FV |
|
| Winbond | W25Q32FV |
|
||||||
| Winbond | W25Q32JV |
|
| Winbond | W25Q32JV |
|
||||||
| Winbond | W25Q16JL |
|
| Winbond | W25Q16JL |
|
||||||
| Winbond | W25Q16DV |
|
| Winbond | W25Q16DV |
|
||||||
| Winbond | W25Q80DV |
|
| Winbond | W25Q80DV |
|
||||||
| Fundan | FM25Q16A |
|
|
||||||
|
|
||||||
*NOTE*: Part numbers are incomplete. Part numbers may contain additional information such as package, temperature specifications, and even the number of devices on a reel. So always check the datasheet so that you have the right orderable partnumber.
|
*NOTE*: Part numbers are incomplete. Part numbers may contain additional information such as package, temperature specifications, and even the number of devices on a reel. So always check the datasheet so that you have the right orderable partnumber.
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# Storm Control
|
||||||
|
Storm control limits the rate at which a port admits broadcast, multicast,
|
||||||
|
unknown unicast and unknown multicast frames. Frames of a type above its limit
|
||||||
|
are dropped at ingress, so a loop or a misbehaving host cannot flood the rest
|
||||||
|
of the network through that port. Known unicast traffic is not affected.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
```
|
||||||
|
storm <port> bcast|mcast|ucast|umcast <rate> pps
|
||||||
|
storm <port> bcast|mcast|ucast|umcast <rate> kbps
|
||||||
|
storm <port> bcast|mcast|ucast|umcast off
|
||||||
|
storm
|
||||||
|
```
|
||||||
|
`ucast` is unicast to a MAC address the switch has not learned yet, and
|
||||||
|
`umcast` is multicast without an entry in the address table. Multicast groups
|
||||||
|
get their entries from IGMP snooping, so without `igmp on` all multicast is
|
||||||
|
unknown and only the `umcast` limit applies to it; `mcast` covers the groups
|
||||||
|
IGMP has learned. A limit in
|
||||||
|
packets per second goes from 1 to 1048575, a limit in kbit/s from 1 to
|
||||||
|
10000000. `storm` without arguments prints the limits of every port. The
|
||||||
|
limits are kept in the configuration like any other setting, and the Bandwidth
|
||||||
|
page of the web interface has a Storm control card to set them.
|
||||||
|
|
||||||
|
## Registers
|
||||||
|
Each port and type has an enable bit and a meter index, and each limit uses
|
||||||
|
one of the 64 shared meters of the switch. RTLPlayground gives every port and
|
||||||
|
type its own meter, index `24 + port * 4 + type`, so one port's storm does not
|
||||||
|
eat into the limit of another. Storm control uses meters 24 to 63 and leaves
|
||||||
|
0 to 23 to the ACL. The limit of a meter is in `RTL837X_METER_RATE + 4 *
|
||||||
|
meter`, and bit `meter % 32` of `RTL837X_METER_MODE + 4 * (meter / 32)`
|
||||||
|
selects pps instead of kbit/s.
|
||||||
|
```
|
||||||
|
#define RTL837X_STORM_CTRL 0x54e4 /* + 4 * type, bit = port */
|
||||||
|
#define RTL837X_STORM_MIDX 0x54f4 /* + 8 * type + 4 * (port / 5), 6 bits per port */
|
||||||
|
#define RTL837X_METER_RATE 0x5cf0 /* + 4 * meter, 24 bits, kbit/s or pps */
|
||||||
|
#define RTL837X_METER_MODE 0x5ef0 /* + 4 * (meter / 32), bit set = pps */
|
||||||
|
```
|
||||||
|
In kbit/s mode one step of the rate is 1 kbit/s. Measured with 100 and 1000 byte
|
||||||
|
frames, the meter counts a frame with its FCS, but without preamble and
|
||||||
|
interframe gap. Every meter has a bit that adds them, in `0x5f08 + 4 * (meter
|
||||||
|
/ 32)`, which storm control leaves cleared. `IGBW_INC_IFG` and `EGBW_INC_IFG`
|
||||||
|
are the matching bits of the bandwidth control.
|
||||||
|
|
||||||
|
An ingress bandwidth limit on the same port works on the same arriving frames
|
||||||
|
as the storm limit rather than after it, and the two together pass far less
|
||||||
|
than either one: a 1 Mbit/s `umcast` limit with a 10 Mbit/s ingress limit let
|
||||||
|
0.12 to 0.16 Mbit/s of a 1.4 Gbit/s stream through, where each alone passed
|
||||||
|
1.17 and 10.2 Mbit/s.
|
||||||
|
|
||||||
|
The type is 0 for broadcast, 1 for multicast, 2 for unknown unicast and 3 for
|
||||||
|
unknown multicast. The burst size of a meter (0x5df0 + 4 * meter) counts packets
|
||||||
|
in pps mode; its default of 0x2000 lets 8192 frames through before a pps limit
|
||||||
|
bites, so a pps limit sets the burst to one second of traffic. A kbit/s limit
|
||||||
|
puts back the default.
|
||||||