?? card.c
字號:
//
// Set direction (Read)
//
NdisRawWritePortUchar(
Adapter->IoPAddr + NIC_COMMAND,
CR_START | CR_PAGE0 | CR_DMA_READ
);
NdisRawReadPortUshort(
Adapter->IoPAddr + NIC_RACK_NIC,
&Tmp
);
*TargetBuffer = MSB(Tmp);
//
// Wait for DMA to complete
//
Count = 0xFFFF;
while (Count) {
NdisRawReadPortUchar(
Adapter->IoPAddr + NIC_INTR_STATUS,
&IsrValue
);
if (IsrValue & ISR_DMA_DONE) {
break;
} else {
Count--;
NdisStallExecution(4);
}
#if DBG
if (!(IsrValue & ISR_DMA_DONE)) {
DbgPrint("CopyUpDMA didn't finish!");
}
#endif // DBG
}
SourceBuffer++;
TargetBuffer++;
BufferLength--;
}
//
// Set Count and destination address
//
NdisRawWritePortUchar(
Adapter->IoPAddr + NIC_RMT_ADDR_LSB,
LSB(PtrToUlong(SourceBuffer))
);
NdisRawWritePortUchar(
Adapter->IoPAddr + NIC_RMT_ADDR_MSB,
MSB(PtrToUlong(SourceBuffer))
);
// NE2000 PCMCIA CHANGE!!! start
// NdisRawWritePortUchar(
// Adapter->IoPAddr + NIC_RMT_COUNT_LSB,
// LSB(BufferLength)
// );
//
// NdisRawWritePortUchar(
// Adapter->IoPAddr + NIC_RMT_COUNT_MSB,
// MSB(BufferLength)
// );
if (BufferLength & 1)
{
NdisRawWritePortUchar(
Adapter->IoPAddr + NIC_RMT_COUNT_LSB,
LSB(BufferLength + 1)
);
NdisRawWritePortUchar(
Adapter->IoPAddr + NIC_RMT_COUNT_MSB,
MSB(BufferLength + 1)
);
}
else
{
NdisRawWritePortUchar(
Adapter->IoPAddr + NIC_RMT_COUNT_LSB,
LSB(BufferLength)
);
NdisRawWritePortUchar(
Adapter->IoPAddr + NIC_RMT_COUNT_MSB,
MSB(BufferLength)
);
}
// NE2000 PCMCIA CHANGE!!! end
//
// Set direction (Read)
//
NdisRawWritePortUchar(
Adapter->IoPAddr + NIC_COMMAND,
CR_START | CR_PAGE0 | CR_DMA_READ
);
//
// Read words from port
//
NdisRawReadPortBufferUshort(
Adapter->IoPAddr + NIC_RACK_NIC,
(PUSHORT)TargetBuffer,
(BufferLength >> 1));
//
// Read trailing byte (if necessary)
//
if (BufferLength & 1) {
TargetBuffer += (BufferLength - 1);
// NE2000 PCMCIA CHANGE!!! start
//NdisRawReadPortUchar(
// Adapter->IoPAddr + NIC_RACK_NIC,
// TargetBuffer
//);
NdisRawReadPortUshort(
Adapter->IoPAddr + NIC_RACK_NIC,
&Tmp
);
*TargetBuffer = LSB(Tmp);
// NE2000 PCMCIA CHANGE!!! end
}
}
//
// Wait for DMA to complete
//
Count = 0xFFFF;
while (Count) {
NdisRawReadPortUchar(
Adapter->IoPAddr + NIC_INTR_STATUS,
&IsrValue
);
if (IsrValue & ISR_DMA_DONE) {
break;
} else {
Count--;
NdisStallExecution(4);
}
}
#if DBG
if (!(IsrValue & ISR_DMA_DONE)) {
DbgPrint("CopyUpDMA didn't finish!\n");
}
IF_LOG(Ne2000Log('<');)
#endif // DBG
return TRUE;
}
ULONG
CardComputeCrc(
IN PUCHAR Buffer,
IN UINT Length
)
/*++
Routine Description:
Runs the AUTODIN II CRC algorithm on buffer Buffer of
length Length.
Arguments:
Buffer - the input buffer
Length - the length of Buffer
Return Value:
The 32-bit CRC value.
Note:
This is adapted from the comments in the assembly language
version in _GENREQ.ASM of the DWB NE1000/2000 driver.
--*/
{
ULONG Crc, Carry;
UINT i, j;
UCHAR CurByte;
Crc = 0xffffffff;
for (i = 0; i < Length; i++) {
CurByte = Buffer[i];
for (j = 0; j < 8; j++) {
Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01);
Crc <<= 1;
CurByte >>= 1;
if (Carry) {
Crc = (Crc ^ 0x04c11db6) | Carry;
}
}
}
return Crc;
}
VOID
CardGetMulticastBit(
IN UCHAR Address[NE2000_LENGTH_OF_ADDRESS],
OUT UCHAR * Byte,
OUT UCHAR * Value
)
/*++
Routine Description:
For a given multicast address, returns the byte and bit in
the card multicast registers that it hashes to. Calls
CardComputeCrc() to determine the CRC value.
Arguments:
Address - the address
Byte - the byte that it hashes to
Value - will have a 1 in the relevant bit
Return Value:
None.
--*/
{
ULONG Crc;
UINT BitNumber;
//
// First compute the CRC.
//
Crc = CardComputeCrc(Address, NE2000_LENGTH_OF_ADDRESS);
//
// The bit number is now in the 6 most significant bits of CRC.
//
BitNumber = (UINT)((Crc >> 26) & 0x3f);
*Byte = (UCHAR)(BitNumber / 8);
*Value = (UCHAR)((UCHAR)1 << (BitNumber % 8));
}
VOID
CardFillMulticastRegs(
IN PNE2000_ADAPTER Adapter
)
/*++
Routine Description:
Erases and refills the card multicast registers. Used when
an address has been deleted and all bits must be recomputed.
Arguments:
Adapter - pointer to the adapter block
Return Value:
None.
--*/
{
UINT i;
UCHAR Byte, Bit;
//
// First turn all bits off.
//
for (i=0; i<8; i++) {
Adapter->NicMulticastRegs[i] = 0;
}
//
// Now turn on the bit for each address in the multicast list.
//
for ( ; i > 0; ) {
i--;
CardGetMulticastBit(Adapter->Addresses[i], &Byte, &Bit);
Adapter->NicMulticastRegs[Byte] |= Bit;
}
}
BOOLEAN SyncCardStop(
IN PVOID SynchronizeContext
)
/*++
Routine Description:
Sets the NIC_COMMAND register to stop the card.
Arguments:
SynchronizeContext - pointer to the adapter block
Return Value:
TRUE if the power has failed.
--*/
{
PNE2000_ADAPTER Adapter = ((PNE2000_ADAPTER)SynchronizeContext);
NdisRawWritePortUchar(
Adapter->IoPAddr + NIC_COMMAND,
CR_STOP | CR_NO_DMA
);
return(FALSE);
}
VOID
CardStartXmit(
IN PNE2000_ADAPTER Adapter
)
/*++
Routine Description:
Sets the NIC_COMMAND register to start a transmission.
The transmit buffer number is taken from Adapter->CurBufXmitting
and the length from Adapter->PacketLens[Adapter->CurBufXmitting].
Arguments:
Adapter - pointer to the adapter block
Return Value:
TRUE if the power has failed.
--*/
{
UINT Length = Adapter->PacketLens[Adapter->CurBufXmitting];
UCHAR Tmp;
//
// Prepare the NIC registers for transmission.
//
NdisRawWritePortUchar(Adapter->IoPAddr+NIC_XMIT_START,
(UCHAR)(Adapter->NicXmitStart + (UCHAR)(Adapter->CurBufXmitting*BUFS_PER_TX)));
//
// Pad the length to 60 (plus CRC will be 64) if needed.
//
if (Length < 60) {
Length = 60;
}
NdisRawWritePortUchar(Adapter->IoPAddr+NIC_XMIT_COUNT_MSB, MSB(Length));
NdisRawWritePortUchar(Adapter->IoPAddr+NIC_XMIT_COUNT_LSB, LSB(Length));
//
// Start transmission, check for power failure first.
//
NdisRawReadPortUchar(Adapter->IoPAddr+NIC_COMMAND, &Tmp);
NdisRawWritePortUchar(Adapter->IoPAddr+NIC_COMMAND,
CR_START | CR_XMIT | CR_NO_DMA);
IF_LOG( Ne2000Log('x');)
}
BOOLEAN
SyncCardGetCurrent(
IN PVOID SynchronizeContext
)
/*++
Routine Description:
Gets the value of the CURRENT NIC register and stores it in Adapter->Current
Arguments:
SynchronizeContext - pointer to the adapter block
Return Value:
None.
--*/
{
PNE2000_ADAPTER Adapter = ((PNE2000_ADAPTER)SynchronizeContext);
//
// Have to go to page 1 to read this register
//
NdisRawWritePortUchar(Adapter->IoPAddr+NIC_COMMAND,
CR_START | CR_NO_DMA | CR_PAGE1);
NdisRawReadPortUchar(Adapter->IoPAddr+NIC_CURRENT,
&Adapter->Current);
NdisRawWritePortUchar(Adapter->IoPAddr+NIC_COMMAND,
CR_START | CR_NO_DMA | CR_PAGE0);
return FALSE;
}
BOOLEAN
SyncCardGetXmitStatus(
IN PVOID SynchronizeContext
)
/*++
Routine Description:
Gets the value of the "transmit status" NIC register and stores
it in Adapter->XmitStatus.
Arguments:
SynchronizeContext - pointer to the adapter block
Return Value:
None.
--*/
{
PNE2000_ADAPTER Adapter = ((PNE2000_ADAPTER)SynchronizeContext);
NdisRawReadPortUchar( Adapter->IoPAddr+NIC_XMIT_STATUS, &Adapter->XmitStatus);
return FALSE;
}
VOID
CardSetBoundary(
IN PNE2000_ADAPTER Adapter
)
/*++
Routine Description:
Sets the value of the "boundary" NIC register to one behind
Adapter->NicNextPacket, to prevent packets from being received
on top of un-indicated ones.
Arguments:
Adapter - pointer to the adapter block
Return Value:
None.
--*/
{
//
// Have to be careful with "one behind NicNextPacket" when
// NicNextPacket is the first buffer in receive area.
//
if (Adapter->NicNextPacket == Adapter->NicPageStart) {
NdisRawWritePortUchar( Adapter->IoPAddr+NIC_BOUNDARY,
(UCHAR)(Adapter->NicPageStop-(UCHAR)1));
} else {
NdisRawWritePortUchar( Adapter->IoPAddr+NIC_BOUNDARY,
(UCHAR)(Adapter->NicNextPacket-(UCHAR)1));
}
}
BOOLEAN
SyncCardSetReceiveConfig(
IN PVOID SynchronizeContext
)
/*++
Routine Description:
Sets the value of the "receive configuration" NIC register to
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -