52 Commits
Author SHA1 Message Date
feelfree69 f778b9159b Merge pull request #462 from DrDoof/fix/gui-save-merge
web: keep stored config lines and per-port ingress when saving
2026-09-23 08:53:05 +02:00
feelfree69 b6d6d2391d Merge pull request #473 from DrDoof/fix/config-replay-skip
config, httpd: skip an over-long line and refuse to store one
2026-09-23 08:52:19 +02:00
feelfree69 fa93340c24 Merge pull request #443 from DrDoof/build/xram-size
Makefile: let the linker check external RAM against 0xBFFF
2026-09-22 20:50:59 +02:00
feelfree69 e9523a2f67 Merge pull request #460 from DrDoof/fix/multipart-request-path
httpd: keep a continued upload away from the cmd and login handlers
2026-09-22 20:46:52 +02:00
feelfree69 088be074f5 Merge pull request #411 from DrDoof/fix/httpd-upload-bound
httpd: stop a firmware upload at the end of the image area
2026-09-22 20:45:55 +02:00
DrDoof 09ce4b391b httpd: stop a firmware upload at the end of the image area
edc469f made max_upload count, which bounds how many bytes a request may
carry. Nothing bounds where those bytes land. The two are not the same
check: the first watches the request, the second watches the flash address.

uptr walks forward one page at a time from FIRMWARE_UPLOAD_START and has no
ceiling. A body whose closing boundary never arrives keeps writing page after
page past the staging region, and on a flash exactly twice FIRMWARE_UPLOAD_START
the address wraps onto the running image at zero, so a bad upload takes the
working firmware with it. That commit's own message notes the related hazard:
flash_write_bytes() carries the address in three bytes and drops what does not
fit.

Bound it where uptr actually moves: refuse the next page once it would leave
the area check_and_flash_update_image() reads back, and answer 400. A partial
image left behind is harmless - boot rejects it on CRC and erases it.

This rebase drops the part of the original patch that removed max_upload;
the length limit and the address limit now sit side by side.
2026-09-22 20:04:44 +02:00
feelfree69 7e6577a811 Merge pull request #415 from DrDoof/fix/syslog-ring-overrun
syslog: stop the log ring from lapping its reader
2026-09-22 18:54:51 +02:00
René van Dorst 38241f0a08 Merge pull request #500 from 13974684927/add-f7008-2-5
machine: add the F7008-2.5 (GPOE-V1.2) 8+1 target
2026-09-22 13:28:01 +02:00
笙笙宝宝 0fe323b12f machine: add the F7008-2.5 (GPOE-V1.2) 8+1 target
Add support for the F7008-2.5 board (PCB F7008-2.5GPOE-V1.2), an
RTL8373N + RTL8224N design with eight 2.5GBASE-T ports and one SFP+ cage.

The LED pads are not wired in port order, so the generic DEFAULT_8C_1SFP
target lights the wrong lamp on this board. The pad to lamp map was
measured on the hardware and is documented in doc/devices/F7008-2.5.md.

The green lamp marks a 2.5G link, the yellow lamp blinks while data flows.
2026-09-22 19:12:12 +08:00
René van Dorst 4bd6ffd083 Merge pull request #492 from vDorst/feat_build
CI: Turn on error on warning also for sdcc-compiler.
2026-09-21 18:11:15 +00:00
René van Dorst 94cfec8693 CI: Build a 4x2/8372 and 8x1/8373 version 2026-09-21 19:50:15 +02:00
René van Dorst a4bb3f1725 CI: Enable CI option to stop at warnings 2026-09-21 19:50:15 +02:00
René van Dorst 931e6da0ab Makefile: Add option CI to turn all warnings into errors 2026-09-21 19:50:11 +02:00
René van Dorst 88454ec7d7 Merge pull request #439 from vDorst/feat_i2c_precompute
I2CBUS: Calculate I2C-settings as compiletime instead at runtime.
2026-09-21 15:30:56 +02:00
René van Dorst f0efb84abb Merge pull request #494 from tofurky/sdcc_4.6.0_warnings
Fix warnings seen on SDCC 4.6.0 due to missing const qualifiers
2026-09-21 10:51:54 +02:00
René van Dorst 62d3424a92 Merge pull request #496 from DrDoof/fix/sfp-nonblocking-wake
sfp: do not block the main loop while a module wakes up
2026-09-21 10:32:22 +02:00
DrDoof a3860c29cb sfp: do not block the main loop while a module wakes up
handle_sfp() called sfp_module_read() as soon as it saw a module appear, and
that path opened with delay(100). delay() spins on PCON until the tick counter
runs down, so the main loop stood still for 100 ticks - half a second at
SYS_TICK_HZ 200. Nothing else ran in that window: no STP, no LACP, no packet
handling. A diagnostic build measured the sfp phase at up to 107 ticks, the
longest stall of any phase in the loop.

Remember when the module showed up and let the loop continue. The I2C read
happens on a later pass, once the wake-up period has elapsed. Pulling a module
cancels a pending read, and a failed read still restores the detect bit, so the
existing retry-on-the-next-poll behaviour is unchanged.

The comparison is written out rather than using a helper so that this does not
depend on anything outside the current tree. The pending flag is an array
indexed by slot, like the other per-slot state in this file.

Cost on SWTGW218AS, measured against the branch point: BANK3 11173 -> 11264,
CSEG, BANK1 and BANK2 unchanged, plus 4 bytes of xdata.
2026-09-21 09:45:18 +02:00
René van Dorst b1961c6955 Merge pull request #495 from tofurky/sfp_normalize_nul
Properly handle NULs when normalizing SFP fields
2026-09-21 08:51:57 +02:00
Matt Merhar bb84bdc55a Properly handle NULs when normalizing SFP fields
Some generic 1.25gbps DAC cables were seen to have a NUL *after* the
space padding in the model field. This caused the normalization to miss
the space padding in the string. The vendor field did not have the
issue.

Note that this seems to be against spec per SFF-8472, which mentions
only space padding or *all* NUL, not a combination of both. In the case
of all NUL, we'll waste a few cycles with no-op writes.
2026-09-20 19:55:07 -04:00
Matt Merhar 1b5243714e Fix warnings seen on SDCC 4.6.0 due to missing const qualifiers
Building with SDCC 4.6.0 emits tons of warnings e.g.:

	cmd_parser.c:31: warning 356: object in read-only code space should be const
	cmd_parser.c:36: warning 357: pointer to object in read-only code space should be pointer to const

These of course become fatal when building with --Werror.

Comparing resultant binaries, it seems that a single string is shifted
(deduplication?) but the numbers emitted at the end of the build are
otherwise identical.
2026-09-20 18:25:17 -04:00
René van Dorst ce11790a0d I2C: Silence compiler warning, de-magic values. 2026-09-20 20:31:43 +02:00
René van Dorst 55431b39f6 Merge pull request #483 from DrDoof/perf/rx-nosleep
rtlplayground: do not sleep in idle() while a packet is waiting
2026-09-20 13:02:59 +00:00
René van Dorst 46e1c955ba Merge pull request #482 from DrDoof/perf/rx-budget
rtlplayground: take several packets per loop in handle_rx()
2026-09-20 13:02:07 +00:00
d00f 7b728cec6f rtlplayground: do not sleep in idle() while a packet is waiting
idle() went to sleep before it looked at the receive buffer, so a packet that
arrived just after the loop dozed off waited for the next tick before anything
touched it. Every TCP round-trip paid that toll, which is why the web UI felt
sluggish even though no phase of the loop was anywhere near busy.

Check the receive buffer first and only sleep when it is empty. The read takes
its result straight from SFR_DATA_U16 rather than going through reg_read_m()
and the sfr_data[] copy, which is what the rest of the tree already does.

Measured on SWTGW218AS with this change alone:

  web UI, median of 15 requests for the main page   88 ms -> 76 ms
  CPU port under a one-way UDP stream               159 -> 230 packets/s

The loop still sleeps normally when there is nothing to do, so this does not
turn the core into a busy-wait: loops/ticks stays at 0.99 on an idle switch,
and rises above 1.0 only while packets are actually queued.

Costs 12 bytes of code and no extra XDATA.
2026-09-20 14:56:44 +02:00
d00f 0d17dd563f rtlplayground: take several packets per loop in handle_rx()
handle_rx() picked up exactly one packet per iteration of the main loop. Since
the loop sleeps until the next tick, that capped the CPU port at roughly one
packet per tick no matter how little work it had to do. A burst of broadcast,
ARP or IGMP traffic aimed at the CPU queued up behind that and pushed out the
STP and LACP timers.

Drain up to RX_BUDGET packets in one pass instead. The budget matters: without
one a sustained flood would spin here and starve everything else in the loop.

The two register reads in the loop take their result straight from
SFR_DATA_U16 rather than going through reg_read_m() and the sfr_data[] copy,
which is what the rest of the tree already does.

Measured on SWTGW218AS with a one-way UDP stream, counting the packets the CPU
actually processed, with this change alone:

  before          159 packets/s
  RX_BUDGET 4     245 packets/s, loop iteration ~16 ms
  RX_BUDGET 8     298 packets/s, loop iteration ~26 ms

Throughput is already most of the way there at 4, so the larger budget mostly
buys a longer worst-case delay for the other phases. STP stayed responsive in
both cases.

Costs 71 bytes of code and no extra XDATA.
2026-09-20 14:42:50 +02:00
René van Dorst d556d634ca Merge pull request #487 from jagheterfredrik/patch-1
add zlib1g-dev to Dockerfile
2026-09-20 12:34:33 +00:00
Fredrik Gustafsson 2844a1ed6d add zlib1g-dev to Dockerfile
Current Docker-based build fails without it
2026-09-20 14:31:03 +02:00
René van Dorst 7b5e365d5e Merge pull request #409 from gnacho/i18n-es
feat(translate): add Spanish (es) translations
2026-09-20 11:40:56 +00:00
gnacho 45fb382b07 feat(translate): add Spanish option to the language selector 2026-09-20 13:29:12 +02:00
René van Dorst 8973774594 Merge pull request #476 from bloqaudio/fix/eee-port-argument
eee: accept a port again, and stop the web UI discarding other ports
2026-09-20 09:50:25 +00:00
René van Dorst 48c5b0c9cf Merge pull request #486 from bloqaudio/fix/syslog-null-conn
syslog: do not read the connection before there is one
2026-09-20 09:39:04 +00:00
René van Dorst 1557a7cf3c MACHINE: rebase, update the new added devices 2026-09-20 11:30:17 +02:00
René van Dorst 131bc106af boot/i2c-setup(): Remove the switch-statement defaults.
All the possibilities are handled, or otherwise a compile-time macro
I2CBUS_VALID ensures invalid options are rejected with a compiler error.

Also fix a compiler warning.
2026-09-20 11:25:35 +02:00
René van Dorst 19ccc4003d i2c: Add compiletime check macro for validating the i2c pins.
Use 0x7 as error value for an invalid I2C SDA/SCL-pin value.
The macro `I2CBUS_VALID` checks for this value.
When a invalid pin is ues, the compiler errors out with:
  "machine.c:<line>: error 176: sizeof applied to an incomplete type",

Error message is not ideal but at-least points to the right location in
the code.
2026-09-20 11:25:35 +02:00
René van Dorst b5fe9f217f i2c/sfp: Demagic shift-values 2026-09-20 11:25:35 +02:00
René van Dorst f65d14f452 I2CBUS: Calculate I2C-settings as compiletime instead at runtime.
We can reduce the i2c-settings to just one byte, and this new const value
can directly be used by the I2C-peripheral without additional computation.
This saves 1-xdata load and a lot of bit-shifting.

I see a codesize savings of +200 bytes.
2026-09-20 11:25:34 +02:00
René van Dorst b92fba870c Merge pull request #484 from bloqaudio/fix/upload-auth-gate
httpd: gate /upload on authentication before it changes state, and make the length limit count
2026-09-20 09:21:25 +00:00
René van Dorst 4deee377a7 Merge pull request #485 from bloqaudio/fix/led-set-index
leds: index the second LED register from the set it belongs to
2026-09-20 08:40:52 +00:00
bloqaudio fd058ea74d port: name the port an eee command acted on the way the user wrote it
port_eee_enable() and port_eee_disable() report the port with
print_byte(), which prints the internal index in hex, so turning EEE off
on port 5 answers "EEE off for 04". port_eee_status() in the same file
already uses print_phys_port(), and the status listing it produces counts
from one, so the two halves of the same command disagreed.

Use print_phys_port() in all three messages.
2026-09-18 14:59:47 -05:00
bloqaudio edc469fe29 httpd: make the firmware upload length limit count
max_upload was armed once when the upload began and never reduced, so
`max_upload - uip_len > 0` was an unsigned expression that only went
false when a segment arrived whose length matched the limit exactly. The
write pointer climbed from the staging address with nothing to stop it,
while flash_write_bytes() carries the address in three bytes and drops
whatever does not fit.

Subtract each segment as it is taken and compare before subtracting, which
is what the comment there described. The limit was only ever armed for
firmware uploads; configuration uploads keep the bound their own buffer
already imposes.
2026-09-18 14:01:03 -05:00
bloqaudio a71c5359a5 httpd: refuse an unauthenticated firmware upload before it changes state
The multipart branch for /config tests authenticated before it touches
anything; the branch for /upload does not, and the 401 for it is only
raised further down at the dispatch. By then the request has already set
config_upload, uptr, verify_crc, max_upload and pre_acc, and announced a
firmware upload on the console.

Those five are globals while the transfer state they steer is per
connection, and the stack is built for ten connections, so a request that
is about to be rejected can still retarget an upload another client is in
the middle of: a configuration upload continues as a firmware one and its
remaining parts are written to the staging area instead of the
configuration sector.

Apply the same test the neighbouring branch uses, before the assignments.
2026-09-18 14:00:51 -05:00
bloqaudio 9e3863cc4e syslog: do not read the connection before there is one
udp_callbacks() offers every UDP connection event to syslog_callback(),
which decides whether the event is its own by comparing the local port
against state.syslog_conn->lport. The pointer is null until syslog is
started: syslog_init() clears it at boot and syslog_stop() clears it
again, so with syslog off, which is the default, every poll dereferences
null and reads whatever lives at the bottom of xdata.

Should that word ever match the port being offered, the send path runs on
another application's connection, overwrites uip_appdata and drops the
log line it was holding.

Test the pointer first.
2026-09-18 13:59:59 -05:00
bloqaudio d22ec04b5b leds: index the second LED register from the set it belongs to
leds_setup() walks all four LED sets and writes the high-speed nibble of
each into one of two registers, LED3_0_SET1 for sets 0 and 1 and
LED3_0_SET3 for sets 2 and 3. The second branch reuses the index
expression of the first without rebasing it, so sets 2 and 3 address
sfr_data[-1], [-2], [-3] and [-4].

Two things follow. Sets 2 and 3 never receive their nibble, because the
read-modify-write pair writes back exactly what it read. And four bytes
below sfr_data are overwritten on every boot of every machine: the loop
runs over all four sets whatever the board declares. On this build the
linker places sfr_data directly after the serial receive ring, so the
writes land in the tail of that ring.

leds_dump() reads the same two registers back and already rebases with
(set - 2); use the same form here.
2026-09-18 13:59:50 -05:00
bloqaudio 0a65536a7f web: send an eee command in the documented argument order
The EEE toggle posted `eee <port> <on|off>`, the reverse of the
`eee [on|off|status] [port] [100m|1g|2g5]` the parser and the
documentation describe, so the switch answered with its usage line and
the checkbox sprang back. The multi-page UI this replaced sent `eee on`
with no port at all, which toggled every port instead of one.

Moving the port to the end breaks the stored-configuration merge, which
builds its drop key as a line prefix: with the port trailing, a per-port
line matches the bare eee entry and replaces every eee line in the
configuration rather than the one for that port. Give the command its own
case beside the bandwidth one, so a line with a port replaces only that
port and a line without one clears them all, and accept the optional
speed word the command has always taken.

Reported by tofurky in issue #459.
2026-09-18 13:57:07 -05:00
bloqaudio 0631c813e2 cmd: parse the port of an eee command from the start of the word
parse_eee() sniffs word 2 for a trailing 'g' or 'm' to tell a speed from
a port number, and advances idx past the digits to do so. The port branch
then hands that advanced idx to cmd_parse_port_separator(), which expects
the first character of the number and finds the separator instead, so it
returns 0 and the command is rejected. Every other caller passes
cmd_words_b[].

The result is that no eee command carrying a port number works, in any
argument order, and the stored per-port lines a saved configuration
replays are silently dropped.

Reported by tofurky in issue #459, along with this fix.
2026-09-18 13:56:53 -05:00
d00f 3c8de6da87 httpd: refuse a configuration with a line the replay cannot take
The replay takes a line of at most 126 bytes, so a longer one is skipped
on boot. Neither the upload path nor the editor looked at line length,
so the file the user saved was not the configuration the switch would
come up with.

Reject such a body in config_take(), before the sector is erased, which
the upload path already maps to 400. The editor points at the offending
line and its length, and measures it in bytes rather than characters, so
a name written in a non-ASCII script is counted the way the switch
counts it.
2026-09-18 16:03:16 +02:00
d00f 3a6f62b1d5 config: skip a line the parser cannot buffer instead of stopping
execute_config() replays the saved configuration line by line into
cmd_buffer. A line that does not fit, or one cmd_tokenize() rejects,
ended the replay right there: everything below it was silently left
unapplied, while the file itself and the editor showing it stayed
complete. On a switch here, a 130-byte line placed after the last real
setting was enough to lose every line that followed it on the next boot.

Report the offending line and carry on with the next one. The skip flag
lives across the flash page refill, so a long line that crosses a page
boundary is not resumed halfway and run as a truncated command.
2026-09-18 16:03:16 +02:00
d00f 3dcab09047 web: keep stored config lines and per-port ingress when saving
Save to flash ran the stored config through the same filter as the
command log, so stored lines the page does not know were dropped. The
stored lines are now carried over as they are and only the log is
filtered.

ingress only changes the ports it lists, but the merge replaced every
stored ingress line. It now merges per port; "ingress t|u|a" still
replaces everything, and per-port settings an all-ports line already
overrode are not revived.

Write from the config editor no longer clears the command log or the
unsaved marker, since the edited text does not hold the changes made on
other pages; only Save, which merges them, clears the log.

The command log grows from 1 kB to 2 kB, which still fits the 2500 byte
output buffer, and send_cmd_log() stops at the end of that buffer.
2026-09-15 20:18:17 +02:00
d00f 18b28edcbb httpd: keep a continued upload away from the cmd and login handlers
handle_post() takes the request path from byte 6 of the segment it is
given. For the first segment of a POST that is the path, but for a later
segment of a multipart upload it is whatever part of the file happens to
sit there. The cmd and login handlers were matched before the multipart
state was checked, so a segment of a config or firmware upload with
"cmd " at that offset ran the rest of the segment as CLI commands, and
one with "login " there aborted the upload with 400.

Check for an upload in progress, and for new upload and config requests,
before looking at cmd and login. A new POST cannot match both sets of
words, so nothing changes for requests that are not uploads.
2026-09-15 09:57:49 +02:00
gnacho ae77ffe495 feat(translate): add Spanish (es) translations for single-page UI 2026-09-14 22:44:25 +02:00
d00f eb4bae278b Makefile: let the linker check external RAM against 0xBFFF
The 8051 in the RTL837x has 48 kB of XDATA, 0x0000 to 0xBFFF. Writing
a byte and reading it back from the same address works all the way up
to 0xBFFF on a SWTGW218AS, while at 0xC000 the byte comes back as 0x00.
Without --xram-size the linker assumes 16 MB, so running past the end
would still build cleanly and only show up at run time.

The value is 49151 rather than 49152. The linker check adds up the
sizes of the XDATA areas, and XDATA allocation starts at 0x0001, so a
limit of 49152 would still let the last byte land on 0xC000.
2026-09-14 02:07:57 +02:00
d00f 552bd1cb18 syslog: stop the log ring from lapping its reader
write_char() masked writeptr and never looked at readptr, so once more
than LOGBUF_SIZE bytes were written between two drains the ring wrapped
over content that had not been sent yet.

That is not a corner case. The ring is emptied once per main loop pass,
while a single command runs to completion inside one pass, and a full L2
listing prints well over twice the 512 byte buffer. On hardware the whole
1227 byte dump came out as one 174 byte datagram whose first line began in
the middle of a MAC address.

Drop the character when the ring is full instead of overwriting, so what
has been logged stays intact and it is the tail that is lost. A full ring
also flags a line, otherwise a burst without a newline would leave the
reader waiting on line_available forever and syslog would stop for good.
2026-09-07 22:51:57 +02:00
40 changed files with 533 additions and 233 deletions

No files matched your search

+4 -2
View File
@@ -22,5 +22,7 @@ jobs:
run: make -C test
- name: Check if machine.c can be compiled for all machines
run: make machine_check
- name: Make project
run: make MACHINE="KP_9000_6XHML_X2"
- name: Make project (4x2/RTL8372)
run: make CI=1 MACHINE="KP_9000_6XHML_X2"
- name: Make project (8x1/RTL8373)
run: make CI=1 MACHINE="KP_9000_9XHML_X_V3_1"
+6
View File
@@ -14,6 +14,12 @@
## 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
+1
View File
@@ -8,6 +8,7 @@ RUN apt-get update && apt-get install -y \
python3 \
libjson-c-dev \
git \
zlib1g-dev \
&& rm -rf /var/lib/apt/lists/*
# git safe.directory for mounted repos (Makefile uses git describe)
+5 -1
View File
@@ -20,6 +20,10 @@ else
CC_FLAGS += -DMACHINE_$(MACHINE)
endif
ifeq ($(CI),1)
CC_FLAGS += --Werror
endif
BUILDDIR = output/$(MACHINE)
VERSION_HEADER := version.h
@@ -134,7 +138,7 @@ $(BUILDDIR)/%.rel: %.asm | create_build_dir
# mv -f $(addprefix $(basename $^), .lst .rel .sym) .
$(BUILDDIR)/rtlplayground.ihx: $(OBJS) $(BUILDDIR)/crtbank.rel $(BUILDDIR)/crc16.rel
$(CC) $(CC_FLAGS) -Wl-bHOME=0x00000 -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-bBANK3=0x34000 -Wl-r -o $@ $^
$(CC) $(CC_FLAGS) --xram-size 49151 -Wl-bHOME=0x00000 -Wl-bBANK1=0x14000 -Wl-bBANK2=0x24000 -Wl-bBANK3=0x34000 -Wl-r -o $@ $^
$(BUILDDIR)/rtlplayground.img: $(BUILDDIR)/rtlplayground.ihx
objcopy --input-target=ihex -O binary $< $@
+6 -8
View File
@@ -22,7 +22,7 @@ extern __xdata struct machine_runtime machine_detected;
extern __xdata uint8_t sfr_data[4];
extern volatile __xdata uint32_t ticks;
extern __xdata uint8_t tx_seq;
extern __code uint8_t * __code hex;
extern __code const uint8_t * __code const hex;
@@ -397,10 +397,12 @@ void setup_i2c(void) __banked
// 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++) {
const uint8_t scl_bus = i2c_bus_from_scl_pin(machine.sfp_port[sfp].i2c.scl);
const uint8_t sda_bus = i2c_bus_from_sda_pin(machine.sfp_port[sfp].i2c.sda);
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');
switch (scl_bus) {
// `& 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);
@@ -419,8 +421,6 @@ void setup_i2c(void) __banked
sfr_mask_data(0, 0x80, 0x80);
sfr_mask_data(1, 0x01, 0x00);
break;
default:
print_string("Invalid SCL bus number: "); print_byte(scl_bus); write_char('\n');
}
switch (sda_bus) {
@@ -444,8 +444,6 @@ void setup_i2c(void) __banked
// Bit 9-10 0b01 -> SDA
sfr_mask_data(1, 0x06, 0x02);
break;
default:
print_string("Invalid SDA bus number: "); print_byte(sda_bus); write_char('\n');
}
}
reg_write_m(RTL837X_PIN_MUX_1);
+23 -17
View File
@@ -26,15 +26,15 @@
#pragma codeseg BANK2
#pragma constseg BANK2
extern __code struct machine machine;
extern __code const struct machine machine;
extern __xdata bool stp_enabled;
extern __code uint8_t log_to_phys_port[9];
extern __code const uint8_t log_to_phys_port[9];
extern volatile __xdata uint32_t ticks;
extern volatile __xdata uint8_t sfr_data[4];
extern __code uint8_t * __code greeting;
extern __code uint8_t * __code hex;
extern __code const uint8_t * __code const greeting;
extern __code const uint8_t * __code const hex;
extern __xdata uint8_t flash_buf[FLASH_BUF_SIZE];
extern __xdata struct flash_region_t flash_region;
@@ -105,7 +105,7 @@ inline uint8_t isnumber(uint8_t l)
return (l <= ('9'-'0'));
}
uint8_t cmd_compare(uint8_t start, __code uint8_t * cmd)
uint8_t cmd_compare(uint8_t start, __code const uint8_t * cmd)
{
if (cmd_words_len == 0 || start > (cmd_words_len - 1)) {
return 0;
@@ -1427,7 +1427,7 @@ void parse_eee(void)
speed_word = 2;
} else if (cmd_is_space_or_nul(idx)) {
// Word 2 is a port number
if (cmd_parse_port_separator(idx) == 0) {
if (cmd_parse_port_separator(cmd_words_b[2]) == 0) {
cmd_error("Speed word invalid, use: [100m|1g|2g5]\n");
return;
}
@@ -1962,6 +1962,7 @@ void execute_config(void) __banked
save_cmd = 0;
uint8_t cmd_idx = 0;
uint8_t skipping = 0;
do {
flash_region.addr = pos;
flash_region.len = FLASH_READ_BURST_SIZE;
@@ -1972,20 +1973,23 @@ void execute_config(void) __banked
do {
if (cmd_idx >= (CMD_BUF_SIZE - 1)) {
cmd_buffer[cmd_idx] = NUL;
print_string("ERROR: Command too long: ");
print_string("ERROR: Command too long, skipped: ");
print_string_x(cmd_buffer);
write_char('\n');
err_status = ERR_CMD_TOO_LONG;
goto config_done;
cmd_idx = 0;
skipping = 1;
}
c = flash_buf[cfg_idx++];
if (c == 0 || c == '\n') {
cmd_buffer[cmd_idx] = NUL;
if (cmd_idx) {
cmd_tokenize();
if (err_status != ERR_OK)
goto config_done;
cmd_parser();
if (skipping) {
skipping = 0;
} else {
cmd_buffer[cmd_idx] = NUL;
if (cmd_idx) {
cmd_tokenize();
if (err_status == ERR_OK)
cmd_parser();
}
}
if (c == 0)
goto config_done;
@@ -1993,8 +1997,10 @@ void execute_config(void) __banked
continue;
}
cmd_buffer[cmd_idx] = c;
cmd_idx++;
if (!skipping) {
cmd_buffer[cmd_idx] = c;
cmd_idx++;
}
} while (cfg_idx);
pages_left--;
+70
View File
@@ -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
Binary file not shown.

After

Width:  |  Height:  |  Size: 519 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 KiB

+1
View File
@@ -36,6 +36,7 @@ The following devices have been tested and are fully working:
| Xikestore| SKS3200M-4GPY2XF| Yes | [SWTG024AS-v1.0](devices/SWTG024AS.md) | | 4 + 2 |
| XikeStor | SKS3200-8E1X | Yes | [SWTG118AS-V2.1-17462](devices/SWTGW218AS.md) | 2M | 8 + 1 |
| Ztyuav | Z-QWYT0402 | No | [PCB-K0402WS-V3.0](devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
| Guangnianwei | 7018-2.5G | No | [F7008-2.5GPOE-V1.2](devices/F7008-2.5.md) | 8M | 8 + 1 |
For KP-9000-6XH-X2 / KP-9000-6XHML-X2 / Mokerlink 2G040210GSM devices, select
the machine target by PCB revision. The ML/non-ML or managed/unmanaged label
+158 -18
View File
@@ -90,6 +90,7 @@ sy_rebooting:"Rebooting, reconnect in about 20 s",sy_bytes:"bytes",
cw_title:"Write this startup configuration?",cw_save_title:"Save running configuration to flash?",
cw_info:"{n} / 2048 bytes, replayed line by line on every boot",
cw_toolarge:"Too large: the config sector accepts at most 2048 bytes. Remove lines first.",
cw_longline:"Line {n} is {m} bytes long: the switch can only replay lines up to 126 bytes and would skip it on boot, so the write is refused. Shorten it first.",
cw_unknown:"Not in the known config grammar (will still be written): ",cw_empty:"(empty)",
cw_writing:"Writing configuration...",cw_failed:"config write failed: HTTP {n}",
cw_verify_fail:"Verification failed: flash content differs from what was sent. Command log NOT cleared.",
@@ -201,6 +202,7 @@ sy_rebooting:"再起動中です。約 20 秒後に再接続してください",
cw_title:"この起動設定を書き込みますか?",cw_save_title:"実行中の設定をフラッシュに保存しますか?",
cw_info:"{n} / 2048 バイト、起動のたびに 1 行ずつ実行されます",
cw_toolarge:"サイズ超過: 設定セクタは最大 2048 バイトです。先に行を削除してください。",
cw_longline:"{n} 行目は {m} バイトです: スイッチが起動時に実行できる行は 126 バイトまでで、この行は読み飛ばされるため、書き込みを拒否します。先に短くしてください。",
cw_unknown:"既知の設定文法に含まれない行 (そのまま書き込まれます): ",cw_empty:"(空)",
cw_writing:"設定を書き込み中...",cw_failed:"設定の書き込みに失敗しました: HTTP {n}",
cw_verify_fail:"検証失敗: フラッシュの内容が送信内容と異なります。コマンドログは消去されていません。",
@@ -312,6 +314,7 @@ sy_rebooting:"正在重启,约 20 秒后重新连接",sy_bytes:"字节",
cw_title:"写入此启动配置?",cw_save_title:"将运行配置保存到 Flash?",
cw_info:"{n} / 2048 字节,每次启动时逐行执行",
cw_toolarge:"过大: 配置扇区最多容纳 2048 字节。请先删除部分行。",
cw_longline:"第 {n} 行有 {m} 字节: 交换机启动时只能执行不超过 126 字节的行,该行会被跳过,因此拒绝写入。请先缩短该行。",
cw_unknown:"不属于已知配置语法的行 (仍会写入): ",cw_empty:"(空)",
cw_writing:"正在写入配置...",cw_failed:"配置写入失败: HTTP {n}",
cw_verify_fail:"校验失败: Flash 内容与发送内容不一致。命令日志未清除。",
@@ -332,6 +335,117 @@ fw_applied:"升级已应用",fw_done_t:"固件已升级",
fw_done:"交换机已校验镜像并以新镜像重启。会话已重置,需要重新登录。",
fw_login:"前往登录",fw_rebooting:"交换机正在重启...",
fw_timeout:"150 秒后交换机仍未恢复: 请检查电源 / 串口控制台"
},
es:{
nav_dash:"Panel",nav_ports:"Puertos",nav_stp:"Árbol de expansión",nav_stats:"Estadísticas",
nav_vlan:"VLAN",nav_l2:"Tabla MAC",nav_mirror:"Duplicación",nav_lag:"LAG",nav_eee:"EEE",
nav_bw:"Ancho de banda",nav_system:"Sistema",nav_fw:"Firmware",
hdr_dirty:"cambios sin guardar",hdr_dirty_t:"La configuración en ejecución difiere de la guardada",
hdr_save:"Guardar en flash",hdr_save_t:"Persistir la configuración en ejecución a flash",
th_auto:"Sistema",th_auto_sel:"Sistema (Selenized)",sy_display:"Pantalla",sy_theme:"Tema",sy_display_note:"Se almacena solo en este navegador.",th_light:"Claro",th_dark:"Oscuro",
th_sel_light:"Selenized claro",th_sel_dark:"Selenized oscuro",
c_port:"Puerto",c_name:"Nombre",c_link:"Enlace",c_apply:"Aplicar",c_cancel:"Cancelar",c_confirm:"Confirmar",
c_close:"Cerrar",c_refresh:"Actualizar",c_off:"apagado",c_offc:"Apagado",c_down:"caído",c_on:"Encendido",c_auto:"Auto",c_delete:"Eliminar",
c_type:"Tipo",c_state:"Estado",c_enabled:"Habilitado",c_load:"Cargar",c_disable:"Deshabilitar",c_sfp:"SFP",
c_full:"dúplex completo",c_half:"semidúplex",c_devices:"dispositivos",c_yes:"sí",c_no:"no",
d_ports:"Puertos",d_ports_h:"pulsa un puerto para ver detalles",d_system:"Sistema",d_traffic:"Tráfico",
d_traffic_h:"paquetes/s, en vivo",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX erróneos",d_rxbad:"RX erróneos",
i_host:"Nombre de host",i_ip:"Dirección IP",i_mask:"Máscara de red",i_gw:"Puerta de enlace",i_mac:"MAC",i_fw:"Firmware",
i_built:"Compilado",i_hw:"Hardware",i_flash:"Flash",i_syslog:"Syslog",
p_state:"Estado",p_disabled:"deshabilitado",p_up:"activo",p_txgb:"TX correctos / erróneos",p_rxgb:"RX correctos / erróneos",
p_pkts:"paquetes",p_module:"Módulo",p_temp:"Temperatura",p_vcc:"Vcc",p_txbias:"Polarización TX",p_txpower:"Potencia TX",
p_rxpower:"Potencia RX",p_txfault:"Fallo TX",p_txdis:"TX deshabilitado",p_rxlos:"Pérdida RX (LOS)",p_adv:"Anunciado",
pt_title:"Configuración de puerto",pt_conn:"Conectado",pt_speed:"Velocidad",pt_mtu:"MTU",
pt_sfp_note:"La velocidad del SFP se ajusta por ranura y no se guarda en la configuración de inicio.",
pt_name_err:"Nombre de puerto: 1-15 caracteres, sin espacios",pt_mtu_err:"El MTU debe estar entre 64 y 16383",
stp_title:"Árbol de expansión",stp_h:"RSTP, 802.1w",stp_version:"Versión",stp_v_stp:"STP compatible",
stp_prio:"Prioridad del puente",stp_hello:"Hello [s]",stp_maxage:"Edad máxima [s]",stp_fwd:"Retardo de reenvío [s]",
stp_txhold:"Retención TX",stp_bridge_apply:"Aplicar ajustes del puente",
stp_off_msg:"El árbol de expansión está deshabilitado: todos los puertos reenvían.",stp_bridge:"Puente",stp_root:"Raíz",
stp_root_self:"este puente es la raíz",stp_via:"vía puerto",stp_cost:"coste de ruta",stp_tc:"cambios de topología",
stp_prio_note:"La prioridad más baja gana la elección de raíz (8 por defecto = 32768). Los ajustes se aplican inmediatamente; usa Guardar en flash para conservarlos.",
stp_portcfg:"Configuración de puertos",stp_edge:"Borde",stp_pcost:"Coste de ruta",stp_pprio:"Prioridad",
stp_guard:"Protección",stp_filter:"Filtro BPDU",stp_p2p:"Punto a punto",
stp_port_note:"Los puertos de borde reenvían inmediatamente y no causan cambios de topología; Auto trata un puerto como de borde tras 3 s sin BPDUs, y cualquier BPDU recibido lo revoca. Coste de ruta 0 = automático.",
stp_status:"Estado de puertos",stp_role:"Rol",stp_db:"Puente designado",stp_dp:"Puerto designado",
stp_dc:"Coste designado",stp_oedge:"Borde operativo",stp_op2p:"P2P operativo",
stp_s0:"deshabilitado",stp_s1:"bloqueo",stp_s2:"aprendizaje",stp_s3:"reenvío",
stp_r1:"Raíz",stp_r2:"Designado",stp_r3:"Alternativo",stp_trip:"protección disparada",
stp_g_none:"Ninguno",stp_g_bpdu:"BPDU",stp_g_root:"Raíz",
stp_en_q:"¿Habilitar el árbol de expansión?",
stp_en_d:"Los puertos empiezan bloqueados y tardan hasta el doble del retardo de reenvío en alcanzar el reenvío; los puertos de borde se recuperan inmediatamente.",
stp_dis_q:"¿Deshabilitar el árbol de expansión?",stp_dis_d:"Todos los puertos pasan directamente a reenviar; se pierde la protección contra bucles.",
stp_cost_err:"El coste de ruta debe estar entre 0 y 200000000",
st_title:"Estadísticas de puertos",st_h:"totales desde el arranque",st_txg:"TX correctos",st_txb:"TX erróneos",st_rxg:"RX correctos",
st_rxb:"RX erróneos",st_details:"Detalles",st_counters:"Contadores MIB",st_nonzero:"solo no nulos",
st_autoref:"actualización automática",st_counter:"Contador",st_value:"Valor",st_fail:"error al cargar contadores",
v_title:"VLANs",v_vid:"VID",v_members:"Miembros",v_tagged:"Etiquetados",v_untagged:"Sin etiquetar",v_pvid_on:"PVID activo",
v_empty:"No hay VLANs configuradas.",v_mgmt:"VLAN de gestión",v_mgmt_none:"sin etiquetar",v_editor:"Editor de VLANs",
v_optional:"opcional",v_setmgmt:"Establecer como VLAN de gestión",v_setmgmt_t:"Hacer esta la VLAN de gestión",
v_member:"Miembro",v_pvid:"PVID",
v_legend:"U = miembro sin etiquetar, T = miembro etiquetado, - = no miembro. PVID asigna esta VLAN al tráfico entrante sin etiquetar.",
v_ingress:"Filtrado de entrada",v_ingress_h:"solo escritura: el estado no se puede leer desde el switch",
v_accept:"Aceptar",v_ing_all:"Todos",v_ing_apply:"Aplicar modos de entrada",v_del_t:"Eliminar VLAN",
v_del_q:"¿Eliminar VLAN {n}?",v_del_d:"Los puertos conservan su PVID hasta que se reasignen.",
v_vid_err:"Introduce un ID de VLAN (1-4094)",v_name_err:"El nombre debe empezar por una letra (letras, dígitos, _)",
v_loaded:"VLAN {n} cargada",v_notfound:"VLAN {n} no encontrada (aún se puede crear una nueva)",
v_nomember:"Selecciona al menos un puerto miembro (o elimina la VLAN)",
v_ing_none:"Elige un modo de entrada para al menos un puerto",v_vid_first:"Introduce primero un ID de VLAN",
v_mgmt_q:"¿Establecer VLAN {n} como VLAN de gestión?",
v_mgmt_d:"El switch empezará a etiquetar su propio tráfico con esa VLAN. Si el puerto por el que te conectas no la transporta, esta página dejará de ser accesible y el ajuste solo podrá deshacerse por la consola.",
l2_title:"Tabla de direcciones MAC",l2_filter:"filtrar...",l2_flush:"Vaciar entradas aprendidas",l2_static:"estática",
l2_learned:"aprendida",l2_loading:"cargando...",l2_failed:"error de carga",l2_entries:"entradas",
l2_del_t:"Eliminar entrada",l2_flush_q:"¿Vaciar todas las entradas MAC aprendidas?",
m_title:"Duplicación de puertos",m_active:"activa",m_monitor:"Puerto monitor",m_mirror:"Duplicar",m_both:"Ambos",
m_note:"Ambos = duplica RX y TX del puerto al puerto monitor.",m_none:"Selecciona al menos un puerto duplicado",
lag_hash:"Hash:",lag_note:"Un LAG necesita al menos un miembro para guardarse en la configuración de inicio; aplicar un grupo vacío lo borra.",
lag_clear_q:"¿Borrar LAG {n}?",lag_clear_d:"Todos los puertos miembros vuelven a la operación normal.",
e_title:"Ethernet de bajo consumo",e_adv:"Anunciado",e_lp:"Par de enlace",e_active:"Activo",e_enable:"Habilitar",
e_note:"Banderas anunciadas y del socio de enlace por velocidad: 100M, 1G, 2.5G. Los puertos SFP no soportan EEE.",
e_idle:"inactivo",e_na:"n/d",
bw_title:"Límites de ancho de banda",bw_h:"Mbit/s, 0.016-10000",bw_in:"Límite de entrada",bw_out:"Límite de salida",
bw_exceed:"Al excederse",bw_fc:"Control de flujo",bw_drop:"Descartar",
bw_in_err:"El límite de entrada debe estar entre 0.016 y 10000 Mbit/s",bw_out_err:"El límite de salida debe estar entre 0.016 y 10000 Mbit/s",
sy_network:"Red",sy_dhcp:"Usar DHCP",sy_dhcp_t:"Solicitar dirección mediante DHCP",sy_services:"Servicios",
sy_igmp:"IGMP snooping",sy_sysip:"IP del servidor",sy_server:"Servidor",sy_port:"Puerto",
sy_services_note:"El estado del servicio refleja la configuración de inicio; el estado en ejecución no es legible.",
sy_password:"Contraseña de administrador",sy_newpw:"Nueva contraseña",sy_repeat:"Repetir",sy_pwapply:"Cambiar contraseña",
sy_pw_note:"Toma efecto inmediatamente; guarda en flash para conservarla tras el reinicio.",sy_console:"Consola",
sy_cmd:"Comando de CLI...",sy_send:"Enviar",sy_startup:"Configuración de inicio",sy_replayed:"reaplicada en cada arranque",
sy_reload:"Recargar desde flash",sy_write:"Escribir en flash",sy_unknown_note:"Las líneas desconocidas se resaltan antes de escribir.",
sy_maint:"Mantenimiento",sy_reboot:"Reiniciar switch",sy_lang:"Idioma",
sy_ip_err:"IP / máscara / puerta de enlace no válidos",sy_host_err:"Nombre de host: 1-23 caracteres imprimibles, sin espacios ni comillas",
sy_net_q:"¿Aplicar ajustes de red?",sy_net_d:"La IP de gestión cambia a {ip}: esta página deberá reabrirse allí.",
sy_ip_changed:"IP cambiada, reconecta en http://{ip}/",sy_dhcp_q:"¿Cambiar a DHCP?",
sy_dhcp_d:"El switch solicita una dirección mediante DHCP. Deberás encontrar su nueva IP para reconectar.",
sy_sysip_err:"IP del servidor syslog no válida",sy_sysport_err:"El puerto de syslog debe estar entre 1 y 65535",
sy_pw_len:"Contraseña: 1-20 caracteres",sy_pw_space:"La contraseña no puede contener espacios",sy_pw_match:"Las contraseñas no coinciden",
sy_pw_q:"¿Cambiar la contraseña de administrador?",sy_pw_d:"Toma efecto inmediatamente para los nuevos inicios de sesión. Guarda en flash para persistir.",
sy_reboot_q:"¿Reiniciar el switch?",sy_reboot_d:"Hay cambios SIN GUARDAR y se perderán. Guarda en flash primero si quieres conservarlos.",
sy_rebooting:"Reiniciando, reconecta en unos 20 s",sy_bytes:"bytes",
cw_title:"¿Escribir esta configuración de inicio?",cw_save_title:"¿Guardar la configuración en ejecución en flash?",
cw_info:"{n} / 2048 bytes, reaplicada línea a línea en cada arranque",
cw_toolarge:"Demasiado grande: el sector de configuración admite como máximo 2048 bytes. Elimina líneas primero.",
cw_unknown:"No está en la gramática de configuración conocida (aun así se escribirá): ",cw_empty:"(vacío)",
cw_writing:"Escribiendo configuración...",cw_failed:"error al escribir la configuración: HTTP {n}",
cw_verify_fail:"Verificación fallida: el contenido de la flash difiere de lo enviado. El registro de comandos NO se ha borrado.",
cw_saved:"Configuración de inicio guardada y verificada",cw_collect:"Recopilando cambios en ejecución...",
t_applied:"Aplicado: {c}",t_cmds:"{n} comando(s) aplicado(s)",t_rejected:"comando rechazado: {c}",t_failed:"fallo: {c}",
fw_title:"Actualización de firmware",
fw_intro:"Sube una imagen de RTLPlayground (512 KiB .bin). La imagen se almacena provisionalmente en flash y se comprueba con CRC; si es correcta, el switch se reinicia, vuelve a verificar la imagen y la aplica. La configuración de inicio se conserva.",
fw_upload:"Subir",fw_checking:"{f}: {n} bytes. Comprobando...",fw_size_err:"el tamaño es {n}, se esperaban 524288 (512 KiB)",
fw_magic_err:"falta la cabecera de banco / magia LJMP: no es una imagen de firmware",fw_crc_err:"comprobación CRC16 fallida: imagen corrupta",
fw_valid:"imagen de RTLPlayground válida (tamaño, magia y CRC16 correctos)",fw_q:"¿Subir firmware?",
fw_d:"Si la suma de comprobación es correcta, el switch se reinicia y aplica la imagen durante el arranque (la configuración de inicio se conserva). No lo apagues hasta que vuelva.",
fw_finishing:"terminando escritura en flash... {s} s",fw_uploading:"subiendo... {p}% / {s} s",
fw_verified:"suma de comprobación verificada, el switch se está reiniciando...",
fw_rejected:"el switch rechazó la imagen (suma de comprobación incorrecta), no se aplicó nada",
fw_lost:"error de subida: conexión perdida durante la transferencia",
fw_noreboot:"no se detectó reinicio: lo más probable es que la imagen fuera rechazada. Si actualizas desde un firmware antiguo, verifica la versión en la barra lateral tras volver a iniciar sesión.",
fw_applied:"actualización aplicada",fw_done_t:"Firmware actualizado",
fw_done:"El switch verificó la imagen y se reinició con ella. La sesión se restableció, así que se te pedirá que vuelvas a iniciar sesión.",
fw_login:"Ir al inicio de sesión",fw_rebooting:"el switch se está reiniciando...",
fw_timeout:"el switch no ha vuelto tras 150 s: comprueba la alimentación / consola serie"
}
};
var rtlLang=(function(){
@@ -434,7 +548,7 @@ var CONF_CMDS=[
/^ingress(\s+\d{1,2}[tua])+$/,/^ingress\s+[tua]$/,
/^port\s+\d{1,2}\s+(10m|100m|1g|2g5|5g|10g|auto|on|off)(\s+(half|full))?$/,
/^port\s+\d{1,2}\s+name\s+\S+$/,
/^eee(\s+\d{1,2})?\s+(on|off)$/,
/^eee\s+(on|off)(\s+\d{1,2})?(\s+(100m|1g|2g5))?$/,
/^mirror(\s+\d{1,2})(\s+\d{1,2}[tr]?)+$/,/^mirror\s+off$/,
/^lag\s+[1-4](\s+\d{1,2})+$/,/^lag\s+[1-4]\s+d$/,/^laghash\s+[1-4](\s+\w+)+$/,
/^isolate\s+\d{1,2}(\s+(off|\d{1,2}))+$/,
@@ -1432,7 +1546,7 @@ function eeeLoad(){
var on=parseInt(p.eee,2)!==0;
var sw=h("label",{class:"switch"},[
h("input",{type:"checkbox",onchange:function(){
postCmd("eee "+p.portNum+" "+(this.checked?"on":"off"))
postCmd("eee "+(this.checked?"on":"off")+" "+p.portNum)
.then(function(){setTimeout(eeeLoad,300)}).catch(function(){});
}}),h("i")]);
sw.firstChild.checked=on;
@@ -1604,11 +1718,16 @@ function cfgReload(){
cfgParseKnown(x);
}).catch(function(){});
}
function cfgLongLine(v){
var ls=v.split("\n");
for(var i=0;i<ls.length;i++){var n=new Blob([ls[i]]).size;if(n>126)return{n:i+1,m:n};}
return null;
}
function cfgBytes(){
var n=new Blob([$("cfgedit").value]).size;
var v=$("cfgedit").value,n=new Blob([v]).size;
var el=$("cfgbytes");
el.textContent=n+" / 2048 "+t("sy_bytes");
el.style.color=n>2048?"var(--bad)":"";
el.style.color=(n>2048||cfgLongLine(v))?"var(--bad)":"";
return n;
}
$("cfgedit").addEventListener("input",cfgBytes);
@@ -1622,9 +1741,9 @@ var CONF_OVERWRITE=[
/^ip\b/,/^gw\b/,/^netmask\b/,/^hostname\b/,
/^syslog\s+ip\b/,/^syslog\s+port\b/,/^passwd\b/,
/^vlan\s+\d{1,4}\s+mgmt$/,/^vlan\s+\d{1,4}(?!\s+mgmt\b)/,
/^pvid\s+\d{1,2}\b/,/^ingress\b/,
/^pvid\s+\d{1,2}\b/,
/^port\s+\d{1,2}(?!\s+name\b)/,/^port\s+\d{1,2}\s+name\b/,
/^eee\s+\d{1,2}\b/,/^eee\b/,/^mirror\b/,
/^mirror\b/,
/^lag\s+\d\b/,/^laghash\s+\d\b/,/^isolate\s+\d{1,2}\b/,
/^stp\s+(prio|hello|maxage|fwd|txhold|version)\b/,
/^stp\s+(port\s+\d{1,2}|lag\s+[1-4])\s+(edge|cost|prio|guard|filter|p2p)\b/,
@@ -1641,8 +1760,28 @@ function mergeConf(base,texts){
var m;
if((m=line.match(/^vlan (\d{1,4}) d$/))){drop(new RegExp("^vlan "+m[1]+"( |$)"));return;}
if((m=line.match(/^lag (\d) d$/))){drop(new RegExp("^lag(hash)? "+m[1]+"( |$)"));return;}
if((m=line.match(/^eee (on|off)(?: (\d{1,2}))?(?: (?:100m|1g|2g5))?$/))){
if(m[2])drop(new RegExp("^eee (on|off) "+m[2]+"\\b"));
else drop(/^eee /);
conf.push(line);return;
}
if(line==="mirror off"){drop(/^mirror /);return;}
if(!isConfCmd(line))return;
if((m=line.match(/^ingress (.+)$/))){
if(/^[tua]$/.test(m[1])){drop(/^ingress /);conf.push(line);return;}
var ports={},order=[],last=-1;
conf.forEach(function(c,i){if(/^ingress [tua]$/.test(c))last=i;});
conf.forEach(function(c,i){
var cm=c.match(/^ingress (.+)$/);
if(!cm||/^[tua]$/.test(cm[1])||i<last)return;
cm[1].split(" ").forEach(function(tk){var n=tk.slice(0,-1);if(!(n in ports))order.push(n);ports[n]=tk;});
});
m[1].split(" ").forEach(function(tk){var n=tk.slice(0,-1);if(!(n in ports))order.push(n);ports[n]=tk;});
conf=conf.filter(function(c){var cm=c.match(/^ingress (.+)$/);return!cm||/^[tua]$/.test(cm[1])});
order.sort(function(a,b){return a-b});
conf.push("ingress "+order.map(function(n){return ports[n]}).join(" "));
return;
}
if((m=line.match(/^bw (in|out) (\d{1,2}) (\S+)$/))){
var pre="^bw "+m[1]+" "+m[2]+" ";
if(m[1]==="out"||m[3]==="off")drop(new RegExp(pre));
@@ -1670,18 +1809,18 @@ function mergeConf(base,texts){
});
return conf;
}
function writeConfig(txt,title){
function writeConfig(txt,title,fromLog){
var info=h("p",{class:"small mut"}),warn=h("p",{class:"small"});
var ed=h("textarea",{class:"cfg",spellcheck:"false",placeholder:t("cw_empty"),style:"min-height:45vh"});
ed.value=txt.replace(/\r\n/g,"\n");
var ok=h("button",{class:"ctl pri",text:t("sy_write"),onclick:function(){closeModal();doWriteConfig(cfgText(ed.value))}});
var ok=h("button",{class:"ctl pri",text:t("sy_write"),onclick:function(){closeModal();doWriteConfig(cfgText(ed.value),fromLog)}});
function refresh(){
var v=cfgText(ed.value),bytes=new Blob([v]).size;
var v=cfgText(ed.value),bytes=new Blob([v]).size,long=cfgLongLine(v);
var unknown=v.split("\n").filter(function(l){return l.trim()&&!isConfCmd(l.trim().replace(/\s+/g," "))});
info.textContent=t("cw_info",{n:bytes});
ok.disabled=bytes>2048;
ok.disabled=bytes>2048||!!long;
warn.style.color=ok.disabled?"var(--bad)":"var(--warn)";
warn.textContent=ok.disabled?t("cw_toolarge"):(unknown.length?t("cw_unknown")+unknown.join(" | "):"");
warn.textContent=bytes>2048?t("cw_toolarge"):long?t("cw_longline",long):(unknown.length?t("cw_unknown")+unknown.join(" | "):"");
}
ed.addEventListener("input",refresh);refresh();
modal(title,h("div",null,[info,warn,ed]),[h("button",{class:"ctl",text:t("c_cancel"),onclick:closeModal}),ok]);
@@ -1690,7 +1829,7 @@ function cfgText(txt){
txt=txt.replace(/\r\n/g,"\n");
return txt&&txt.slice(-1)!=="\n"?txt+"\n":txt;
}
function doWriteConfig(txt){
function doWriteConfig(txt,fromLog){
var form=new FormData();
form.append("configuration",new Blob([txt],{type:"application/octet-stream"}),"config.txt");
toast(t("cw_writing"));
@@ -1700,9 +1839,10 @@ function doWriteConfig(txt){
}).then(function(back){
back=back.replace(/\0[\s\S]*$/,"").replace(/\r\n/g,"\n").trim();
if(back!==txt.trim())throw new Error(t("cw_verify_fail"));
return api("/cmd_log_clear").catch(function(){});
}).then(function(){
setDirty(false);
if(!fromLog)return false;
return api("/cmd_log_clear").then(function(){return true},function(){return true});
}).then(function(cleared){
if(cleared)setDirty(false);
$("cfgedit").value=txt;cfgBytes();cfgParseKnown(txt);
toast(t("cw_saved"),"ok");
}).catch(function(e){toast(e.message||String(e),"err")});
@@ -1713,9 +1853,9 @@ $("saveBtn").addEventListener("click",function(){
getText("/config").catch(function(){return""}),
getText("/cmd_log").catch(function(){return""}),
]).then(function(r){
var cur=r[0].replace(/\0[\s\S]*$/,"");
var merged=mergeConf([],[cur,r[1].replace(/\0[\s\S]*$/,"")]);
writeConfig(merged.join("\n"),t("cw_save_title"));
var cur=r[0].replace(/\0[\s\S]*$/,"").split(/\r?\n/).map(function(l){return l.trim().replace(/\s+/g," ")}).filter(Boolean);
var merged=mergeConf(cur,[r[1].replace(/\0[\s\S]*$/,"")]);
writeConfig(merged.join("\n"),t("cw_save_title"),true);
});
});
+1
View File
@@ -396,6 +396,7 @@ button.danger{background:var(--bad);color:#fff;border-color:transparent}
<option value="en">English</option>
<option value="ja">日本語</option>
<option value="zh">中文</option>
<option value="es">Español</option>
</select></label>
<label class="row"><span class="lb" data-i18n="sy_theme">Theme</span>
<select class="in" id="themeSel">
+2 -1
View File
@@ -83,7 +83,8 @@ button:hover{filter:brightness(1.1)}
var L={
en:["Switch Login","RTLPlayground management interface","Password","Sign in","Wrong password, try again."],
ja:["スイッチ ログイン","RTLPlayground 管理インターフェース","パスワード","ログイン","パスワードが違います。もう一度お試しください。"],
zh:["交换机登录","RTLPlayground 管理界面","密码","登录","密码错误,请重试。"]
zh:["交换机登录","RTLPlayground 管理界面","密码","登录","密码错误,请重试。"],
es:["Inicio de sesión del switch","Interfaz de gestión de RTLPlayground","Contraseña","Iniciar sesión","Contraseña incorrecta, inténtalo de nuevo."]
};
var l=null;
try{l=localStorage.getItem("rtl_lang");}catch(e){}
+51 -26
View File
@@ -22,9 +22,9 @@
extern volatile __xdata uint8_t sfr_data[4];
extern volatile __xdata uint32_t ticks;
extern __xdata uint8_t cmd_capture; /* owned by rtlplayground.c, see write_char_no_syslog() */
extern __code uint8_t * __code hex;
extern __code struct f_data f_data[];
extern __code char * __code mime_strings[];
extern __code const uint8_t * __code const hex;
extern __code const struct f_data f_data[];
extern __code const char * __code const mime_strings[];
extern __xdata struct flash_region_t flash_region;
extern __xdata uint32_t flash_size;
@@ -127,7 +127,7 @@ uint8_t find_entry(__xdata uint8_t *e)
}
bool is_word(__xdata uint8_t *xdata_str_p, __code uint8_t * __xdata code_str_p)
bool is_word(__xdata uint8_t *xdata_str_p, __code const uint8_t * __xdata code_str_p)
{
uint8_t u, c;
@@ -149,7 +149,7 @@ bool is_word(__xdata uint8_t *xdata_str_p, __code uint8_t * __xdata code_str_p)
/* name must be lower-case, starting with the '\n' of the previous line's end */
__xdata uint8_t *header_value(__xdata uint8_t *p, __code uint8_t *name)
__xdata uint8_t *header_value(__xdata uint8_t *p, __code const uint8_t *name)
{
uint8_t u, c;
@@ -377,8 +377,8 @@ void gen_random_hex_chars(__xdata uint8_t * b, __xdata uint8_t bytes)
static uint8_t config_take(void)
{
// #386: needs static, otherwise it still lands in SRAM/DSEG
static __xdata uint16_t cfg_pos, cfg_hdr, cfg_body, cfg_end, cfg_last;
__xdata uint8_t cfg_bl;
static __xdata uint16_t cfg_pos, cfg_hdr, cfg_body, cfg_end, cfg_last, cfg_i;
__xdata uint8_t cfg_bl, cfg_run;
cfg_bl = strlen_x(boundary);
@@ -420,6 +420,13 @@ static uint8_t config_take(void)
// the payload plus its terminator must fit the sector
if (cfg_end - cfg_body + 1 > CONFIG_LEN)
return 2;
cfg_run = 0;
for (cfg_i = cfg_body; cfg_i < cfg_end; cfg_i++) {
if (config_buf[cfg_i] == '\n')
cfg_run = 0;
else if (++cfg_run >= CMD_BUF_SIZE - 1)
return 2;
}
config_buf[cfg_end] = 0;
flash_region.addr = CONFIG_START;
flash_sector_erase();
@@ -532,6 +539,19 @@ uint8_t stream_upload(void)
crc16_bank1(upload_settings.p + upload_settings.bptr);
flash_buf[write_len++] = upload_settings.p[upload_settings.bptr++];
if (write_len >= FLASH_PAGE_SIZE) {
/* The staged image spans FIRMWARE_UPLOAD_START to twice that,
* the span check_and_flash_update_image() reads back. Nothing
* else bounds uptr: a body whose closing boundary never arrives
* keeps writing, and on a flash exactly this size the address
* wraps onto the running image at zero. */
if (uptr >= (uint32_t)FIRMWARE_UPLOAD_START * 2) {
print_string("Upload runs past the image area! Aborting.\n");
slen = strtox(outbuf, "HTTP/1.1 400 Bad Request\r\nContent-Length: 30\r\n"
"Content-Type: text/plain\r\n\r\n"
"NO: upload exceeds image area\n");
s->tstate = TSTATE_NONE;
return 0;
}
dbg_string("len: "); dbg_short(write_len); dbg_char(' ');
dbg_string("CRC16: "); dbg_short(crc_value); dbg_char('\n');
if (uptr % FLASH_SECTOR_SIZE == 0) {
@@ -752,6 +772,10 @@ void handle_post(void)
return;
}
if (is_word(request_path, "upload")) {
if (!authenticated) {
send_unauthorized();
return;
}
if (flash_size < FIRMWARE_UPLOAD_START*2)
{
print_string("Flash too small for firmware upload!\n");
@@ -779,7 +803,23 @@ void handle_post(void)
dbg_string("Multipart request\n");
}
if (is_word(request_path, "cmd")) {
if (s->tstate == TSTATE_MULTIPART || is_word(request_path, "upload") || is_word(request_path, "config")) {
dbg_string("POST upload/config request\n");
if (!authenticated) {
send_unauthorized();
return;
}
if (!boundary[0]) {
dbg_string("Bad request, no boundary!\n");
send_bad_request();
return;
}
if (config_upload)
handle_config_fragment(p);
else
handle_firmware_fragment(p);
return;
} else if (is_word(request_path, "cmd")) {
p += 4;
if (!authenticated) {
send_unauthorized();
@@ -805,22 +845,6 @@ void handle_post(void)
return;
run_login_body(p);
return;
} else if (s->tstate == TSTATE_MULTIPART || is_word(request_path, "upload") || is_word(request_path, "config")) {
dbg_string("POST upload/config request\n");
if (!authenticated) {
send_unauthorized();
return;
}
if (!boundary[0]) {
dbg_string("Bad request, no boundary!\n");
send_bad_request();
return;
}
if (config_upload)
handle_config_fragment(p);
else
handle_firmware_fragment(p);
return;
} else {
send_not_found();
return;
@@ -907,8 +931,9 @@ void httpd_appcall(void)
reset_chip();
}
} else if (uip_newdata() && s->tstate == TSTATE_POST) {
// Check here maxupload by subtracting uip_len and close socekt if fails!
if (max_upload - uip_len > 0) {
if (config_upload || uip_len <= max_upload) {
if (!config_upload)
max_upload -= uip_len;
upload_settings.p = uip_appdata;
upload_settings.bptr = 0;
upload_settings.plen = uip_len;
+5 -5
View File
@@ -30,7 +30,7 @@ extern __xdata uint16_t slen;
extern __xdata uint16_t management_vlan;
extern __xdata uint16_t cont_len;
extern __xdata uint32_t cont_addr;
extern __code uint8_t * __code hex;
extern __code const uint8_t * __code const hex;
extern __xdata uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
extern __xdata uint8_t sfr_data[4];
@@ -47,8 +47,8 @@ extern __xdata char sfp_module_model[2][17];
extern __xdata char sfp_module_serial[2][17];
extern __xdata uint8_t sfp_options[2];
__code uint8_t * __code HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: application/json\r\n\r\n";
__code uint8_t * __code HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: text/plain\r\n\r\n";
__code const uint8_t * __code const HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: application/json\r\n\r\n";
__code const uint8_t * __code const HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: text/plain\r\n\r\n";
// Convert uint8_t to ascii HEX char push on html-buffer.
void charhex_to_html(char c)
@@ -127,7 +127,7 @@ void itoa16_html(uint16_t v) /* sufficient for VLAN IDs (max 4094) */
char_to_html('0' + (v % 10));
}
void string_to_html(__code char *s)
void string_to_html(__code const char *s)
{
while (*s) char_to_html(*s++);
}
@@ -1011,7 +1011,7 @@ void send_cmd_log(void)
__xdata uint8_t found_begin = 0;
dbg_string("History ptr: ");
dbg_short(cmd_history_ptr); dbg_char('\n');
while (p != cmd_history_ptr) {
while (p != cmd_history_ptr && slen < TCP_OUTBUF_SIZE) {
if (!cmd_history[p] || cmd_history[p] == '\n')
found_begin = 1;
if (found_begin && cmd_history[p])
+1 -1
View File
@@ -3,7 +3,7 @@
#include <stdbool.h>
extern __code uint8_t * __code HTTP_RESPONCE_TXT;
extern __code const uint8_t * __code const HTTP_RESPONCE_TXT;
bool send_counters(uint8_t phys_port);
void send_status(void);
+2 -2
View File
@@ -30,7 +30,7 @@
__xdata uint8_t buffer[0x1000];
__xdata uint8_t dio_enabled;
__code uint8_t * __code hex = "0123456789abcdef";
__code const uint8_t * __code const hex = "0123456789abcdef";
void isr_timer0(void) __interrupt(1)
{
@@ -67,7 +67,7 @@ void write_char(char c)
}
void print_string(__code char *p)
void print_string(__code const char *p)
{
while (*p)
write_char(*p++);
+104 -47
View File
@@ -5,6 +5,29 @@
#include "rtl837x_regs.h"
#include "rtl837x_common.h"
#define I2CBUS_INVALID (7)
// This is a MACRO to check if I2C_BUS_FROM_SDA_PIN or I2C_BUS_FROM_SCL_PIN don't return I2CBUS_INVALID.
// When I2CBUS_INVALID is returned, compiler stops with "machine.c:<line>: error 176: sizeof applied to an incomplete type"
#define I2CBUS_VALID(bus) (0 * sizeof(char[(bus) != I2CBUS_INVALID ? 1 : 0]))
#define I2CBUS(sda, scl) \
((uint8_t)((I2C_BUS_FROM_SCL_PIN(scl) << RTL837X_REG_I2C_SCL_SHIFT) | \
(I2C_BUS_FROM_SDA_PIN(sda) << RTL837X_REG_I2C_SDA_SHIFT) | \
I2CBUS_VALID(I2C_BUS_FROM_SCL_PIN(scl)) | \
I2CBUS_VALID(I2C_BUS_FROM_SDA_PIN(sda))))
#define I2C_BUS_FROM_SDA_PIN(sda_pin) \
((sda_pin) == GPIO47_I2C_SDA0 ? 0 : \
(sda_pin) == GPIO49_I2C_SDA1 ? 1 : \
(sda_pin) == GPIO51_I2C_SDA2_UART1_RX ? 2 : \
(sda_pin) == GPIO41_I2C_SDA3_MDIO1 ? 3 : \
(sda_pin) == GPIO39_I2C_SDA4 ? 4 : I2CBUS_INVALID)
#define I2C_BUS_FROM_SCL_PIN(scl_pin) \
((scl_pin) == GPIO46_I2C_SCL0 ? 0 : \
(scl_pin) == GPIO48_I2C_SCL1 ? 1 : \
(scl_pin) == GPIO50_I2C_SCL2_UART1_TX ? 2 : \
(scl_pin) == GPIO40_I2C_SCL3_MDC1 ? 3 : I2CBUS_INVALID)
#if defined(MACHINE_KP_9000_6XHML_X2) || \
defined(MACHINE_KP_9000_6XH_X2_V1_1) || \
defined(MACHINE_KP_9000_6XHML_X2_V1_1) || \
@@ -34,13 +57,13 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO10_LED10,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 0,
.sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
// Right SFP port (6)
.sfp_port[1].pin_detect = GPIO30_ACL_BIT3_EN,
.sfp_port[1].pin_los = GPIO37,
.sfp_port[1].pin_tx_disable = GPIO_NA,
.sfp_port[1].sds = 1,
.sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[1].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO54_ACL_BIT2_EN,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
@@ -70,7 +93,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
/* Conditions for LED on:
* dual led orange: ledset_0 & ledset_2
@@ -105,13 +128,13 @@ __code const struct machine machine = {
.sfp_port[0].pin_detect = GPIO38,
.sfp_port[0].pin_los = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
// Right SFP port
.sfp_port[1].pin_detect = GPIO37,
.sfp_port[1].pin_los = GPIO_NA,
.sfp_port[1].sds = 0,
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO48_I2C_SCL1, // Button-Switch is unpopulated on PCB, but can be added manually (hole in case is already there)
.high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 },
@@ -152,7 +175,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
@@ -177,7 +200,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO54_ACL_BIT2_EN,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1 },
@@ -227,7 +250,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_detect = GPIO38,
.sfp_port[0].pin_los = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO48_I2C_SCL1,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
@@ -265,13 +288,13 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO_NA,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 39 */
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), /* GPIO 39 */
// Right SFP port (J2)
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
.sfp_port[1].pin_los = GPIO_NA,
.sfp_port[1].pin_tx_disable = GPIO_NA,
.sfp_port[1].sds = 0,
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 40 */
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), /* GPIO 40 */
.reset_pin = GPIO54_ACL_BIT2_EN,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
@@ -306,13 +329,13 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 39 */
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), /* GPIO 39 */
// Right SFP port (J2)
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
.sfp_port[1].pin_los = GPIO51_I2C_SDA2_UART1_RX,
.sfp_port[1].pin_tx_disable = GPIO_NA,
.sfp_port[1].sds = 0,
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 40 */
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), /* GPIO 40 */
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
@@ -346,7 +369,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO_NA,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO48_I2C_SCL1,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
@@ -385,12 +408,12 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = 10,
.sfp_port[0].pin_tx_disable = 0xFF,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
.sfp_port[1].pin_detect = 30,
.sfp_port[1].pin_los = 51,
.sfp_port[1].pin_tx_disable = 0xFF,
.sfp_port[1].sds = 0,
.sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[1].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 , .enable = LED_27 | LED_29 },
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
@@ -425,7 +448,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO54_ACL_BIT2_EN,
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
@@ -458,7 +481,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO_NA, // no LOS pin wired
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO54_ACL_BIT2_EN,
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
@@ -499,7 +522,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO54_ACL_BIT2_EN,
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
@@ -531,7 +554,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0},
@@ -556,12 +579,12 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO50_I2C_SCL2_UART1_TX,
.sfp_port[0].pin_tx_disable = GPIO54_ACL_BIT2_EN,
.sfp_port[0].sds = 0,
.sfp_port[0].i2c = { .sda = GPIO47_I2C_SDA0, .scl = GPIO46_I2C_SCL0 },
.sfp_port[0].i2c = I2CBUS( GPIO47_I2C_SDA0, GPIO46_I2C_SCL0 ),
.sfp_port[1].pin_detect = GPIO36_PWM_OUT,
.sfp_port[1].pin_los = GPIO37,
.sfp_port[1].pin_tx_disable = GPIO51_I2C_SDA2_UART1_RX,
.sfp_port[1].sds = 1,
.sfp_port[1].i2c = { .sda = GPIO49_I2C_SDA1, .scl = GPIO48_I2C_SCL1 },
.sfp_port[1].i2c = I2CBUS( GPIO49_I2C_SDA1, GPIO48_I2C_SCL1 ),
.reset_pin = GPIO_NA,
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
.led_sets = {
@@ -596,13 +619,13 @@ __code const struct machine machine = {
.sfp_port[0].pin_detect = GPIO38,
.sfp_port[0].pin_los = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
// Right SFP port
.sfp_port[1].pin_detect = GPIO37,
.sfp_port[1].pin_los = GPIO_NA,
.sfp_port[1].sds = 0,
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 },
@@ -641,7 +664,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
@@ -676,7 +699,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO_NA,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO48_I2C_SCL1,
.high_leds = { .mux = LED_28_SYS, .enable = LED_27 | LED_28_SYS | LED_29 },
.led_mux_custom = 1,
@@ -720,14 +743,14 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
// Right SFP port (6)
// LED pin 24
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
.sfp_port[1].pin_los = GPIO51_I2C_SDA2_UART1_RX,
.sfp_port[1].pin_tx_disable = GPIO_NA,
.sfp_port[1].sds = 0,
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1},
@@ -769,11 +792,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = {
.sda = GPIO39_I2C_SDA4,
.scl = GPIO40_I2C_SCL3_MDC1
},
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.high_leds = {
@@ -823,14 +842,14 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
/* Right SFP (logical 3, SDS0): GPIO50=ModAbs, GPIO51=RX_LOS */
.sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX,
.sfp_port[1].pin_los = GPIO51_I2C_SDA2_UART1_RX,
.sfp_port[1].pin_tx_disable = GPIO_NA,
.sfp_port[1].sds = 0,
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
@@ -879,14 +898,14 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO_NA,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 0,
.sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
// SFP port on SDS1 / logical port 8
.sfp_port[1].pin_detect = GPIO38,
.sfp_port[1].pin_los = GPIO_NA,
.sfp_port[1].pin_tx_disable = GPIO_NA,
.sfp_port[1].sds = 1,
.sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[1].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 },
@@ -925,7 +944,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO_NA,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 },
@@ -968,7 +987,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 },
@@ -1049,13 +1068,13 @@ __code const struct machine machine = {
.sfp_port[0].pin_detect = GPIO38,
.sfp_port[0].pin_los = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
// Right SFP port
.sfp_port[1].pin_detect = GPIO37,
.sfp_port[1].pin_los = GPIO_NA,
.sfp_port[1].sds = 0,
.sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
@@ -1114,7 +1133,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO_NA,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = {0, 0, 0, 0, 0, 0, 0, 0, 1},
@@ -1160,10 +1179,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = {
.sda = GPIO39_I2C_SDA4,
.scl = GPIO40_I2C_SCL3_MDC1
},
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.high_leds = { .mux = 0, .enable = 0 },
@@ -1197,7 +1213,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
@@ -1241,7 +1257,7 @@ __code const struct machine machine = {
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
@@ -1309,6 +1325,47 @@ __code const struct machine machine = {
},
};
#elif defined MACHINE_F7008_2_5
__code const struct machine machine = {
.machine_name = "F7008-2.5 8+1 SFP Port Switch",
.isRTL8373 = 1,
.min_port = 0,
.max_port = 8,
.n_sfp = 1,
.log_to_phys_port = {1, 2, 3, 4, 5, 6, 7, 8, 9},
.phys_to_log_port = {0, 1, 2, 3, 4, 5, 6, 7, 8},
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
.sfp_port[0].pin_los = GPIO37,
.sfp_port[0].pin_tx_disable = GPIO_NA,
.sfp_port[0].sds = 1,
.sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ),
.reset_pin = GPIO_NA,
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
.port_led_set = {0, 0, 0, 0, 0, 0, 0, 0, 1},
.led_sets = {
{ /* SET0 */
LEDS_2G5 | LEDS_LINK, /* LEDID0 - green: 2.5G link */
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT, /* LEDID1 - yellow: traffic */
0,
0,
},
{ /* SET1 - SFP+ */
LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_LINK,
LEDS_10G | LEDS_5G | LEDS_2G5 | LEDS_1G | LEDS_LINK | LEDS_ACT,
0,
0,
},
},
.led_mux_custom = 1,
.led_mux = {
0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0c, 0x02,
0x0d, 0x10, 0x11, 0x02, 0x14, 0x02, 0x02, 0x15,
0x02, 0x02, 0x18, 0x02, 0x02, 0x19, 0x02, 0x02,
0x1c, 0x1d, 0x02, 0x02,
},
};
#else
#error "Please select a machine type in machine.h"
#endif
+2 -8
View File
@@ -48,13 +48,7 @@
// #define MACHINE_POE_2G080110GS
// #define MACHINE_PB_2132
// #define MACHINE_HASIVO_S600W_4GT_2XGT_SE
typedef struct {
// GPIO pins for SDA/SCL
uint8_t sda;
uint8_t scl;
} i2c_bus_t;
// #define MACHINE_F7008_2_5
#define LED_27 1
// SYSTEM LED
@@ -74,7 +68,7 @@ struct sfp_port
uint8_t pin_los; // gpio number 0-63, 0xFF = don't have it?
uint8_t pin_tx_disable; // gpio number 0-63, 0xFF = not present
uint8_t sds;
i2c_bus_t i2c;
uint8_t i2c;
};
struct machine {
+3 -3
View File
@@ -98,7 +98,7 @@ struct vlan_tag {
#define FIRMWARE_UPLOAD_START 0x80000
// Constants for the circular command buffer, the size must be 2^n
#define CMD_HISTORY_SIZE 0x400
#define CMD_HISTORY_SIZE 0x800
#define CMD_HISTORY_MASK (CMD_HISTORY_SIZE - 1)
enum sfp_speeds {
@@ -183,13 +183,13 @@ uint16_t strlen(__code const char *s);
uint16_t strcpy(__xdata uint8_t *dst, const char *s);
char strcmp(__xdata const uint8_t *a, __code const uint8_t *b);
#endif
void memcpyc(__xdata uint8_t *dst, __code uint8_t *src, uint16_t len);
void memcpyc(__xdata uint8_t *dst, __code const uint8_t *src, uint16_t len);
uint16_t strlen_x(__xdata const char *s);
uint16_t strtox(__xdata uint8_t *dst, __code const char *s);
bool strstart(__xdata const uint8_t *a, __code const uint8_t *b);
bool strstart_x(__xdata const uint8_t *a, __xdata const uint8_t *b);
void tcpip_output(void);
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
uint8_t read_flash(uint8_t bank, __code const uint8_t *addr);
void get_random_32(void);
void read_reg_timer(__xdata uint32_t * tmr);
bool gpio_pin_test(uint8_t pin);
+1 -1
View File
@@ -171,7 +171,7 @@ void flash_read_uid(void)
flash_configure_mmio();
}
__code char* get_flash_size_str(void)
__code const char* get_flash_size_str(void)
{
switch (flash_capacity_code) {
case 0x12: return "256 KB";
+1 -1
View File
@@ -19,7 +19,7 @@ void flash_read_security(void);
void flash_sector_erase(void);
void flash_read_bulk(__xdata uint8_t *dst);
void flash_write_bytes(__xdata uint8_t *ptr);
__code char* get_flash_size_str(void);
__code const char* get_flash_size_str(void);
#endif
+1 -1
View File
@@ -15,7 +15,7 @@
#include "rtl837x_igmp.h"
#include "machine.h"
extern __code struct machine machine;
extern __code const struct machine machine;
extern __xdata uint8_t igmpEnabled;
#include "uip.h"
+1 -1
View File
@@ -9,7 +9,7 @@
#include "boot.h"
extern __xdata uint8_t sfr_data[4];
extern __code struct machine machine;
extern __code const struct machine machine;
extern __xdata struct machine_runtime machine_detected;
#pragma codeseg BANK2
+4 -4
View File
@@ -15,7 +15,7 @@
#include "rtl837x_leds.h"
#include "machine.h"
extern __code struct machine machine;
extern __code const struct machine machine;
#include "uip.h"
@@ -261,7 +261,7 @@ void leds_setup(void) __banked
sfr_data[3] = sfr_data[2] = sfr_data[1] = sfr_data[0] = 0;
reg_write_m(RTL837X_REG_LED3_0_SET1);
reg_write_m(RTL837X_REG_LED3_0_SET3);
__code uint8_t * __xdata lptr = &machine.led_sets[0][0];
__code const uint8_t * __xdata lptr = &machine.led_sets[0][0];
for (__xdata uint8_t set = 0; set < 4; set++) {
sfr_data[0] = *(lptr + 5);
sfr_data[1] = *(lptr + 4);
@@ -275,7 +275,7 @@ void leds_setup(void) __banked
reg_write_m(RTL837X_REG_LED3_0_SET1);
} else {
reg_read_m(RTL837X_REG_LED3_0_SET3);
sfr_data[3 - (set << 1)] = (*(lptr + 6) << 4) | (*(lptr + 2));
sfr_data[3 - ((set - 2) << 1)] = (*(lptr + 6) << 4) | (*(lptr + 2));
reg_write_m(RTL837X_REG_LED3_0_SET3);
}
lptr += 8;
@@ -291,7 +291,7 @@ void leds_setup(void) __banked
reg_write_m(RTL837X_REG_LED3_0_SET1);
} else {
reg_read_m(RTL837X_REG_LED3_0_SET3);
sfr_data[2 - (set << 1)] = (*(lptr + 6) << 4) | (*(lptr + 2));
sfr_data[2 - ((set - 2) << 1)] = (*(lptr + 6) << 4) | (*(lptr + 2));
reg_write_m(RTL837X_REG_LED3_0_SET3);
}
lptr += 8;
+2 -2
View File
@@ -20,7 +20,7 @@
#pragma codeseg BANK2
#pragma constseg BANK2
extern __code uint16_t bit_mask[16];
extern __code const uint16_t bit_mask[16];
extern __code const struct machine machine;
extern __xdata struct machine_runtime machine_detected;
@@ -33,7 +33,7 @@ __xdata struct phy_settings phy_settings;
// Note: Adding `Swapping the RX for N-devices`-setting on the end of the array, didn't work.
// Setting will apply but still no packets flow.
// Settings are `0x2000, 0xc10c`,
__code uint16_t rtl8224_sds0_setttings[42] = {
__code const uint16_t rtl8224_sds0_setttings[42] = {
// SDS_DATA, SDS_CMD
0x4480, 0xc842,
0x0400, 0xc9c2,
+1 -34
View File
@@ -10,38 +10,6 @@ extern __xdata uint8_t sfr_data[4];
#pragma codeseg BANK2
#pragma constseg BANK2
uint8_t i2c_bus_from_sda_pin(uint8_t sda_pin) __banked {
switch (sda_pin) {
case GPIO47_I2C_SDA0:
return 0;
case GPIO49_I2C_SDA1:
return 1;
case GPIO51_I2C_SDA2_UART1_RX:
return 2;
case GPIO41_I2C_SDA3_MDIO1:
return 3;
case GPIO39_I2C_SDA4:
return 4;
default:
return 0xFF;
}
}
uint8_t i2c_bus_from_scl_pin(uint8_t scl_pin) __banked{
switch (scl_pin) {
case GPIO46_I2C_SCL0:
return 0;
case GPIO48_I2C_SCL1:
return 1;
case GPIO50_I2C_SCL2_UART1_TX:
return 2;
case GPIO40_I2C_SCL3_MDC1:
return 3;
default:
return 0xFF;
}
}
/* Returns RTL837X_REG_GPIO_XX_OUTPUT register address */
static uint16_t gpio_output_reg(uint8_t pin) __banked{
return pin < 32 ? RTL837X_REG_GPIO_00_31_OUTPUT : RTL837X_REG_GPIO_32_63_OUTPUT;
@@ -147,8 +115,7 @@ bool sfp_read_block(uint8_t slot, uint8_t reg, uint8_t len) __banked __reentrant
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00,
0x1 << (I2C_MEM_ADDR_WIDTH - 16) | len,
(dev >> 5) | i2c_bus_from_scl_pin(machine.sfp_port[slot].i2c.scl) << 5
| i2c_bus_from_sda_pin(machine.sfp_port[slot].i2c.sda) << 2,
(dev >> 5) | machine.sfp_port[slot].i2c,
((dev << 3) & 0xff) | 0x1);
do {
-6
View File
@@ -71,12 +71,6 @@
/* Not available GPIO */
#define GPIO_NA 0xFF
/* Convert SDA PIN GPIO to I2C bus number */
uint8_t i2c_bus_from_sda_pin(uint8_t sda_pin) __banked;
/* Convert SCL PIN GPIO to I2C bus number */
uint8_t i2c_bus_from_scl_pin(uint8_t scl_pin) __banked;
/*
* Setup a GPIO pin as input
* pin: GPIO pin number 0-63
+6 -6
View File
@@ -18,9 +18,9 @@
#pragma codeseg BANK1
#pragma constseg BANK1
extern __code uint8_t * __code hex;
extern __code uint16_t bit_mask[16];
extern __code struct machine machine;
extern __code const uint8_t * __code const hex;
extern __code const uint16_t bit_mask[16];
extern __code const struct machine machine;
extern __xdata uint8_t sfr_data[4];
extern __xdata uint16_t vlan_ptr;
extern __xdata uint8_t vlan_names[VLAN_NAMES_SIZE];
@@ -590,12 +590,12 @@ void port_eee_enable(__xdata uint8_t port,__xdata uint8_t speed) __banked
if (machine.is_sfp[port])
{
print_string("EEE can't be enabled for SFP port "); print_byte(port); print_string("\n");
print_string("EEE can't be enabled for SFP port "); print_phys_port(port); print_string("\n");
return;
}
REG_SET(RTL837X_EEE_CTRL_BASE + (port << 8), EEE_RX_ENABLE | EEE_TX_ENABLE);
print_string("EEE on for "); print_byte(port); print_string(" speed ");
print_string("EEE on for "); print_phys_port(port); print_string(" speed ");
// Enable all speeds up to the specified speed
if (speed & EEE_100) {
print_string("100m\n");
@@ -654,7 +654,7 @@ void port_eee_disable(uint8_t port) __banked
if (machine.is_sfp[port])
return;
print_string("EEE off for "); print_byte(port); write_char('\n');
print_string("EEE off for "); print_phys_port(port); write_char('\n');
REG_SET(RTL837X_EEE_CTRL_BASE + (port << 8), 0);
// Disable EEE advertisement for 100/1000BASE-T via EEE Advertisement Reg
phy_write(port, PHY_MMD_AN, PHY_EEE_ADV, 0);
+4
View File
@@ -126,6 +126,10 @@
#define RTL837X_REG_I2C_CTRL2 0x041c
#define RTL837X_REG_I2C_IN 0x0420
#define RTL837X_REG_I2C_OUT 0x0424
#define RTL837X_REG_I2C_SCL_SHIFT 5
#define RTL837X_REG_I2C_SDA_SHIFT 2
#define RTL837X_REG_I2C_SCL_MASK 0x3
#define RTL837X_REG_I2C_SDA_MASK 0x7
/*
* NIC Related registers
+2 -2
View File
@@ -22,7 +22,7 @@ extern __xdata uint8_t err_status;
#pragma codeseg BANK2
#pragma constseg BANK2
extern __code struct machine machine;
extern __code const struct machine machine;
extern __xdata uint8_t sfr_data[4];
extern __xdata struct machine_runtime machine_detected;
@@ -35,7 +35,7 @@ extern __xdata uint8_t cmd_buffer[CMD_BUF_SIZE];
extern __xdata uint8_t cmd_words_len;
extern __xdata uint8_t cmd_words_b[15];
extern __xdata char save_cmd; /* 0 while execute_config() replays the saved config */
uint8_t cmd_compare(uint8_t start, __code uint8_t * cmd);
uint8_t cmd_compare(uint8_t start, __code const uint8_t * cmd);
uint8_t atoi_byte(uint8_t idx);
uint8_t cmd_parse_port_separator(uint8_t idx);
extern __xdata uint8_t atoi_results_u8;
+35 -17
View File
@@ -79,9 +79,9 @@ void crc16_bank1(__xdata uint8_t *v) __naked;
__xdata uint8_t idle_ready;
__code uint8_t ownIP[] = { 192, 168, 2, 2 };
__code uint8_t gatewayIP[] = { 192, 168, 2, 22};
__code uint8_t netmask[] = { 255, 255, 255, 0};
__code const uint8_t ownIP[] = { 192, 168, 2, 2 };
__code const uint8_t gatewayIP[] = { 192, 168, 2, 22};
__code const uint8_t netmask[] = { 255, 255, 255, 0};
__xdata struct uip_eth_addr uip_ethaddr;
@@ -108,8 +108,8 @@ extern __xdata uint8_t gpio_last_value[8];
extern __xdata struct flash_region_t flash_region;
__code uint8_t * __code greeting = "\nA minimal prompt to explore the RTL8372:\n";
__code uint8_t * __code hex = "0123456789abcdef";
__code const uint8_t * __code const greeting = "\nA minimal prompt to explore the RTL8372:\n";
__code const uint8_t * __code const hex = "0123456789abcdef";
__xdata uint8_t flash_buf[FLASH_BUF_SIZE];
@@ -126,7 +126,7 @@ __xdata bool stp_enabled;
__xdata uint8_t igmpEnabled;
__xdata char hostname[24]; /* device hostname, default set at boot, see rtl837x_common.h */
__code uint16_t bit_mask[16] = {
__code const uint16_t bit_mask[16] = {
0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000
};
@@ -254,8 +254,19 @@ void write_char(char c)
write_char_no_syslog(c);
if (syslog_state.enabled) {
logbuf[syslog_state.writeptr++] = c;
syslog_state.writeptr &= (LOGBUF_SIZE - 1);
__xdata uint16_t next = (syslog_state.writeptr + 1) & (LOGBUF_SIZE - 1);
/* The ring is drained once per main loop pass, and a single command
* can print several times its size, so writing on regardless laps
* the reader and the datagram starts mid record. Drop instead, and
* flag a line so the reader empties what is there even if no
* newline has been seen yet. */
if (next == syslog_state.readptr) {
syslog_state.line_available = 1;
return;
}
logbuf[syslog_state.writeptr] = c;
syslog_state.writeptr = next;
if (c == '\n')
syslog_state.line_available = 1;
}
@@ -349,7 +360,7 @@ int memcmp(__xdata const void *a, __xdata const void *b, uint16_t len)
return 0;
}
void memcpyc(__xdata uint8_t *dst, __code uint8_t *src, uint16_t len)
void memcpyc(__xdata uint8_t *dst, __code const uint8_t *src, uint16_t len)
{
while (len--)
*dst++ = *src++;
@@ -785,7 +796,7 @@ void nic_tx_packet(uint16_t ring_ptr)
* Note that the address in the flash memory is not simply 0xbbaddr, because
* the size of a bank is merely 0xc000.
*/
uint8_t read_flash(uint8_t bank, __code uint8_t *addr)
uint8_t read_flash(uint8_t bank, __code const uint8_t *addr)
{
uint8_t v;
uint8_t current_bank = PSBANK;
@@ -973,14 +984,19 @@ void tcpip_output(void)
}
#define RX_BUDGET 4
void handle_rx(void)
{
// Check the amount of data available on the NIC/ASIC side
reg_read_m(RTL837X_REG_NIC_RX_BUFF_DATA);
if (sfr_data[2] != 0 || sfr_data[3] != 0) {
reg_read_m(RTL837X_REG_CPU_RX_CURR_PKT);
uint16_t ring_ptr = ((uint16_t)sfr_data[2]) << 8;
ring_ptr |= sfr_data[3];
__xdata uint8_t budget = RX_BUDGET;
while (budget--) {
// Check the amount of data available on the NIC/ASIC side
reg_read(RTL837X_REG_NIC_RX_BUFF_DATA);
if (!SFR_DATA_U16)
break;
reg_read(RTL837X_REG_CPU_RX_CURR_PKT);
uint16_t ring_ptr = SFR_DATA_U16;
ring_ptr <<= 3;
if (!nic_rx_header(ring_ptr)) {
REG_SET(RTL837X_REG_NIC_RXCMD, 1);
@@ -1157,7 +1173,9 @@ void handle_button(void)
//
void idle(void)
{
PCON |= 1;
reg_read(RTL837X_REG_NIC_RX_BUFF_DATA);
if (!SFR_DATA_U16)
PCON |= 1;
if (sec_counter >= SYS_TICK_HZ) {
sec_counter -= SYS_TICK_HZ;
reg_read_m(RTL837X_REG_SEC_COUNTER);
+14 -5
View File
@@ -20,6 +20,8 @@ extern __code const struct machine machine;
// SFP1 b0 = 1 => module missing, b1 = 1 => LOS;
// SFP2 b4 = 1 => module missing, b5 = 1 => LOS;
extern volatile __xdata uint32_t ticks;
__xdata uint8_t sfp_pins_last;
__xdata char sfp_module_vendor[2][17];
__xdata char sfp_module_model[2][17];
@@ -28,6 +30,8 @@ __xdata uint8_t sfp_options[2];
__xdata uint8_t sfp_buf[16]; /* scratch for one I2C transaction, the controller reads at most 16 bytes */
__xdata uint8_t sfp_speed[2];
__xdata uint8_t sfp_quirks[2];
__xdata uint8_t sfp_wake_at[2];
__xdata uint8_t sfp_wake_pending[2];
__code enum sfp_quirk {
@@ -35,12 +39,12 @@ __code enum sfp_quirk {
};
struct sfp_quirk_entry {
__code char *vendor; // Set vendor or model to 0 to act as wildcard
__code char *model;
__code const char *vendor; // Set vendor or model to 0 to act as wildcard
__code const char *model;
uint8_t quirks;
};
static __code struct sfp_quirk_entry sfp_quirk_table[] = {
static __code const struct sfp_quirk_entry sfp_quirk_table[] = {
{ "QSFPTEK", "QT-SFP+-T", SFP_QUIRK_DDM },
};
@@ -95,7 +99,7 @@ bool sfp_read_field(__xdata char *dst, uint8_t sfp, uint8_t start, uint8_t lengt
dst[i] = c;
}
while (length > 0 && dst[--length] == ' ')
while (length-- > 0 && (dst[length] == ' ' || dst[length] == NUL))
dst[length] = NUL;
return true;
@@ -157,7 +161,6 @@ static bool sfp_module_read(uint8_t sfp)
// Read Reg 11: Encoding, see SFF-8472 and SFF-8024
// Read Reg 12: Signalling rate (including overhead) in 100Mbit: 0xd: 1Gbit, 0x67:10Gbit
delay(100); // Delay, because some modules need time to wake up
if (!sfp_read_block(sfp, 11, 2))
return false;
@@ -199,6 +202,11 @@ void handle_sfp(void) __banked
if (sfp_pins_last & (0x1 << (sfp << 2))) {
sfp_pins_last &= ~(0x01 << (sfp << 2));
print_string("\n<MODULE INSERTED> Slot: "); write_char('1' + sfp);
sfp_wake_at[sfp] = ticks;
sfp_wake_pending[sfp] = 1;
} else if (sfp_wake_pending[sfp]
&& (uint8_t)((uint8_t)ticks - sfp_wake_at[sfp]) >= SFP_WAKE_TICKS) {
sfp_wake_pending[sfp] = 0;
if (!sfp_module_read(sfp)) {
print_string("SFP: an I2C read failed, retrying on the next poll\n");
sfp_pins_last |= 0x01 << (sfp << 2);
@@ -207,6 +215,7 @@ void handle_sfp(void) __banked
} else {
if (!(sfp_pins_last & (0x1 << (sfp << 2)))) {
sfp_pins_last |= 0x01 << (sfp << 2);
sfp_wake_pending[sfp] = 0;
print_string("\n<MODULE REMOVED> Slot: "); write_char('1' + sfp); write_char('\n');
}
}
+2
View File
@@ -1,6 +1,8 @@
#ifndef SFP_H
#define SFP_H
#define SFP_WAKE_TICKS 100
extern __xdata uint8_t sfp_pins_last;
extern __xdata char sfp_module_vendor[2][17];
extern __xdata char sfp_module_model[2][17];
+1 -1
View File
@@ -60,7 +60,7 @@ void syslog_stop(void) __banked
void syslog_callback(uint16_t lport) __banked
{
uint16_t syslog_hdr;
if (lport != state.syslog_conn->lport)
if (!state.syslog_conn || lport != state.syslog_conn->lport)
return;
if ((state.readptr != state.writeptr) && state.line_available)
+1 -1
View File
@@ -90,7 +90,7 @@ struct uip_eth_addr uip_ethaddr = { .addr = { 0x02, 0x11, 0x22, 0x33, 0x44, 0x55
/* ---- leaf calls into subsystems not under test ---- */
void flash_read_bulk(uint8_t *dst) { (void)dst; }
char *get_flash_size_str(void) { return (char *)"2M"; }
const char *get_flash_size_str(void) { return "2M"; }
uint8_t sfp_read_reg(uint8_t slot, uint8_t reg) { (void)slot; (void)reg; return 0; }
bool gpio_pin_test(uint8_t pin) { (void)pin; return false; }
void phy_read(uint8_t phy_id, uint8_t dev_id, uint16_t reg) { (void)phy_id; (void)dev_id; (void)reg; }
+1 -1
View File
@@ -5,7 +5,7 @@
#define FDATA_DEFS_H
#include <stdint.h>
typedef enum mime_type_e { mime_HTML = 0, mime_SVG, mime_ICO, mime_PNG, mime_JS, mime_CSS, mime_TXT } mime_type_t;
struct f_data { __code char *file; uint32_t start; uint16_t len; mime_type_t mime; uint8_t gzip; };
struct f_data { __code const char *file; uint32_t start; uint16_t len; mime_type_t mime; uint8_t gzip; };
#define FDATA_START_login_html 0x00040000UL
#define FDATA_START_favicon_ico 0x00041000UL
#endif
+6 -6
View File
@@ -67,18 +67,18 @@ volatile uint8_t sfr_data[4];
volatile uint32_t ticks;
uint8_t cmd_capture;
uint8_t err_status;
uint8_t *hex = (uint8_t *)"0123456789abcdef";
const uint8_t * const hex = (const uint8_t *)"0123456789abcdef";
uint16_t crc_value;
uint8_t *HTTP_RESPONCE_TXT = (uint8_t *)"HTTP/1.1 200 OK\r\n\r\n";
const uint8_t * const HTTP_RESPONCE_TXT = (const uint8_t *)"HTTP/1.1 200 OK\r\n\r\n";
uint32_t flash_size = 0x80000;
uint8_t flash_buf[FLASH_BUF_SIZE];
uint8_t rx_headers[16];
struct flash_region_t flash_region;
char *mime_strings[] = { "text/html", "image/svg+xml", "image/x-icon",
const char * const mime_strings[] = { "text/html", "image/svg+xml", "image/x-icon",
"image/png", "text/javascript", "text/css", "text/plain" };
struct f_data f_data[] = {
const struct f_data f_data[] = {
{ FILE_NAME, FILE_START, FILE_LEN, mime_HTML, 0 },
{ 0, 0, 0, mime_HTML, 0 },
};
@@ -92,7 +92,7 @@ void flash_read_bulk(uint8_t *dst)
void flash_init(uint8_t enable_dio) { (void)enable_dio; }
void flash_sector_erase(void) { }
void flash_write_bytes(uint8_t *ptr) { (void)ptr; }
char *get_flash_size_str(void) { return "512 kB"; }
const char *get_flash_size_str(void) { return "512 kB"; }
void crc16_bank1(uint8_t *v) { (void)v; }
void reset_chip(void) { }
void delay(uint16_t t) { (void)t; }
@@ -124,7 +124,7 @@ uint16_t strtox(uint8_t *dst, const char *s)
return n;
}
void memcpyc(uint8_t *dst, uint8_t *src, uint16_t len) { memcpy(dst, src, len); }
void memcpyc(uint8_t *dst, const uint8_t *src, uint16_t len) { memcpy(dst, src, len); }
bool strstart(const uint8_t *a, const uint8_t *b)
{
+3 -3
View File
@@ -318,7 +318,7 @@ int main(int argc, char **argv)
defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "#include <stdint.h>\n\n");
defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p,
"typedef enum mime_type_e {\n mime_HTML = 0,\n mime_SVG,\n mime_ICO,\n mime_PNG,\n mime_JS,\n mime_CSS,\n mime_TXT\n} mime_type_t;\n\n");
defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "struct f_data {\n __code char *file;\n uint32_t start;\n uint16_t len;\n mime_type_t mime;\n uint8_t gzip;\n};\n\n");
defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "struct f_data {\n __code const char *file;\n uint32_t start;\n uint16_t len;\n mime_type_t mime;\n uint8_t gzip;\n};\n\n");
// defbuf_p += snprintf(&dbuf[defbuf_p], DEF_SIZE - defbuf_p, "typedef uint16_t (* fcall_ptr)(void);\n\n");
ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, "// This file is automatically generated, do not edit!\n\n");
@@ -326,9 +326,9 @@ int main(int argc, char **argv)
ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, "#include \"%s.h\"\n\n", arguments.prefix);
if (arguments.bank)
ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, "#pragma codeseg %s\n#pragma constseg %s\n\n", arguments.bank, arguments.bank);
ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, " __code char * __code mime_strings[] = {\n \"text/html\",\n \"image/svg+xml\",\n"
ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, " __code const char * __code const mime_strings[] = {\n \"text/html\",\n \"image/svg+xml\",\n"
" \"image/svg+xml\",\n \"image/png\",\n \"text/javascript\",\n \"text/css\",\n \"text/plain\"};\n\n");
ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, "__code struct f_data f_data[] = {\n");
ibuf_p += snprintf(&ibuf[ibuf_p], INDEX_SIZE - ibuf_p, "__code const struct f_data f_data[] = {\n");
// fbuf_p += snprintf(&fbuf[fbuf_p], DEF_SIZE - fbuf_p, "\n__code fcall_ptr f_calls[] = {\n");
// Now that the beginning of the buffer is filled with out image, optionally resize the image
+2 -2
View File
@@ -912,8 +912,8 @@ __xdata struct uip_udp_conn *uip_udp_new(__xdata uip_ipaddr_t * __xdata ripaddr,
((__xdata u16_t *)addr1)[1] == ((__xdata u16_t *)addr2)[1])
#define uip_ipaddr_cmpx(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__xdata u16_t *)addr2)[0] && \
((__xdata u16_t *)addr1)[1] == ((__xdata u16_t *)addr2)[1])
#define uip_ipaddr_cmpc(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__code u16_t *)addr2)[0] && \
((__xdata u16_t *)addr1)[1] == ((__code u16_t *)addr2)[1])
#define uip_ipaddr_cmpc(addr1, addr2) (((__xdata u16_t *)addr1)[0] == ((__code const u16_t *)addr2)[0] && \
((__xdata u16_t *)addr1)[1] == ((__code const u16_t *)addr2)[1])
#else /* !UIP_CONF_IPV6 */
#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
#endif /* !UIP_CONF_IPV6 */