📄 8390.c
字号:
NdisRawReadPortUchar(Adapter->IOBase + PG0_ISR, &Tmp);
if (Tmp & ISR_RST)
break;
NdisStallExecution(500);
}
#ifdef DBG
if (i == 4)
NDIS_DbgPrint(MIN_TRACE, ("NIC was not reset after 2ms.\n"));
#endif
/* Initialize RCR - Receive Configuration Register (monitor mode) */
NdisRawWritePortUchar(Adapter->IOBase + PG0_RCR, RCR_MON);
/* Initialize TCR - Transmit Configuration Register (loopback mode) */
NdisRawWritePortUchar(Adapter->IOBase + PG0_TCR, TCR_LOOP);
/* Start NIC */
NdisRawWritePortUchar(Adapter->IOBase + PG0_CR, CR_STA | CR_RD2);
return NDIS_STATUS_SUCCESS;
}
NDIS_STATUS NICReset(
PNIC_ADAPTER Adapter)
/*
* FUNCTION: Resets a NIC
* ARGUMENTS:
* Adapter = Pointer to adapter information
* RETURNS:
* Status of operation
*/
{
UCHAR Tmp;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
/* Stop the NIC */
NICStop(Adapter);
/* Reset the NIC */
NdisRawReadPortUchar(Adapter->IOBase + NIC_RESET, &Tmp);
/* Wait for 1.6ms */
NdisStallExecution(1600);
/* Write the value back */
NdisRawWritePortUchar(Adapter->IOBase + NIC_RESET, Tmp);
/* Restart the NIC */
NICStart(Adapter);
return NDIS_STATUS_SUCCESS;
}
static VOID NICStartTransmit(
PNIC_ADAPTER Adapter)
/*
* FUNCTION: Starts transmitting a packet
* ARGUMENTS:
* Adapter = Pointer to adapter information
*/
{
UINT Length;
UCHAR FrameStart;
UCHAR Tmp;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
//FrameStart = Adapter->TXStart + Adapter->TXCurrent * DRIVER_BLOCK_SIZE;
//FrameStart = Adapter->TXStart;
FrameStart = (UCHAR)(Adapter->TXStart + (UCHAR)(Adapter->TXCurrent * BUFFERS_PER_TX_BUF));
/* Set start of frame */
NdisRawReadPortUchar(Adapter->IOBase + PG0_TPSR, &Tmp);
// NdisRawWritePortUchar(Adapter->IOBase + PG0_TPSR,
// Adapter->TXStart + Adapter->TXCurrent * DRIVER_BLOCK_SIZE);
NdisRawWritePortUchar(Adapter->IOBase + PG0_TPSR, FrameStart);
//NDIS_DbgPrint(MID_TRACE, ("Setting start of frame to (%d).\n", FrameStart));
/* Set length of frame */
Length = Adapter->TXSize[Adapter->TXCurrent];
NdisRawWritePortUchar(Adapter->IOBase + PG0_TBCR0, Length & 0xFF);
NdisRawWritePortUchar(Adapter->IOBase + PG0_TBCR1, Length >> 8);
/* Start transmitting */
NdisRawWritePortUchar(Adapter->IOBase + PG0_CR, CR_STA | CR_TXP | CR_RD2);
NDIS_DbgPrint(MID_TRACE, ("Transmitting. FrameStart (%d) TXCurrent (%d) TXStart (%d) Length (%d).\n\n",
FrameStart,
Adapter->TXCurrent,
Adapter->TXStart,
Length));
}
static VOID NICSetBoundaryPage(
PNIC_ADAPTER Adapter)
/*
* FUNCTION: Sets the boundary page on the adapter to be one less than NextPacket
* ARGUMENTS:
* Adapter = Pointer to adapter information
*/
{
if (Adapter->NextPacket == Adapter->PageStart) {
NdisRawWritePortUchar(Adapter->IOBase + PG0_BNRY,
(UCHAR)(Adapter->PageStop - 1));
} else {
NdisRawWritePortUchar(Adapter->IOBase + PG0_BNRY,
(UCHAR)(Adapter->NextPacket - 1));
}
}
static VOID NICGetCurrentPage(
PNIC_ADAPTER Adapter)
/*
* FUNCTION: Retrieves the current page from the adapter
* ARGUMENTS:
* Adapter = Pointer to adapter information
*/
{
UCHAR Current;
/* Select page 1 */
NdisRawWritePortUchar(Adapter->IOBase + PG0_CR, CR_STA | CR_RD2 | CR_PAGE1);
/* Read current page */
NdisRawReadPortUchar(Adapter->IOBase + PG1_CURR, &Current);
/* Select page 0 */
NdisRawWritePortUchar(Adapter->IOBase + PG0_CR, CR_STA | CR_RD2 | CR_PAGE0);
Adapter->CurrentPage = Current;
}
VOID NICUpdateCounters(
PNIC_ADAPTER Adapter)
/*
* FUNCTION: Updates counters
* ARGUMENTS:
* Adapter = Pointer to adapter information
*/
{
UCHAR Tmp;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
NdisRawReadPortUchar(Adapter->IOBase + PG0_CNTR0, &Tmp);
Adapter->FrameAlignmentErrors += Tmp;
NdisRawReadPortUchar(Adapter->IOBase + PG0_CNTR1, &Tmp);
Adapter->CrcErrors += Tmp;
NdisRawReadPortUchar(Adapter->IOBase + PG0_CNTR2, &Tmp);
Adapter->MissedPackets += Tmp;
}
VOID NICReadDataAlign(
PNIC_ADAPTER Adapter,
PUSHORT Target,
ULONG_PTR Source,
USHORT Length)
/*
* FUNCTION: Copies data from a NIC's RAM into a buffer
* ARGUMENTS:
* Adapter = Pointer to adapter information
* Target = Pointer to buffer to copy data into (in host memory)
* Source = Offset into NIC's RAM (must be an even number)
* Length = Number of bytes to copy from NIC's RAM (must be an even number)
*/
{
UCHAR Tmp;
USHORT Count;
Count = Length;
/* Select page 0 and start the NIC */
NdisRawWritePortUchar(Adapter->IOBase + PG0_CR, CR_STA | CR_RD2 | CR_PAGE0);
/* Initialize RSAR0 and RSAR1 - Remote Start Address Registers */
NdisRawWritePortUchar(Adapter->IOBase + PG0_RSAR0, (UCHAR)(Source & 0xFF));
NdisRawWritePortUchar(Adapter->IOBase + PG0_RSAR1, (UCHAR)(Source >> 8));
/* Initialize RBCR0 and RBCR1 - Remote Byte Count Registers */
NdisRawWritePortUchar(Adapter->IOBase + PG0_RBCR0, (UCHAR)(Count & 0xFF));
NdisRawWritePortUchar(Adapter->IOBase + PG0_RBCR1, (UCHAR)(Count >> 8));
/* Select page 0, read and start the NIC */
NdisRawWritePortUchar(Adapter->IOBase + PG0_CR, CR_STA | CR_RD0 | CR_PAGE0);
if (Adapter->WordMode)
NdisRawReadPortBufferUshort(Adapter->IOBase + NIC_DATA, Target, Count >> 1);
else
NdisRawReadPortBufferUchar(Adapter->IOBase + NIC_DATA, Target, Count);
/* Wait for remote DMA to complete, but timeout after some time */
for (Count = 0; Count < 0xFFFF; Count++) {
NdisRawReadPortUchar(Adapter->IOBase + PG0_ISR, &Tmp);
if (Tmp & ISR_RDC)
break;
NdisStallExecution(4);
}
#ifdef DBG
if (Count == 0xFFFF)
NDIS_DbgPrint(MIN_TRACE, ("Remote DMA did not complete.\n"));
#endif
/* Clear remote DMA bit in ISR - Interrupt Status Register */
NdisRawWritePortUchar(Adapter->IOBase + PG0_ISR, ISR_RDC);
}
VOID NICWriteDataAlign(
PNIC_ADAPTER Adapter,
ULONG_PTR Target,
PUSHORT Source,
USHORT Length)
/*
* FUNCTION: Copies data from a buffer into the NIC's RAM
* ARGUMENTS:
* Adapter = Pointer to adapter information
* Target = Offset into NIC's RAM (must be an even number)
* Source = Pointer to buffer to copy data from (in host memory)
* Length = Number of bytes to copy from the buffer (must be an even number)
*/
{
UCHAR Tmp;
USHORT Count;
/* Select page 0 and start the NIC */
NdisRawWritePortUchar(Adapter->IOBase + PG0_CR, CR_STA | CR_RD2 | CR_PAGE0);
/* Handle read-before-write bug */
/* Initialize RSAR0 and RSAR1 - Remote Start Address Registers */
NdisRawWritePortUchar(Adapter->IOBase + PG0_RSAR0, (UCHAR)(Target & 0xFF));
NdisRawWritePortUchar(Adapter->IOBase + PG0_RSAR1, (UCHAR)(Target >> 8));
/* Initialize RBCR0 and RBCR1 - Remote Byte Count Registers */
NdisRawWritePortUchar(Adapter->IOBase + PG0_RBCR0, 0x02);
NdisRawWritePortUchar(Adapter->IOBase + PG0_RBCR1, 0x00);
/* Read and start the NIC */
NdisRawWritePortUchar(Adapter->IOBase + PG0_CR, CR_STA | CR_RD0 | CR_PAGE0);
/* Read data */
NdisRawReadPortUshort(Adapter->IOBase + NIC_DATA, &Count);
/* Wait for remote DMA to complete, but timeout after some time */
for (Count = 0; Count < 0xFFFF; Count++) {
NdisRawReadPortUchar(Adapter->IOBase + PG0_ISR, &Tmp);
if (Tmp & ISR_RDC)
break;
NdisStallExecution(4);
}
#ifdef DBG
if (Count == 0xFFFF)
NDIS_DbgPrint(MIN_TRACE, ("Remote DMA did not complete.\n"));
#endif
/* Clear remote DMA bit in ISR - Interrupt Status Register */
NdisRawWritePortUchar(Adapter->IOBase + PG0_ISR, ISR_RDC);
/* Now output some data */
Count = Length;
/* Initialize RSAR0 and RSAR1 - Remote Start Address Registers */
NdisRawWritePortUchar(Adapter->IOBase + PG0_RSAR0, (UCHAR)(Target & 0xFF));
NdisRawWritePortUchar(Adapter->IOBase + PG0_RSAR1, (UCHAR)(Target >> 8));
/* Initialize RBCR0 and RBCR1 - Remote Byte Count Registers */
NdisRawWritePortUchar(Adapter->IOBase + PG0_RBCR0, (UCHAR)(Count & 0xFF));
NdisRawWritePortUchar(Adapter->IOBase + PG0_RBCR1, (UCHAR)(Count >> 8));
/* Write and start the NIC */
NdisRawWritePortUchar(Adapter->IOBase + PG0_CR, CR_STA | CR_RD1 | CR_PAGE0);
if (Adapter->WordMode)
NdisRawWritePortBufferUshort(Adapter->IOBase + NIC_DATA, Source, Count >> 1);
else
NdisRawWritePortBufferUchar(Adapter->IOBase + NIC_DATA, Source, Count);
/* Wait for remote DMA to complete, but timeout after some time */
for (Count = 0; Count < 0xFFFF; Count++) {
NdisRawReadPortUchar(Adapter->IOBase + PG0_ISR, &Tmp);
if (Tmp & ISR_RDC)
break;
NdisStallExecution(4);
}
#ifdef DBG
if (Count == 0xFFFF)
NDIS_DbgPrint(MIN_TRACE, ("Remote DMA did not complete.\n"));
#endif
/* Clear remote DMA bit in ISR - Interrupt Status Register */
NdisRawWritePortUchar(Adapter->IOBase + PG0_ISR, ISR_RDC);
}
VOID NICReadData(
PNIC_ADAPTER Adapter,
PUCHAR Target,
ULONG_PTR Source,
USHORT Length)
/*
* FUNCTION: Copies data from a NIC's RAM into a buffer
* ARGUMENTS:
* Adapter = Pointer to adapter information
* Target = Pointer to buffer to copy data into (in host memory)
* Source = Offset into NIC's RAM
* Length = Number of bytes to copy from NIC's RAM
*/
{
USHORT Tmp;
/* Avoid transfers to odd addresses */
if (Source & 0x01) {
/* Transfer one word and use the MSB */
NICReadDataAlign(Adapter, &Tmp, Source - 1, 0x02);
*Target = (UCHAR)(Tmp >> 8);
Source++;
Target++;
Length--;
}
if (Length & 0x01) {
/* Transfer as many words as we can without exceeding the buffer length */
Tmp = Length & 0xFFFE;
NICReadDataAlign(Adapter, (PUSHORT)Target, Source, Tmp);
Source += Tmp;
Target = (PUCHAR)((ULONG_PTR) Target + Tmp);
/* Read one word and keep the LSB */
NICReadDataAlign(Adapter, &Tmp, Source, 0x02);
*Target = (UCHAR)(Tmp & 0x00FF);
} else
/* Transfer the rest of the data */
NICReadDataAlign(Adapter, (PUSHORT)Target, Source, Length);
}
VOID NICWriteData(
PNIC_ADAPTER Adapter,
ULONG_PTR Target,
PUCHAR Source,
USHORT Length)
/*
* FUNCTION: Copies data from a buffer into NIC's RAM
* ARGUMENTS:
* Adapter = Pointer to adapter information
* Target = Offset into NIC's RAM to store data
* Source = Pointer to buffer to copy data from (in host memory)
* Length = Number of bytes to copy from buffer
*/
{
USHORT Tmp;
/* Avoid transfers to odd addresses */
if (Target & 0x01) {
/* Read one word */
NICReadDataAlign(Adapter, &Tmp, Target - 1, 0x02);
/* Merge LSB with the new byte which become the new MSB */
Tmp = (Tmp & 0x00FF) | (*Source << 8);
/* Finally write the value back */
NICWriteDataAlign(Adapter, Target - 1, &Tmp, 0x02);
/* Update pointers */
Source = (PUCHAR) ((ULONG_PTR) Source + 1);
Target += 1;
Length--;
}
if (Length & 0x01) {
/* Transfer as many words as we can without exceeding the transfer length */
Tmp = Length & 0xFFFE;
NICWriteDataAlign(Adapter, Target, (PUSHORT)Source, Tmp);
Source += Tmp;
Target += Tmp;
/* Read one word */
NICReadDataAlign(Adapter, &Tmp, Target, 0x02);
/* Merge MSB with the new byte which become the new LSB */
Tmp = (Tmp & 0xFF00) | (*Source);
/* Finally write the value back */
NICWriteDataAlign(Adapter, Target, &Tmp, 0x02);
} else
/* Transfer the rest of the data */
NICWriteDataAlign(Adapter, Target, (PUSHORT)Source, Length);
}
static VOID NICIndicatePacket(
PNIC_ADAPTER Adapter)
/*
* FUNCTION: Indicates a packet to the wrapper
* ARGUMENTS:
* Adapter = Pointer to adapter information
*/
{
UINT IndicateLength;
IndicateLength = (Adapter->PacketHeader.PacketLength <
(Adapter->LookaheadSize + DRIVER_HEADER_SIZE))?
(Adapter->PacketHeader.PacketLength) :
(Adapter->LookaheadSize + DRIVER_HEADER_SIZE);
/* Fill the lookahead buffer */
NICReadData(Adapter,
(PUCHAR)&Adapter->Lookahead,
Adapter->PacketOffset + sizeof(PACKET_HEADER),
IndicateLength + DRIVER_HEADER_SIZE);
NDIS_DbgPrint(MID_TRACE, ("Indicating (%d) bytes.\n", IndicateLength));
NDIS_DbgPrint(MID_TRACE, ("ne2000!NICIndicatePacket: Indicating (%d) bytes.\n", IndicateLength));
#if 0
NDIS_DbgPrint(MAX_TRACE, ("FRAME:\n"));
for (i = 0; i < (IndicateLength + 7) / 8; i++) {
NDIS_DbgPrint(MAX_TRACE, ("%02X %02X %02X %02X %02X %02X %02X %02X\n",
Adapter->Lookahead[i*8+0],
Adapter->Lookahead[i*8+1],
Adapter->Lookahead[i*8+2],
Adapter->Lookahead[i*8+3],
Adapter->Lookahead[i*8+4],
Adapter->Lookahead[i*8+5],
Adapter->Lookahead[i*8+6],
Adapter->Lookahead[i*8+7]));
}
#endif
if (IndicateLength >= DRIVER_HEADER_SIZE) {
NDIS_DbgPrint(MAX_TRACE,("Adapter->MiniportAdapterHandle: %x\n",
Adapter->MiniportAdapterHandle));
NdisMEthIndicateReceive(Adapter->MiniportAdapterHandle,
NULL,
(PVOID)&Adapter->Lookahead,
DRIVER_HEADER_SIZE,
(PVOID)&Adapter->Lookahead[DRIVER_HEADER_SIZE],
IndicateLength - DRIVER_HEADER_SIZE,
Adapter->PacketHeader.PacketLength - DRIVER_HEADER_SIZE);
} else {
NdisMEthIndicateReceive(Adapter->MiniportAdapterHandle,
NULL,
(PVOID)&Adapter->Lookahead,
IndicateLength,
NULL,
0,
0);
}
}
static VOID NICReadPacket(
PNIC_ADAPTER Adapter)
/*
* FUNCTION: Reads a full packet from the receive buffer ring
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -