PCnet driver: fix ~10 Mbps download cap, bridged mode no-RX, multiple BSODs, and TX path inefficiencies#4
PCnet driver: fix ~10 Mbps download cap, bridged mode no-RX, multiple BSODs, and TX path inefficiencies#4Copilot wants to merge 20 commits into
Conversation
…line speed Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
…eGetActiveMediaInfo for PCnet-FAST III Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
…o CSR82 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
…ws 7 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
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 Upload root cause (6.95 Mbps): Download root cause (13.8 Mbps): The |
…iaInfo for all PCI variants Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
…ffers to 256 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
…W_64 from hardware init Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
…contiguous-memory BSOD Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
…before-TDMD, fix NDIS5 MAC options Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>
…in LanceSetupRegistersAndInit Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com>


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
LanceGetActiveMediaInfohard-codedLineSpeed = 10in 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.Also extended the
OID_GEN_LINK_SPEEDhandler to callLanceGetActiveMediaInfofor all PCI variants (DeviceType != LANCE), not onlyPCNET_PCI3. PreviouslyPCNET_PCI1/PCNET_PCI2_B2permanently returnedLineSpeed = LINESPEED_DEFAULT = 10.Bridged mode: zero receive descriptors after first multicast filter update (
RLen/TLenoverflow)LanceSetupRegistersAndInitis called at init and on every multicast filter change (LanceChangeAddress → LanceInit).RLen/TLeninLANCE_INIT_BLOCK_HIareUCHARfields accumulated with+=. With 256-entry rings,log2(256) × 0x10 = 0x80; on the second call0x80 + 0x80 = 0x100overflows to0x00→ RLEN=0 → chip initialized with 1 receive descriptor → broadcast flood in bridged mode fills it immediately → RINT never fires.Contiguous DMA allocation failure → pool corruption BSODs (0x19 / 0xC5)
A single
NdisMAllocateSharedMemoryfor 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).Hardware register optimizations
BCR18 |= LANCE_BCR18_LINBC (0x0800)CSR82 ← Adapter->BusTimerCSR4 |= LANCE_CSR4_TXSTRTMAPAD_XMT/DXSUFLO/DMAPLUSCSR4 &= ~LANCE_CSR4_DPOLLCSR80 = LANCE_CSR80_XMTSP_6480, 0x0800with named constantsNot applied (documented as unsafe):
LAPPEN(CSR3): VirtualBox always presents complete frames; split-DMA state machine stalls after some framesRCVFW_64 = 0x2000: RCVFW field is at CSR80 bits 9:8 (=0x0200), not bits 13:12 — bit 13 is reservedTOKINTD(CSR5): suppressesCSR0_TINT, which is the only signal that triggersXmitComplete; TX ring starves after 256 packetsTX send path
LanceMovePacketcall (was causing an extraNdisQueryPacket+ buffer-chain traversal per outbound packet)Bufferstruct setup (leftover from commented-outNdisFlushBuffer)CSR4_APAD_XMThandles short frames in hardwareLanceReadCsr(CSR0) → mask → LanceWriteCsr(CSR0|TDMD)with directLanceWriteCsr(IENA|TDMD)— saves one VM exit per sendMAX_SEND_PACKETS: 4 → 64NDIS attributes (
NdisMSetAttributes)Reverted
NdisMSetAttributesExwithIGNORE_REQUEST_TIMEOUT | IGNORE_PACKET_TIMEOUT | NO_HALT_ON_SUSPENDback toNdisMSetAttributes(..., TRUE, NdisInterfacePci). The extended flags caused pool corruption (0x19/0xC5BSODs) via Windows 7 NDIS5 compat shim internal state machine interaction.Debug logging (
#if DBG)Added verbose
DbgPrintcoverage for: chunk alloc success/failure,LanceGetActiveMediaInfofinal LineSpeed/FullDuplex,OID_GEN_LINK_SPEEDreturn value,BABL/MERR/CERR/MISSinterrupt flags, TX ring full (with Next/Tail indices), andXmitCompleteentry. High-frequency OID polling logs gated behind newLanceQueryDbgflag (separate fromLanceDbg) to avoid flooding output during speed tests.Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.