- Anonymous memory can be reserved without being backed: large mappings, MAP_NORESERVE and PROT_NONE are recorded and each page appears, zeroed, on first touch -- from trap() for the program, from uva2ka() for the kernel on its behalf. WebKit reserves 4 GB at start and touches a sliver; backing it all failed with ENOMEM and Epiphany aborted. - r8169: the 8168G generation and later (the laptop's 8168H, XID 541) are taken from the firmware's out-of-band mode, get their PLL powered, the receive gate opened, and their PHY reached through the OCP window. The PHY's power-down bit is cleared; the old code kept it while restarting autonegotiation. Untested on the hardware so far. - The network thread follows each device's link into lwIP. The link was read once at attach, 0.02 s into boot; real autonegotiation takes seconds, so on hardware the interface stayed down for good. - Twelve terminals, switched with Ctrl+Alt+F1..F12 by default: the keys X uses, so the console and the desktop agree. AltGr+F-key is gone from the defaults (chvt -c altgr+F brings it back). - SO_PASSCRED on Unix sockets, with SCM_CREDENTIALS delivered by recvmsg. WebKit sets it on its IPC sockets and aborted when refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
723 lines
22 KiB
C
723 lines
22 KiB
C
// Realtek RTL8169/8168/8111 gigabit Ethernet.
|
|
//
|
|
// The NIC in a very large number of laptops and desktop boards: every
|
|
// RTL8111/8168 variant answers to 10EC:8168, and the RTL8111H in particular is
|
|
// what prompted this driver.
|
|
//
|
|
// **Native rather than through LDLS**, and the reason is worth recording
|
|
// because the first plan was the other way round. Running Linux's r8169.ko
|
|
// under kernel/../ldls would mean implementing 130 kernel functions it calls,
|
|
// and 35 of those 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 a
|
|
// symbol it does not implement -- 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 see. A native driver reaches the PHY
|
|
// through the chip's own MII window instead and skips the whole subsystem.
|
|
//
|
|
// The register layout below is a *fact about the hardware*, taken the way
|
|
// docs/architecture/ldls.md §3 says facts may be taken. None of the expression
|
|
// is Linux's: this is a descriptor-ring driver in the same shape as the e1000
|
|
// beside it, because that is the shape this kernel's netdev class wants.
|
|
|
|
#include "core/types.h"
|
|
#include "core/defs.h"
|
|
#include "core/param.h"
|
|
#include "arch/x86.h"
|
|
#include "core/spinlock.h"
|
|
#include "core/sleeplock.h"
|
|
#include "fs/fs.h"
|
|
#include "fs/file.h"
|
|
#include "arch/memlayout.h"
|
|
#include "arch/mmu.h"
|
|
#include "dev/pci.h"
|
|
#include "dev/device.h"
|
|
#include "dev/netdev.h"
|
|
#include "core/dma.h"
|
|
#include "core/irq.h"
|
|
|
|
// --- registers --------------------------------------------------------------
|
|
|
|
#define R_IDR0 0x00 // station address, six bytes
|
|
#define R_MAR0 0x08 // multicast filter
|
|
#define R_TNPDS 0x20 // Tx normal-priority descriptors, 64-bit
|
|
#define R_CR 0x37 // command
|
|
#define R_TPPOLL 0x38 // tell the chip to look at the Tx ring
|
|
#define R_IMR 0x3C
|
|
#define R_ISR 0x3E
|
|
#define R_TCR 0x40 // Tx config
|
|
#define R_RCR 0x44 // Rx config
|
|
#define R_9346CR 0x50 // unlocks the config registers
|
|
#define R_CONFIG1 0x52
|
|
#define R_PHYAR 0x60 // the MII window
|
|
#define R_PHYSTATUS 0x6C
|
|
#define R_PMCH 0x6F // PLL power
|
|
#define R_ERIDR 0x70 // extended register window: data
|
|
#define R_ERIAR 0x74 // and address
|
|
#define R_GPHY_OCP 0xB8 // the PHY's registers, 8168G and later
|
|
#define R_MAC_OCP 0xB0 // the MAC's own OCP registers
|
|
#define R_MCU 0xD3
|
|
#define R_MISC 0xF0
|
|
#define R_RMS 0xDA // largest frame the chip will accept
|
|
#define R_CPCR 0xE0 // "C+" command
|
|
#define R_RDSAR 0xE4 // Rx descriptors, 64-bit
|
|
#define R_MTPS 0xEC
|
|
|
|
#define CR_RST 0x10
|
|
#define CR_RE 0x08
|
|
#define CR_TE 0x04
|
|
|
|
#define TPPOLL_NPQ 0x40
|
|
|
|
#define C9346_UNLOCK 0xC0
|
|
#define C9346_LOCK 0x00
|
|
|
|
// Interrupt causes. Write-1-to-clear, which is the detail that matters: a
|
|
// cause left set on a level-triggered line re-enters the handler for ever.
|
|
#define ISR_ROK 0x0001
|
|
#define ISR_RER 0x0002
|
|
#define ISR_TOK 0x0004
|
|
#define ISR_TER 0x0008
|
|
#define ISR_RDU 0x0010 // ran out of Rx descriptors
|
|
#define ISR_LINKCHG 0x0020
|
|
#define ISR_TDU 0x0080
|
|
|
|
#define PHYSTATUS_LINK 0x02
|
|
|
|
#define MCU_NOW_IS_OOB 0x80 // the firmware, not a driver, owns the MAC
|
|
#define MCU_LL_READY 0x02 // link-list FIFO ready
|
|
#define MISC_RXDV_GATE 0x00080000
|
|
#define OCP_FLAG 0x80000000
|
|
#define OCP_STD_PHY_BASE 0xA400
|
|
#define BMCR_PDOWN 0x0800
|
|
#define BMCR_ANENABLE 0x1000
|
|
#define BMCR_ANRESTART 0x0200
|
|
|
|
// Rx config: accept frames addressed to us, broadcast and multicast, with the
|
|
// largest DMA burst and Rx FIFO threshold the chip offers. Promiscuous is
|
|
// deliberately not set -- a NIC that hands the stack every frame on the wire
|
|
// is a NIC that makes its own bugs look like somebody else's traffic.
|
|
#define RCR_AAP 0x00000001 // (not set)
|
|
#define RCR_APM 0x00000002 // physical match
|
|
#define RCR_AM 0x00000004 // multicast
|
|
#define RCR_AB 0x00000008 // broadcast
|
|
// MXDMA is bits 8-10 and RXFTH is bits 13-15, and "unlimited" is all ones in
|
|
// each: 0x700 | 0xE000. The first version of this had 0x7700, which sets bits
|
|
// 12-14 -- an Rx FIFO threshold of *half* rather than none, and one bit of
|
|
// MXDMA short. It would have worked and been slower, which is the worst kind
|
|
// of wrong to leave in a register constant.
|
|
#define RCR_UNLIMITED 0x0000E700
|
|
|
|
#define TCR_IFG_STD 0x03000000
|
|
#define TCR_MXDMA 0x00000700
|
|
|
|
// --- descriptors ------------------------------------------------------------
|
|
//
|
|
// Sixteen bytes, and the ring is a ring only because the last descriptor
|
|
// carries EOR. The chip walks forward and wraps when it sees it.
|
|
|
|
struct rtl_desc {
|
|
uint32 opts1;
|
|
uint32 opts2;
|
|
uint64 addr;
|
|
};
|
|
|
|
#define DESC_OWN 0x80000000 // the chip owns it
|
|
#define DESC_EOR 0x40000000 // last descriptor in the ring
|
|
#define DESC_FS 0x20000000 // first fragment of a frame
|
|
#define DESC_LS 0x10000000 // last fragment
|
|
#define DESC_LEN 0x00003FFF
|
|
|
|
#define NRX 32
|
|
#define NTX 32
|
|
#define BUFSZ 2048 // one frame, with room for a VLAN tag
|
|
|
|
#define R8169_MAX_NICS 2
|
|
|
|
struct r8169 {
|
|
volatile uint8 *mmio;
|
|
struct rtl_desc *rx, *tx;
|
|
uint8 *rxbuf, *txbuf;
|
|
uint64 rx_phys, tx_phys, rxbuf_phys, txbuf_phys;
|
|
|
|
int rx_next; // the descriptor we will look at next
|
|
int tx_next;
|
|
uint8 mac[6];
|
|
int ready;
|
|
int gen_g; // 8168G or later: see r8169_gen_g()
|
|
uint16 ocp_base; // the PHY page selected through register 0x1F
|
|
uint64 rx_packets, tx_packets;
|
|
|
|
struct spinlock lock;
|
|
struct pci_dev *pdev;
|
|
struct device *ndev;
|
|
};
|
|
|
|
static struct r8169 nics[R8169_MAX_NICS];
|
|
|
|
static struct r8169 *
|
|
of(struct device *d)
|
|
{
|
|
return d ? (struct r8169 *)d->priv : 0;
|
|
}
|
|
|
|
static inline uint8 rd8 (struct r8169 *r, int o) { return *(volatile uint8 *)(r->mmio + o); }
|
|
static inline uint16 rd16(struct r8169 *r, int o) { return *(volatile uint16 *)(r->mmio + o); }
|
|
static inline uint32 rd32(struct r8169 *r, int o) { return *(volatile uint32 *)(r->mmio + o); }
|
|
static inline void wr8 (struct r8169 *r, int o, uint8 v) { *(volatile uint8 *)(r->mmio + o) = v; }
|
|
static inline void wr16(struct r8169 *r, int o, uint16 v) { *(volatile uint16 *)(r->mmio + o) = v; }
|
|
static inline void wr32(struct r8169 *r, int o, uint32 v) { *(volatile uint32 *)(r->mmio + o) = v; }
|
|
|
|
static void
|
|
wr64(struct r8169 *r, int o, uint64 v)
|
|
{
|
|
// Low half first. The chip latches the pair on the high write, so the other
|
|
// order hands it half of one address and half of the previous one.
|
|
wr32(r, o, (uint32)v);
|
|
wr32(r, o + 4, (uint32)(v >> 32));
|
|
}
|
|
|
|
// --- the PHY, through the chip's own window ---------------------------------
|
|
//
|
|
// This is the part that makes the driver native rather than a phylib port:
|
|
// PHYAR is a one-register MII bus. Write it with the register number and a
|
|
// value to write; read it back until the chip says the access finished.
|
|
|
|
#define PHYAR_FLAG 0x80000000
|
|
|
|
static void
|
|
phyar_write(struct r8169 *r, int reg, uint16 val)
|
|
{
|
|
wr32(r, R_PHYAR, PHYAR_FLAG | ((reg & 0x1F) << 16) | val);
|
|
for (int i = 0; i < 1000; i++) {
|
|
microdelay(20);
|
|
if (!(rd32(r, R_PHYAR) & PHYAR_FLAG))
|
|
return;
|
|
}
|
|
}
|
|
|
|
static int
|
|
phyar_read(struct r8169 *r, int reg)
|
|
{
|
|
wr32(r, R_PHYAR, (reg & 0x1F) << 16);
|
|
for (int i = 0; i < 1000; i++) {
|
|
microdelay(20);
|
|
uint32 v = rd32(r, R_PHYAR);
|
|
if (v & PHYAR_FLAG)
|
|
return (int)(v & 0xFFFF);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// From the 8168G on, the PHY sits behind an OCP window instead: its standard
|
|
// registers are at 0xA400 + 2*reg, and "select page N" through register 0x1F
|
|
// becomes a base address. PHYAR still answers reads on some of these chips,
|
|
// which is how this driver got away without it -- until a write mattered.
|
|
static void
|
|
ocp_phy_write(struct r8169 *r, uint16 addr, uint16 val)
|
|
{
|
|
wr32(r, R_GPHY_OCP, OCP_FLAG | ((uint32)(addr >> 1) << 16) | val);
|
|
for (int i = 0; i < 1000; i++) {
|
|
microdelay(20);
|
|
if (!(rd32(r, R_GPHY_OCP) & OCP_FLAG))
|
|
return;
|
|
}
|
|
}
|
|
|
|
static int
|
|
ocp_phy_read(struct r8169 *r, uint16 addr)
|
|
{
|
|
wr32(r, R_GPHY_OCP, (uint32)(addr >> 1) << 16);
|
|
for (int i = 0; i < 1000; i++) {
|
|
microdelay(20);
|
|
uint32 v = rd32(r, R_GPHY_OCP);
|
|
if (v & OCP_FLAG)
|
|
return (int)(v & 0xFFFF);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static void
|
|
mii_write(struct r8169 *r, int reg, uint16 val)
|
|
{
|
|
if (!r->gen_g) {
|
|
phyar_write(r, reg, val);
|
|
return;
|
|
}
|
|
if (reg == 0x1F) {
|
|
r->ocp_base = val ? (uint16)(val << 4) : OCP_STD_PHY_BASE;
|
|
return;
|
|
}
|
|
if (r->ocp_base != OCP_STD_PHY_BASE)
|
|
reg -= 0x10;
|
|
ocp_phy_write(r, (uint16)(r->ocp_base + reg * 2), val);
|
|
}
|
|
|
|
static int
|
|
mii_read(struct r8169 *r, int reg)
|
|
{
|
|
if (!r->gen_g)
|
|
return phyar_read(r, reg);
|
|
if (r->ocp_base != OCP_STD_PHY_BASE)
|
|
reg -= 0x10;
|
|
return ocp_phy_read(r, (uint16)(r->ocp_base + reg * 2));
|
|
}
|
|
|
|
// The MAC's OCP registers. No completion flag to wait on.
|
|
static uint16
|
|
mac_ocp_read(struct r8169 *r, uint16 reg)
|
|
{
|
|
wr32(r, R_MAC_OCP, (uint32)(reg >> 1) << 16);
|
|
return (uint16)rd32(r, R_MAC_OCP);
|
|
}
|
|
|
|
static void
|
|
mac_ocp_write(struct r8169 *r, uint16 reg, uint16 val)
|
|
{
|
|
wr32(r, R_MAC_OCP, OCP_FLAG | ((uint32)(reg >> 1) << 16) | val);
|
|
}
|
|
|
|
// The extended (ERI) registers, all four bytes at once.
|
|
static uint32
|
|
eri_read(struct r8169 *r, int addr)
|
|
{
|
|
wr32(r, R_ERIAR, (0xFu << 12) | addr);
|
|
for (int i = 0; i < 100; i++) {
|
|
microdelay(10);
|
|
if (rd32(r, R_ERIAR) & OCP_FLAG)
|
|
return rd32(r, R_ERIDR);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
eri_write(struct r8169 *r, int addr, uint32 val)
|
|
{
|
|
wr32(r, R_ERIDR, val);
|
|
wr32(r, R_ERIAR, OCP_FLAG | (0xFu << 12) | addr);
|
|
for (int i = 0; i < 100; i++) {
|
|
microdelay(10);
|
|
if (!(rd32(r, R_ERIAR) & OCP_FLAG))
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Which XIDs are the 8168G generation and later: 8168G, GU, 8411B, EP, H.
|
|
// They share the OCP windows and the firmware handover below.
|
|
static int
|
|
r8169_gen_g(uint32 xid)
|
|
{
|
|
switch (xid) {
|
|
case 0x4C0: case 0x4C1: case 0x5C8: case 0x509:
|
|
case 0x500: case 0x501: case 0x502:
|
|
case 0x540: case 0x541:
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
wait_ll_ready(struct r8169 *r)
|
|
{
|
|
for (int i = 0; i < 42; i++) {
|
|
if (rd8(r, R_MCU) & MCU_LL_READY)
|
|
return;
|
|
microdelay(100);
|
|
}
|
|
}
|
|
|
|
// Taking the chip from the firmware. A laptop that was last running Windows,
|
|
// or that keeps Wake-on-LAN armed, hands it over in out-of-band mode with the
|
|
// receive path gated off: the MAC answers its registers and moves no frames.
|
|
static void
|
|
r8169_takeover_g(struct r8169 *r)
|
|
{
|
|
wr32(r, R_MISC, rd32(r, R_MISC) | MISC_RXDV_GATE);
|
|
wr8(r, R_CR, rd8(r, R_CR) & ~(CR_TE | CR_RE));
|
|
microdelay(1000);
|
|
wr8(r, R_MCU, rd8(r, R_MCU) & ~MCU_NOW_IS_OOB);
|
|
mac_ocp_write(r, 0xE8DE, mac_ocp_read(r, 0xE8DE) & ~(1u << 14));
|
|
wait_ll_ready(r);
|
|
mac_ocp_write(r, 0xE8DE, mac_ocp_read(r, 0xE8DE) | (1u << 15));
|
|
wait_ll_ready(r);
|
|
}
|
|
|
|
// The PHY up and negotiating: page 0, out of power-down, autoneg on and
|
|
// restarted. Power-down is what firmware leaves set after a shutdown, and
|
|
// the old code ORed autoneg into BMCR and kept it.
|
|
static void
|
|
r8169_phy_up(struct r8169 *r)
|
|
{
|
|
mii_write(r, 0x1F, 0);
|
|
int bmcr = mii_read(r, 0);
|
|
if (bmcr < 0)
|
|
return;
|
|
bmcr &= ~BMCR_PDOWN;
|
|
mii_write(r, 0, (uint16)bmcr);
|
|
if (r->gen_g) {
|
|
// Wait for the PHY to report it is on: its state, low three bits of
|
|
// OCP 0xA420, reads 3 once it is.
|
|
for (int i = 0; i < 100; i++) {
|
|
int st = ocp_phy_read(r, 0xA420);
|
|
if (st >= 0 && (st & 7) == 3)
|
|
break;
|
|
microdelay(1000);
|
|
}
|
|
}
|
|
mii_write(r, 0, (uint16)(bmcr | BMCR_ANENABLE | BMCR_ANRESTART));
|
|
}
|
|
|
|
// --- the class ops ----------------------------------------------------------
|
|
|
|
static const unsigned char *
|
|
r8169_mac_op(struct device *d)
|
|
{
|
|
struct r8169 *r = of(d);
|
|
static const unsigned char zero[6];
|
|
return r ? r->mac : zero;
|
|
}
|
|
|
|
static int
|
|
r8169_link_up(struct device *d)
|
|
{
|
|
struct r8169 *r = of(d);
|
|
return r ? (rd8(r, R_PHYSTATUS) & PHYSTATUS_LINK) != 0 : 0;
|
|
}
|
|
|
|
static int
|
|
r8169_transmit(struct device *d, const void *frame, int len)
|
|
{
|
|
struct r8169 *r = of(d);
|
|
struct rtl_desc *t;
|
|
int idx;
|
|
|
|
if (!r || !r->ready)
|
|
return -1;
|
|
if (len <= 0 || len > BUFSZ)
|
|
return -1;
|
|
|
|
acquire(&r->lock);
|
|
idx = r->tx_next;
|
|
t = &r->tx[idx];
|
|
|
|
// Still the chip's? Then the ring is full. Congestion rather than failure:
|
|
// the caller retries, which is what the netdev contract says -1 means.
|
|
if (t->opts1 & DESC_OWN) {
|
|
release(&r->lock);
|
|
return -1;
|
|
}
|
|
|
|
// The runt rule. Ethernet's minimum frame is 60 bytes before the FCS, and
|
|
// this chip does not pad for you -- a shorter frame goes out short and the
|
|
// other end drops it. ARP requests are 42 bytes, so getting this wrong is
|
|
// not a corner case, it is "the machine cannot resolve anything".
|
|
int n = len < 60 ? 60 : len;
|
|
memmove(r->txbuf + (uint64)idx * BUFSZ, frame, len);
|
|
if (n > len)
|
|
memset(r->txbuf + (uint64)idx * BUFSZ + len, 0, n - len);
|
|
|
|
t->addr = r->txbuf_phys + (uint64)idx * BUFSZ;
|
|
t->opts2 = 0;
|
|
__sync_synchronize();
|
|
t->opts1 = DESC_OWN | DESC_FS | DESC_LS | (uint32)n |
|
|
(idx == NTX - 1 ? DESC_EOR : 0);
|
|
__sync_synchronize();
|
|
|
|
// Poke it. Without this the chip may sit on a ring it already owns until
|
|
// something else wakes it.
|
|
wr8(r, R_TPPOLL, TPPOLL_NPQ);
|
|
|
|
r->tx_next = (idx + 1) % NTX;
|
|
r->tx_packets++;
|
|
release(&r->lock);
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
r8169_receive(struct device *d, void *out, int cap)
|
|
{
|
|
struct r8169 *r = of(d);
|
|
struct rtl_desc *rx;
|
|
int idx, len;
|
|
|
|
if (!r || !r->ready)
|
|
return 0;
|
|
|
|
acquire(&r->lock);
|
|
idx = r->rx_next;
|
|
rx = &r->rx[idx];
|
|
|
|
if (rx->opts1 & DESC_OWN) { // still the chip's: nothing arrived
|
|
release(&r->lock);
|
|
return 0;
|
|
}
|
|
|
|
// The length includes the four-byte FCS, which the stack does not want and
|
|
// lwIP would otherwise carry to the end of the world as trailing garbage.
|
|
len = (int)(rx->opts1 & DESC_LEN) - 4;
|
|
if (len < 0)
|
|
len = 0;
|
|
if (len > cap)
|
|
len = cap;
|
|
if (len > 0)
|
|
memmove(out, r->rxbuf + (uint64)idx * BUFSZ, len);
|
|
|
|
// Hand the descriptor back. Address and size first, OWN last: the chip may
|
|
// start filling it the instant OWN is set.
|
|
rx->addr = r->rxbuf_phys + (uint64)idx * BUFSZ;
|
|
rx->opts2 = 0;
|
|
__sync_synchronize();
|
|
rx->opts1 = DESC_OWN | (uint32)BUFSZ | (idx == NRX - 1 ? DESC_EOR : 0);
|
|
__sync_synchronize();
|
|
|
|
r->rx_next = (idx + 1) % NRX;
|
|
r->rx_packets++;
|
|
release(&r->lock);
|
|
return len;
|
|
}
|
|
|
|
// --- interrupt --------------------------------------------------------------
|
|
|
|
static void
|
|
r8169_intr(void *arg)
|
|
{
|
|
struct r8169 *r = arg;
|
|
uint16 isr;
|
|
|
|
if (!r || !r->mmio)
|
|
return;
|
|
|
|
isr = rd16(r, R_ISR);
|
|
if (!isr)
|
|
return;
|
|
|
|
// Write-1-to-clear, and it has to happen whatever else does: a cause left
|
|
// asserted on a level-triggered PCI line re-enters this handler until the
|
|
// machine does nothing else. See docs/history/kernel.md section 13 for the
|
|
// last time that was learned here.
|
|
wr16(r, R_ISR, isr);
|
|
|
|
// Nothing is read from the ring here, for the same reason as the e1000: the
|
|
// frame is pulled by the network thread, which may sleep on the buffer cache
|
|
// and take the lwIP lock, and an interrupt handler may do neither. All this
|
|
// does is end that thread's wait early.
|
|
if (isr & (ISR_ROK | ISR_RDU))
|
|
netdev_rx_signal();
|
|
}
|
|
|
|
// --- bring-up ---------------------------------------------------------------
|
|
|
|
static int
|
|
rings_init(struct r8169 *r)
|
|
{
|
|
// 256-byte alignment is the chip's requirement for both descriptor bases,
|
|
// and it is not advisory: a misaligned base is a ring the chip walks
|
|
// somewhere else entirely.
|
|
r->rx = dma_alloc(NRX * sizeof(struct rtl_desc), 256);
|
|
r->tx = dma_alloc(NTX * sizeof(struct rtl_desc), 256);
|
|
r->rxbuf = dma_alloc(NRX * BUFSZ, 8);
|
|
r->txbuf = dma_alloc(NTX * BUFSZ, 8);
|
|
if (!r->rx || !r->tx || !r->rxbuf || !r->txbuf)
|
|
return -1;
|
|
|
|
r->rx_phys = dma_phys(r->rx);
|
|
r->tx_phys = dma_phys(r->tx);
|
|
r->rxbuf_phys = dma_phys(r->rxbuf);
|
|
r->txbuf_phys = dma_phys(r->txbuf);
|
|
|
|
memset(r->rx, 0, NRX * sizeof(struct rtl_desc));
|
|
memset(r->tx, 0, NTX * sizeof(struct rtl_desc));
|
|
|
|
for (int i = 0; i < NRX; i++) {
|
|
r->rx[i].addr = r->rxbuf_phys + (uint64)i * BUFSZ;
|
|
r->rx[i].opts1 = DESC_OWN | (uint32)BUFSZ |
|
|
(i == NRX - 1 ? DESC_EOR : 0);
|
|
}
|
|
for (int i = 0; i < NTX; i++)
|
|
r->tx[i].opts1 = (i == NTX - 1 ? DESC_EOR : 0);
|
|
|
|
r->rx_next = 0;
|
|
r->tx_next = 0;
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
r8169_probe(struct pci_dev *d)
|
|
{
|
|
struct r8169 *r = 0;
|
|
uint64 bar = 0;
|
|
uint64 barlen = 0;
|
|
|
|
for (int i = 0; i < R8169_MAX_NICS; i++)
|
|
if (!nics[i].ready) { r = &nics[i]; break; }
|
|
if (!r)
|
|
return -1;
|
|
|
|
// BAR 2 on a PCIe part, BAR 1 on the older PCI ones, and BAR 0 is I/O on
|
|
// both. Picking the first memory BAR rather than a number is what makes one
|
|
// driver cover the family.
|
|
for (int i = 0; i < 6; i++)
|
|
if (d->bar[i].base && !d->bar[i].is_io) {
|
|
bar = d->bar[i].base;
|
|
barlen = d->bar[i].size;
|
|
break;
|
|
}
|
|
if (!bar) {
|
|
cprintf("r8169: no memory BAR; not driving this device\n");
|
|
return -1;
|
|
}
|
|
|
|
r->pdev = d;
|
|
r->ocp_base = OCP_STD_PHY_BASE;
|
|
initlock(&r->lock, "r8169");
|
|
pci_enable(d, PCI_CMD_MEMORY | PCI_CMD_BUS_MASTER);
|
|
|
|
// ioremap, not P2V: a 64-bit BAR on a laptop routinely sits above the
|
|
// 4 GB the direct map covers, and this is the same lesson the virtio-gpu
|
|
// driver's comment records.
|
|
r->mmio = ioremap(bar, barlen ? barlen : 0x1000);
|
|
if (!r->mmio) {
|
|
cprintf("r8169: cannot map registers at %p\n", (void *)bar);
|
|
return -1;
|
|
}
|
|
|
|
r->gen_g = r8169_gen_g((rd32(r, R_TCR) >> 20) & 0xFCF);
|
|
if (r->gen_g)
|
|
r8169_takeover_g(r);
|
|
|
|
// Soft reset, and wait for the chip to say it finished.
|
|
wr8(r, R_CR, CR_RST);
|
|
for (int i = 0; i < 1000; i++) {
|
|
microdelay(100);
|
|
if (!(rd8(r, R_CR) & CR_RST))
|
|
break;
|
|
}
|
|
if (rd8(r, R_CR) & CR_RST) {
|
|
cprintf("r8169: the chip did not come out of reset\n");
|
|
return -1;
|
|
}
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
r->mac[i] = rd8(r, R_IDR0 + i);
|
|
|
|
if (rings_init(r) != 0) {
|
|
cprintf("r8169: no DMA memory for the rings\n");
|
|
return -1;
|
|
}
|
|
|
|
wr8(r, R_9346CR, C9346_UNLOCK); // config registers are writable now
|
|
|
|
if (r->gen_g) {
|
|
// The PLL powered, the extra ERI bits the 8168H wants with it, and the
|
|
// receive gate opened again.
|
|
wr8(r, R_PMCH, rd8(r, R_PMCH) | 0xC0);
|
|
uint32 xid = (rd32(r, R_TCR) >> 20) & 0xFCF;
|
|
if (xid == 0x540 || xid == 0x541)
|
|
eri_write(r, 0x1A8, eri_read(r, 0x1A8) | 0xFC000000);
|
|
wr32(r, R_MISC, rd32(r, R_MISC) & ~MISC_RXDV_GATE);
|
|
}
|
|
|
|
// CPCR is deliberately left alone.
|
|
//
|
|
// An earlier version set bit 3 here with a comment calling it "PCI multiple
|
|
// read/write". Bit 3 is PCIDAC -- dual address cycle, which is 64-bit DMA
|
|
// addressing -- and the comment was describing bit 4. Neither is wanted:
|
|
// this driver's rings come from the DMA arena, which is below 4 GB, so DAC
|
|
// would be asking the chip to do something it does not need to do on the
|
|
// strength of a constant nobody had checked.
|
|
//
|
|
// The descriptor registers written below *are* the C+ ones on this part;
|
|
// unlike the 8139 it has no other programming model to be in.
|
|
|
|
wr16(r, R_RMS, BUFSZ);
|
|
wr8(r, R_MTPS, 0x3B);
|
|
|
|
wr64(r, R_RDSAR, r->rx_phys);
|
|
wr64(r, R_TNPDS, r->tx_phys);
|
|
|
|
wr32(r, R_TCR, TCR_IFG_STD | TCR_MXDMA);
|
|
wr32(r, R_RCR, RCR_APM | RCR_AM | RCR_AB | RCR_UNLIMITED);
|
|
|
|
// Multicast: everything. The stack filters, and a hash filter that is wrong
|
|
// drops IPv6 neighbour discovery in a way that looks like a routing problem.
|
|
wr32(r, R_MAR0, 0xFFFFFFFF);
|
|
wr32(r, R_MAR0 + 4, 0xFFFFFFFF);
|
|
|
|
wr8(r, R_CR, CR_RE | CR_TE);
|
|
wr8(r, R_9346CR, C9346_LOCK);
|
|
|
|
r8169_phy_up(r);
|
|
|
|
wr16(r, R_ISR, 0xFFFF); // clear anything left over
|
|
wr16(r, R_IMR, ISR_ROK | ISR_RER | ISR_TOK | ISR_TER |
|
|
ISR_RDU | ISR_LINKCHG);
|
|
|
|
// MSI first: every 8111 has it, and on the boards these are soldered to it
|
|
// is the only interrupt that is sure to arrive. See pci_irq_attach().
|
|
if (pci_irq_attach(d, r8169_intr, r, "r8169", 0) < 0)
|
|
kinfo("r8169: no usable interrupt line; the link will be polled\n");
|
|
|
|
r->ready = 1;
|
|
|
|
// Said with cprintf rather than kinfo, and said in full.
|
|
//
|
|
// This driver's first run is on a machine nobody here can attach a debugger
|
|
// to, so the one line it prints has to carry everything a bug report would
|
|
// need: which variant answered, what address it claims, whether the PHY sees
|
|
// anything, and which line it will interrupt on. XID is the hardware version
|
|
// -- the top bits of TxConfig -- and is how Realtek parts are told apart,
|
|
// because the PCI device id is 8168 for two decades of silicon.
|
|
{
|
|
uint32 xid = (rd32(r, R_TCR) >> 20) & 0xFCF;
|
|
int bmsr = mii_read(r, 1);
|
|
|
|
kinfo("r8169: xid %x, %x:%x:%x:%x:%x:%x, irq %d (%s), %s (bmsr %x)\n",
|
|
xid,
|
|
r->mac[0], r->mac[1], r->mac[2], r->mac[3], r->mac[4], r->mac[5],
|
|
d->irq_line, pci_irq_kind(d),
|
|
(rd8(r, R_PHYSTATUS) & PHYSTATUS_LINK) ? "link up" : "link down",
|
|
bmsr);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
r8169_attached(struct pci_dev *d, struct device *dev)
|
|
{
|
|
for (int i = 0; i < R8169_MAX_NICS; i++)
|
|
if (nics[i].ready && nics[i].pdev == d) {
|
|
dev->priv = &nics[i];
|
|
nics[i].ndev = dev;
|
|
return;
|
|
}
|
|
}
|
|
|
|
static const struct netdev_ops r8169_netdev_ops = {
|
|
.transmit = r8169_transmit,
|
|
.receive = r8169_receive,
|
|
.mac = r8169_mac_op,
|
|
.link_up = r8169_link_up,
|
|
};
|
|
|
|
// The whole RTL8111/8168 family answers to 8168, which is why one entry covers
|
|
// most of the laptops this will ever run on. The others are the older PCI
|
|
// 8169, the Fast Ethernet 8101/8106, and the 2.5G 8125 -- listed because they
|
|
// share this programming model, and untested because none of them is here.
|
|
static const struct pci_match r8169_match[] = {
|
|
{ 0x10EC, 0x8168, 0, 0 }, // RTL8111/8168/8411 -- includes the 8111H
|
|
{ 0x10EC, 0x8169, 0, 0 }, // the original gigabit part
|
|
{ 0x10EC, 0x8136, 0, 0 }, // RTL8101/8102/8106, Fast Ethernet
|
|
{ 0x10EC, 0x8161, 0, 0 },
|
|
{ 0x10EC, 0x2502, 0, 0 },
|
|
{ 0x10EC, 0x2600, 0, 0 },
|
|
{ 0, 0, 0, 0 },
|
|
};
|
|
|
|
const struct pci_driver r8169_driver = {
|
|
.name = "r8169",
|
|
.devname = "eth",
|
|
.match = r8169_match,
|
|
.ops = &r8169_netdev_ops,
|
|
.probe = r8169_probe,
|
|
.attached = r8169_attached,
|
|
};
|