K4sum1 Posted February 16 Posted February 16 Sorry for hijacking the thread for this, but @Dietmar you have messages disabled and idk where else to ask. I found this post trying to find X300 drivers for my R52 (rebranded T43 afaik) and I noticed you have all the drivers. Do you think you can give me those drivers pls? https://winraid.level1techs.com/t/how-to-install-win98-onto-a-thinkpad-t43/34539
Damnation Posted February 16 Posted February 16 @Dietmar Sorry for my late reply. My NIC deviceID is PCI\VEN_10EC&DEV_8125&CC_0200 I'm using an ASRock B550 Steel Legend.
Dietmar Posted February 16 Posted February 16 (edited) How to switch from Polling mode to legacy IRQ for the i219 lan driver under XP SP3 1) MSI/MSI-X must be OFF on XP → force legacy INTx On PCIe NICs (like Intel i219), the device can deliver interrupts either via MSI/MSI-X (message writes) or via legacy INTx (asserting the interrupt pin). For Windows XP / NDIS 5.1, the safest path is: MSI=OFF, MSI-X=OFF, INTx allowed. If MSI/MSI-X stays enabled, XP may never get a working line-based interrupt even if you “see IRQ resources”. How to do it (PCI configuration space): A) Find MSI / MSI-X capability blocks - Walk the PCI “Capabilities List” (linked list) in config space until you find: - Capability ID 0x05 = MSI - Capability ID 0x11 = MSI-X B) Disable MSI (CapID 0x05) - In the MSI capability structure, clear the “MSI Enable” bit in the MSI Message Control register: - MSI Enable = 0 C) Disable MSI-X (CapID 0x11) - In the MSI-X capability structure, clear the “MSI-X Enable” bit in the MSI-X Message Control register: - MSI-X Enable = 0 D) Ensure INTx is not blocked by PCI Command (offset 0x04) - Set the basic required bits: - Memory Space Enable = 1 (MMIO BAR works) - Bus Master Enable = 1 (DMA works) - And the critical INTx kill-switch must be OFF: - Interrupt Disable (bit 10) = 0 If bit 10 is 1, INTx is blocked even if everything else is correct. Resulting goal state for XP: - MSI Enable = 0 - MSI-X Enable = 0 - PCI Command.IntDisable(bit10) = 0 - PCI Command.MEM=1 and BusMaster=1 2) Fixing NdisMRegisterInterrupt returning STATUS_UNSUCCESSFUL = 0xC0000001 If NdisMRegisterInterrupt(...) returns 0xC0000001 (STATUS_UNSUCCESSFUL), a very common XP/NDIS 5.1 mistake is passing the “wrong kind” of interrupt vector/level. The core rule (this was the real breakthrough): Call NdisMRegisterInterrupt using BUS-relative values from AllocatedResources, NOT translated/system values from TranslatedResources. Why this matters: NDIS does not want you to pre-map vectors. Internally, NdisMRegisterInterrupt performs the mapping itself: - it calls HalGetInterruptVector(...) to translate BUS vector/level → SYSTEM vector/IRQL - then it calls IoConnectInterrupt(...) to connect the ISR So if the miniport passes already-translated numbers (system vector/IRQL), the mapping path can break and you get 0xC0000001. What you must do in the driver (procedure): A) Retrieve both resource lists via NdisMGetDeviceProperty(...) - AllocatedResources → BUS-relative IRQ info (USE THIS for NdisMRegisterInterrupt) - TranslatedResources → SYSTEM-translated IRQ info (LOG/DIAG only) B) In AllocatedResources, locate the descriptor: - Type == CmResourceTypeInterrupt C) Pass exactly these BUS values into NdisMRegisterInterrupt: - InterruptLevel = AllocatedResources.Interrupt.Level - InterruptVector = AllocatedResources.Interrupt.Vector D) Derive “shared” and “mode” from the descriptor: - If ShareDisposition is shared, set: - SharedInterrupt = TRUE - If flags indicate latched vs level-sensitive, pass matching mode: - Latched → NdisInterruptLatched - otherwise → NdisInterruptLevelSensitive Concrete example (typical IOAPIC case, exactly what we saw on i219): - AllocatedResources (BUS): level=16 vector=16 - TranslatedResources (SYSTEM): level=5 vector=865 (and you might see an “XP vector” like 97) Correct behavior was: - NdisMRegisterInterrupt try=BUS lvl=16 vec=16 ... → 0x00000000 Wrong behavior was: - NdisMRegisterInterrupt using translated/system values (e.g. lvl=5 vec=97 or lvl=5 vec=865) → 0xC0000001 Sources - ReactOS NDIS source (shows NdisMRegisterInterrupt using HalGetInterruptVector + IoConnectInterrupt): https://doxygen.reactos.org/dd/d5f/drivers_2network_2ndis_2ndis_2io_8c.html - Microsoft documentation for IoConnectInterrupt: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-ioconnectinterrupt - PCI basics + capability list (background reference): https://wiki.osdev.org/PCI - PCIe interrupt behavior / INTx vs MSI (background reference): https://docs.amd.com/r/en-US/pg213-pcie4-ultrascale-plus/Generating-Interrupt-Requests Edited February 16 by Dietmar
George King Posted February 17 Posted February 17 (edited) On 2/12/2026 at 10:29 AM, Dietmar said: @George King Hi, I dont know, how to do this "Can you also please create PR with these changes for everyone to main repo?". My new driver nvme2k.sys is stable for XP SP3, I work now with it on daily use Dietmar Fork https://github.com/techomancer/nvme2k repo, minimize your changes, commit them to your repo, open Pull request to https://github.com/techomancer/nvme2k. If accepted and merged, source code and new builds will be available for everyone. EDIT: Like this: https://github.com/techomancer/nvme2k/pull/25 Edited February 17 by George King
Dietmar Posted February 18 Posted February 18 (edited) Oh..I spend soso many hours to overcome the crazy ULP etc. on this crazy lan chip i219 Dev_15B8. Now for the very first time I come to 100 MB/s, before it was ALWAYS only 10 MB/s because of crazy energy saving.. Here is this driver i219 for XP SP3 Dietmar https://files.catbox.moe/ye06bv.zip Tutorial (MSFN): Getting 100 Mb/s (Fast Ethernet) link on Intel i219 (DEV_15B8) under Windows XP SP3 — the ULP/LPLU “crazy register” fix Problem we hit On i219 (PCH-integrated PHY), Windows XP does not handle Intel’s modern low-power PHY/MAC features correctly. The PHY can stay in (or partially return to) low-power states after reset / link events, which can break auto-negotiation and leave you stuck at 10 Mb/s or with unstable negotiation. What finally made 100 Mb/s work (our “fixed6” build) We had to do two things together: 1) Force a clean exit from ULP/DPG and “sticky” low-power configuration 2) Disable LPLU and restart auto-negotiation with a clean 100FD advertisement ──────────────────────────────────────────────────────────────────────────── 1) ULP / DPG: force the PHY fully “awake” (exit Ultra Low Power) Key idea: ULP settings can be sticky and survive resets. When leaving ULP, hardware may have disabled K1 automatically; you must re-enable it explicitly. Registers involved (names from Linux e1000e): - E1000_H2ME (0x05B50) + bits START_DPG / EXIT_DPG / ULP (Host↔ME handshake) - FWSM flags like ULP_CFG_DONE and EXFWSM_DPG_EXIT_DONE (status/handshake) - PHY reg I218_ULP_CONFIG1 (page 779, reg 16) with bits: STICKY_ULP, INBAND_EXIT, RESET_TO_SMBUS, WOL_HOST, etc. - PHY reg HV_PM_CTRL (page 770, reg 17): HV_PM_CTRL_K1_ENABLE - PHY reg CV_SMB_CTRL (page 769, reg 23): clear FORCE_SMBUS if set - MAC regs: CTRL_EXT (unforce SMBus), FEXTNVM7 (DISABLE_SMB_PERST handling) Minimal “XP-friendly” sequence (conceptual checklist): - Ensure you are allowed to touch PHY regs (lock/semaphore in your driver as needed). - If the platform uses ME/DPG: request DPG exit and/or wait for DPG_EXIT_DONE / ULP_CFG_DONE style indications. - Unforce SMBus mode: - PHY: clear CV_SMB_CTRL_FORCE_SMBUS - MAC: clear CTRL_EXT_FORCE_SMBUS - Re-enable K1 on exit: - PHY: set HV_PM_CTRL_K1_ENABLE - Clear all “ULP enabled configuration” bits in I218_ULP_CONFIG1: - clear at least: IND, STICKY_ULP, RESET_TO_SMBUS, WOL_HOST, INBAND_EXIT, EN_ULP_LANPHYPC, DIS_CLR_STICKY_ON_PERST, DISABLE_SMB_PERST - Commit those PHY changes: - set I218_ULP_CONFIG1_START once after writing - (Optional but recommended for XP testing) ensure DPG is not forced: - set DPGFR to a “not forced” state (typically clearing force bits / leaving default) Why this matters for 100 Mb/s: If the PHY is still partially in ULP / SMBus-forced mode, auto-negotiation can behave “wrong” (bad timing, wrong advertised set, negotiation never completes correctly), especially with XP’s older network stack and power handling. ──────────────────────────────────────────────────────────────────────────── 2) LPLU: disable Low Power Link Up and restart Auto-Negotiation Key idea: LPLU is meant to save power during Dx states. Under XP, it can interfere with negotiation and speed switching. We disabled it and forced a clean auto-neg restart. Registers involved (names from Linux e1000e): - PHY reg HV_OEM_BITS (page 768, reg 25): - HV_OEM_BITS_LPLU (Low Power Link Up) - HV_OEM_BITS_GBE_DIS (Gigabit disable — useful when forcing 10/100 only) - HV_OEM_BITS_RESTART_AN (Restart auto-negotiation) - MAC reg PHY_CTRL (CSR offset 0x00F10) contains LPLU/GBE control bits mirrored into OEM bits on some PCH designs. What we did in practice: - Make sure LPLU is OFF: - clear HV_OEM_BITS_LPLU - clear any LPLU-related bits in PHY_CTRL (PCH-integrated PHY control) - Advertise only what you want (100FD in our case): - Disable/clear 1000Base-T advertisement (and/or set HV_OEM_BITS_GBE_DIS) - Set 10/100 advertisement so that 100 Full Duplex is included (or only 100FD if you want strict) - Restart auto-neg: - set HV_OEM_BITS_RESTART_AN (or trigger autoneg restart via standard PHY control) - Wait for link-up, then read speed/duplex. Practical note (important): Some PCH designs won’t fully apply LPLU changes unless you also do an explicit auto-neg restart. That restart is what finally made the PHY “re-decide” with the corrected (non-low-power) configuration. ──────────────────────────────────────────────────────────────────────────── 3) What to post as the “takeaway” for other XP users If your i219 under XP is stuck at 10 Mb/s or negotiation behaves strangely, try this order: 1) Exit ULP cleanly (clear sticky ULP, unforce SMBus, commit with START, re-enable K1) 2) Disable LPLU 3) Force/limit advertisement (e.g., 10/100 only, or 100FD) 4) Restart auto-neg That combination was the first time we got a stable 100 Mb/s link on DEV_15B8 with XP SP3. ──────────────────────────────────────────────────────────────────────────── Complete Sources (links you can cite on MSFN) 1) Linux kernel e1000e (PCH/i217/i218/i219) — ULP disable flow + K1 re-enable + clearing I218_ULP_CONFIG1: https://codebrowser.dev/linux/linux/drivers/net/ethernet/intel/e1000e/ich8lan.c.html 2) Linux kernel e1000e — ULP/LPLU/ME/DPG related defines (I218_ULP_CONFIG1 bits, HV_OEM_BITS, HV_PM_CTRL_K1_ENABLE, H2ME bits): https://codebrowser.dev/linux/linux/drivers/net/ethernet/intel/e1000e/ich8lan.h.html 3) Linux kernel e1000e — MAC register offsets used here (PHY_CTRL 0x00F10, DPGFR 0x00FAC, CTRL_EXT, FEXTNVM7, etc.): https://codebrowser.dev/linux/linux/drivers/net/ethernet/intel/e1000e/regs.h.html 4) (For historical macro values referenced in some trees) E1000_PHY_CTRL_D0A_LPLU / E1000_PHY_CTRL_NOND0A_LPLU definitions (older e1000 header docs): https://docs.huihoo.com/doxygen/linux/kernel/3.7/e1000_2e1000__hw_8h_source.html Edited February 18 by Dietmar 2
Dietmar Posted February 18 Posted February 18 (edited) Oh..my, sometimes only the dirtiest hack give you success.. I sit like a drunk duck in polling (Windows timer 15.6 ms) for the i219 lan Driver under XP SP3. IRQ registration never succeeded → so RX got serviced only on the timer. So.. I changed the IRQ-registration via this crazy hack 1) Now I try 3 candidate interrupt pairs: - a->IrqVector / a->IrqLevel NdisMQueryAdapterResources, mostly (?!) works but not for me and XP. - a->IrqSysVector / a->IrqSysLevel - a->IrqBusVector / a->IrqBusLevel What this hack is doing: - On modern boards with IOAPIC routing, XP/NDIS can expose interrupt information in multiple.. “views” (resource list, system-translated, bus-related). - If you pick only one pair (the “clean” way), NdisMRegisterInterrupt may fail or the IRQ never fires, and you fall back to timer-driven polling, means a ping of 15 ms. Hack: During MiniportInitialize, take the (Vector,Level) pairs XP already reports, and try registering them in the above order. The first pair that NdisMRegisterInterrupt accepts, becomes the selected IRQ configuration. Only ONE pair is used in the end(!). 2) I normalized BOTH vector and level when XP/IOAPIC gives “translated” values: Here with my values on Asrock z370 k6 board (from my working setup: Vector = 97, Level/IRQ-line = 5) On my compi, the “real” pair is: - vec = 97 decimal = 0x61 - lvl = 5 decimal = 0x05 Now the XP/IOAPIC “translated” case looks like this (same information, just encoded): - raw vec = 0x361 (this is in 0x300..0x3FF) - raw lvl = 0x305 (this is in 0x300..0x3FF) Normalization rule: - if value in 0x300..0x3FF => value = value - 0x300 Do the math (HEX): - vec: 0x361 - 0x300 = 0x061 => 0x61 = 97 decimal - lvl: 0x305 - 0x300 = 0x005 => 0x05 = 5 decimal So after this normalization you end up exactly at your usable XP pair: - vec = 0x61 (97) - lvl = 0x05 (5) If XP already reports normal values (not translated), nothing changes: - raw vec = 0x61 => not in 0x300..0x3FF => keep 0x61 - raw lvl = 0x05 => not in 0x300..0x3FF => keep 0x05 Before, sometimes I had a good vector but a still-translated level, so NdisMRegisterInterrupt failed and I stayed in polling forever, ping always 15 ms, but via IRQ to my router at 192.168.2.1 ping time should be <1 ms. 3) Now I force the XP-safe interrupt mode - shared = TRUE - mode = NdisInterruptLevelSensitive Why this works - This matches how INTx behind IOAPIC behaves in practice on modern chipsets (like crazy). - “Edge” / “not shared” settings are a common reason for missed / never-fired interrupts on XP. Dietmar PS: Because I have no idea, how to test the quality of my driver i219 for XP SP3, I would be very happy, if a user here can do this for me or gives me Tutorial, how to do this by myself. PPS: Here is this my version of the i219 lan driver, running under XP SP3. Now it is the fastest lan, that I ever had. https://files.catbox.moe/rmxl63.zip Edited February 18 by Dietmar 2
Dietmar Posted February 18 Posted February 18 With all the tools that I know, I get this result for my i219 driver for XP SP3: Based on my XP SP3 logs and real-world behaviour, my custom Intel i219 (DEV_15B8) driver currently reaches roughly ~70–80% of the “feel” of an official Intel i218 XP driver in stability + latency. Which is kind of hilarious, because: - Intel never intended i219 to run on XP at all. - Yet here it is, happily pushing packets like it belongs in 2002. - In practice I’m basically cosplaying parts of Intel’s later driver logic under NDIS 5.1 and XP just shrugs and says “ok”. Where a real official Intel i218 XP driver would still win clearly: ✔ High-throughput efficiency at very high bandwidth ✔ Adaptive / smarter interrupt moderation ✔ Power-state transitions / energy features done “the Intel way” But in the areas that matter first for daily use: - Link reliability: solid - Ping stability: clean, no crazy jitter spikes - Error-free transfer: no obvious discards/errors in counters under load …my i219 driver is already surprisingly close to production-grade behaviour. Blunt engineer-style punchline: "If an Intel NIC developer saw these logs, he’d probably say: 'This is not supposed to work… why is it working?' 😄" 1
Dietmar Posted February 18 Posted February 18 (edited) Hi, I have some motherboards with the Realtek RTL8125 2.5 GB lan chip and with real COM port for using Windbg to its full. And all those 8125(B,G) chips are nearly the same, as you can see in Linux device tree. Question for me is, how much energy I have to spend for this, to make a full working driver for XP SP3 on NDIS 5.1, without any extra file or function. For the Intel i219 I spend 10 days, about 160 hours work. And I am getting soso much better in using Windbg. But I think, I need at least about double this time. And I am not sure, that I get the full 2.5 GB to work because as Linux tells about crazy firmware needed for this Dietmar Edited February 18 by Dietmar
Dietmar Posted February 19 Posted February 19 (edited) Hi, I just now add all the Dev_ numbers for i219, that I can find, to the i219.inf . And I test this my i219 driver for XP SP3 on my Asrock z690 Extreme board with DEV_1A1D works at once Dietmar https://files.catbox.moe/lkhvuu.zip Edited February 19 by Dietmar
Dietmar Posted February 20 Posted February 20 (edited) I succeed to install my from scratch build generic RTL8125 driver. So, the first most most crazy step is done. Mostly all OIDs are unknown to me and I have to recognice them all one by one with "hand" means Windbg Dietmar PS: Next is from “driver starts” → “TCP/IP binds + DHCP works” → “real traffic” 20: kd> !devnode 8bed55a8 DevNode 0x8bed55a8 for PDO 0x8bed5c10 Parent 0x8be67288 Sibling 0000000000 Child 0000000000 InstancePath is "PCI\VEN_10EC&DEV_8125&SUBSYS_E0001458&REV_05\4&2b19def8&0&00E2" ServiceName is "rtl8125" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) StateHistory[07] = DeviceNodeEnumerateCompletion (0x30d) StateHistory[06] = DeviceNodeStarted (0x308) StateHistory[05] = DeviceNodeStartPostWork (0x307) StateHistory[04] = DeviceNodeStartCompletion (0x306) StateHistory[03] = DeviceNodeResourcesAssigned (0x304) StateHistory[02] = DeviceNodeDriversAdded (0x303) StateHistory[01] = DeviceNodeInitialized (0x302) StateHistory[00] = DeviceNodeUninitialized (0x301) StateHistory[19] = Unknown State (0x0) StateHistory[18] = Unknown State (0x0) StateHistory[17] = Unknown State (0x0) StateHistory[16] = Unknown State (0x0) StateHistory[15] = Unknown State (0x0) StateHistory[14] = Unknown State (0x0) StateHistory[13] = Unknown State (0x0) StateHistory[12] = Unknown State (0x0) StateHistory[11] = Unknown State (0x0) StateHistory[10] = Unknown State (0x0) StateHistory[09] = Unknown State (0x0) StateHistory[08] = Unknown State (0x0) Flags (0x000000f0) DNF_ENUMERATED, DNF_IDS_QUERIED, DNF_HAS_BOOT_CONFIG, DNF_BOOT_CONFIG_RESERVED CapabilityFlags (0x00002003) DeviceD1, DeviceD2, WakeFromD3 Edited February 20 by Dietmar 2
K4sum1 Posted February 20 Posted February 20 I wasn't sure if you were going to do it, but wow. I'm happy you're doing this for the community. Unfortunately I've had a potential hardware failure now, and I might have to do some swapping around in the B550 Tomahawk system, which means I might not be able to test the driver much if at all when it comes out unfortunately. I was able to get the hardware ID for you though. PCI\VEN_10EC&DEV_8125&CC_0200. If this driver does end up expanding to support other cards that the Realtek driver does like the RTL8126, I'll definitely buy one to test it with.
reboot12 Posted February 20 Posted February 20 23 hours ago, Dietmar said: I just now add all the Dev_ numbers for i219, that I can find, to the i219.inf . Wow, I didn't know that something had changed in the topic because the notifications from MSFN seemed to have gone wrong. I have a motherboard with integrated network card I219-LM 8086-15BB, I see that in the i219.inf file there is this string. I will try to test the driver on my WinXP SP2 32-bit modern: https://forums.mydigitallife.net/threads/winxp-32-bit-on-a-modern-pc-iso-boot-wim-install-wim.88834/
reboot12 Posted February 20 Posted February 20 (edited) @Dietmar I have tested all versions of the driver but they all have the same problem. Drivers install correctly, detects connected or disconnected network cable but no communication 0 sent/0 received packets: I tried static IP instead of DHCP but still problem Edited February 20 by reboot12
Dietmar Posted February 20 Posted February 20 @reboot12 Hi, do you have a 100MB or a 1000MB connection? This you can see from the coulors of your LEDs on the network card. Orange: 100MB Green: 1000 MB I have only 100MB and so I tested only 100MB connection Dietmar PS: And have you tested this your network cable on another nick, so that with DHCP all is ok? This you can see wenn in CMD you put ipconfig /all .
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now