net: a native RTL8169/8111 driver, because phylib is not a set of leaf calls
The laptop's NIC is an RTL8111H, and the request was to add it to LDLS.
Measuring it is what changed the answer, so the measurement is the commit
message: r8169.ko (6.18.52) has **183 undefined symbols, 130 of them not
implemented by ldls/kpi/, and 35 of those 130 are phylib** --
phy_connect_direct, phy_start, mdiobus_read, genphy_soft_reset and the rest.
phylib is a subsystem with a link state machine, not a set of leaf calls, and
LDLS's usual answer for an unimplemented symbol -- a stub that reports itself
and returns zero -- is exactly wrong for it. phy_start returning zero means the
link never comes up and there is nothing to look at. The 8139too that ldls.md
uses as its model has no phylib dependency, which is why that one was
tractable and this one is not.
So: a native driver. It reaches the PHY through the chip's own MII window --
PHYAR is one register that is a whole MII bus -- and skips the subsystem. Less
work than the port, no GPL entanglement, no firmware blob, no coupling to one
Linux version, and it covers the whole RTL8111/8168 family because all of it
answers to 10EC:8168. The register layout is a fact about the hardware, taken
the way ldls.md section 3 says facts may be taken; the expression is this
tree's, in the same shape as the e1000 beside it.
**It has not run on hardware, and that is not a hedge.** QEMU emulates rtl8139
and nothing else from Realtek, and the 8139 is a different programming model --
a circular receive buffer rather than descriptors -- so it is deliberately not
in the match table. What is verified: it builds, its presence changes nothing
on a machine without the device, and with an rtl8139 on the bus it correctly
leaves it unclaimed. What is not: every register write, on a real part.
The probe therefore says everything a first bug report needs, with cprintf
rather than kinfo so it reaches the screen of a machine with no serial port:
r8169: xid 5c0, 1c:1b:b5:xx:xx:xx, irq 11, link up (bmsr 796d)
xid is the hardware version from the top of TxConfig -- the PCI device id has
been 8168 for twenty years and says nothing. bmsr is MII register 1: bit 2 is
link, bit 5 is autonegotiation complete. Those four facts separate "the chip is
not there" from "the PHY sees nothing" from "the rings are wrong".
Two constants were wrong in the first draft and are recorded because both would
have worked quietly. RxConfig had 0x7700 for "unlimited": MXDMA is bits 8-10
and RXFTH is bits 13-15, so that was one bit short of a full burst and a
half-full FIFO threshold. And CPCR bit 3 was being set under a comment calling
it "PCI multiple read/write" -- bit 3 is PCIDAC, 64-bit addressing, and bit 4
is what the comment described; neither is wanted, so the write is gone.
Both supported configurations: one boot each, no traps, no panics, socktest and
memfdtest green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
30a0d0fbed
commit
4a723cfc0e
4 changed files with 611 additions and 0 deletions
|
|
@ -29,6 +29,75 @@ that completes a handshake and drops every byte.
|
|||
└────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Realtek RTL8169/8168/8111 — `drivers/net/r8169/`
|
||||
|
||||
The NIC in a very large number of laptops and desktop boards. Every
|
||||
RTL8111/8168 variant answers to **10EC:8168**, which is why one match entry
|
||||
covers two decades of silicon — and why the driver prints the chip's XID on
|
||||
probe, since the PCI device id tells you almost nothing about which part
|
||||
arrived.
|
||||
|
||||
### Why it is native, when the plan said LDLS
|
||||
|
||||
The first plan was to run Linux's `r8169.ko` under [ldls.md](ldls.md). Measuring
|
||||
it is what changed the answer: the module has **183 undefined symbols, 130 of
|
||||
them not implemented**, and 35 of those 130 are **phylib** —
|
||||
`phy_connect_direct`, `phy_start`, `mdiobus_read`, `genphy_soft_reset`.
|
||||
|
||||
phylib is a subsystem with a link state machine, not a set of leaf calls, and
|
||||
LDLS's usual answer for an unimplemented symbol — a stub that reports itself
|
||||
and returns zero — is precisely wrong for it. `phy_start` returning zero means
|
||||
the link never comes up and there is nothing on screen to say why. The 8139too
|
||||
that ldls.md uses as its model has no phylib dependency, which is why that one
|
||||
was tractable.
|
||||
|
||||
A native driver reaches the PHY through the chip's own MII window (`PHYAR`,
|
||||
one register that is a whole MII bus) and skips the subsystem entirely. It is
|
||||
less work than the port, it carries no GPL entanglement, it needs no firmware
|
||||
blob, and it is not coupled to one Linux version.
|
||||
|
||||
The register layout is a *fact about the hardware*, taken the way
|
||||
[ldls.md](ldls.md) §3 says facts may be taken. The expression is this tree's:
|
||||
a descriptor-ring driver in the same shape as the e1000 beside it.
|
||||
|
||||
### It has not run on hardware
|
||||
|
||||
**Stated plainly because it cannot be tested here.** QEMU emulates `rtl8139`
|
||||
and nothing else from Realtek, and the 8139 is a different programming model —
|
||||
a circular receive buffer rather than descriptors — so it is deliberately *not*
|
||||
in the match table. Claiming it would break a NIC that works.
|
||||
|
||||
What has been verified: the driver builds, its presence changes nothing on a
|
||||
machine without the device, and with an `rtl8139` on the bus it correctly
|
||||
leaves it unclaimed (`10ec:8139 network controller [-]`).
|
||||
|
||||
What has not: every register write, on a real part.
|
||||
|
||||
So the probe says everything a first bug report would need, with `cprintf`
|
||||
rather than `kinfo` so it reaches the screen on a machine with no serial port:
|
||||
|
||||
```
|
||||
r8169: xid 5c0, 1c:1b:b5:xx:xx:xx, irq 11, link up (bmsr 796d)
|
||||
```
|
||||
|
||||
`xid` is the hardware version out of the top of `TxConfig`; `bmsr` is MII
|
||||
register 1, where bit 2 is link and bit 5 is autonegotiation complete. Those
|
||||
four facts separate "the chip is not there", "the chip is there and the PHY
|
||||
sees nothing", and "everything is up and the rings are wrong".
|
||||
|
||||
### Two constants that were wrong first
|
||||
|
||||
Recorded because both would have worked, quietly:
|
||||
|
||||
- `RxConfig` had `0x7700` for unlimited burst and threshold. `MXDMA` is bits
|
||||
8-10 and `RXFTH` is bits 13-15, so that is one bit short of a full burst and
|
||||
a half-full FIFO threshold rather than none — slower, and invisible.
|
||||
- `CPCR` bit 3 was being set under a comment calling it "PCI multiple
|
||||
read/write". Bit 3 is PCIDAC, 64-bit DMA addressing; bit 4 is the one the
|
||||
comment described. Neither is wanted, since the rings come from the DMA arena
|
||||
below 4 GB, so the write is gone rather than corrected.
|
||||
|
||||
|
||||
## The netdev class
|
||||
|
||||
A driver publishes a [`struct netdev_ops`](../../include/netdev.h) and is then
|
||||
|
|
|
|||
Loading…
Reference in a new issue