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

📄 vchip8950.c

📁 Cirrus EP9315 wince bsp
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (Errors & RX_ERR_FRAMING)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_FRAMING\n"))
        );
        pvMini_Context->RcvErrorAlignments++;
    }
    if (Errors & RX_ERR_OVERRUN)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_OVERRUN\n"))
        );
        pvMini_Context->RcvOverrun++;
    }
    if (Errors & RX_ERR_RX_ERR)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_RX_ERR\n"))
        );
    }

    if (Errors & RX_ERR_RX_MISS)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_RX_MISS\n"))
        );
    }

    if (Errors & RX_ERR_DRIBBLE)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_DRIBBLE\n"))
        );
    }
    if (Errors & RX_ERR_TOO_MANY_FRAGS)
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_TOO_MANY_FRAGS\n"))
        );
    }
    if ( Errors & RX_ERR_NO_BUFFER ) 
    {
        DEBUGMSG
        (
            ZONE_RECVERROR,
            (TEXT("VpsRecvError(): RX_ERR_NO_BUFFER\n"))
        );
        pvMini_Context->RcvNoBuffers++;
    }
}



/******************************************************************************
*
* ProcessTxStatusQueue()
*
******************************************************************************/

void ProcessTxStatusQueue( PCHIP pChip )
{
    PCD   pCD;
    WORD  Status;
    MAXFL MaxFL;
    PTXREQ pTxReq;
 
    pCD    = pChip->pData;


    /* While the transmit status entry is not processed */
    while ( pCD->pTxStatNext->TxStat & TxStat_TxFP )
    {
        /* Get a derefrenced copy of the status */
        Status = pCD->pTxStatNext->TxStat;

        /* Find the associated transmit request */
        pTxReq = &pCD->TxReq[pCD->pTxStatNext->BufIndx];

        /* If the frame was not sent without errors */
        if ( !(Status & TxStat_TxWE) )
        {
            /* Report the errors */
            VpsSendError( pChip, pTxReq->SendID, (WORD)(Status&TxStat_Error_Mask));
        }

        if ( Status & TxStat_TxUnderrun )
        {
            /* If two underruns happen close together */
            if ( pCD->TxGoodCount < TXGOODMIN )
            {
                /* Read the Max Frame Length register */
                MaxFL.DWord = ReadDWord(OpReg_MaxFL);

                /* If the transmit start threshold is less than the maximum */
                if ( MaxFL.Word.TxStartThresh < TXSTARTMAX )
                {
                    /* Increase the transmit start threshold */
                    MaxFL.Word.TxStartThresh += TXSTARTSTEP;
                    WriteDWord( OpReg_MaxFL, MaxFL.DWord );
                }
            }

            /* Reset the number of frames transmitted without underruns */
            pCD->TxGoodCount = 0;

            RestartTransmit( pChip, pTxReq->StartIndex );
        }
        else  /* The frame did not have an underrun error */
        {
            /* Another frame has been transmitted without an underrun */
            pCD->TxGoodCount++;

            /* The transmit descriptors for this frame are now available */
            pCD->TxDescAvail += pTxReq->DescCount;


            /* Report that this send is now complete */
            VpsSendComplete( pChip, pTxReq->SendID );
        }

        /* The transmit status entry is now processed */
        pCD->pTxStatNext->TxStat = 0;

        /* Increment to the next transmit status entry (with wrap-around) */
        pCD->pTxStatNext++;
        if ( pCD->pTxStatNext == pCD->pTxStatLimit )
        {
            pCD->pTxStatNext = pCD->pTxStat;
        }
    }
}


/******************************************************************************
*
* VpsSendError(()
*
******************************************************************************/
static void VpsSendError( PCHIP pChip, DWORD SendID, WORD Errors )
{

    VPM_SetupMiniContextFromPchip
    pvMini_Context->XmitErrors++;

    if (Errors & TX_ERR_EXCESS_COLL)
    {
        DEBUGMSG
        (
            ZONE_SENDERROR,
            (TEXT("VpsSendError(): TX_ERR_EXCESS_COLL!\n"))
        );
        pvMini_Context->XmitMaxCollisions++;
    }
    if (Errors & TX_ERR_UNDERRUN)
    {
        DEBUGMSG
        (
            ZONE_SENDERROR,
            (TEXT("VpsSendError(): TX_ERR_UNDERRUN!\n"))
        );
        pvMini_Context->XmitUnderrun++;
       }
    if (Errors & TX_ERR_LOSS_CRS)
    {
        DEBUGMSG
        (
            ZONE_SENDERROR,
            (TEXT("VpsSendError(): TX_ERR_EXCESS_LOSS_CRS!\n"))
        );

        pvMini_Context->XmitLostCRS++;
    }
}

/******************************************************************************
*
* RestartTransmit()
*
******************************************************************************/
void RestartTransmit( PCHIP pChip, WORD StartIndex )
{
    PCD   pCD;
    WORD  NextIndex;
    WORD  BMControl;
    BYTE  BMStatus;
    int   x;

    pCD    = pChip->pData;

    /* Reset the transmit channel */
    BMControl=ReadWord( OpReg_BMCTL);
    WriteWord( OpReg_BMCTL, (WORD)(BMControl | BMCTL_TxChRes) );

    /* Wait until the channel reset is complete */
    for ( x=0; x<MAXLOOP; x++ )
    {
        BMControl=ReadWord( OpReg_BMCTL);
        if ( !(BMControl & BMCTL_TxChRes) ) 
            break;
    }

    /* Set descriptor current address to the starting transmit descriptor */
    WriteDWord( OpReg_TxDCA,
         pCD->TxDescPhysAddr + (StartIndex * sizeof(TxDesc_t)) );

    /* Re-enable (and initialize) the transmit descriptor processor */
    BMControl=ReadWord( OpReg_BMCTL);
    WriteWord( OpReg_BMCTL, (WORD)(BMControl | BMCTL_TxEn) );

    /* Wait until the transmit descriptor processor is active */
    for ( x=0; x<MAXLOOP; x++ )
    {
        BMStatus=ReadByte( OpReg_BMSts);
        if ( BMStatus & BMSts_TxAct ) 
            break;
    }

    /* Get the index of the next transmit descriptor */
    NextIndex = (WORD)(pCD->pTxDescNext - pCD->pTxDesc);
    if ( NextIndex <= StartIndex ) 
    {
        NextIndex += TXDESCCOUNT;
    }

    /* Re-enqueue the unprocessed transmit descriptors */
    WriteDWord( OpReg_TxDEQ, NextIndex-StartIndex );
}

/******************************************************************************
*
* VpsSendComplete()
*
******************************************************************************/
static void VpsSendComplete( PCHIP pChip, DWORD SendID )
{

    NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
    PNDIS_PACKET Packet;

    PNDIS_PACKET pTempTxPacket;
    PTXQUEUEELEMENT pTempTxQueueElem;
    PTXQUEUEELEMENT pTxQueueElem;

    VPM_SetupMiniContextFromPchip;

//    DEBUGMSG(ZONE_ERROR,(TEXT("VpsSendComplete packet %d\n"),(DWORD)SendID));

    pvMini_Context->XmitOKs++;

    if (pvMini_Context->TxQueueHead != NULL) 
    {
        pvMini_Context->XmitQueueDepth--;
        pTxQueueElem = (PVOID)&(pvMini_Context->TxQueueHead->MiniportReserved);
        if ( pTxQueueElem->XmitRC == NDIS_STATUS_NOT_INDICATING ) 
        {

            // No Indication needed, Send has not returned
            pTxQueueElem->XmitRC = Status;

        } 
        else 
        {

            Packet = NULL;
            // Run the Queue to the End or till packet SendID is found
            for (pTempTxPacket=pvMini_Context->TxQueueHead,
                 pTempTxQueueElem=(PVOID)&pTempTxPacket->MiniportReserved ;
                 pvMini_Context->TxQueueHead != NULL;
                 pTempTxPacket=pvMini_Context->TxQueueHead,
                 pTempTxQueueElem=(PVOID)&pTempTxPacket->MiniportReserved )
            {
                pvMini_Context->TxQueueHead = pTempTxQueueElem->NextPacket;
                if (pTempTxPacket == (PNDIS_PACKET)SendID)
                {
                    Packet = pTempTxPacket;
                    break;
                } 
                else 
                {
                    NdisMSendComplete
                    (
                        MiniportAdapterHandle,
                        pTempTxPacket,
                        NDIS_STATUS_FAILURE
                    );
                }
            } 

            // Confirm Send
            if (Packet != NULL) 
            {
                NdisMSendComplete(MiniportAdapterHandle,
                                  Packet,
                                  Status
                                  );
            }
        } 
    } 
    else 
    {
        pvMini_Context->XmitQueueDepth = 0;
    }

}


/******************************************************************************
*
* VchipSend()
*
* The return code indicates if the VCHIP held on the the transmit buffers.
* If the return code is TRUE, then the VCHIP held on to the transmit buffers
* and the VPS can not reuse the buffers until the VCHIP calls the
* ChipFreeSendBuff() routine.  If the return code is FALSE, then the VCHIP
* did not hold on to the transmit buffers and the VPS may immediately reuse
* them.
*
******************************************************************************/

WORD VchipSend( PCHIP pChip, DWORD SendID, WORD TotalLength)
{
    PCD    pCD;
    PTXREQ pTxReq;
    WORD   DescCount;
    TxDesc_t *pTxDesc;
//    BYTE  *pTxBuff;
//    int Frag;

    pCD    = pChip->pData;

    /* Verify that the total length is not too big */
    if ( TotalLength > 1514 )
    {
        VpsSendError( pChip, SendID, TX_ERR_TOO_BIG );
        VpsSendComplete( pChip, SendID);
        return FALSE;  /* Transmit buffers are not held */
    }

    pTxDesc=pCD->pTxDescNext;
    /* Only one transmit descriptor is used */
    DescCount=1;

    /* Fill in the transmit descriptor */
    pTxDesc->TxBufAdr  = pCD->TxBuff[pCD->TxReqIndex].PhysAddr;
    pTxDesc->BufLength = TotalLength;
    pTxDesc->BufIndx   = pCD->TxReqIndex;

    /* Start copying at the beginning of the next transmit buffer */
//    pTxBuff = pCD->TxBuff[pCD->TxReqIndex].pBuff;

    /* Copy the contents of the fragment buffers to the transmit buffer */
//    for ( Frag=0; Frag<FragCount; Frag++,pFrag++ )
//    {
//        NdisMoveMemory( pTxBuff, pFrag->pBuffer, pFrag->BuffLength );
//        pTxBuff += pFrag->BuffLength;
//    }

    /* Increment to the next transmit descriptor (with wrap-around) */
    pTxDesc++;
    if ( pTxDesc == pCD->pTxDescLimit )
    {
        pTxDesc = pCD->pTxDesc;
    }


    /* Save the transmit request in the transmit request table */
    pTxReq = &pCD->TxReq[pCD->TxReqIndex];
    pTxReq->SendID     = SendID;
    pTxReq->StartIndex = (WORD)(pCD->pTxDescNext - pCD->pTxDesc);
    pTxReq->DescCount  = DescCount;

    /* Increment to the next entry in the transmit request table */
    pCD->TxReqIndex++;
    if ( pCD->TxReqIndex == TXREQCOUNT )
    {
        pCD->TxReqIndex = 0;
    }

    /* Update the pointer to the next transmit descriptor */
    pCD->pTxDescNext = pTxDesc;

    /* Update the number of transmit descriptors available */
    pCD->TxDescAvail -= DescCount;

    /* Set the End-of-Frame bit in the last transmit descriptor */
    if ( pTxDesc == pCD->pTxDesc )
      pTxDesc = pCD->pTxDescLimit;
    pTxDesc--;
    pTxDesc->BufIndx |= TxDesc_EOF;

    /* Enqueue the transmit descriptors to the chip */
    WriteDWord(OpReg_TxDEQ, DescCount );

    return FALSE;   /* Transmit buffers are not held, can be released immiately*/
}


/******************************************************************************
*
* VchipGetConfig()
*
******************************************************************************/

BOOL VchipGetConfig( PCHIP pChip)
{

    pChip->Config.EthernetAddr.Part[0]=0x0000;
    pChip->Config.EthernetAddr.Part[1]=0x2401;
    pChip->Config.EthernetAddr.Part[2]=0x0300;

    /* Get duplex mode from auto-negotiation control */
    pChip->Config.RequestedDuplexMode = DUPLEX_AUTO_NEGOTIATE;
    pChip->Config.RequestedMediaSpeed    = MEDIA_AUTO_DETECT;
    pChip->Config.LookAheadSize = (WORD)UNSPECIFIED;
    pChip->Config.CurrentDuplexMode = DUPLEX_NONE;
    pChip->Config.DetectedMediaType = MEDIA_NONE;

    /* The maximum number of outstanding transmits is the number of entries */
    /* in the Transmit Request table */
    pChip->Config.MaxTxCount = TXREQCOUNT;

    /* The maximum number of outstanding receives is the number of entries */
    /* in the Receive Status Queue */
    pChip->Config.MaxRxCount = RXSTATCOUNT;

    pChip->Config.IntLine = 9; //QQQQ default interrupt line
 
    /* QQQQ */
    //pChip->Config.Memoryize = 2048;

    return TRUE;
}


/******************************************************************************
*

⌨️ 快捷键说明

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