pureikyubu/Docs/RE/eth.txt
Andruxa 574b40f37b Some old reversing found )
RE: DVDLow
RE: DVD file open
RE: Some ETH (BBA lib)
2015-09-07 02:48:37 +03:00

165 lines
3.1 KiB
Text

typedef struct ETHStat
{
u32 rcvcount;
u32 sendcount;
u32 cntof;
u16 re;
u16 te;
u16 fifoe;
u16 rbf;
u16 rx_bf;
u16 rx_crc;
u16 rx_fae;
u16 rx_fo;
u16 rx_rw;
u16 rx_rf;
u16 tx_crs;
u16 tx_uf;
u16 tx_owc;
} ETHStat;
static int __ETHVersion = 0;
static ETHStat ethstat;
static OSThreadQueue threadQ;
static OSAlarm rcvchk_alarm;
static OSResetFunctionInfo ResetFunctionInfo = { OnReset, 127 };
static u8 private_macaddr[6];
static u8 broadcastheader[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
static u8 __revid;
static u16 __devid = 0xd107;
static u8 __acstart = 0x4e;
// SI EXI Clock Lock register.
#define SIEXILK ( *(volatile u32 *)(0xCC00643C))
#define SIEXILK_LOCK 0x80000000
// ---------------------------------------------------------------------------
int ETHInit(void)
{
static BOOL firsttime = TRUE;
u32 cid, fcsr, phy0r;
if(firsttime)
OSRegisterVersion(__ETHVersion);
OSInitThreadQueue(&threadQ);
// Unlock 32 MHz EXI clock.
SIEXILK &= ~SIEXILK_LOCK;
waitexilock();
__sendbusy = 0;
memset(&ethstat, 0, sizeof(ETHStat));
protoarray = 0;
protonum = 0;
recvcallback0 = 0;
recvcallback1 = 0;
// Retrieve and check the ID of an ethernet adapter.
cid = readCID();
if(cid != 0x04020200)
{
EXIUnlock(0);
OSReport("cid = %08x\n", cid);
return -1;
}
reset();
readcmdLong(0x20, private_macaddr, 6);
__revid = readEXIcmd(1);
writeEXIcmdLong(4, &__devid, 2);
writeEXIcmd(5, __acstart);
fcsr = readcmd(0x5b) & ~0x80;
writecmd(0x5b, fcsr);
writecmd(0x5e, 1);
phy0r = readcmd(0x5c) | 0x04;
writecmd(0x5c, phy0r);
writecmd(1, 0);
writecmd(0x50, 0x80);
writecmd(8, 0);
writeEXIcmd(2, 0xF8);
EXISetExiCallback(2, exiinthandler);
if(firsttime)
{
OSCreateAlarm(&rcvchk_alarm);
OSSetPeriodicAlarm(&rcvchk_alarm,
firsttime = FALSE;
}
OSRegisterResetFunction(&ResetFunctionInfo);
EXIUnlock(0);
return 1;
}
// ---------------------------------------------------------------------------
void exiinthandler(void)
{
u32 ret, ir, exiisr;
if( EXILock(0, 2, exiinthandler) == 0) return;
ir = readEXIcmd(3);
writeEXIcmd(2, 0);
}
// ---------------------------------------------------------------------------
void unlockcallback(void)
{
OSWakeupThread(&threadQ);
}
void waitexilock(void)
{
BOOL enabled = OSDisableInterrupts();
if( EXILock(0, 2, 0, unlockcallback) != 1 )
{
OSRestoreInterrupts(enabled);
return;
}
OSSleepThread(&threadQ);
OSRestoreInterrupts(enabled);
}
u32 readCID(void)
{
u32 cid;
u16 ethcmd = 0;
EXISelect(0, 2, 0);
EXIImm(0, &ethcmd, 2, 1, 0);
EXISync(0);
EXIImm(0, &cid, 4, 0, 0);
EXISync(0);
EXIDeselect(0);
return cid;
}
void reset(void)
{
writecmd(0x60, 0);
waitmicro(10000);
readEXIcmdWait200Micro(15);
waitmicro(10000);
writecmd(0, 1);
writecmd(0, 0);
}