temp
This commit is contained in:
1 parent
d36f19509c
commit
30d20457f0
309 files changed
+121746
-1963
No files matched your search
@@ -4,9 +4,6 @@
|
||||
#include "rtl816x.h"
|
||||
|
||||
static DRIVER_OBJECT gRtl816xDriver;
|
||||
static RTL816X_DEVICE* gRtl816xDevices[RTL816X_MAX_DEVICES];
|
||||
static uint32_t gRtl816xDeviceCount;
|
||||
static SPINLOCK gRtl816xRegistryLock = SPINLOCK_INIT;
|
||||
|
||||
static const IO_DEVICE_ID gRtl816xIds[] = {
|
||||
{ IoBusPci, { "PCI\\VEN_10EC&DEV_8168", sizeof("PCI\\VEN_10EC&DEV_8168") - 1 } },
|
||||
@@ -295,71 +292,18 @@ static void RtlDpcRoutine(KDPC* dpc, void* context, void* systemArgument1, void*
|
||||
DbgPrint("RTL816X: interrupt status error bits=0x%04x\n", status);
|
||||
}
|
||||
|
||||
// Implements the rtl Register Device operation.
|
||||
static KSTATUS RtlRegisterDevice(RTL816X_DEVICE* r) {
|
||||
if (!r) return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gRtl816xRegistryLock);
|
||||
for (uint32_t i = 0; i < gRtl816xDeviceCount; i++) {
|
||||
if (gRtl816xDevices[i] == r) {
|
||||
KeReleaseSpinlock(&gRtl816xRegistryLock, flags);
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (gRtl816xDeviceCount >= RTL816X_MAX_DEVICES) {
|
||||
KeReleaseSpinlock(&gRtl816xRegistryLock, flags);
|
||||
return NTLSTATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
gRtl816xDevices[gRtl816xDeviceCount++] = r;
|
||||
KeReleaseSpinlock(&gRtl816xRegistryLock, flags);
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Implements the rtl Unregister Device operation.
|
||||
static void RtlUnregisterDevice(RTL816X_DEVICE* r) {
|
||||
if (!r) return;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gRtl816xRegistryLock);
|
||||
for (uint32_t i = 0; i < gRtl816xDeviceCount; i++) {
|
||||
if (gRtl816xDevices[i] == r) {
|
||||
gRtl816xDevices[i] = gRtl816xDevices[gRtl816xDeviceCount - 1u];
|
||||
gRtl816xDevices[gRtl816xDeviceCount - 1u] = (RTL816X_DEVICE*)0;
|
||||
gRtl816xDeviceCount--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
KeReleaseSpinlock(&gRtl816xRegistryLock, flags);
|
||||
}
|
||||
|
||||
// Implements the rtl Isr operation.
|
||||
static void RtlIsr(void) {
|
||||
RTL816X_DEVICE* snapshot[RTL816X_MAX_DEVICES];
|
||||
uint32_t count = 0;
|
||||
static void RtlIsr(void* context) {
|
||||
RTL816X_DEVICE* r = (RTL816X_DEVICE*)context;
|
||||
if (!r || !r->Started || r->Removed || r->SurpriseRemoved) return;
|
||||
uint16_t status = RtlRead16(r, RTL_REG_INTR_STAT);
|
||||
status &= RTL_INTR_ENABLES;
|
||||
if (!status || status == 0xFFFFu)
|
||||
return;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gRtl816xRegistryLock);
|
||||
count = gRtl816xDeviceCount;
|
||||
if (count > RTL816X_MAX_DEVICES)
|
||||
count = RTL816X_MAX_DEVICES;
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
snapshot[i] = gRtl816xDevices[i];
|
||||
KeReleaseSpinlock(&gRtl816xRegistryLock, flags);
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
RTL816X_DEVICE* r = snapshot[i];
|
||||
if (!r || !r->Started || r->Removed || r->SurpriseRemoved)
|
||||
continue;
|
||||
|
||||
uint16_t status = RtlRead16(r, RTL_REG_INTR_STAT);
|
||||
status &= RTL_INTR_ENABLES;
|
||||
if (!status || status == 0xFFFFu)
|
||||
continue;
|
||||
|
||||
RtlWrite16(r, RTL_REG_INTR_STAT, status);
|
||||
r->PendingIsr |= status;
|
||||
KeInsertQueueDpc(&r->Dpc, (void*)0, (void*)0);
|
||||
}
|
||||
RtlWrite16(r, RTL_REG_INTR_STAT, status);
|
||||
r->PendingIsr |= status;
|
||||
KeInsertQueueDpc(&r->Dpc, (void*)0, (void*)0);
|
||||
}
|
||||
|
||||
// Implements the rtl Send Frame operation.
|
||||
@@ -468,39 +412,13 @@ static KSTATUS RtlSelectRegisterBar(RTL816X_DEVICE* r) {
|
||||
return NTLSTATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
// Configures a dedicated MSI vector and falls back to a routed INTx line.
|
||||
// Connects a PCI message interrupt or a routed INTx source.
|
||||
static KSTATUS RtlConfigureInterrupt(RTL816X_DEVICE* r) {
|
||||
if (!r || !r->Pdo)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
r->Irq = 0xFFu;
|
||||
r->UsingMsi = false;
|
||||
|
||||
KSTATUS msiStatus = PciEnableMsiAuto(r->Pdo, &r->Irq);
|
||||
if (KSUCCESS(msiStatus)) {
|
||||
r->UsingMsi = true;
|
||||
DbgPrint("RTL816X: using MSI IRQ slot %u\n", r->Irq);
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
DbgPrint("RTL816X: MSI setup failed status=0x%x; attempting explicit INTx fallback\n",
|
||||
msiStatus);
|
||||
|
||||
KSTATUS intxStatus = PciGetInterrupt(r->Pdo, &r->Irq);
|
||||
if (!KSUCCESS(intxStatus))
|
||||
return intxStatus;
|
||||
if (r->Irq == 0xFFu || r->Irq >= 24u)
|
||||
return NTLSTATUS_NOT_SUPPORTED;
|
||||
|
||||
intxStatus = PciEnableDevice(r->Pdo,
|
||||
PCI_ENABLE_BUSMASTER |
|
||||
PCI_ENABLE_INTX |
|
||||
(r->UseMmio ? PCI_ENABLE_MEMORY : PCI_ENABLE_IO));
|
||||
if (!KSUCCESS(intxStatus))
|
||||
return intxStatus;
|
||||
|
||||
DbgPrint("RTL816X: using legacy INTx IRQ %u\n", r->Irq);
|
||||
return NTLSTATUS_SUCCESS;
|
||||
r->InterruptRequest.Routine = RtlIsr;
|
||||
r->InterruptRequest.Context = r;
|
||||
r->InterruptRequest.Affinity = 0;
|
||||
r->InterruptRequest.Interrupt = (KE_INTERRUPT*)0;
|
||||
return PciConnectInterrupts(r->Pdo, &r->InterruptRequest, 1u, &r->UsingMsi);
|
||||
}
|
||||
|
||||
// Implements the rtl Start Device operation.
|
||||
@@ -547,18 +465,7 @@ static KSTATUS RtlStartDevice(RTL816X_DEVICE* r) {
|
||||
return st;
|
||||
}
|
||||
|
||||
st = RtlConfigureInterrupt(r);
|
||||
if (!KSUCCESS(st)) {
|
||||
DbgPrint("RTL816X: no usable MSI or INTx interrupt status=0x%x\n", st);
|
||||
return st;
|
||||
}
|
||||
|
||||
RtlReadMac(r);
|
||||
DbgPrint("RTL816X: MAC %02x:%02x:%02x:%02x:%02x:%02x irq=%u mode=%s\n",
|
||||
r->NetDevice.HardwareAddress[0], r->NetDevice.HardwareAddress[1],
|
||||
r->NetDevice.HardwareAddress[2], r->NetDevice.HardwareAddress[3],
|
||||
r->NetDevice.HardwareAddress[4], r->NetDevice.HardwareAddress[5],
|
||||
r->Irq, r->UsingMsi ? "MSI" : "INTx");
|
||||
|
||||
st = RtlAllocateDma(r);
|
||||
if (!KSUCCESS(st))
|
||||
@@ -571,13 +478,21 @@ static KSTATUS RtlStartDevice(RTL816X_DEVICE* r) {
|
||||
r->NetDevice.DriverContext = r;
|
||||
r->NetDevice.SendFrame = RtlSendFrame;
|
||||
|
||||
st = RtlRegisterDevice(r);
|
||||
st = RtlConfigureInterrupt(r);
|
||||
if (!KSUCCESS(st)) {
|
||||
DbgPrint("RTL816X: no usable MSI or INTx interrupt status=0x%x\n", st);
|
||||
RtlReleaseDma(r);
|
||||
return st;
|
||||
}
|
||||
|
||||
KeIrqRegister(r->Irq, RtlIsr);
|
||||
KE_INTERRUPT_INFO route;
|
||||
if (KSUCCESS(KeInterruptQuery(r->InterruptRequest.Interrupt, &route)))
|
||||
DbgPrint("RTL816X: MAC %02x:%02x:%02x:%02x:%02x:%02x cpu=%u vector=0x%02x mode=%s\n",
|
||||
r->NetDevice.HardwareAddress[0], r->NetDevice.HardwareAddress[1],
|
||||
r->NetDevice.HardwareAddress[2], r->NetDevice.HardwareAddress[3],
|
||||
r->NetDevice.HardwareAddress[4], r->NetDevice.HardwareAddress[5],
|
||||
route.CpuIndex, route.Vector, r->UsingMsi ? "MSI/MSI-X" : "INTx");
|
||||
|
||||
r->Started = true;
|
||||
RtlProgramHardware(r);
|
||||
r->Fdo->PnpState = DevicePnpStarted;
|
||||
@@ -585,13 +500,14 @@ static KSTATUS RtlStartDevice(RTL816X_DEVICE* r) {
|
||||
st = NetRegisterDevice(&r->NetDevice);
|
||||
if (!KSUCCESS(st)) {
|
||||
RtlStopDma(r);
|
||||
RtlUnregisterDevice(r);
|
||||
if (r->InterruptRequest.Interrupt)
|
||||
PciDisconnectInterrupts(r->Pdo, &r->InterruptRequest, 1u);
|
||||
RtlReleaseDma(r);
|
||||
return st;
|
||||
}
|
||||
|
||||
DbgPrint("RTL816X: initialized; RX/TX enabled on %s IRQ %u\n",
|
||||
r->UsingMsi ? "MSI" : "INTx", r->Irq);
|
||||
DbgPrint("RTL816X: initialized; RX/TX enabled via %s\n",
|
||||
r->UsingMsi ? "MSI/MSI-X" : "INTx");
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -626,7 +542,8 @@ KSTATUS Rtl816xDispatchPnp(DEVICE_OBJECT* device, IRP* irp) {
|
||||
r->Removed = true;
|
||||
device->PnpState = DevicePnpDeleted;
|
||||
RtlStopDma(r);
|
||||
RtlUnregisterDevice(r);
|
||||
if (r->InterruptRequest.Interrupt)
|
||||
PciDisconnectInterrupts(r->Pdo, &r->InterruptRequest, 1u);
|
||||
RtlReleaseDma(r);
|
||||
IoDetachDevice(device);
|
||||
IoDeleteDevice(device);
|
||||
@@ -653,7 +570,7 @@ KSTATUS Rtl816xAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObj
|
||||
r->Magic = RTL816X_DEVICE_MAGIC;
|
||||
r->Fdo = fdo;
|
||||
r->Pdo = physicalDeviceObject;
|
||||
r->Irq = 0xFFu;
|
||||
r->PciInfo.InterruptLine = 0xFFu;
|
||||
r->TxLock = (SPINLOCK)SPINLOCK_INIT;
|
||||
|
||||
r->LowerDevice = IoAttachDeviceToDeviceStack(fdo, physicalDeviceObject);
|
||||
@@ -671,8 +588,6 @@ static KSTATUS DriverInitialize(NTL_MODULE* module) {
|
||||
|
||||
DbgPrint("RTL816X: driver loading...\n");
|
||||
|
||||
gRtl816xDeviceCount = 0;
|
||||
|
||||
memset(&gRtl816xDriver, 0, sizeof(gRtl816xDriver));
|
||||
IoInitializeDriverObject(&gRtl816xDriver, SYS_SV_LITERAL("rtl816x"));
|
||||
gRtl816xDriver.IdTable = &gRtl816xIdTable;
|
||||
|
||||
@@ -116,7 +116,7 @@ typedef struct RTL816X_DEVICE {
|
||||
PCI_DEVICE_INFO PciInfo;
|
||||
PCI_BAR RegisterBar;
|
||||
uint64_t RegisterBytes;
|
||||
uint8_t Irq;
|
||||
PCI_INTERRUPT_REQUEST InterruptRequest;
|
||||
bool UsingMsi;
|
||||
|
||||
bool Started;
|
||||
|
||||
Reference in new issue
Block a user