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

📄 vchip8950.c

📁 EP9315开发板的Wince6.0的BSP包文件
💻 C
📖 第 1 页 / 共 5 页
字号:
                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; //default interrupt line
 
    /* QQQQ */
    //pChip->Config.Memoryize = 2048;

    return TRUE;
}


/******************************************************************************
*
* VchipMulticastAddAll()
*
******************************************************************************/

void VchipMulticastAddAll( PCHIP pChip )
{
    DWORD RxControl;

 
    /* Get the current settings of the receiver control register */
    RxControl=ReadDWord( OpReg_RxCTL );

    /* Turn off the receiver while changing the hash table */
    WriteDWord( OpReg_RxCTL, RxControl & ~RxCTL_SerRxON );
    
    /* Set all the bits in the hash table */
    WriteByte( OpReg_AFP, AFP_Hash );
    WriteDWord( OpReg_HashTb , 0xFFFFFFFF );
    WriteDWord( OpReg_HashTb+4, 0xFFFFFFFF );

    /* Turn the receiver back on */
    WriteDWord(OpReg_RxCTL, RxControl );

}


/******************************************************************************
*
* VchipMulticastDeleteAll()
*
******************************************************************************/

void VchipMulticastDeleteAll( PCHIP pChip )
{
    DWORD RxControl;


    /* Get the current settings of the receiver control register */
    RxControl=ReadDWord( OpReg_RxCTL );

    /* Turn off the receiver while changing the hash table */
    WriteDWord( OpReg_RxCTL, RxControl & ~RxCTL_SerRxON );

    /* Clear all the bits in the hash table */
    WriteByte(OpReg_AFP, AFP_Hash );
    WriteDWord( OpReg_HashTb , 0 );
    WriteDWord( OpReg_HashTb+4, 0 );

    /* Turn the receiver back on */
    WriteDWord( OpReg_RxCTL, RxControl );
}


/******************************************************************************
*
* VchipMulticastAdd()
*
******************************************************************************/

void VchipMulticastAdd( PCHIP pChip, PEA pMulticastAddr )
{
    DWORD RxControl;
    DWORD  HashTable;
    BYTE  HashIndex;
    DWORD HashValue;

    HashTable = OpReg_HashTb;

    /* Calculate the hash index for this multicast address */
    HashIndex = CalculateHashIndex( (BYTE  *)pMulticastAddr );

    /* If the hash index is in the second double word of the hash table */
    if ( HashIndex >= 32 )
    {
      HashTable += 4;
      HashIndex -= 32;
    }

    /* Get the current settings of the receiver control register */
    RxControl=ReadDWord( OpReg_RxCTL );

    /* Turn off the receiver while changing the hash table */
    WriteDWord( OpReg_RxCTL, RxControl & ~RxCTL_SerRxON );

    /* Set the hash bit in the hash table */
    WriteByte( OpReg_AFP, AFP_Hash );
    HashValue = ReadDWord( HashTable);
    WriteDWord( HashTable, HashValue | (1L<<HashIndex) );

    /* Turn the receiver back on */
    WriteDWord( OpReg_RxCTL, RxControl );
}


/******************************************************************************
*
* VchipMulticastDelete()
*
******************************************************************************/

v

⌨️ 快捷键说明

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