#include "3C90x.h"
void
Apple3Com3C90x::receivePacket( void * pkt, UInt32 * pkt_len, UInt32 timeout )
{
UInt32 status;
UInt32 pktLength;
SInt32 us_timeout = timeout * 1000;
*pkt_len = 0;
if ( !_linkTest && ( _driverEnableCount == 0 ) ) return;
do {
for ( status = OSReadLittleInt32( &_rxRingTail->status, 0 );
status & kRxDescStatusUpCompleteMask;
status = OSReadLittleInt32( &_rxRingTail->status, 0 ) )
{
pktLength = GetBitField( RxDescStatus, Length, status );
if ( ( status & kRxDescStatusUpErrorMask ) ||
( pktLength < ( kIOEthernetMinPacketSize - kIOEthernetCRCSize ) ) )
{
LOG_DEBUG("receivePacket: bad packet\n");
_rxRingTail->status = 0;
_rxRingTail = _rxRingTail->drvNext;
sendCommand( UpUnStall );
}
else
{
*pkt_len = pktLength;
if ( pkt )
bcopy( mbuf_data(_rxRingTail->drvMbuf), pkt, *pkt_len );
_rxRingTail->status = 0;
_rxRingTail = _rxRingTail->drvNext;
sendCommand( UpUnStall );
return;
}
}
if ( _linkTest )
{
if ( timeout ) IOSleep( 10 );
us_timeout -= 10 * 1000;
}
else
{
IODelay( 50 );
us_timeout -= 50;
}
}
while ( us_timeout > 0 );
}
#define kSendPacketDelayLoops 100000
#define kSendPacketSleepLoops 100
void Apple3Com3C90x::sendPacket( void * pkt, UInt32 pkt_len )
{
int i;
TxDescriptor * txDesc;
const int maxLoops = (_linkTest) ? kSendPacketSleepLoops :
kSendPacketDelayLoops;
if (pkt_len > kIOEthernetMaxPacketSize)
return;
if (!_linkTest && (_driverEnableCount == 0))
return;
if (_txRingFree == 0)
{
UInt32 listPtrReg = getDnListPtr();
while (_txRingFree < _txRingSize)
{
if (listPtrReg == _txRingTail->drvPhysAddr)
break;
if (_txRingTail->drvMbuf)
{
_kdpPacketQueue->enqueue(_txRingTail->drvMbuf);
_txRingTail->drvMbuf = 0;
}
_txRingTail = _txRingTail->drvNext;
_txRingFree++;
}
if (_txRingFree == 0)
return;
}
for (i = 0; (i < maxLoops) && getDnListPtr(); i++)
{
if (_linkTest) IOSleep( 10 );
else IODelay( 10 );
}
if (i >= maxLoops)
{
kprintf("sendPacket: idle poll timed out\n");
return;
}
_newWDCounters[ kWDInterruptsRetired ] += 1;
if (_txRingHead->drvMbuf != NULL)
{
LOG_DEBUG("sendPacket: mbuf not NULL\n");
}
txDesc = _txRingHead;
bcopy(pkt, mbuf_data(_kdpMbuf), pkt_len);
OSWriteLittleInt32(&txDesc->header, 0,
SetBitField(TxFragment, Length, pkt_len));
txDesc->fragments[0].address = _kdpMbufSeg.location;
txDesc->fragments[0].command =
OSSwapHostToLittleInt32(kTxFragmentLastMask | pkt_len);
txDesc->nextPtr = 0; _txRingFree--;
sendCommandWait( DnStall );
OSWriteLittleInt32( &txDesc->drvPrevious->nextPtr,
0, txDesc->drvPhysAddr );
setDnListPtr( txDesc->drvPhysAddr );
sendCommand( DnUnStall );
for (i = 0; (i < maxLoops) && getDnListPtr(); i++)
{
if (_linkTest) IOSleep( 10 );
else IODelay( 10 );
}
if (i >= maxLoops)
{
kprintf("sendPacket: idle poll timed out\n");
}
}