drivers/i8255x: get to work on a real device #725

Merged
Burer merged 4 commits from i8255x-tx-reclaim into main 2026-09-29 19:03:25 +00:00
Contributor
  • the TX reclaim loop in int_handler multiplied sizeof.txfd by itself (mul eax) instead of by last_tx, so it looked 1024 bytes past tx_ring and never freed a descriptor
  • it also left txfd.status set, and transmit treats a non-zero status as busy, so once the 16-entry ring wrapped every send ended in "TX overrun": DHCP fell back to link-local, ping showed "Socket error", while the link still read as connected
  • reclaim only descriptors the device completed (TXFD_STATUS_C) and zero their status; transmit now checks for an unreclaimed buffer (virt_addr)

Seen on an EtherExpress Pro/100 in a Pentium II. Reproduced in QEMU (-cpu pentium2, i82557b): ping stopped at the 12th reply every time; with the fix it runs indefinitely, also under a UDP flood.

- the TX reclaim loop in int_handler multiplied sizeof.txfd by itself (mul eax) instead of by last_tx, so it looked 1024 bytes past tx_ring and never freed a descriptor - it also left txfd.status set, and transmit treats a non-zero status as busy, so once the 16-entry ring wrapped every send ended in "TX overrun": DHCP fell back to link-local, ping showed "Socket error", while the link still read as connected - reclaim only descriptors the device completed (TXFD_STATUS_C) and zero their status; transmit now checks for an unreclaimed buffer (virt_addr) Seen on an EtherExpress Pro/100 in a Pentium II. Reproduced in QEMU (-cpu pentium2, i82557b): ping stopped at the 12th reply every time; with the fix it runs indefinitely, also under a UDP flood.
CODEOWNERS rules requested review from system 2026-09-26 17:48:34 +00:00
CODEOWNERS rules requested review from network 2026-09-26 17:48:34 +00:00
Leency requested review from hidnplayr 2026-09-26 17:48:48 +00:00
Leency marked the pull request as work in progress 2026-09-26 23:57:27 +00:00
Leency changed title from WIP: drivers/i8255x: reclaim sent TX descriptors, network died after 16 packets to drivers/i8255x: get to work on a real device 2026-09-27 10:52:12 +00:00
hidnplayr approved these changes 2026-09-28 10:49:44 +00:00
Burer approved these changes 2026-09-29 13:09:34 +00:00
Dismissed
Burer left a comment
Owner

Must fix:

  1. init_tx_ring doesn't clear txfd.virt_addr. After a reset with unreclaimed frames, transmit reports "TX overrun" forever. NetFree or zero it in .next_desc.
  2. DEBUGF 2 is errors-only. Move "Command ... done" and "Restarting receiver" to level 1, and drop "Out of resources!" (now handled).

Nits:

  • confcmd_wait waits ~100 ms, not 1 s (udelay = Sleep(1)).
  • .out_of_mem still counts the dropped frame in packets_rx/bytes_rx.
Must fix: 1. `init_tx_ring` doesn't clear `txfd.virt_addr`. After a reset with unreclaimed frames, `transmit` reports "TX overrun" forever. `NetFree` or zero it in `.next_desc`. 2. `DEBUGF 2` is errors-only. Move "Command ... done" and "Restarting receiver" to level 1, and drop "Out of resources!" (now handled). Nits: - `confcmd_wait` waits ~100 ms, not 1 s (`udelay` = `Sleep(1)`). - `.out_of_mem` still counts the dropped frame in `packets_rx`/`bytes_rx`.
Burer requested changes 2026-09-29 13:10:02 +00:00
Dismissed
Burer left a comment
Owner

See comment above.

See comment above.
CODEOWNERS rules requested review from system 2026-09-29 16:10:25 +00:00
CODEOWNERS rules requested review from network 2026-09-29 16:10:25 +00:00
Burer approved these changes 2026-09-29 18:11:06 +00:00
Burer added 4 commits 2026-09-29 18:59:51 +00:00
- the TX reclaim loop in int_handler multiplied sizeof.txfd by itself
  (mul eax) instead of by last_tx, so it looked 1024 bytes past tx_ring
  and never freed a descriptor
- it also left txfd.status set, and transmit treats a non-zero status
  as busy, so once the 16-entry ring wrapped every send ended in
  "TX overrun": DHCP fell back to link-local, ping showed "Socket error",
  while the link still read as connected
- reclaim only descriptors the device completed (TXFD_STATUS_C) and zero
  their status; transmit now checks for an unreclaimed buffer (virt_addr)

Seen on an EtherExpress Pro/100 in a Pentium II. Reproduced in QEMU
(-cpu pentium2, i82557b): ping stopped at the 12th reply every time;
with the fix it runs indefinitely, also under a UDP flood.

Assisted-by: Claude Opus 5 <noreply@anthropic.com>
The driver keeps a single RFD and re-armed the receive unit only after
taking a frame (FR). A frame arriving before that left the RU in No
Resources, and on the RNR interrupt the driver just printed "Out of
resources!": on an EtherExpress Pro/100 in a Pentium II every DHCP
answer was dropped this way.

- handle RNR like FR, and after the RX loop re-arm the RFD whenever the
  RU is not Ready (once per interrupt, marked in reserved bit 0 of the
  saved status, so a device that never gets Ready cannot loop us)
- set the RBD address to 0xFFFFFFFF, as simplified mode wants; it held
  whatever the net buffer had
- without a new buffer, drop the frame and reuse the RFD: the buffer was
  handed to the stack while the RFD still pointed at it

QEMU never enters No Resources; the restart path was exercised with a
build that skips the normal RX_START (38 restarts, DHCP and ping fine).
On the Pentium II the log shows "Restarting receiver, RU status 08".

Assisted-by: Claude Opus 5 <noreply@anthropic.com>
reset() gives the chip Individual Address Setup and then Configure in
the same confcmd block, waiting in between only for the SCB to accept
the command (cmd_wait). A real chip had not read the MAC yet when the
Configure data overwrote it, so our address never reached the filter:
broadcasts came in, frames sent to us (DHCP offer, ARP reply, TCP) were
dropped - "connected", yet nothing worked. QEMU executes at once and
never showed it.

- confcmd_wait: poll the C bit of confcmd (up to 1 s) after both
  commands and log the result; the Pentium II now logs
  "Command 0x4001 done, status 0xA000" and gets its DHCP lease
- transmit: CU_START is only valid while the CU is idle or suspended,
  so wait for the previous frame to leave before starting the next

Assisted-by: Claude Opus 5 <noreply@anthropic.com>
drivers/i8255x: address review of #725
Test PR / Build (es_ES) (pull_request) Successful in 2m56s
Test PR / Build (en_US) (pull_request) Successful in 2m59s
Test PR / Build (ru_RU) (pull_request) Successful in 3m2s
fa87fa33e3
- init_tx_ring frees and clears txfd.virt_addr: after a reset with frames
  still unreclaimed, transmit took the descriptor as busy and reported
  "TX overrun" forever; init_rx_ring frees the RFD of an earlier reset
- "Command ... done" and "Restarting receiver" go to debug level 1, level
  2 is for errors; "Out of resources!" is dropped, the RU is re-armed now
- confcmd_wait: udelay is Sleep(1) = 1 ms, so 1000 rounds for the 1 s the
  comment promises (it waited 100 ms)
- a frame dropped for want of a buffer is taken back out of packets_rx /
  bytes_rx and counted in packets_rx_drop

Checked in QEMU on i82557a, i82558b, i82559c: DHCP, ping under a UDP flood.

Assisted-by: Claude Opus 5 <noreply@anthropic.com>
Burer force-pushed i8255x-tx-reclaim from 3479361723 to fa87fa33e3 2026-09-29 18:59:51 +00:00 Compare
Burer merged commit 9ec66b0eba into main 2026-09-29 19:03:25 +00:00
Burer deleted branch i8255x-tx-reclaim 2026-09-29 19:03:25 +00:00
Sign in to join this conversation.
No Reviewers
KolibriOS/system
KolibriOS/network
No labels
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: KolibriOS/kolibrios#725