📄 rtfast.c
字号:
#include "rtfast.h"
#define DBG 1
typedef struct _RT_WUFPATT
{
ULONG WUFBufSize;
UCHAR WUFPacketBytes[0x80];
UCHAR CRC; //84
ULONG Wakeup; //88
ULONG LSBWakeup;//8C
UCHAR LSBCRC; //90
} RT_WUFPATT, *PRT_WUFPATT;
typedef struct _RTFAST_ADAPTER {
NDIS_HANDLE MiniportHandle; // 000
NDIS_HANDLE ContextHandle; // 004
UINT ChipVersion; // 008
struct _RTFAST_ADAPTER * NextAdapter; // 00C
UINT IoBaseAddr; // 010
UINT IoRange; // 014
UCHAR InterruptVector; // 018
UCHAR InterruptLevel; // 019
ULONG DuplexMode; // 01C
ULONG ChipOnCardbus; // 020
ULONG EarlyTxThreshold; // 024
ULONG slotnum; // 028
UCHAR Sloth;
ULONG RxMaxDMABurst; // 030
ULONG TxMaxDMABurst; // 034
ULONG EarlyRxThreshold; // 038
ULONG TxInterFrameGap; // 03C
ULONG RxBufLen; // 040
ULONG RxConfig; // 044
ULONG TxConfig; // 048
UCHAR StationAddress[MAC_LENGTH]; // 04C[6]
UCHAR PermanentAddress[MAC_LENGTH];// 052[6]
NDIS_MINIPORT_INTERRUPT Interrupt; // 058-0A8
USHORT pad_0a8; // 0A8
USHORT sysInterruptStatus; // 0AA ???
USHORT pad_0ac; // 0AC
USHORT regInterruptStatus; // 0AE ???
BOOLEAN bResetingNIC; // 0B0
NDIS_MINIPORT_TIMER ResetCheckingTimer; // 0B8-10C
ULONG pad_110[5]; // 110 - 124
ULONG64 FramesXmitGood; // 128 12C
ULONG64 FramesRcvGood; // 130 134
ULONG FramesXmitBad; // 138
ULONG FramesXmitOneCollision; // 13C
ULONG FramesXmitManyCollisions; // 140
ULONG FrameAlignmentErrors; // 144
ULONG CrcErrors; // 148
ULONG MissedPackets; // 14C
PVOID pad_150[4];
NDIS_STATUS connectStatus; // 160
USHORT pad_164;
BOOLEAN bInReseting; // 166
BOOLEAN bAutoNegCompleted; // 167
ULONG pad_168;
ULONG pad_16c;
NDIS_MINIPORT_TIMER NwayCheckingTimer; // 170-1C8
ULONG NWaytimerExpireRemains; // 1C8
NDIS_MINIPORT_TIMER InitNwayChkingTimer; // 1D0-224
NDIS_MINIPORT_TIMER LnkChgReNwayTimer; // 228-280
UINT TimeRem2InitNWay; // 280
UCHAR MCList[0xC0]; // 284-344 802_3_MULTICAST_LIST
UCHAR MulticastRegs[8]; // 344-34C
ULONG PacketFilter; // 34C ???
ULONG eMacOptions; // 350
ULONG MaxLookAhead; // 354
PVOID RxReadPtr; // 358
USHORT CurChipReadPtr; // 35C
PUCHAR RxPktDMAStart; // 360
PUCHAR RxPktDMAStop; // 364
UINT PacketxLen; // 368
ULONG pad_36c;
USHORT NicRxHeader; // 370
BOOLEAN bRxIntEnabled; // 372
PNDIS_PACKET FirstPacket; // 374
PNDIS_PACKET LastPacket; // 378
USHORT RegXmitStatus; // 37C Transmit Status of All
UCHAR HwFinishTxPacket; // 37E
UCHAR HwUnFinTxPackets; // 37F
// pair
UCHAR CurTxDesc; // 380
UCHAR CurrentTxPacket; // 381
UCHAR NextTxPacket; // 382
UINT NumXmitInQueue; // 384
UINT PacketTxStatus[MAX_X_BUFS]; // 388-3C8
PUCHAR TxBufReadPtr[MAX_X_BUFS]; // 3C8-408
PNDIS_PACKET Packets[MAX_X_BUFS]; // 408-448
PUCHAR DMADataVa[MAX_X_BUFS]; // 448-488
PUCHAR RxDMABufStart; // 488
NDIS_PHYSICAL_ADDRESS DmaPhyAddr; // 490
ULONG pad_498[0x20];
PUCHAR DMADataPa[MAX_X_BUFS]; // 518-558
PUCHAR RcvBufStartPa; // 558
PNDIS_PACKET TxPacket[MAX_X_BUFS]; // 55C-59C
NDIS_SPIN_LOCK SpinLock; // 5A0
USHORT RegConnectStatus; // 5A8
ULONG pad_5a8;
ULONG VarStuff[0x1C]; // 5AC-61C
ULONG dwEnviron; // 61C
ULONG pad_620;
ULONG pad_624;
ULONG PowerDeviceState; // 628
ULONG PowerSystemState; // 62C
RT_WUFPATT regPattern[8]; // 630-AD0 regPattern
UCHAR WUPattCount; // AD0
UCHAR pad_ad1;
UCHAR bWIN98APM; // AD2
UCHAR enableWOL; // AD3
UCHAR bWakeUpFrame; // AD4
UCHAR bWakeUpEnable; // AD5
BOOLEAN bPME; // AD6
ULONG dWakeOnLan; // AD8
ULONG dMassBrowse; // ADC
BOOLEAN bInterruptDisabled; // AE0
BOOLEAN pad_ae1[3];
ULONG enableLDPS; // AE4
ULONG RamAddr; // AE8
ULONG RamSize; // AEC
PVOID RamBase; // AF0
ULONG NicWakeupPattern[0x14]; // AF4-B44
ULONG RegWakeupFrameBytes[0x14];
} RTFAST_ADAPTER, * PRTFAST_ADAPTER;
BOOLEAN CardSetup (
IN PRTFAST_ADAPTER Adapter
)
{
UCHAR v[8];
ULONG i = 0;
#if DBG
DbgPrint("===>CardSetup\n");
#endif
while(i < 0x9C40)
{
WritePortUCHAR(CR, 0xC);
if(0xC == (0xC & ReadPortUCHAR(CR)))
break;
KeStallExecutionProcessor(0x32);
i++;
};
WritePortUCHAR(CR, 0x10);
WritePortUCHAR(CR, 0xC);
WritePortULONG(RCR, Adapter->RxConfig);
WritePortUCHAR(CR9346, 0xC0);
WritePortULONG(IDR0, (Adapter->PermanentAddress[3]<<24) + \
(Adapter->PermanentAddress[2]<<16) + \
(Adapter->PermanentAddress[1]<<8) + \
(Adapter->PermanentAddress[0]));
WritePortULONG(IDR0 + 4, (Adapter->PermanentAddress[5]<<8 ) + \
(Adapter->PermanentAddress[4]) );
WritePortUCHAR(CR9346, 0);
WritePortULONG(MAR0, 0xFFFFFFFF);
WritePortULONG(MAR0 + 4, 0xFFFFFFFF);
WritePortULONG(RCR, Adapter->RxConfig);
WritePortULONG(TCR, Adapter->TxConfig);
Adapter->CurChipReadPtr = 0xFFF0; // CAPR
Adapter->RxPktDMAStart = Adapter->RxDMABufStart;
Adapter->RxPktDMAStop = Adapter->RxDMABufStart + (0x2000<<Adapter->RxBufLen);
Adapter->HwFinishTxPacket = 0;
Adapter->HwUnFinTxPackets = 0x10;
Adapter->CurTxDesc = 4;
Adapter->CurrentTxPacket = 0;
Adapter->NextTxPacket = 0;
if(4 & Adapter->PacketFilter)
{
i = 0;
while(i < 8)
{
v[i] = Adapter->MulticastRegs[i];
i++;
}
}
WritePortULONG(MAR0, v[0] + (v[1]<<8) + (v[2]<<0x10) + (v[3]<<0x18));
WritePortULONG(MAR0 + 4, v[4] + (v[5]<<8) + (v[6]<<0x10) + (v[7]<<0x18));
WritePortUSHORT(ISR, 0xFFFF);
WritePortULONG(RBSTART, Adapter->RcvBufStartPa);
#if DBG
DbgPrint("<===CardSetup\n");
#endif
return(TRUE);
}
VOID WriteOurCapability (
IN PRTFAST_ADAPTER Adapter
)
{
ULONG dmode;
USHORT usCap = 0;
#if DBG
DbgPrint("===>WriteOurCapability\n");
#endif
dmode = Adapter->DuplexMode;
if(dmode == 2)
usCap = 0x21;
else if(dmode == 3)
usCap = 0x61;
else if(dmode == 4)
usCap = 0xE1;
else if(dmode == 5 || dmode <= 1)
usCap = 0x1E1;
else
return;
WritePortUSHORT(ANAR, usCap);
#if DBG
DbgPrint("<===WriteOurCapability\n");
#endif
return;
}
VOID RestartNway (
IN PRTFAST_ADAPTER Adapter
)
{
#if DBG
DbgPrint("===>RestartNway\n");
#endif
WriteOurCapability(Adapter);
Adapter->bInReseting = 1;
Adapter->bAutoNegCompleted = 0;
WritePortUSHORT(BMCR, 0x1200); // enable Auto-negotiation & restart it
NdisSetTimer((PNDIS_TIMER)&Adapter->NwayCheckingTimer, 0x32);
#if DBG
DbgPrint("<===RestartNway\n");
#endif
}
VOID NwayCheckingTimerProc (
IN PVOID SystemSpecific1,
IN PRTFAST_ADAPTER Adapter,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3
)
{
#if DBG
DbgPrint("===>NwayCheckingTimerProc\n");
#endif
if(ReadPortUSHORT( ANER))
{
RestartNway(Adapter);
Adapter->NWaytimerExpireRemains = 0;
#if DBG
DbgPrint("<===NwayCheckingTimerProc: read error\n");
#endif
return;
}
if(Adapter->bAutoNegCompleted)
{
WritePortUSHORT(ISR, 0x20);
Adapter->bInReseting = 0;
#if DBG
DbgPrint("<===NwayCheckingTimerProc: bAutoNegCompleted\n");
#endif
return;
}
if(0 == (0x20 & ReadPortUSHORT(BMSR)))
{
Adapter->NWaytimerExpireRemains = 0;
Adapter->bAutoNegCompleted = 1;
NdisSetTimer((PNDIS_TIMER)&Adapter->NwayCheckingTimer, 0x1F4); // timer
#if DBG
DbgPrint("<===NwayCheckingTimerProc: BMSR != 20h\n");
#endif
return;
}
NdisSetTimer((PNDIS_TIMER)&Adapter->NwayCheckingTimer, 0x32); // timer
Adapter->NWaytimerExpireRemains += 0x32;
#if DBG
DbgPrint("<===NwayCheckingTimerProc\n");
#endif
return;
}
//=====================================================
VOID Rtl8139set_param (
IN PRTFAST_ADAPTER Adapter,
IN ULONG u1,
IN ULONG u2
)
{
ULONG index;
#if DBG
DbgPrint("===>Rtl8139set_param\n");
#endif
if(u1 >= 4)
{
WritePortULONG(NWAYTR, 0x20);
WritePortULONG(PHY1_PARM, 0x78FA8388);
WritePortULONG(TW_PARM, 0xCB38DE43);
#if DBG
DbgPrint("<===Rtl8139set_param p1: %08x >= 4\n", u1);
#endif
return;
}
WritePortULONG(NWAYTR, 0);
index = 0;
while (index < 4)
{
if(Adapter->ChipVersion == 1 && u1 == 3)
u1 = 2;
WritePortULONG(TW_PARM, Adapter->VarStuff[u1*5 + index]);
index++;
};
#if DBG
DbgPrint("<===Rtl8139set_param\n");
#endif
return;
}
__inline
VOID Enque (
IN PRTFAST_ADAPTER Adapter,
IN PNDIS_PACKET packet
)
{
#if DBG
DbgPrint("===>Enque\n");
#endif
if(Adapter->FirstPacket == NULL) {
Adapter->LastPacket = packet;
} else {
*(UINT*)Adapter->LastPacket->MiniportReserved = (UINT )packet;
}
Adapter->NumXmitInQueue++;
Adapter->FirstPacket = packet;
#if DBG
DbgPrint("<===Enque\n");
#endif
return;
}
__inline
PNDIS_PACKET Deque (
IN PRTFAST_ADAPTER Adapter
)
{
PNDIS_PACKET p;
#if DBG
DbgPrint("===>Deque\n");
#endif
if(Adapter->FirstPacket == NULL)
return NULL;
p = Adapter->FirstPacket;
if(Adapter->LastPacket == Adapter->FirstPacket)
{
Adapter->LastPacket = Adapter->FirstPacket = NULL;
} else {
Adapter->FirstPacket = *(PNDIS_PACKET *)(Adapter->FirstPacket->MiniportReserved);
}
Adapter->NumXmitInQueue--;
#if DBG
DbgPrint("<===Deque\n");
#endif
return p;
}
PNDIS_PACKET GetTxPacket (
IN PRTFAST_ADAPTER Adapter,
IN UCHAR serial
)
{
if(serial >= 0 && serial <= 0xF)
return Adapter->TxPacket[serial];
return NULL;
}
NDIS_STATUS CleanupSendedPackets (
IN PRTFAST_ADAPTER Adapter
)
{
NDIS_STATUS Status;
UCHAR i, j;
PNDIS_PACKET p;
#if DBG
DbgPrint("===>CleanupSendedPackets\n");
#endif
Status = NDIS_STATUS_FAILURE;
i = 0x10 - Adapter->HwUnFinTxPackets;
j = Adapter->HwFinishTxPacket;
while( i > 0)
{
NdisMSendComplete(Adapter->MiniportHandle,
GetTxPacket(Adapter, j & 0xF), Status);
Adapter->HwUnFinTxPackets++;
j++;
i--;
};
while(NULL != (p=Deque(Adapter)))
{
NdisMSendComplete(Adapter->MiniportHandle, p, Status);
}
#if DBG
DbgPrint("<===CleanupSendedPackets\n");
#endif
return NDIS_STATUS_SUCCESS;
}
VOID LinkChangeReNwayTimerProc (
IN ULONG para1,
IN PRTFAST_ADAPTER Adapter,
IN USHORT BMCRegister,
IN ULONG para4
)
{
USHORT us, us1, us2;
#if DBG
DbgPrint("===>LinkChangeReNwayTimerProc\n");
#endif
us = ReadPortUSHORT(BMSR);
us1 = ReadPortUSHORT(ANER);
if(us1 & 1)
{
#if DBG
DbgPrint("<===LinkChangeReNwayTimerProc BMSR: %04x\n", us);
#endif
return;
}
switch( Adapter->DuplexMode) {
case 1:
us2 = 0x1000;
break;
case 2:
us2 = 0;
break;
case 3:
us2 = 0x100;
break;
case 4:
us2 = 0x2000;
break;
default:
us2 = (USHORT)Adapter->MiniportHandle;
}
#if DBG
DbgPrint("<===LinkChangeReNwayTimerProc BMSR: %04x\n", us);
#endif
WritePortUSHORT(BMCR, us2);
WritePortUSHORT(ISR, 0x20); // packet underrun or link change
return;
}
VOID RTFast_DisableInterrupt (
IN PRTFAST_ADAPTER Adapter
)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -