📄 vchip8950.c
字号:
return FALSE;
}
}
/* Initialize receive and transmit buffer thresholds */
WriteDWord( OpReg_RxBTH, 0x00800040 );
WriteDWord( OpReg_TxBTH, 0x00200010 );
return TRUE;
}
/******************************************************************************
*
* StartupRxPacketQue()
*
******************************************************************************/
static BOOL StartupRxPacketQue( PCHIP pChip )
{
PCD pCD;
WORD index, i;
NDIS_STATUS AllocationStatus;
WORD *pWord;
BOOL Result;
pCD = pChip->pData;
/* Allocate Packet pool */
NdisAllocatePacketPool(&AllocationStatus,
&pCD->ReceivePacketPool,
TOTAL_RX_PKT_CNT,
16);
if(AllocationStatus != NDIS_STATUS_SUCCESS)
{
return FALSE;
}
/*
* Allocate Buffer Pool, we will have 1 buffer per packet, so allocate as
* many buffers as we have packets.
*/
NdisAllocateBufferPool(&AllocationStatus,
&pCD->ReceiveBufferPool,
TOTAL_RX_PKT_CNT);
if(AllocationStatus != NDIS_STATUS_SUCCESS)
{
return FALSE;
}
for(index = 0; index < TOTAL_RX_PKT_CNT; index++)
{
NdisAllocatePacket(&AllocationStatus,
&(pCD->RxPacketPtQ[index]),
pCD->ReceivePacketPool);
if(AllocationStatus != NDIS_STATUS_SUCCESS)
{
return FALSE;
}
NDIS_SET_PACKET_HEADER_SIZE(pCD->RxPacketPtQ[index], 14);
pWord=(WORD *)(pCD->RxPacketPtQ[index])->MiniportReserved;
*pWord=index;
/* For every packet, allocate a NDIS_BUFFER which will be
* indicated to the upper layers after receive completion.
*/
if ( index>=RXDESCCOUNT)
{
//The Rx Buffs are used for Rx Free Packets.
Result = VosAllocSharedMemory( pChip, RXBUFFSIZE,
&(PVOID)pCD->RxBuff[index].pBuff, &pCD->RxBuff[index].PhysAddr);
if ( Result != TRUE )
{
return FALSE;
}
}
NdisAllocateBuffer(&AllocationStatus,
&(pCD->RxBuffPtQ[index]),
pCD->ReceiveBufferPool,
pCD->RxBuff[index].pBuff,
RXBUFFSIZE);
if(AllocationStatus != NDIS_STATUS_SUCCESS)
{
return FALSE;
}
//Associate the buffer with the packet.
NdisChainBufferAtFront(pCD->RxPacketPtQ[index], pCD->RxBuffPtQ[index]);
//Add the indexes of these packets to Rx_free_packet QUE
if ( index >= RXDESCCOUNT)
{
i=index-RXDESCCOUNT;
pCD->RxFreePacketQ[i]=index;
}
} //end for
pCD->numRxFreePackets=FREE_RX_PKT_CNT;
pCD->NextGetFreePacket=0;
pCD->NextAddFreePacket=-1;
return TRUE;
}
/******************************************************************************
*
* VchipInit()
*
******************************************************************************/
static BOOL VchipInit( PCHIP pChip )
{
PCD pCD;
BYTE Status;
BOOL b;
LARGE_INTEGER liCurrent, liStart;
pCD = pChip->pData;
/* Reset the chip */
//Result = VchipReset( pChip );
//if ( Result != TRUE )
//{
// return FALSE;
//}
/* Reset the queues */
ResetQueues( pChip );
/* Enable the transmit descriptor processor */
WriteWord( OpReg_BMCTL, BMCTL_TxEn );
/* Wait until the transmit descriptor processor is active */
b = QueryPerformanceCounter(&liStart);
for(;;)
{
b = QueryPerformanceCounter(&liCurrent);
ASSERT(b);
if((liCurrent.QuadPart - liStart.QuadPart) > MAC_INITIALIZATION_TIMEOUT)
{
DEBUGMSG
(
ZONE_ERROR,
(
TEXT("CS8950: The transmit descriptor processor is not active 0x%08x!\n"),
Status
)
);
DumpRegisters();
return FALSE;
}
Status=ReadByte( OpReg_BMSts);
if ( Status & BMSts_TxAct )
break;
}
/* Enable the receive descriptor processor */
WriteWord( OpReg_BMCTL, BMCTL_RxEn );
/* Wait until the receive descriptor processor is active */
b = QueryPerformanceCounter(&liStart);
ASSERT(b);
for(;;)
{
b = QueryPerformanceCounter(&liCurrent);
ASSERT(b);
if((liCurrent.QuadPart - liStart.QuadPart) > MAC_INITIALIZATION_TIMEOUT)
{
DEBUGMSG
(
ZONE_ERROR,
(
TEXT("CS8950: The receive descriptor processor is not active! OpReg_BMSts=%x \n"),
Status
)
);
DumpRegisters();
return FALSE;
}
Status=ReadByte( OpReg_BMSts);
if ( Status & BMSts_RxAct )
break;
}
/* Enqueue all the Receive Descriptors to the chip */
WriteDWord(OpReg_RxDEQ, RXDESCCOUNT );
/* Enqueue all the Receive Status entries to the chip */
WriteDWord( OpReg_RxSEQ, RXSTATCOUNT );
/* Use MII registers to reset or initialize the PHY chip? */
/* If full duplex mode was negotiated by the PHY then set */
/* the MAC FDX bit in the TestCtl register (10 Mbps only?). */
/* Initialize the Interrupt Enable register */
WriteDWord( OpReg_IntEn, IntEn_TxStsQiE | IntEn_RxEOFiE );
/* Initialize the Transmit Control register */
WriteByte( OpReg_TxCTL, TxCTL_SerTxON );
/* Initialize the Receive Control register */
//********************************************************************
// From EP9312 errata
//
// Description:
// The ethernet Mac does not correctly receive frames that have a
// size of 64 bytes.
//
// Workaround:
// In order to receive frames of 64 bytes, enable the RCRCA bit in
// the RxCTRL register. This will allow the ethernet controller
// to ingore the CRC information and not discard the frames.
//
// The Windows CE ethernet debugger sends lots of frames that are
// 64 bytes in length.
//********************************************************************
WriteDWord( OpReg_RxCTL, RxCTL_SerRxON | RxCTL_RuntCRCA);
/* Initialize the filtering criteria */
VchipChangeFiltering( pChip );
/* Initialize chip look ahead */
VchipChangeLookAhead( pChip );
/* Enable interrupts at the chip */
VchipEnableInterrupts(pChip);
return TRUE;
}
/******************************************************************************
*
* VchipReset()
*
******************************************************************************/
BOOL VchipReset( PCHIP pChip )
{
volatile BYTE Status;
int x;
/* Reset the chip */
WriteByte( OpReg_SelfCTL, SelfCTL_RESET );
/* Wait until the reset is complete */
for ( x=0; x<MAXLOOP; x++ )
{
Status=ReadByte( OpReg_SelfCTL);
if ( !(Status & SelfCTL_RESET) )
break;
}
if ( x == MAXLOOP )
{
DEBUGMSG
(
ZONE_ERROR,
(
TEXT("The CS Chip reset does not complete!\r\n")
)
);
return FALSE;
}
return TRUE;
}
/******************************************************************************
*
* ResetQueues()
*
******************************************************************************/
static void ResetQueues( PCHIP pChip )
{
PCD pCD;
RxDesc_t *pRxDesc;
RxStat_t *pRxStat;
TxStat_t *pTxStat;
pCD = pChip->pData;
/* Set receive descriptor queue current address to the base address */
WriteDWord( OpReg_RxDCA, pCD->RxDescPhysAddr );
/* Set receive status queue current address to the base address */
WriteDWord( OpReg_RxSCA, pCD->RxStatPhysAddr );
/* Set transmit descriptor queue current address to the base address */
WriteDWord( OpReg_TxDCA, pCD->TxDescPhysAddr );
/* Set transmit status queue current address to the base address */
WriteDWord( OpReg_TxSCA, pCD->TxStatPhysAddr );
/* Set the queue pointers to be beginning of the queues */
pCD->pRxStatNext = pCD->pRxStat;
pCD->pTxStatNext = pCD->pTxStat;
pCD->pTxDescNext = pCD->pTxDesc;
/* No receive buffers are currently held */
pCD->RxHoldCount = 0;
/* The receive fragment array is empty */
pCD->RxFragCount = 0;
/* We have not yet started to receive a frame */
pCD->RxStartIndex = (WORD)UNSPECIFIED;
/* We have not yet received a status, Set to last status possible */
pCD->LastRxStatus = RXBUFFCOUNT-1;
/* No frames have been transmitted (without underruns) yet */
pCD->TxGoodCount = 0;
/* Start filling in the transmit request table at index zero */
pCD->TxReqIndex = 0;
/* All the transmit descriptors are available */
pCD->TxDescAvail = TXDESCCOUNT;
/* Set all the receive descriptors to available (not held) */
for ( pRxDesc=pCD->pRxDesc; pRxDesc<pCD->pRxDescLimit; pRxDesc++ )
pRxDesc->BufLength = RXBUFFSIZE;
/* Clear all the Frame Processed flags in the receive status queue */
for ( pRxStat=pCD->pRxStat; pRxStat<pCD->pRxStatLimit; pRxStat++ )
pRxStat->RxStat = 0;
/* Clear all the Frame Processed flags in the transmit status queue */
for ( pTxStat=pCD->pTxStat; pTxStat<pCD->pTxStatLimit; pTxStat++ )
pTxStat->TxStat = 0;
}
/******************************************************************************
*
* VchipChangeFiltering()
*
******************************************************************************/
void VchipChangeFiltering( PCHIP pChip )
{
DWORD RxControl;
/* Get the current settings of the receiver control register */
RxControl=ReadDWord( OpReg_RxCTL);
/* Turn off the receiver while changing the filtering criteria */
WriteDWord( OpReg_RxCTL, RxControl & ~RxCTL_SerRxON );
/* Clear all of the accept bits */
RxControl &= ~(RxCTL_IndividualAccept0 | RxCTL_BroadcastA |
RxCTL_MulticastA | RxCTL_PromiscuousA);
/* Set only the specified accept bits */
if ( pChip->Config.Filtering & FILTER_INDIVIDUAL_ACCEPT )
RxControl |= RxCTL_IndividualAccept0;
if ( pChip->Config.Filtering & FILTER_BROADCAST_ACCEPT )
RxControl |= RxCTL_BroadcastA;
if ( pChip->Config.Filtering & FILTER_MULTICAST_ACCEPT )
RxControl |= RxCTL_MulticastA;
if ( pChip->Config.Filtering & FILTER_PROMISCUOUS_ACCEPT )
RxControl |= RxCTL_PromiscuousA;
/* Write the new filtering criteria to the chip and turn receiver back on */
WriteDWord( OpReg_RxCTL, RxControl );
}
/******************************************************************************
*
* VchipChangeLookAhead()
*
******************************************************************************/
static void VchipChangeLookAhead( PCHIP pChip )
{
WORD BMControl;
DWORD IntEnable;
/* Read the bus master control register */
BMControl=ReadWord( OpReg_BMCTL);
/* Read the interrupt enable register */
IntEnable=ReadDWord( OpReg_IntEn);
if ( pChip->Config.LookAheadSize == (WORD)UNSPECIFIED )
{
/* Clear the receive header length */
WriteDWord( OpReg_RxHLen, 0 );
/* Disable header status from being put into the receive status queue */
BMControl &= ~BMCTL_EnHeader1;
/* Disable receive header interrupts */
IntEnable &= ~IntEn_RxHdriE;
}
else /* The look ahead size is specified */
{
/* Set the receive header length to the look ahead size */
WriteDWord( OpReg_RxHLen, pChip->Config.LookAheadSize );
/* Enable header status to be put into the receive status queue */
BMControl |= BMCTL_EnHeader1;
/* Enable receive header interrupts */
IntEnable |= IntEn_RxHdriE;
}
/* Update the bus master control register */
WriteWord( OpReg_BMCTL, BMControl );
/* Update the receive enable register */
WriteDWord( OpReg_IntEn, IntEnable );
}
/******************************************************************************
*
* VchipISR()
*
******************************************************************************/
WORD VchipISR( PCHIP pChip )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -