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

📄 nscfir.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 2 页
字号:
        {
            LOG_ERROR("receive error: disc stat=%02x, lost=%d\n",frameStat,rcvFrameSize);
             // Do nothing
        }
        else if (frameStat != 0) {
            /*
             *  Some rcv error occurred. Reset DMA.
             */

            LOG_ERROR("Receive error: stat=%02x, lost=%d\n",frameStat,rcvFrameSize);

            DEBUGFIR(DBG_RX|DBG_ERR, ("NSC: RCV ERR: frameStat=%xh FrameSize=%d \n",
                                      (UINT)frameStat,rcvFrameSize));

            if (frameStat & 0x40) {
                if (frameStat & 0x01) {
                    RegStats.StatusFIFOOverflows++;
                }
                if (frameStat & 0x02) {
                    RegStats.ReceiveFIFOOverflows++;
                }
                RegStats.MissedPackets += rcvFrameSize;
            }
            else{
                if (frameStat & 0x01) {
                    RegStats.StatusFIFOOverflows++;
                }
                if (frameStat & 0x02) {
                    RegStats.ReceiveFIFOOverflows++;
                }
                if (frameStat & 0x04) {
                    RegStats.ReceiveCRCErrors++;
                }
                if (frameStat & 0x08) {
                }
                if (frameStat & 0x10) {
                }
                LOG("Bytes Lost: %d",rcvFrameSize);
                ASSERT((thisDev->rcvPktOffset + rcvFrameSize)<= RCV_DMA_SIZE);

                /* Advance pointer past bad packet.  */
                thisDev->rcvPktOffset += rcvFrameSize;
            }
        }

        else if (thisDev->rcvPktOffset + rcvFrameSize > EndOfData )
        {

            LOG_ERROR("Receive: Frame extends beyond where dma control wrote: offset=%x, Frame size=%x, EndOfData=%x",(ULONG)thisDev->rcvPktOffset,(ULONG)rcvFrameSize,(ULONG)EndOfData);

            DBGERR(("Packet won't fit in received data!\n"));
            DBGERR(("rcvPktOffset:%x rcvFrameSize:%x LastReadDmaCount:%x\n",
                     thisDev->rcvPktOffset,
                     rcvFrameSize,
                     LastReadDMACount));
            DBGERR(("rcvDmaOffset:%x rcvDmaSize:%x EndOfData:%x\n",
                     thisDev->rcvDmaOffset, thisDev->rcvDmaSize, EndOfData));

            //
            //  The frame seems to have extended past the end of where we dma the data.
            //  This should only happen if the dma space just less than the size of
            //  the fifo too small. The remaining data is still sitting in the fifo
            //  Attempt to read it out so it will be empty when we got read more frames
            //
            while (BytesInFifo > 0) {

                SyncReadBankReg(&thisDev->interruptObj,thisDev->portInfo.ioBase, BANK_0, TXD_RXD_OFFSET);
                BytesInFifo--;
            }


            BytesInFifo=SyncReadBankReg(&thisDev->interruptObj,thisDev->portInfo.ioBase, 2, 7) & 0x3f;

            if (BytesInFifo > 0) {
                //
                //  still bytes in the fifo after attmpting to read them out.
                //  Another frame has probably started showing up, Can trust the data collected
                //  so mark these frames to be discarded
                //
                LOG_ERROR("Receive: Still have bytes in the fifo after attempting to flush, %d bytes remaining",BytesInFifo);

                BytesInFifo=0;

                thisDev->DiscardNextPacketSet = TRUE;
            }
            //
            //  this should be the last frame to be received with out error, advance this pointer
            //  anyway.
            //
            thisDev->rcvPktOffset += rcvFrameSize;

        }

        else {

            DEBUGFIR(DBG_RX|DBG_OUT, ("NSC:  *** >>> FIR_DeliverFrames DMA offset 0x%x:\n",
                                      thisDev->rcvDmaOffset));

            //
            //  this is where the new frame starts
            //
#pragma prefast(suppress:12008, "This summation is guarenteed to be valid");
            NewFrame = thisDev->dmaReadBuf + thisDev->rcvPktOffset;

            //
            //  the next frame will start after the end of this frame
            //
            thisDev->rcvPktOffset += rcvFrameSize;

            ASSERT(thisDev->rcvPktOffset < RCV_DMA_SIZE);

            //
            //  the FCS is included in the length of the frame, remove that from the length
            //  we send to the protocol
            //
            rcvFrameSize -= fcsSize;

            if (rcvFrameSize <= MAX_NDIS_DATA_SIZE &&
                rcvFrameSize >= IR_ADDR_SIZE + IR_CONTROL_SIZE)
            {
                //
                // Queue this rcv packet.  Move Newframe pointer
                // into RxDMA buffer.
                //
                RegStats.ReceivedPackets++;
                RegStats.RxWindow++;
                QueueReceivePacket(thisDev, NewFrame, rcvFrameSize, TRUE);
            }
            else {
                LOG("Error: invalid packet size in FIR_DeliverFrames %d", rcvFrameSize);

                DEBUGFIR(DBG_RX|DBG_ERR, ("NSC: invalid packet size in FIR_DeliverFrames; %xh > %xh\n", rcvFrameSize, MAX_RCV_DATA_SIZE));
                //
                // Discard the rest of the packets.
                //
                while (SyncReadBankReg(&thisDev->interruptObj,thisDev->portInfo.ioBase, 5, 5)&0x80)
                {
                    SyncReadBankReg(&thisDev->interruptObj,thisDev->portInfo.ioBase, 5, 6);
                    SyncReadBankReg(&thisDev->interruptObj,thisDev->portInfo.ioBase, 5, 7);
                }
                thisDev->DiscardNextPacketSet = TRUE;
            }
        }

        SyncGetFifoStatus(
            &thisDev->interruptObj,
            thisDev->portInfo.ioBase,
            &frameStat,
            &rcvFrameSize
            );

        LOG("frameStat: %x, size=%d ", (UINT) frameStat,rcvFrameSize);
        DEBUGFIR(DBG_RX|DBG_OUT, ("NSC: frameStat = %xh\n", (UINT) frameStat));

        //
        // Clear the line status register, of any past events.
        //
        thisDev->LineStatus = SyncReadBankReg(&thisDev->interruptObj,thisDev->portInfo.ioBase, 0, 5);

    }

    thisDev->FirIntMask = 0x04;

    SetupRecv(thisDev);

    LOG("<== FIR_DeliverFrames");
    DEBUGFIR(DBG_RX|DBG_OUT, ("NSC: <== FIR_DeliverFrames\n"));
}

BOOLEAN NSC_Setup(IrDevice *thisDev)
{
    NDIS_DMA_DESCRIPTION DMAChannelDcr;
    NDIS_STATUS stat;

    /*
     *  Initialize rcv DMA channel
     */
    RtlZeroMemory(&DMAChannelDcr,sizeof(DMAChannelDcr));

    DMAChannelDcr.DemandMode = TRUE;
    DMAChannelDcr.AutoInitialize = FALSE;
    DMAChannelDcr.DmaChannelSpecified = FALSE;
    DMAChannelDcr.DmaWidth = Width8Bits;
    DMAChannelDcr.DmaSpeed = Compatible;
    DMAChannelDcr.DmaPort = 0;
    DMAChannelDcr.DmaChannel = thisDev->portInfo.DMAChannel; // 0;

    stat = NdisMRegisterDmaChannel(&thisDev->DmaHandle,
                                   thisDev->ndisAdapterHandle,
                                   thisDev->portInfo.DMAChannel,
                                   FALSE, &DMAChannelDcr, RCV_DMA_SIZE);

    if (stat != NDIS_STATUS_SUCCESS) {

        DEBUGFIR(DBG_ERR, ("NSC: NdisMRegisterDmaChannel failed\n"));
        return FALSE;
    }

    InitializeDmaUtil(
        &thisDev->DmaUtil,
        thisDev->DmaHandle
        );


    thisDev->rcvDmaOffset = 0;

    /*
     *  Because we enable rcv DMA while SIR receives may still be
     *  going on, we need to keep a separate receive buffer for DMA.
     *  This buffer gets swapped with the rcvBuffer data pointer
     *  and must be the same size.
     */
    thisDev->dmaReadBuf=NscAllocateDmaBuffer(
        thisDev->ndisAdapterHandle,
        RCV_DMA_SIZE,
        &thisDev->ReceiveDmaBufferInfo
        );

    if (thisDev->dmaReadBuf == NULL) {

        return FALSE;
    }

    thisDev->TransmitDmaBuffer=NscAllocateDmaBuffer(
        thisDev->ndisAdapterHandle,
        MAX_IRDA_DATA_SIZE,
        &thisDev->TransmitDmaBufferInfo
        );


    NdisAllocateBufferPool(&stat, &thisDev->dmaBufferPoolHandle, 2);

    if (stat != NDIS_STATUS_SUCCESS){
        LOG("Error: NdisAllocateBufferPool failed in NSC_Setup");
        DEBUGFIR(DBG_ERR, ("NSC: NdisAllocateBufferPool failed in NSC_Setup\n"));
        return FALSE;
    }

    NdisAllocateBuffer(&stat, &thisDev->rcvDmaBuffer,
                       thisDev->dmaBufferPoolHandle,
                       thisDev->dmaReadBuf,
                       RCV_DMA_SIZE
                       );

    if (stat != NDIS_STATUS_SUCCESS) {
        LOG("Error: NdisAllocateBuffer failed (rcv) in NSC_Setup");
        DEBUGFIR(DBG_ERR, ("NSC: NdisAllocateBuffer failed (rcv) in NSC_Setup\n"));
        return FALSE;
    }

    NdisAllocateBuffer(&stat, &thisDev->xmitDmaBuffer,
                       thisDev->dmaBufferPoolHandle,
                       thisDev->TransmitDmaBuffer,
                       MAX_IRDA_DATA_SIZE
                       );

    if (stat != NDIS_STATUS_SUCCESS) {
        LOG("NdisAllocateBuffer failed (xmit) in NSC_Setup");
        DEBUGFIR(DBG_ERR, ("NSC: NdisAllocateBuffer failed (xmit) in NSC_Setup\n"));
        return FALSE;
    }




    return TRUE;
}


void NSC_Shutdown(IrDevice *thisDev)
{

    if (thisDev->xmitDmaBuffer){
        NdisFreeBuffer(   thisDev->xmitDmaBuffer);
        thisDev->xmitDmaBuffer = NULL;
    }

    if (thisDev->rcvDmaBuffer){
        NdisFreeBuffer(thisDev->rcvDmaBuffer);
        thisDev->rcvDmaBuffer = NULL;
    }

    if (thisDev->dmaBufferPoolHandle){
        NdisFreeBufferPool(thisDev->dmaBufferPoolHandle);
        thisDev->dmaBufferPoolHandle = NULL;
    }

    if (thisDev->dmaReadBuf){

        NscFreeDmaBuffer(&thisDev->ReceiveDmaBufferInfo);
        thisDev->dmaReadBuf = NULL;
    }

    if (thisDev->TransmitDmaBuffer){

        NscFreeDmaBuffer(&thisDev->TransmitDmaBufferInfo);
        thisDev->TransmitDmaBuffer = NULL;
    }


    if (thisDev->DmaHandle){
        NdisMDeregisterDmaChannel(thisDev->DmaHandle);
        thisDev->DmaHandle = NULL;
    }

}


BOOLEAN
NdisToFirPacket(
    PNDIS_PACKET   Packet,
    UCHAR         *irPacketBuf,
    UINT           TotalDmaBufferLength,
    UINT          *ActualTransferLength
    )
{
    PNDIS_BUFFER ndisBuf;
    UINT ndisPacketBytes = 0;
    UINT ndisPacketLen;

    LOG("==> NdisToFirPacket");
    DEBUGFIR(DBG_OUT, ("NSC: ==> NdisToFirPacket\n"));

    /*
     *  Get the packet's entire length and its first NDIS buffer
     */
    NdisQueryPacket(Packet, NULL, NULL, &ndisBuf, &ndisPacketLen);

    LOG("NdisToFirPacket, number of bytes: %d", ndisPacketLen);
    DEBUGFIR(DBG_OUT, ("NSC: NdisToFirPacket, number of bytes: %d\n", ndisPacketLen));

    /*
     *  Make sure that the packet is big enough to be legal.
     *  It consists of an A, C, and variable-length I field.
     */
    if (ndisPacketLen < IR_ADDR_SIZE + IR_CONTROL_SIZE){
        LOG("Error: packet too short in %d", ndisPacketLen);
        DEBUGFIR(DBG_ERR, ("NSC: packet too short in NdisToFirPacket (%d bytes)\n", ndisPacketLen));
        return FALSE;
    }

    /*
     *  Make sure that we won't overwrite our contiguous buffer.
     */
    if (ndisPacketLen > TotalDmaBufferLength){
        /*
         *  The packet is too large
         *  Tell the caller to retry with a packet size large
         *  enough to get past this stage next time.
         */
        LOG("Error: packet too large in %d ", ndisPacketLen);
        DEBUGFIR(DBG_ERR, ("NSC: Packet too large in NdisToIrPacket (%d=%xh bytes), MAX_IRDA_DATA_SIZE=%d, TotalDmaBufferLength=%d.\n",
                           ndisPacketLen, ndisPacketLen, MAX_IRDA_DATA_SIZE, TotalDmaBufferLength));
        *ActualTransferLength = ndisPacketLen;

        return FALSE;
    }


    /*
     *  Read the NDIS packet into a contiguous buffer.
     *  We have to do this in two steps so that we can compute the
     *  FCS BEFORE applying escape-byte transparency.
     */
    while (ndisBuf) {
        UCHAR *bufData;
        UINT bufLen;

        NdisQueryBufferSafe(ndisBuf, (PVOID *)&bufData, &bufLen,NormalPagePriority);

        // Validate the packet size, test for possible integer overflow
        //
        if (bufData==NULL ||
            ((ULONGLONG)ndisPacketBytes + (ULONGLONG)bufLen > (ULONGLONG)ndisPacketLen)){
            /*
             *  Packet was corrupt -- it misreported its size.
             */
            *ActualTransferLength = 0;
            ASSERT(0);
            return FALSE;
        }

        NdisMoveMemory((PVOID)(irPacketBuf+ndisPacketBytes),
                       (PVOID)bufData, (ULONG)bufLen);
        ndisPacketBytes += bufLen;

        NdisGetNextBuffer(ndisBuf, &ndisBuf);
    }

    if (WPP_LEVEL_ENABLED(DBG_LOG_INFO)) {

        UCHAR   CommandByte=*(irPacketBuf+1);
        UCHAR   Nr=CommandByte >> 5;
        UCHAR   Ns=(CommandByte >> 1) & 0x7;
        UCHAR   Pf=(CommandByte >> 4) & 0x1;

        if ((CommandByte & 1) == 0) {

            LOG("Sending - I frame, Nr=%d, Ns=%d p/f=%d",Nr,Ns,Pf);

        } else {

            if ((CommandByte & 0x3) == 0x1) {

                LOG("Sending - S frame, Nr=%d, xx=%d, p/f=%d",Nr, (CommandByte > 2) & 0x3, Pf);

            } else {

                LOG("Sending - U frame, p/f=%d",Pf);
            }
        }
    }

    /*
     *  Do a sanity check on the length of the packet.
     */
    if (ndisPacketBytes != ndisPacketLen){
        /*
         *  Packet was corrupt -- it misreported its size.
         */
        LOG("Error: Packet corrupt in NdisToIrPacket "
            "(buffer lengths don't add up to packet length)");
        DEBUGFIR(DBG_ERR, ("NSC: Packet corrupt in NdisToIrPacket (buffer lengths don't add up to packet length).\n"));
        *ActualTransferLength = 0;
        return FALSE;
    }

#ifdef DBG_ADD_PKT_ID
    if (addPktIdOn){
        static USHORT uniqueId = 0;
        DEBUGFIR(DBG_OUT, ("NSC:  *** --> SEND PKT ID: %xh\n", (UINT)uniqueId));
        LOG("ID: Send (FIR) Pkt id: %x", uniqueId);
        *(USHORT *)(irPacketBuf+ndisPacketBytes) = uniqueId++;
        ndisPacketBytes += sizeof(USHORT);
    }
#endif

    *ActualTransferLength = ndisPacketBytes;

    LOG("<== NdisToFirPacket");
    DEBUGFIR(DBG_OUT, ("NSC: <== NdisToFirPacket\n"));

    return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -