⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 8390.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
        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 + -