#include "3C90x.h"
UInt8
Apple3Com3C90x::setRegisterWindow( UInt8 newWindow )
{
UInt8 currentWindow = _window;
if ( _window != newWindow )
{
sendCommand( SelectWindow, newWindow );
_window = newWindow;
}
return currentWindow;
}
void
Apple3Com3C90x::setStationAddress( const IOEthernetAddress * addr )
{
setRegisterWindow( kStationAddressWindow );
for ( int i = 0 ; i < kIOEthernetAddressSize ; i++ )
outb( _ioBase + kStationAddressMaskOffset + i, 0 );
for ( int i = 0 ; i < kIOEthernetAddressSize ; i++ )
outb( _ioBase + kStationAddressOffset + i, addr->bytes[i] );
}
void
Apple3Com3C90x::sendCommand( UInt16 cmd, UInt16 arg = 0 )
{
setCommandStatus( cmd | (arg & 0x7ff) );
}
void
Apple3Com3C90x::sendCommandWait( UInt16 cmd, UInt16 arg = 0 )
{
SInt32 i = 1000 * 1000 * 10;
setCommandStatus( cmd | (arg & 0x7ff) );
while ( ( i-- > 0 ) &&
( getCommandStatus() & kCommandStatusCmdInProgressMask ) )
; }
void
Apple3Com3C90x::selectTransceiverPort( MediaPort port )
{
UInt32 internalConfig = getInternalConfig();
internalConfig &= ~kInternalConfigXcvrSelectMask;
internalConfig |= SetBitField( InternalConfig, XcvrSelect, port );
setInternalConfig( internalConfig );
}
UInt8
Apple3Com3C90x::hashMulticastAddress( UInt8 * Address )
{
UInt32 Crc, Carry;
UInt32 i, j;
UInt8 ThisByte;
Crc = 0xffffffff;
for (i = 0; i < 6; i++) {
ThisByte = Address[i];
for (j = 0; j < 8; j++) {
Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (ThisByte & 0x01);
Crc <<= 1;
ThisByte >>= 1;
if (Carry)
Crc = (Crc ^ 0x04c11db6) | Carry;
}
}
return Crc & 0x000000FF;
}
void
Apple3Com3C90x::waitForTransmitterIdle()
{
const int maxPollLoops = 1000 * 1000;
for ( int i = maxPollLoops; i > 0; i-- )
{
if ( ( getDMACtrl() & kDMACtrlDnInProgMask ) == 0 )
break;
IODelay(1);
}
for ( int i = maxPollLoops; i > 0; i-- )
{
if ( ( getMediaStatus() & kMediaStatusTxInProgMask ) == 0 )
break;
IODelay(1);
}
}
#define kEEPROMPollLoops 10 // number of times to poll for not busy
#define kEEPROMPollSleep 1 // ms sleep before next poll
UInt16
Apple3Com3C90x::readEEPROM( UInt8 offset )
{
UInt16 word;
for ( int i = kEEPROMPollLoops; i > 0; i-- )
{
if ( ( getEEPROMCommand() & kEEPROMCommandBusyMask ) == 0 )
break;
IOSleep( kEEPROMPollSleep );
}
word = SetBitField( EEPROMCommand, Address, offset ) | kEEPROMOpcodeRead;
setEEPROMCommand( word );
for ( int i = kEEPROMPollLoops; i > 0; i-- )
{
if ( ( getEEPROMCommand() & kEEPROMCommandBusyMask ) == 0 )
break;
IOSleep( kEEPROMPollSleep );
}
return ( getEEPROMData() );
}
void
Apple3Com3C90x::getStationAddress( IOEthernetAddress * addr )
{
UInt8 eepromAddr = eepromOAddr0;
bool retry = true;
UInt16 word;
start:
for ( int i = 0; i < 3; i++, eepromAddr++ )
{
for ( int j = kEEPROMPollLoops; j > 0; j-- )
{
if ( ( getEEPROMCommand() & kEEPROMCommandBusyMask ) == 0 )
break;
IOSleep( kEEPROMPollSleep );
}
word = SetBitField( EEPROMCommand, Address, eepromAddr ) |
kEEPROMOpcodeRead;
setEEPROMCommand( word );
for ( int j = kEEPROMPollLoops; j > 0; j-- )
{
if ( ( getEEPROMCommand() & kEEPROMCommandBusyMask ) == 0 )
break;
IOSleep( kEEPROMPollSleep );
}
word = getEEPROMData();
addr->bytes[i*2] = (word >> 8) & 0xff;
addr->bytes[i*2+1] = (word & 0xff);
}
if ( retry )
{
for ( int i = 0; i < 6; i++ )
{
if ( addr->bytes[i] != 0 ) return;
}
eepromAddr = eepromAddr0;
retry = false;
goto start;
}
}