BMacEnetPrivate.cpp [plain text]
#include <IOKit/assert.h>
#include <IOKit/system.h>
#include "BMacEnetPrivate.h"
#include <IOKit/IOLib.h>
typedef unsigned long long ns_time_t;
#define NSEC_PER_SEC 1000000000
static void
_IOGetTimestamp(ns_time_t *nsp)
{
mach_timespec_t now;
IOGetTime(&now);
*nsp = ((ns_time_t)now.tv_sec * NSEC_PER_SEC) + now.tv_nsec;
}
extern kern_return_t kmem_alloc_wired();
static IODBDMADescriptor dbdmaCmd_Nop;
static IODBDMADescriptor dbdmaCmd_NopWInt;
static IODBDMADescriptor dbdmaCmd_LoadInt;
static IODBDMADescriptor dbdmaCmd_LoadIntWInt;
static IODBDMADescriptor dbdmaCmd_Stop;
static IODBDMADescriptor dbdmaCmd_Branch;
static u_int8_t reverseBitOrder(u_int8_t data )
{
u_int8_t val = 0;
int i;
for ( i=0; i < 8; i++ )
{
val <<= 1;
if (data & 1) val |= 1;
data >>= 1;
}
return( val );
}
bool BMacEnet::_allocateMemory()
{
dmaCommandsSize = round_page(
RX_RING_LENGTH * sizeof( enet_dma_cmd_t )
+ TX_RING_LENGTH * sizeof (enet_txdma_cmd_t )
+ 2 * sizeof( IODBDMADescriptor ) );
dmaCommandsDesc = IOBufferMemoryDescriptor::withOptions( kIOMemoryPhysicallyContiguous,
dmaCommandsSize,
PAGE_SIZE );
if ( dmaCommandsDesc == NULL )
{
IOLog( "BMacEnet::_allocateMemory: Cannot allocate channel DBDMA commands\n" );
return false;
}
dmaCommandsDesc->prepare( kIODirectionOutIn );
dmaCommands = (UInt8*)dmaCommandsDesc->getBytesNoCopy(); dmaCommandsPhys = dmaCommandsDesc->getPhysicalAddress(); if ( dmaCommandsPhys == 0 )
{
IOLog( "BMacEnet::_allocateMemory - Cannot get DBDMA commands physical address.\n" );
return false;
}
rxDMACommands = (enet_dma_cmd_t *)dmaCommands;
rxDMACommandsPhys = dmaCommandsPhys;
rxMaxCommand = RX_RING_LENGTH;
txDMACommands = (enet_txdma_cmd_t *)(dmaCommands +
RX_RING_LENGTH * sizeof(enet_dma_cmd_t) + sizeof(IODBDMADescriptor));
txDMACommandsPhys = dmaCommandsPhys
+ RX_RING_LENGTH * sizeof( enet_dma_cmd_t )
+ sizeof( IODBDMADescriptor );
txMaxCommand = TX_RING_LENGTH;
IOMakeDBDMADescriptor( (&dbdmaCmd_Nop),
kdbdmaNop,
kdbdmaKeyStream0,
kdbdmaIntNever,
kdbdmaBranchNever,
kdbdmaWaitNever,
0,
0);
IOMakeDBDMADescriptor( (&dbdmaCmd_NopWInt),
kdbdmaNop,
kdbdmaKeyStream0,
kdbdmaIntAlways,
kdbdmaBranchNever,
kdbdmaWaitNever,
0,
0);
UInt32 ioBaseEnetPhys = maps[MEMORY_MAP_ENET_INDEX]->getPhysicalAddress();
IOMakeDBDMADescriptor( (&dbdmaCmd_LoadInt),
kdbdmaLoadQuad,
kdbdmaKeySystem,
kdbdmaIntNever,
kdbdmaBranchNever,
kdbdmaWaitNever,
2,
((int)ioBaseEnetPhys + kSTAT) );
IOMakeDBDMADescriptor( (&dbdmaCmd_LoadIntWInt),
kdbdmaLoadQuad,
kdbdmaKeySystem,
kdbdmaIntAlways,
kdbdmaBranchNever,
kdbdmaWaitNever,
2,
((int)ioBaseEnetPhys + kSTAT) );
IOMakeDBDMADescriptor( (&dbdmaCmd_Stop),
kdbdmaStop,
kdbdmaKeyStream0,
kdbdmaIntNever,
kdbdmaBranchNever,
kdbdmaWaitNever,
0,
0);
IOMakeDBDMADescriptor( (&dbdmaCmd_Branch),
kdbdmaNop,
kdbdmaKeyStream0,
kdbdmaIntNever,
kdbdmaBranchAlways,
kdbdmaWaitNever,
0,
0);
return true;
}
bool BMacEnet::_initTxRing()
{
u_int32_t i;
IODBDMADescriptor dbdmaCmd, dbdmaCmdInt;
for ( i = 0; i < txMaxCommand; i++ )
{
if ( txMbuf[i] )
{
freePacket( txMbuf[i] );
txMbuf[i] = 0;
}
}
bzero( (void *)txDMACommands, sizeof(enet_txdma_cmd_t) * txMaxCommand);
txCommandHead = 0;
txCommandTail = 0;
dbdmaCmd = ( chipId >= kCHIPID_PaddingtonXmitStreaming ) ? dbdmaCmd_Nop : dbdmaCmd_LoadInt;
dbdmaCmdInt = ( chipId >= kCHIPID_PaddingtonXmitStreaming ) ? dbdmaCmd_NopWInt : dbdmaCmd_LoadIntWInt;
for( i=0; i < txMaxCommand; i++ )
{
txDMACommands[i].desc_seg[2] = ( (i+1) % TX_PKTS_PER_INT ) ? dbdmaCmd : dbdmaCmdInt;
}
txDMACommands[txMaxCommand].desc_seg[0] = dbdmaCmd_Branch;
IOSetCCCmdDep( &txDMACommands[txMaxCommand].desc_seg[0],
txDMACommandsPhys );
IOSetDBDMACommandPtr( ioBaseEnetTxDMA, txDMACommandsPhys );
return true;
}
bool BMacEnet::_initRxRing()
{
u_int32_t i;
bool status;
bzero((void *)rxDMACommands, sizeof(enet_dma_cmd_t) * rxMaxCommand);
for (i = 0; i < rxMaxCommand-1; i++)
{
if (rxMbuf[i] == NULL)
{
rxMbuf[i] = allocatePacket(NETWORK_BUFSIZE);
if (!rxMbuf[i])
{
IOLog( "BMacEnet::_initRxRing: allocatePacket failed\n" );
return false;
}
}
status = _updateDescriptorFromMbuf(rxMbuf[i], &rxDMACommands[i], true);
if (status == false)
{
IOLog( "BMacEnet::_initRxRing: cannot map mbuf to physical memory in"
" _initRxRing\n" );
return false;
}
}
rxCommandHead = 0;
rxCommandTail = i;
rxDMACommands[i].desc_seg[0] = dbdmaCmd_Stop;
rxDMACommands[i].desc_seg[1] = dbdmaCmd_Nop;
i++;
rxDMACommands[i].desc_seg[0] = dbdmaCmd_Branch;
IOSetCCCmdDep( &rxDMACommands[i].desc_seg[0], rxDMACommandsPhys );
IOSetDBDMACommandPtr (ioBaseEnetRxDMA, rxDMACommandsPhys);
return true;
}
void BMacEnet::_startChip()
{
u_int16_t oldConfig;
IODBDMAContinue( ioBaseEnetRxDMA );
oldConfig = ReadBigMacRegister(ioBaseEnet, kRXCFG);
WriteBigMacRegister(ioBaseEnet, kRXCFG, oldConfig | kRxMACEnable );
oldConfig = ReadBigMacRegister(ioBaseEnet, kTXCFG);
WriteBigMacRegister(ioBaseEnet, kTXCFG, oldConfig | kTxMACEnable );
}
void BMacEnet::_resetChip()
{
volatile u_int32_t *heathrowFCR;
u_int32_t fcrValue;
u_int16_t *pPhyType;
IODBDMAReset( ioBaseEnetRxDMA );
IODBDMAReset( ioBaseEnetTxDMA );
IOSetDBDMAWaitSelect( ioBaseEnetTxDMA,
IOSetDBDMAChannelControlBits( kdbdmaS5 ) );
IOSetDBDMABranchSelect( ioBaseEnetRxDMA,
IOSetDBDMAChannelControlBits( kdbdmaS6 ) );
IOSetDBDMAInterruptSelect( ioBaseEnetRxDMA,
IOSetDBDMAChannelControlBits( kdbdmaS6 ) );
heathrowFCR = (u_int32_t *)((u_int8_t *)ioBaseHeathrow + kHeathrowFCR);
fcrValue = *heathrowFCR;
eieio();
fcrValue = OSReadSwapInt32( &fcrValue, 0 );
fcrValue |= kEnetEnabledBits;
fcrValue &= ~kResetEnetCell;
*heathrowFCR = OSReadSwapInt32( &fcrValue, 0 );
eieio();
IOSleep( 100 );
if ( phyId == 0xff )
{
phyMIIDelay = 20;
if ( miiFindPHY(&phyId) == true )
{
miiResetPHY(phyId);
pPhyType = (u_int16_t *)&phyType;
miiReadWord(pPhyType, MII_ID0, phyId);
miiReadWord(pPhyType+1, MII_ID1, phyId);
if ( (phyType & MII_ST10040_MASK) == MII_ST10040_ID )
{
phyMIIDelay = MII_ST10040_DELAY;
}
else if ( (phyType & MII_DP83843_MASK) == MII_DP83843_ID )
{
phyMIIDelay = MII_DP83843_DELAY;
}
kprintf( "BMacEnet::_resetChip: PHY id = %d\n", phyId );
}
}
fcrValue |= kResetEnetCell;
*heathrowFCR = OSReadSwapInt32( &fcrValue, 0 );
eieio();
IOSleep( 10 );
fcrValue &= ~kResetEnetCell;
*heathrowFCR = OSReadSwapInt32( &fcrValue, 0 );
eieio();
IOSleep( 10 );
chipId = ReadBigMacRegister(ioBaseEnet, kCHIPID) & 0xFF;
if ( chipId >= kCHIPID_PaddingtonXmitStreaming
&& (phyType & MII_DP83843_MASK) == MII_DP83843_ID )
{
chipId = kCHIPID_Paddington;
}
return;
}
bool BMacEnet::_initChip()
{
volatile u_int16_t regValue;
ns_time_t timeStamp;
u_int16_t *pWord16;
WriteBigMacRegister(ioBaseEnet, kTXRST, kTxResetBit);
do
{
regValue = ReadBigMacRegister(ioBaseEnet, kTXRST);
}
while( regValue & kTxResetBit );
WriteBigMacRegister(ioBaseEnet, kRXRST, kRxResetValue);
if ( phyId == 0xff )
{
WriteBigMacRegister(ioBaseEnet, kXCVRIF,
kClkBit | kSerialMode | kCOLActiveLow);
}
_IOGetTimestamp(&timeStamp);
WriteBigMacRegister(ioBaseEnet, kRSEED, (u_int16_t) timeStamp );
regValue = ReadBigMacRegister(ioBaseEnet, kXIFC);
regValue |= kTxOutputEnable;
WriteBigMacRegister(ioBaseEnet, kXIFC, regValue);
ReadBigMacRegister(ioBaseEnet, kPAREG);
WriteBigMacRegister(ioBaseEnet, kNCCNT, 0);
WriteBigMacRegister(ioBaseEnet, kNTCNT, 0);
WriteBigMacRegister(ioBaseEnet, kEXCNT, 0);
WriteBigMacRegister(ioBaseEnet, kLTCNT, 0);
WriteBigMacRegister(ioBaseEnet, kFRCNT, 0);
WriteBigMacRegister(ioBaseEnet, kLECNT, 0);
WriteBigMacRegister(ioBaseEnet, kAECNT, 0);
WriteBigMacRegister(ioBaseEnet, kFECNT, 0);
WriteBigMacRegister(ioBaseEnet, kRXCV, 0);
WriteBigMacRegister(ioBaseEnet, kTXTH, 0xff);
WriteBigMacRegister(ioBaseEnet, kTXFIFOCSR, 0);
WriteBigMacRegister(ioBaseEnet, kTXFIFOCSR, kTxFIFOEnable );
WriteBigMacRegister(ioBaseEnet, kRXFIFOCSR, 0);
WriteBigMacRegister(ioBaseEnet, kRXFIFOCSR, kRxFIFOEnable );
ReadBigMacRegister(ioBaseEnet, kSTAT);
WriteBigMacRegister(ioBaseEnet, kHASH3, hashTableMask[0]); WriteBigMacRegister(ioBaseEnet, kHASH2, hashTableMask[1]); WriteBigMacRegister(ioBaseEnet, kHASH1, hashTableMask[2]); WriteBigMacRegister(ioBaseEnet, kHASH0, hashTableMask[3]);
pWord16 = (u_int16_t *)&myAddress.bytes[0];
WriteBigMacRegister(ioBaseEnet, kMADD0, *pWord16++);
WriteBigMacRegister(ioBaseEnet, kMADD1, *pWord16++);
WriteBigMacRegister(ioBaseEnet, kMADD2, *pWord16);
WriteBigMacRegister(ioBaseEnet, kRXCFG,
kRxCRCEnable | kRxHashFilterEnable | kRxRejectOwnPackets);
return true;
}
void BMacEnet::_disableAdapterInterrupts()
{
WriteBigMacRegister( ioBaseEnet, kINTDISABLE, kNoEventsMask );
}
void BMacEnet::_enableAdapterInterrupts()
{
WriteBigMacRegister( ioBaseEnet,
kINTDISABLE,
( chipId >= kCHIPID_PaddingtonXmitStreaming ) ?
kNoEventsMask: kNormalIntEvents );
}
void BMacEnet::_setDuplexMode(bool duplexMode)
{
u_int16_t txCFGVal;
isFullDuplex = duplexMode;
txCFGVal = ReadBigMacRegister( ioBaseEnet, kTXCFG);
WriteBigMacRegister( ioBaseEnet, kTXCFG, txCFGVal & ~kTxMACEnable );
while( ReadBigMacRegister(ioBaseEnet, kTXCFG) & kTxMACEnable )
;
if ( isFullDuplex )
{
txCFGVal |= (kTxIgnoreCollision | kTxFullDuplex);
}
else
{
txCFGVal &= ~(kTxIgnoreCollision | kTxFullDuplex);
}
WriteBigMacRegister( ioBaseEnet, kTXCFG, txCFGVal );
}
void BMacEnet::_restartTransmitter()
{
u_int16_t regValue;
_stopTransmitDMA();
WriteBigMacRegister( ioBaseEnet, kTXFIFOCSR, 0 );
WriteBigMacRegister( ioBaseEnet, kTXFIFOCSR, kTxFIFOEnable);
ReadBigMacRegister( ioBaseEnet, kSTAT );
regValue = ReadBigMacRegister(ioBaseEnet, kTXCFG);
WriteBigMacRegister(ioBaseEnet, kTXCFG, regValue | kTxMACEnable );
IODBDMAContinue( ioBaseEnetTxDMA );
}
void BMacEnet::_restartReceiver()
{
u_int16_t oldConfig;
_stopReceiveDMA();
WriteBigMacRegister( ioBaseEnet, kRXFIFOCSR, 0 );
WriteBigMacRegister( ioBaseEnet, kRXFIFOCSR, kRxFIFOEnable);
oldConfig = ReadBigMacRegister(ioBaseEnet, kRXCFG);
WriteBigMacRegister(ioBaseEnet, kRXCFG, oldConfig | kRxMACEnable );
IODBDMAContinue( ioBaseEnetRxDMA );
}
void BMacEnet::_stopReceiveDMA()
{
u_int32_t dmaCmdPtr;
u_int8_t rxCFGVal;
rxCFGVal = ReadBigMacRegister(ioBaseEnet, kRXCFG);
WriteBigMacRegister(ioBaseEnet, kRXCFG, rxCFGVal & ~kRxMACEnable );
IODelay( RECEIVE_QUIESCE_uS );
IODBDMAReset( ioBaseEnetRxDMA );
dmaCmdPtr = rxDMACommandsPhys + rxCommandHead * sizeof(enet_dma_cmd_t);
IOSetDBDMACommandPtr( ioBaseEnetRxDMA, dmaCmdPtr );
}
void BMacEnet::_stopTransmitDMA()
{
u_int32_t dmaCmdPtr;
u_int8_t txCFGVal;
txCFGVal = ReadBigMacRegister(ioBaseEnet, kTXCFG);
WriteBigMacRegister(ioBaseEnet, kTXCFG, txCFGVal & ~kTxMACEnable );
IODelay( TRANSMIT_QUIESCE_uS );
IODBDMAReset( ioBaseEnetTxDMA );
dmaCmdPtr = txDMACommandsPhys + txCommandHead * sizeof(enet_txdma_cmd_t);
IOSetDBDMACommandPtr( ioBaseEnetTxDMA, dmaCmdPtr );
}
bool BMacEnet::_transmitPacket( mbuf_t packet )
{
enet_dma_cmd_t tmpCommand;
u_int32_t i;
i = txCommandTail + 1;
if ( i >= txMaxCommand ) i = 0;
if ( (i == txCommandHead) || !_updateDescriptorFromMbuf( packet, &tmpCommand, false ) )
{
IOLog( "BMacEnet::_transmitPacket: Freeing transmit packet eh?\n" );
if (packet != txDebuggerPkt)
freePacket(packet);
return false;
}
txDMACommands[i].desc_seg[0] = dbdmaCmd_Stop;
txDMACommands[i].desc_seg[1] = dbdmaCmd_Nop;
bcopy( ((u_int32_t *)&tmpCommand)+1,
((u_int32_t *)&txDMACommands[txCommandTail])+1,
sizeof(enet_dma_cmd_t)-sizeof(u_int32_t) );
txMbuf[txCommandTail] = packet;
txDMACommands[txCommandTail].desc_seg[0].operation =
tmpCommand.desc_seg[0].operation;
txCommandTail = i;
IODBDMAContinue( ioBaseEnetTxDMA );
return true;
}
void BMacEnet::_receivePacket(void *pkt, unsigned int *pkt_len,
unsigned int timeout)
{
ns_time_t startTime;
ns_time_t currentTime;
u_int32_t elapsedTimeMS;
if (!ready || !pkt || !pkt_len)
return;
*pkt_len = 0;
debuggerPkt = pkt;
debuggerPktSize = 0;
_IOGetTimestamp(&startTime);
do
{
_receivePackets(true);
_IOGetTimestamp(¤tTime);
elapsedTimeMS = (currentTime - startTime) / (1000*1000);
}
while ( (debuggerPktSize == 0) && (elapsedTimeMS < timeout) );
*pkt_len = debuggerPktSize;
}
void BMacEnet::_packetToDebugger( mbuf_t packet, u_int size )
{
debuggerPktSize = size;
bcopy( (char*)mbuf_data( packet ), debuggerPkt, size );
return;
}
void BMacEnet::_sendPacket(void *pkt, unsigned int pkt_len)
{
ns_time_t startTime;
ns_time_t currentTime;
u_int32_t elapsedTimeMS;
if (!ready || !pkt || (pkt_len > (kIOEthernetMaxPacketSize - kIOEthernetCRCSize)) )
return;
_IOGetTimestamp(&startTime);
do
{
_debugTransmitInterruptOccurred();
_IOGetTimestamp(¤tTime);
elapsedTimeMS = (currentTime - startTime) / (1000*1000);
}
while ( (txCommandHead != txCommandTail) &&
(elapsedTimeMS < TX_KDB_TIMEOUT) );
if ( txCommandHead != txCommandTail )
{
IOLog( "BMacEnet::_sendPacket: Polled transmit timeout - 1\n" );
return;
}
bcopy( pkt, (char*)mbuf_data( txDebuggerPkt ), pkt_len );
mbuf_setlen( txDebuggerPkt, pkt_len );
mbuf_pkthdr_setlen( txDebuggerPkt, pkt_len );
_transmitPacket(txDebuggerPkt);
do
{
_debugTransmitInterruptOccurred();
_IOGetTimestamp(¤tTime);
elapsedTimeMS = (currentTime - startTime) / (1000*1000);
}
while ( (txCommandHead != txCommandTail) &&
(elapsedTimeMS < TX_KDB_TIMEOUT) );
if ( txCommandHead != txCommandTail )
{
IOLog( "BMacEnet::_sendPacket: Polled transmit timeout - 2\n" );
}
return;
}
void BMacEnet::_sendDummyPacket()
{
union
{
u_int8_t bytes[64];
IOEthernetAddress enet_addr[2];
} dummyPacket;
bzero( &dummyPacket, sizeof(dummyPacket) );
dummyPacket.enet_addr[0] = myAddress;
dummyPacket.enet_addr[1] = myAddress;
_sendPacket((void *)dummyPacket.bytes, sizeof(dummyPacket));
IOSleep(50);
}
bool BMacEnet::_receiveInterruptOccurred()
{
return _receivePackets(false);
}
bool BMacEnet::_rejectBadUnicastPacket(struct ether_header * etherHeader)
{
bool rejectPacket = false;
#define kBMacEnetGroupByte 0
#define kBMacEnetGroupBit 0x01
if ( useUnicastFilter && (isPromiscuous == false) &&
(etherHeader->ether_dhost[kBMacEnetGroupByte] & kBMacEnetGroupBit) == 0) {
if (bcmp(etherHeader->ether_dhost, &myAddress, kIOEthernetAddressSize) != 0)
rejectPacket = true;
}
return rejectPacket;
}
bool BMacEnet::_receivePackets(bool fDebugger)
{
enet_dma_cmd_t tmpCommand;
mbuf_t packet;
u_int32_t i, j, last;
long unsigned int receivedFrameSize = 0;
u_int32_t dmaCount[2], dmaResid[2], dmaStatus[2];
u_int32_t dmaChnlStatus;
u_int16_t rxPktStatus = 0;
u_int32_t badFrameCount;
bool reusePkt;
bool status;
bool useNetif = !fDebugger && netifEnabled;
bool doFlushQueue = false;
u_int32_t nextDesc;
static const u_int32_t lastResetValue = (u_int32_t)(-1);
last = lastResetValue;
i = rxCommandHead;
while ( 1 )
{
reusePkt = false;
for ( j = 0; j < 2; j++ )
{
dmaResid[j] = IOGetCCResult( &rxDMACommands[i].desc_seg[j] );
dmaStatus[j] = dmaResid[j] >> 16;
dmaResid[j] &= 0x0000ffff;
dmaCount[j] = IOGetCCOperation( &rxDMACommands[i].desc_seg[j] )
& kdbdmaReqCountMask;
}
#if 0
IOLog( "BMacEnet::_receivePackets: Rx NetBuf[%2d] = %08x Resid[0] = %04x Status[0] = %04x Resid[1] = %04x Status[1] = %04x\n",
i, (int)nb_map(rxNetbuf[i]), dmaResid[0], dmaStatus[0], dmaResid[1], dmaStatus[1] );
#endif
if ( !((dmaStatus[0] & kdbdmaBt) || (dmaStatus[1] & kdbdmaActive)) )
{
break;
}
receivedFrameSize = dmaCount[0] - dmaResid[0] + dmaCount[1] -
((dmaStatus[0] & kdbdmaBt) ? dmaCount[1] : dmaResid[1]);
if ( ( receivedFrameSize >= 2 ) &&
( receivedFrameSize <= NETWORK_BUFSIZE ) )
{
rxPktStatus = *(u_int16_t*)((char*)mbuf_data( rxMbuf[i] ) + receivedFrameSize - 2);
receivedFrameSize = rxPktStatus & kRxLengthMask;
}
if ( receivedFrameSize < (kIOEthernetMinPacketSize - kIOEthernetCRCSize) ||
receivedFrameSize > (kIOEthernetMaxPacketSize) ||
rxPktStatus & kRxAbortBit ||
_rejectBadUnicastPacket( (struct ether_header*)mbuf_data( rxMbuf[i] ) )
)
{
if (useNetif) netStats->inputErrors++;
reusePkt = true;
}
else if ( useNetif == false )
{
reusePkt = true;
if (fDebugger)
_packetToDebugger(rxMbuf[i], receivedFrameSize);
}
packet = 0;
if ( reusePkt == false )
{
bool replaced;
packet = replaceOrCopyPacket(&rxMbuf[i], receivedFrameSize,
&replaced);
reusePkt = true;
if (packet && replaced)
{
status = _updateDescriptorFromMbuf(rxMbuf[i],
&rxDMACommands[i], true);
if (status)
{
reusePkt = false;
}
else
{
freePacket(rxMbuf[i]); rxMbuf[i] = packet; packet = 0; IOLog( "BMacEnet::_receivePackets: _updateDescriptorFromMbuf error\n" );
}
}
if (packet == 0)
netStats->inputErrors++;
}
if ( reusePkt )
{
for ( j=0; j < sizeof(enet_dma_cmd_t)/sizeof(IODBDMADescriptor);
j++ )
{
IOSetCCResult( &rxDMACommands[i].desc_seg[j], 0 );
}
}
last = i;
if (++i >= rxMaxCommand) i = 0;
if (fDebugger)
{
break;
}
if (packet)
{
KERNEL_DEBUG(DBG_BMAC_RXCOMPLETE | DBG_FUNC_NONE, (int) packet,
(int)receivedFrameSize, 0, 0, 0 );
networkInterface->inputPacket(packet, receivedFrameSize, true);
doFlushQueue = true;
netStats->inputPackets++;
}
}
#if 0
IOLog( "BMacEnet::_receivePackets: Prev - Rx Head = %2d Rx Tail = %2d Rx Last = %2d\n",
rxCommandHead, rxCommandTail, last );
#endif
if ( last != lastResetValue )
{
packet = rxMbuf[last];
tmpCommand = rxDMACommands[last];
rxDMACommands[last].desc_seg[0] = dbdmaCmd_Stop;
rxDMACommands[last].desc_seg[1] = dbdmaCmd_Nop;
rxMbuf[last] = 0;
nextDesc = rxDMACommandsPhys +
(int) &rxDMACommands[rxCommandTail + 1] - (int)rxDMACommands;
IOSetCCCmdDep( &tmpCommand.desc_seg[0], nextDesc );
bcopy( (u_int32_t *) &tmpCommand + 1,
(u_int32_t *) &rxDMACommands[rxCommandTail] + 1,
sizeof(enet_dma_cmd_t) - sizeof(u_int32_t) );
rxMbuf[rxCommandTail] = packet;
rxDMACommands[rxCommandTail].desc_seg[0].operation =
tmpCommand.desc_seg[0].operation;
rxCommandTail = last;
rxCommandHead = i;
}
badFrameCount = ReadBigMacRegister(ioBaseEnet, kFECNT)
+ ReadBigMacRegister(ioBaseEnet, kAECNT)
+ ReadBigMacRegister(ioBaseEnet, kLECNT);
WriteBigMacRegister(ioBaseEnet, kFECNT, 0);
WriteBigMacRegister(ioBaseEnet, kAECNT, 0);
WriteBigMacRegister(ioBaseEnet, kLECNT, 0);
if (badFrameCount && useNetif)
netStats->inputErrors += badFrameCount;
dmaChnlStatus = IOGetDBDMAChannelStatus( ioBaseEnetRxDMA );
if ( dmaChnlStatus & kdbdmaDead )
{
if (useNetif) netStats->inputErrors++;
IOLog( "BMacEnet::_receivePackets: Rx DMA Error - Status = %04x\n",
dmaChnlStatus );
_restartReceiver();
}
else
{
IODBDMAContinue( ioBaseEnetRxDMA );
}
#if 0
IOLog( "BMacEnet::_receivePackets: New - Rx Head = %2d Rx Tail = %2d\n",
rxCommandHead, rxCommandTail );
#endif
return doFlushQueue;
}
bool BMacEnet::_transmitInterruptOccurred()
{
u_int32_t dmaStatus;
u_int32_t collisionCount;
u_int32_t badFrameCount;
bool fServiced = false;
while ( 1 )
{
dmaStatus = IOGetCCResult(
&(txDMACommands[txCommandHead].desc_seg[1])) >> 16;
if ( !(dmaStatus & kdbdmaActive) )
{
break;
}
if (netifEnabled) netStats->outputPackets++;
fServiced = true;
KERNEL_DEBUG(DBG_BMAC_TXCOMPLETE | DBG_FUNC_NONE,
(int)txMbuf[txCommandHead],
(int)txMbuf[txCommandHead]->m_pkthdr.len, 0, 0, 0 );
if (txMbuf[txCommandHead] != txDebuggerPkt)
{
freePacket( txMbuf[txCommandHead] );
}
txMbuf[txCommandHead] = NULL;
if ( ++(txCommandHead) >= txMaxCommand )
txCommandHead = 0;
}
collisionCount = ReadBigMacRegister(ioBaseEnet, kNCCNT );
WriteBigMacRegister( ioBaseEnet, kNCCNT, 0 );
badFrameCount = ReadBigMacRegister(ioBaseEnet, kEXCNT )
+ ReadBigMacRegister(ioBaseEnet, kLTCNT );
WriteBigMacRegister( ioBaseEnet, kEXCNT, 0 );
WriteBigMacRegister( ioBaseEnet, kLTCNT, 0 );
if (netifEnabled) {
netStats->collisions += collisionCount;
netStats->outputErrors += badFrameCount;
}
dmaStatus = IOGetDBDMAChannelStatus( ioBaseEnetTxDMA );
if ( dmaStatus & kdbdmaDead )
{
if (netifEnabled) netStats->outputErrors++;
IOLog( "BMacEnet::_transmitInterruptOccurred: Tx DMA Error - Status = %04x\n", dmaStatus );
_restartTransmitter();
fServiced = true;
}
return fServiced;
}
bool BMacEnet::_debugTransmitInterruptOccurred()
{
u_int32_t dmaStatus;
u_int32_t badFrameCount;
bool fServiced = false;
debugTxPoll = true;
while ( 1 )
{
dmaStatus = IOGetCCResult(
&(txDMACommands[txCommandHead].desc_seg[1])) >> 16;
if ( !(dmaStatus & kdbdmaActive) )
{
break;
}
fServiced = true;
KERNEL_DEBUG(DBG_BMAC_TXCOMPLETE | DBG_FUNC_NONE,
(int)txMbuf[txCommandHead],
(int)txMbuf[txCommandHead]->m_pkthdr.len, 0, 0, 0 );
if (txMbuf[txCommandHead] != txDebuggerPkt) {
debugQueue->enqueue( txMbuf[txCommandHead] );
}
txMbuf[txCommandHead] = NULL;
if ( ++(txCommandHead) >= txMaxCommand )
txCommandHead = 0;
}
badFrameCount = ReadBigMacRegister(ioBaseEnet, kNCCNT );
WriteBigMacRegister( ioBaseEnet, kNCCNT, 0 );
badFrameCount = ReadBigMacRegister(ioBaseEnet, kEXCNT )
+ ReadBigMacRegister(ioBaseEnet, kLTCNT );
WriteBigMacRegister( ioBaseEnet, kEXCNT, 0 );
WriteBigMacRegister( ioBaseEnet, kLTCNT, 0 );
dmaStatus = IOGetDBDMAChannelStatus( ioBaseEnetTxDMA );
if ( dmaStatus & kdbdmaDead )
{
IOLog( "BMacEnet::_debugTransmitInterruptOccurred: Tx DMA Error - Status = %04x\n", dmaStatus );
_restartTransmitter();
fServiced = true;
}
return fServiced;
}
bool BMacEnet::_updateDescriptorFromMbuf( mbuf_t m, enet_dma_cmd_t *desc, bool isReceive )
{
u_int32_t nextDesc = 0;
u_int32_t waitMask = 0;
UInt32 segments;
struct IOPhysicalSegment segVector[2];
segments = mbufCursor->getPhysicalSegmentsWithCoalesce(m, segVector);
if ((!segments) || (segments > 2)) {
IOLog( "BMac:_updateDescriptorFromMbuf error, %d segments\n", (int)segments );
return false;
}
if ( isReceive || chipId >= kCHIPID_PaddingtonXmitStreaming )
{
waitMask = kdbdmaWaitNever;
}
else
{
waitMask = kdbdmaWaitIfFalse;
}
if ( segments == 1 )
{
IOMakeDBDMADescriptor( (&desc->desc_seg[0]),
((isReceive) ? kdbdmaInputLast : kdbdmaOutputLast),
(kdbdmaKeyStream0),
(kdbdmaIntNever),
(kdbdmaBranchNever),
(waitMask),
(segVector[0].length),
(segVector[0].location) );
desc->desc_seg[1] = (isReceive) ? dbdmaCmd_NopWInt : dbdmaCmd_Nop;
}
else
{
if ( isReceive )
{
nextDesc = rxDMACommandsPhys + (int)desc - (int)rxDMACommands +
sizeof(enet_dma_cmd_t);
}
IOMakeDBDMADescriptorDep( (&desc->desc_seg[0]),
((isReceive) ? kdbdmaInputMore : kdbdmaOutputMore),
(kdbdmaKeyStream0),
((isReceive) ? kdbdmaIntIfTrue : kdbdmaIntNever),
((isReceive) ? kdbdmaBranchIfTrue :
kdbdmaBranchNever),
(kdbdmaWaitNever),
(segVector[0].length),
(segVector[0].location),
nextDesc );
IOMakeDBDMADescriptor( (&desc->desc_seg[1]),
((isReceive) ? kdbdmaInputLast : kdbdmaOutputLast),
(kdbdmaKeyStream0),
((isReceive) ? kdbdmaIntAlways : kdbdmaIntNever),
(kdbdmaBranchNever),
(waitMask),
(segVector[1].length),
(segVector[1].location) );
}
return true;
}
#ifdef DEBUG
void BMacEnet::_dump_srom()
{
unsigned short data;
int i;
for (i = 0; i < 128; i++)
{
reset_and_select_srom(ioBaseEnet);
data = read_srom(ioBaseEnet, i, sromAddressBits);
IOLog( "BMacEnet::_dump_srom: %x = %x ", i, data );
if (i % 10 == 0) IOLog("\n");
}
}
void BMacEnet::_dumpDesc( void* addr, UInt32 physAddr, UInt32 size )
{
u_int32_t i;
unsigned long *p;
p = (UInt32*)addr;
for ( i = 0; i < size/sizeof( IODBDMADescriptor ); i++, p+=4, physAddr+=sizeof( IODBDMADescriptor ) )
{
IOLog( "BMacEnet::_dumpDesc: %08x(v) %08x(p): %08x %08x %08x %08x\n",
(int)p,
(int)physAddr,
(int)OSReadSwapInt32(p, 0), (int)OSReadSwapInt32(p, 4),
(int)OSReadSwapInt32(p, 8), (int)OSReadSwapInt32(p, 12) );
}
return;
}
void BMacEnet::_dumpRegisters()
{
u_int16_t dataValue;
IOLog( "\nBMacEnet::_dumpRegisters: IO Address = %08x", (int)ioBaseEnet );
dataValue = ReadBigMacRegister(ioBaseEnet, kXIFC);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Transceiver I/F = %04x", kXIFC, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kSTAT);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Int Events = %04x", kSTAT, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kINTDISABLE);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Int Disable = %04x", kINTDISABLE, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kTXRST);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Tx Reset = %04x", kTXRST, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kTXCFG);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Tx Config = %04x", kTXCFG, dataValue );
IOLog( "\nBMacEnet::_dumpRegisters: -------------------------------------------------------" );
dataValue = ReadBigMacRegister(ioBaseEnet, kIPG1);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x IPG1 = %04x", kIPG1, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kIPG2);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x IPG2 = %04x", kIPG2, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kALIMIT);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Attempt Limit = %04x", kALIMIT, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kSLOT);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Slot Time = %04x", kSLOT, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kPALEN);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Preamble Length = %04x", kPALEN, dataValue );
IOLog( "\nBMacEnet::_dumpRegisters: -------------------------------------------------------" );
dataValue = ReadBigMacRegister(ioBaseEnet, kPAPAT);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Preamble Pattern = %04x", kPAPAT, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kTXSFD);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Tx Start Frame Delimeter = %04x", kTXSFD, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kJAM);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Jam Size = %04x", kJAM, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kTXMAX);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Tx Max Size = %04x", kTXMAX, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kTXMIN);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Tx Min Size = %04x", kTXMIN, dataValue );
IOLog( "\nBMacEnet::_dumpRegisters: -------------------------------------------------------" );
dataValue = ReadBigMacRegister(ioBaseEnet, kPAREG);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Peak Attempts = %04x", kPAREG, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kDCNT);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Defer Timer = %04x", kDCNT, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kNCCNT);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Normal Collision Count = %04x", kNCCNT, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kNTCNT);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Network Collision Count = %04x", kNTCNT, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kEXCNT);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Excessive Coll Count = %04x", kEXCNT, dataValue );
IOLog( "\nBMacEnet::_dumpRegisters: -------------------------------------------------------" );
dataValue = ReadBigMacRegister(ioBaseEnet, kLTCNT);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Late Collision Count = %04x", kLTCNT, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kRSEED);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Random Seed = %04x", kRSEED, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kTXSM);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Tx State Machine = %04x", kTXSM, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kRXRST);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Rx Reset = %04x", kRXRST, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kRXCFG);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Rx Config = %04x", kRXCFG, dataValue );
IOLog( "\nBMacEnet::_dumpRegisters: -------------------------------------------------------" );
dataValue = ReadBigMacRegister(ioBaseEnet, kRXMAX);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Rx Max Size = %04x", kRXMAX, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kRXMIN);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Rx Min Size = %04x", kRXMIN, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kMADD2);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Mac Address 2 = %04x", kMADD2, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kMADD1);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Mac Address 1 = %04x", kMADD1, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kMADD0);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Mac Address 0 = %04x", kMADD0, dataValue );
IOLog( "\nBMacEnet::_dumpRegisters: -------------------------------------------------------" );
dataValue = ReadBigMacRegister(ioBaseEnet, kFRCNT);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Rx Frame Counter = %04x", kFRCNT, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kLECNT);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Rx Length Error Cnt = %04x", kLECNT, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kAECNT);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Alignment Error Cnt = %04x", kAECNT, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kFECNT);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x FCS Error Cnt = %04x", kFECNT, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kRXSM);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Rx State Machine = %04x", kRXSM, dataValue );
IOLog( "\nBMacEnet::_dumpRegisters: -------------------------------------------------------" );
dataValue = ReadBigMacRegister(ioBaseEnet, kRXCV);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Rx Code Violation = %04x", kRXCV, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kHASH3);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Hash 3 = %04x", kHASH3, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kHASH2);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Hash 2 = %04x", kHASH2, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kHASH1);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Hash 1 = %04x", kHASH1, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kHASH0);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Hash 0 = %04x", kHASH0, dataValue );
IOLog( "\n-------------------------------------------------------" );
dataValue = ReadBigMacRegister(ioBaseEnet, kAFR2);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Address Filter 2 = %04x", kAFR2, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kAFR1);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Address Filter 1 = %04x", kAFR1, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kAFR0);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Address Filter 0 = %04x", kAFR0, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kAFCR);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Adress Filter Mask = %04x", kAFCR, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kTXFIFOCSR);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Tx FIFO CSR = %04x", kTXFIFOCSR, dataValue );
IOLog( "\n-------------------------------------------------------" );
dataValue = ReadBigMacRegister(ioBaseEnet, kTXTH);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Tx Threshold = %04x", kTXTH, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kRXFIFOCSR);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Rx FIFO CSR = %04x", kRXFIFOCSR, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kMEMADD);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Mem Addr = %04x", kMEMADD, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kMEMDATAHI);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Mem Data High = %04x", kMEMDATAHI, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kMEMDATALO);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Mem Data Low = %04x", kMEMDATALO, dataValue );
IOLog( "\n-------------------------------------------------------" );
dataValue = ReadBigMacRegister(ioBaseEnet, kXCVRIF);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Transceiver IF Control = %04x", kXCVRIF, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kCHIPID);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Chip ID = %04x", kCHIPID, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kMIFCSR);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x MII CSR = %04x", kMIFCSR, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kSROMCSR);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x SROM CSR = %04x", kSROMCSR, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kTXPNTR);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Tx Pointer = %04x", kTXPNTR, dataValue );
dataValue = ReadBigMacRegister(ioBaseEnet, kRXPNTR);
IOLog( "\nBMacEnet::_dumpRegisters: Read Register %04x Rx Pointer = %04x", kRXPNTR, dataValue );
IOLog( "\nBMacEnet::_dumpRegisters: -------------------------------------------------------\n" );
return;
}
#endif DEBUG
IOReturn BMacEnet::getHardwareAddress(IOEthernetAddress *ea)
{
int i;
unsigned short data;
for (i = 0; i < (unsigned short)sizeof(*ea)/2; i++)
{
reset_and_select_srom(ioBaseEnet);
data = read_srom(ioBaseEnet, i + enetAddressOffset/2, sromAddressBits);
ea->bytes[2*i] = reverseBitOrder(data & 0x0ff);
ea->bytes[2*i+1] = reverseBitOrder((data >> 8) & 0x0ff);
}
return kIOReturnSuccess;
}
#define ENET_CRCPOLY 0x04c11db7
static int reverse6[] =
{ 0x0,0x20,0x10,0x30,0x8,0x28,0x18,0x38,
0x4,0x24,0x14,0x34,0xc,0x2c,0x1c,0x3c,
0x2,0x22,0x12,0x32,0xa,0x2a,0x1a,0x3a,
0x6,0x26,0x16,0x36,0xe,0x2e,0x1e,0x3e,
0x1,0x21,0x11,0x31,0x9,0x29,0x19,0x39,
0x5,0x25,0x15,0x35,0xd,0x2d,0x1d,0x3d,
0x3,0x23,0x13,0x33,0xb,0x2b,0x1b,0x3b,
0x7,0x27,0x17,0x37,0xf,0x2f,0x1f,0x3f
};
static u_int32_t crc416(unsigned int current, unsigned short nxtval )
{
register unsigned int counter;
register int highCRCBitSet, lowDataBitSet;
nxtval = ((nxtval & 0x00FF) << 8) | (nxtval >> 8);
for (counter = 0; counter != 16; ++counter)
{
if ((current & 0x80000000) == 0)
highCRCBitSet = 0;
else
highCRCBitSet = 1;
current = current << 1;
if ((nxtval & 0x0001) == 0)
lowDataBitSet = 0;
else
lowDataBitSet = 1;
nxtval = nxtval >> 1;
if (highCRCBitSet ^ lowDataBitSet)
current = current ^ ENET_CRCPOLY;
}
return current;
}
static u_int32_t mace_crc(unsigned short *address)
{
register u_int32_t newcrc;
newcrc = crc416(0xffffffff, *address);
newcrc = crc416(newcrc, address[1]);
newcrc = crc416(newcrc, address[2]);
return(newcrc);
}
void BMacEnet::_resetHashTableMask()
{
bzero(hashTableUseCount, sizeof(hashTableUseCount));
bzero(hashTableMask, sizeof(hashTableMask));
}
void BMacEnet::_addToHashTableMask(u_int8_t *addr)
{
u_int32_t crc;
u_int16_t mask;
crc = mace_crc((unsigned short *)addr)&0x3f;
crc = reverse6[crc];
if (hashTableUseCount[crc]++)
return;
mask = crc % 16;
mask = (unsigned short)1 << mask;
hashTableMask[crc/16] |= mask;
}
void BMacEnet::_removeFromHashTableMask(u_int8_t *addr)
{
unsigned int crc;
u_int16_t mask;
crc = mace_crc((unsigned short *)addr)&0x3f;
crc = reverse6[crc];
if (hashTableUseCount[crc] == 0)
return;
if (--hashTableUseCount[crc])
return;
mask = crc % 16;
mask = (u_int16_t)1 << mask;
hashTableMask[crc/16] &= ~mask;
}
void BMacEnet::_updateBMacHashTableMask()
{
u_int16_t rxCFGReg;
rxCFGReg = ReadBigMacRegister(ioBaseEnet, kRXCFG);
WriteBigMacRegister(ioBaseEnet, kRXCFG,
rxCFGReg & ~(kRxMACEnable | kRxHashFilterEnable) );
while ( ReadBigMacRegister(ioBaseEnet, kRXCFG) &
(kRxMACEnable | kRxHashFilterEnable) )
;
WriteBigMacRegister(ioBaseEnet, kHASH0, hashTableMask[0]); WriteBigMacRegister(ioBaseEnet, kHASH1, hashTableMask[1]); WriteBigMacRegister(ioBaseEnet, kHASH2, hashTableMask[2]); WriteBigMacRegister(ioBaseEnet, kHASH3, hashTableMask[3]);
rxCFGReg |= kRxHashFilterEnable;
WriteBigMacRegister(ioBaseEnet, kRXCFG, rxCFGReg );
}