Skip to content

PCnet driver: fix ~10 Mbps download cap, bridged mode no-RX, multiple BSODs, and TX path inefficiencies#4

Draft
Copilot wants to merge 20 commits into
mainfrom
copilot/fix-slow-speed-test
Draft

PCnet driver: fix ~10 Mbps download cap, bridged mode no-RX, multiple BSODs, and TX path inefficiencies#4
Copilot wants to merge 20 commits into
mainfrom
copilot/fix-slow-speed-test

Conversation

Copy link
Copy Markdown

Copilot AI commented Feb 21, 2026

Driver produced ~9.88 Mbps down / ~117 Mbps up against a 343/373 Mbps ISP connection. Bridged adapter mode received no traffic at all. Several regressions introduced and fixed along the way.


Root causes fixed

Line speed reported as 10 Mbps → TCP receive window too small

LanceGetActiveMediaInfo hard-coded LineSpeed = 10 in its no-external-PHY else branch (VirtualBox never exposes MII registers). Windows NT/7 TCP stack sizes its receive window against this value, capping download at ~10 Mbps regardless of link capacity.

// lance.c — LanceGetActiveMediaInfo(), no-external-PHY else branch
- Adapter->LineSpeed = 10;
+ Adapter->LineSpeed = 100;  // PCnet-FAST III is a 100 Mbps chip

Also extended the OID_GEN_LINK_SPEED handler to call LanceGetActiveMediaInfo for all PCI variants (DeviceType != LANCE), not only PCNET_PCI3. Previously PCNET_PCI1/PCNET_PCI2_B2 permanently returned LineSpeed = LINESPEED_DEFAULT = 10.

Bridged mode: zero receive descriptors after first multicast filter update (RLen/TLen overflow)

LanceSetupRegistersAndInit is called at init and on every multicast filter change (LanceChangeAddress → LanceInit). RLen/TLen in LANCE_INIT_BLOCK_HI are UCHAR fields accumulated with +=. With 256-entry rings, log2(256) × 0x10 = 0x80; on the second call 0x80 + 0x80 = 0x100 overflows to 0x00 → RLEN=0 → chip initialized with 1 receive descriptor → broadcast flood in bridged mode fills it immediately → RINT never fires.

// lance.c — LanceSetupRegistersAndInit(), SW_STYLE_2 path
+ InitializationBlockHi->RLen = 0;   // must zero before accumulation; re-entrant
  for (...) InitializationBlockHi->RLen += BUFFER_LENGTH_EXPONENT_H;
+ InitializationBlockHi->TLen = 0;
  for (...) InitializationBlockHi->TLen += BUFFER_LENGTH_EXPONENT_H;

Contiguous DMA allocation failure → pool corruption BSODs (0x19 / 0xC5)

A single NdisMAllocateSharedMemory for 256 × 1536 × 2 ≈ 768 KB of physically contiguous cached memory cannot be reliably satisfied on a running Windows 7 system. The PCnet hardware does not require buffers to be globally contiguous — each descriptor independently holds its own buffer PA. Switched to chunk-based allocation: 8 TX + 8 RX chunks of 32 buffers each (48 KB/chunk, always satisfiable).

#define ALLOC_CHUNK_BUFFERS   32   // buffers per NdisMAllocateSharedMemory call
#define TX_CHUNK_COUNT         8   // 8 × 32 = 256 TX slots
#define RX_CHUNK_COUNT         8
// VA/PA resolved at descriptor level via TX_BUFFER_VA(i) / RX_BUFFER_PA(i) macros

Hardware register optimizations

Change Effect
BCR18 |= LANCE_BCR18_LINBC (0x0800) 8-DWORD DMA burst; was 1-DWORD (re-arbitrates PCI bus per 4 bytes)
CSR82 ← Adapter->BusTimer BusTimer was computed but never written to hardware
CSR4 |= LANCE_CSR4_TXSTRTM Masks per-frame TX-start interrupt; already had APAD_XMT/DXSUFLO/DMAPLUS
CSR4 &= ~LANCE_CSR4_DPOLL VirtualBox auto-polls TX after every received frame; DPOLL=0 enables inline post-RX TX dispatch
CSR80 = LANCE_CSR80_XMTSP_64 Replaced magic number 80, 0x0800 with named constants

Not applied (documented as unsafe):

  • LAPPEN (CSR3): VirtualBox always presents complete frames; split-DMA state machine stalls after some frames
  • RCVFW_64 = 0x2000: RCVFW field is at CSR80 bits 9:8 (= 0x0200), not bits 13:12 — bit 13 is reserved
  • TOKINTD (CSR5): suppresses CSR0_TINT, which is the only signal that triggers XmitComplete; TX ring starves after 256 packets

TX send path

  • Eliminated redundant 6-byte-only LanceMovePacket call (was causing an extra NdisQueryPacket + buffer-chain traversal per outbound packet)
  • Removed dead 8-field Buffer struct setup (leftover from commented-out NdisFlushBuffer)
  • Removed hardware min-size padding if/else — CSR4_APAD_XMT handles short frames in hardware
  • Replaced LanceReadCsr(CSR0) → mask → LanceWriteCsr(CSR0|TDMD) with direct LanceWriteCsr(IENA|TDMD) — saves one VM exit per send
  • MAX_SEND_PACKETS: 4 → 64

NDIS attributes (NdisMSetAttributes)

Reverted NdisMSetAttributesEx with IGNORE_REQUEST_TIMEOUT | IGNORE_PACKET_TIMEOUT | NO_HALT_ON_SUSPEND back to NdisMSetAttributes(..., TRUE, NdisInterfacePci). The extended flags caused pool corruption (0x19/0xC5 BSODs) via Windows 7 NDIS5 compat shim internal state machine interaction.


Debug logging (#if DBG)

Added verbose DbgPrint coverage for: chunk alloc success/failure, LanceGetActiveMediaInfo final LineSpeed/FullDuplex, OID_GEN_LINK_SPEED return value, BABL/MERR/CERR/MISS interrupt flags, TX ring full (with Next/Tail indices), and XmitComplete entry. High-frequency OID polling logs gated behind new LanceQueryDbg flag (separate from LanceDbg) to avoid flooding output during speed tests.

Original prompt

This section details on the original issue you should resolve

<issue_title>Fix slow download and upload speed test</issue_title>
<issue_description>Fix the slow download and upload speed test that is being shown according to this screenshot:

Image</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

…line speed

Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix slow download and upload speed test Fix throughput bottlenecks causing ~10 Mbps download and ~117 Mbps upload on a 100 Mbps+ link Feb 21, 2026
Copilot AI requested a review from Zero3K20 February 21, 2026 19:57
…eGetActiveMediaInfo for PCnet-FAST III

Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Copilot AI changed the title Fix throughput bottlenecks causing ~10 Mbps download and ~117 Mbps upload on a 100 Mbps+ link Fix PCnet-FAST III download speed and restore connectivity for 10 Mbps adapters Feb 21, 2026
…o CSR82

Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Copilot AI changed the title Fix PCnet-FAST III download speed and restore connectivity for 10 Mbps adapters Fix PCnet driver throughput: correct 100 Mbps line speed reporting, increase ring buffers, optimize DMA burst Feb 21, 2026
@Zero3K20
Copy link
Copy Markdown
Owner

@copilot A different speed test is also slow. Here's what it shows under a Windows 7 VM:

image

Here's the same test done under the actual Windows 7 OS:

image

…ws 7

Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Copy link
Copy Markdown
Author

Copilot AI commented Feb 21, 2026

@copilot A different speed test is also slow. Here's what it shows under a Windows 7 VM:

<img width="1920" height="1080" alt="image" src="https://github.com/user-attachments/assets/18a669b8-e2ce-4f...

Two separate issues are at play here:

Why speeds are still slow in the VM: The source code changes in this PR need to be compiled into a new pcntn5m.sys binary and installed in the VM to take effect. The pre-compiled binary in the install/ folder hasn't been rebuilt yet.

Upload root cause (6.95 Mbps): MAX_SEND_PACKETS = 4 told NDIS to batch only 4 packets per LanceSendPackets call. On Windows 7's NDIS5 compatibility shim, the per-call serialization overhead is much higher than on NT 4.0. At 100 Mbps with 1514-byte packets, 4 packets/call means ~2000 calls/second — the call overhead alone caps upload well below the link speed. Fixed in commit 655878b by increasing MAX_SEND_PACKETS from 4 to 64, reducing call frequency ~16× for equivalent throughput.

Download root cause (13.8 Mbps): The LanceGetActiveMediaInfo fix (LineSpeed = 100 for PCnet-FAST III when no external PHY is detected — commit fcfee28) corrects the TCP receive window sizing. Once the driver is compiled and installed, download should improve significantly.

Copilot AI changed the title Fix PCnet driver throughput: correct 100 Mbps line speed reporting, increase ring buffers, optimize DMA burst Fix PCnet driver throughput: correct 100 Mbps line speed reporting, increase ring buffers, optimize DMA burst, increase send batch size Feb 21, 2026
…iaInfo for all PCI variants

Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Copilot AI changed the title Fix PCnet driver throughput: correct 100 Mbps line speed reporting, increase ring buffers, optimize DMA burst, increase send batch size Fix PCnet driver throughput: correct link speed reporting, larger ring buffers, DMA burst optimization Feb 21, 2026
…ffers to 256

Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Copilot AI changed the title Fix PCnet driver throughput: correct link speed reporting, larger ring buffers, DMA burst optimization Fix PCnet driver throughput: correct link speed reporting, deeper ring buffers, DMA/NDIS5 optimizations Feb 21, 2026
Copilot AI changed the title Fix PCnet driver throughput: correct link speed reporting, deepen ring buffers, optimize DMA and TX path PCnet NDIS5 driver: fix throughput (9.88→~100 Mbps download), eliminate BSODs, optimize hot paths Feb 21, 2026
…W_64 from hardware init

Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Copilot AI changed the title PCnet NDIS5 driver: fix throughput (9.88→~100 Mbps download), eliminate BSODs, optimize hot paths PCnet NDIS5: fix ~10 Mbps download cap, BSODs, TX stalls, and post-activity hang Feb 22, 2026
…contiguous-memory BSOD

Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Copilot AI changed the title PCnet NDIS5: fix ~10 Mbps download cap, BSODs, TX stalls, and post-activity hang PCnet: Fix ~10 Mbps download cap and low upload; 256-entry rings via chunk DMA allocation Feb 22, 2026
Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Copilot AI changed the title PCnet: Fix ~10 Mbps download cap and low upload; 256-entry rings via chunk DMA allocation PCnet: Fix TX ring starvation, slow throughput, pool-corruption BSODs, and site timeouts Feb 23, 2026
Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Copilot AI changed the title PCnet: Fix TX ring starvation, slow throughput, pool-corruption BSODs, and site timeouts Fix PCnet driver throughput: 100 Mbps line speed, 256-entry chunked DMA rings, TX path optimization, debug logging Feb 23, 2026
Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Copilot AI changed the title Fix PCnet driver throughput: 100 Mbps line speed, 256-entry chunked DMA rings, TX path optimization, debug logging PCnet driver: fix 9.88 Mbps download, 6.95 Mbps upload, and two pool-corruption BSODs on Windows 7 Feb 23, 2026
…before-TDMD, fix NDIS5 MAC options

Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Copilot AI changed the title PCnet driver: fix 9.88 Mbps download, 6.95 Mbps upload, and two pool-corruption BSODs on Windows 7 PCnet: fix ~10 Mbps download cap, pool-corruption BSODs, TX ring starvation, and VirtualBox VM-exit overhead Feb 23, 2026
…in LanceSetupRegistersAndInit

Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Copilot AI changed the title PCnet: fix ~10 Mbps download cap, pool-corruption BSODs, TX ring starvation, and VirtualBox VM-exit overhead PCnet driver: fix ~10 Mbps download cap, bridged mode no-RX, multiple BSODs, and TX path inefficiencies Feb 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix slow download and upload speed test

2 participants