code cleanup for win32/tap/eth
This commit is contained in:
parent
9a3dd778cb
commit
9cff8316d2
|
@ -192,28 +192,26 @@ bool CEXIETHERNET::Activate()
|
||||||
if (IsActivated())
|
if (IsActivated())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
INFO_LOG(SP1, "Activating BBA...");
|
|
||||||
|
|
||||||
DWORD len;
|
DWORD len;
|
||||||
std::vector<std::string> device_guids;
|
std::vector<std::string> device_guids;
|
||||||
|
|
||||||
if (!Win32TAPHelper::GetGUIDs(device_guids))
|
if (!Win32TAPHelper::GetGUIDs(device_guids))
|
||||||
{
|
{
|
||||||
INFO_LOG(SP1, "Failed to find a TAP GUID");
|
ERROR_LOG(SP1, "Failed to find a TAP GUID");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < device_guids.size(); i++)
|
for (size_t i = 0; i < device_guids.size(); i++)
|
||||||
{
|
{
|
||||||
if (Win32TAPHelper::OpenTAP(mHAdapter, device_guids.at(i)))
|
if (Win32TAPHelper::OpenTAP(mHAdapter, device_guids.at(i)))
|
||||||
{
|
{
|
||||||
ERROR_LOG(SP1, "OPENED %s", device_guids.at(i).c_str());
|
INFO_LOG(SP1, "OPENED %s", device_guids.at(i).c_str());
|
||||||
i = device_guids.size();
|
i = device_guids.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mHAdapter == INVALID_HANDLE_VALUE)
|
if (mHAdapter == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
INFO_LOG(SP1, "Failed to open any TAP");
|
ERROR_LOG(SP1, "Failed to open any TAP");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,14 +238,11 @@ bool CEXIETHERNET::Activate()
|
||||||
if (!DeviceIoControl(mHAdapter, TAP_IOCTL_SET_MEDIA_STATUS,
|
if (!DeviceIoControl(mHAdapter, TAP_IOCTL_SET_MEDIA_STATUS,
|
||||||
&status, sizeof(status), &status, sizeof(status), &len, NULL))
|
&status, sizeof(status), &status, sizeof(status), &len, NULL))
|
||||||
{
|
{
|
||||||
INFO_LOG(SP1, "WARNING: The TAP-Win32 driver rejected a"
|
ERROR_LOG(SP1, "WARNING: The TAP-Win32 driver rejected a"
|
||||||
"TAP_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
|
"TAP_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//RecvInit();
|
|
||||||
|
|
||||||
INFO_LOG(SP1, "Success!");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,50 +265,27 @@ bool CEXIETHERNET::IsActivated()
|
||||||
return mHAdapter != INVALID_HANDLE_VALUE;
|
return mHAdapter != INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO check if still needed
|
|
||||||
// Required for lwip...not sure why
|
|
||||||
void fixup_ip_checksum(u16 *dataptr, u16 len)
|
|
||||||
{
|
|
||||||
u32 acc = 0;
|
|
||||||
u16 *data = dataptr;
|
|
||||||
u16 *chksum = &dataptr[5];
|
|
||||||
|
|
||||||
*chksum = 0;
|
|
||||||
|
|
||||||
while (len > 1) {
|
|
||||||
u16 s = *data++;
|
|
||||||
acc += Common::swap16(s);
|
|
||||||
len -= 2;
|
|
||||||
}
|
|
||||||
acc = (acc >> 16) + (acc & 0xffff);
|
|
||||||
acc += (acc >> 16);
|
|
||||||
*chksum = Common::swap16(~acc);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CEXIETHERNET::SendFrame(u8 *frame, u32 size)
|
bool CEXIETHERNET::SendFrame(u8 *frame, u32 size)
|
||||||
{
|
{
|
||||||
//fixup_ip_checksum((u16*)frame + 7, 20);
|
DEBUG_LOG(SP1, "SendFrame %x\n%s",
|
||||||
|
size, ArrayToString(frame, size, 0x10).c_str());
|
||||||
DEBUG_LOG(SP1, "SendFrame %x\n%s", size, ArrayToString(frame, size, 0x10).c_str());
|
|
||||||
|
|
||||||
DWORD numBytesWrit;
|
DWORD numBytesWrit;
|
||||||
OVERLAPPED overlap;
|
OVERLAPPED overlap;
|
||||||
ZeroMemory(&overlap, sizeof(overlap));
|
ZeroMemory(&overlap, sizeof(overlap));
|
||||||
//overlap.hEvent = mHRecvEvent;
|
|
||||||
|
|
||||||
if (!WriteFile(mHAdapter, frame, size, &numBytesWrit, &overlap))
|
if (!WriteFile(mHAdapter, frame, size, &numBytesWrit, &overlap))
|
||||||
{
|
{
|
||||||
// Fail Boat
|
|
||||||
DWORD res = GetLastError();
|
DWORD res = GetLastError();
|
||||||
WARN_LOG(SP1, "Failed to send packet with error 0x%X", res);
|
ERROR_LOG(SP1, "Failed to send packet with error 0x%X", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numBytesWrit != size)
|
if (numBytesWrit != size)
|
||||||
{
|
{
|
||||||
WARN_LOG(SP1, "BBA SendFrame %i only got %i bytes sent!", size, numBytesWrit);
|
ERROR_LOG(SP1, "BBA SendFrame %i only got %i bytes sent!", size, numBytesWrit);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always report the packet as being sent successfully, even though it might be a lie
|
||||||
SendComplete();
|
SendComplete();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -324,7 +296,7 @@ VOID CALLBACK CEXIETHERNET::ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFir
|
||||||
CEXIETHERNET* self = (CEXIETHERNET*)lpParameter;
|
CEXIETHERNET* self = (CEXIETHERNET*)lpParameter;
|
||||||
|
|
||||||
GetOverlappedResult(self->mHAdapter, &self->mReadOverlapped,
|
GetOverlappedResult(self->mHAdapter, &self->mReadOverlapped,
|
||||||
&self->mRecvBufferLength, false);
|
(LPDWORD)&self->mRecvBufferLength, false);
|
||||||
|
|
||||||
self->RecvHandlePacket();
|
self->RecvHandlePacket();
|
||||||
}
|
}
|
||||||
|
@ -335,7 +307,7 @@ bool CEXIETHERNET::RecvInit()
|
||||||
|
|
||||||
if ((mHRecvEvent = CreateEvent(NULL, false, false, NULL)) == NULL)
|
if ((mHRecvEvent = CreateEvent(NULL, false, false, NULL)) == NULL)
|
||||||
{
|
{
|
||||||
INFO_LOG(SP1, "Failed to create recv event:%x", GetLastError());
|
ERROR_LOG(SP1, "Failed to create recv event:%x", GetLastError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,7 +330,7 @@ bool CEXIETHERNET::RecvStart()
|
||||||
RecvInit();
|
RecvInit();
|
||||||
|
|
||||||
DWORD res = ReadFile(mHAdapter, mRecvBuffer, BBA_RECV_SIZE,
|
DWORD res = ReadFile(mHAdapter, mRecvBuffer, BBA_RECV_SIZE,
|
||||||
&mRecvBufferLength, &mReadOverlapped);
|
(LPDWORD)&mRecvBufferLength, &mReadOverlapped);
|
||||||
|
|
||||||
if (!res && (GetLastError() != ERROR_IO_PENDING))
|
if (!res && (GetLastError() != ERROR_IO_PENDING))
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,16 +16,21 @@
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "Memmap.h"
|
#include "Memmap.h"
|
||||||
//#pragma optimize("",off)
|
|
||||||
#include "EXI_Device.h"
|
#include "EXI_Device.h"
|
||||||
#include "EXI_DeviceEthernet.h"
|
#include "EXI_DeviceEthernet.h"
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
|
|
||||||
|
// XXX: The BBA stores multi-byte elements as little endian.
|
||||||
|
// Multiple parts of this implementation depend on dolphin
|
||||||
|
// being compiled for a little endian host.
|
||||||
|
|
||||||
CEXIETHERNET::CEXIETHERNET(const std::string& mac_addr)
|
CEXIETHERNET::CEXIETHERNET(const std::string& mac_addr)
|
||||||
{
|
{
|
||||||
tx_fifo = new u8[1518];
|
tx_fifo = new u8[1518];
|
||||||
mBbaMem = new u8[BBA_MEM_SIZE];
|
mBbaMem = new u8[BBA_MEM_SIZE];
|
||||||
|
|
||||||
mRecvBuffer = new u8 [BBA_RECV_SIZE];
|
mRecvBuffer = new u8 [BBA_RECV_SIZE];
|
||||||
|
mRecvBufferLength = 0;
|
||||||
|
|
||||||
MXHardReset();
|
MXHardReset();
|
||||||
|
|
||||||
|
@ -34,7 +39,7 @@ CEXIETHERNET::CEXIETHERNET(const std::string& mac_addr)
|
||||||
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
u8 new_addr[6] = { 0 };
|
u8 new_addr[6] = { 0 };
|
||||||
for (int i = 0; i < (int)mac_addr.size() && x < 12; i++)
|
for (size_t i = 0; i < mac_addr.size() && x < 12; i++)
|
||||||
{
|
{
|
||||||
char c = mac_addr.at(i);
|
char c = mac_addr.at(i);
|
||||||
if (c >= '0' && c <= '9') {
|
if (c >= '0' && c <= '9') {
|
||||||
|
@ -61,8 +66,6 @@ CEXIETHERNET::CEXIETHERNET(const std::string& mac_addr)
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
fd = -1;
|
fd = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mRecvBufferLength = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CEXIETHERNET::~CEXIETHERNET()
|
CEXIETHERNET::~CEXIETHERNET()
|
||||||
|
@ -76,8 +79,6 @@ CEXIETHERNET::~CEXIETHERNET()
|
||||||
|
|
||||||
void CEXIETHERNET::SetCS(int cs)
|
void CEXIETHERNET::SetCS(int cs)
|
||||||
{
|
{
|
||||||
DEBUG_LOG(SP1, "chip select: %s", cs ? "true" : "false");
|
|
||||||
|
|
||||||
if (cs)
|
if (cs)
|
||||||
{
|
{
|
||||||
// Invalidate the previous transfer
|
// Invalidate the previous transfer
|
||||||
|
@ -109,14 +110,17 @@ void CEXIETHERNET::ImmWrite(u32 data, u32 size)
|
||||||
transfer.address = (data >> 8) & 0xffff;
|
transfer.address = (data >> 8) & 0xffff;
|
||||||
transfer.direction = IsWriteCommand(data) ? transfer.WRITE : transfer.READ;
|
transfer.direction = IsWriteCommand(data) ? transfer.WRITE : transfer.READ;
|
||||||
|
|
||||||
WARN_LOG(SP1, "%s %s %s %x",
|
DEBUG_LOG(SP1, "%s %s %s %x",
|
||||||
IsMXCommand(data) ? "mx " : "exi",
|
IsMXCommand(data) ? "mx " : "exi",
|
||||||
IsWriteCommand(data) ? "write" : "read ",
|
IsWriteCommand(data) ? "write" : "read ",
|
||||||
GetRegisterName(),
|
GetRegisterName(),
|
||||||
transfer.address);
|
transfer.address);
|
||||||
|
|
||||||
if (transfer.address == BBA_IOB && transfer.region == transfer.MX)
|
if (transfer.address == BBA_IOB && transfer.region == transfer.MX)
|
||||||
|
{
|
||||||
|
ERROR_LOG(SP1, "Usage of BBA_IOB indicates that the rx packet descriptor has been corrupted, killing dolphin...");
|
||||||
exit(0);
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
// transfer has been setup
|
// transfer has been setup
|
||||||
return;
|
return;
|
||||||
|
@ -124,7 +128,7 @@ void CEXIETHERNET::ImmWrite(u32 data, u32 size)
|
||||||
|
|
||||||
// Reach here if we're actually writing data to the EXI or MX region.
|
// Reach here if we're actually writing data to the EXI or MX region.
|
||||||
|
|
||||||
WARN_LOG(SP1, "%s write %0*x",
|
DEBUG_LOG(SP1, "%s write %0*x",
|
||||||
transfer.region == transfer.MX ? "mx " : "exi", size * 2, data);
|
transfer.region == transfer.MX ? "mx " : "exi", size * 2, data);
|
||||||
|
|
||||||
if (transfer.region == transfer.EXI)
|
if (transfer.region == transfer.EXI)
|
||||||
|
@ -178,7 +182,7 @@ u32 CEXIETHERNET::ImmRead(u32 size)
|
||||||
ret |= mBbaMem[transfer.address++] << (i * 8);
|
ret |= mBbaMem[transfer.address++] << (i * 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
WARN_LOG(SP1, "imm r%i: %0*x", size, size * 2, ret);
|
DEBUG_LOG(SP1, "imm r%i: %0*x", size, size * 2, ret);
|
||||||
|
|
||||||
ret <<= (4 - size) * 8;
|
ret <<= (4 - size) * 8;
|
||||||
|
|
||||||
|
@ -187,7 +191,7 @@ u32 CEXIETHERNET::ImmRead(u32 size)
|
||||||
|
|
||||||
void CEXIETHERNET::DMAWrite(u32 addr, u32 size)
|
void CEXIETHERNET::DMAWrite(u32 addr, u32 size)
|
||||||
{
|
{
|
||||||
WARN_LOG(SP1, "dma w: %08x %x", addr, size);
|
DEBUG_LOG(SP1, "dma w: %08x %x", addr, size);
|
||||||
|
|
||||||
if (transfer.region == transfer.MX &&
|
if (transfer.region == transfer.MX &&
|
||||||
transfer.direction == transfer.WRITE &&
|
transfer.direction == transfer.WRITE &&
|
||||||
|
@ -205,7 +209,7 @@ void CEXIETHERNET::DMAWrite(u32 addr, u32 size)
|
||||||
|
|
||||||
void CEXIETHERNET::DMARead(u32 addr, u32 size)
|
void CEXIETHERNET::DMARead(u32 addr, u32 size)
|
||||||
{
|
{
|
||||||
ERROR_LOG(SP1, "dma r: %08x %x", addr, size);
|
DEBUG_LOG(SP1, "dma r: %08x %x", addr, size);
|
||||||
|
|
||||||
memcpy(Memory::GetPointer(addr), &mBbaMem[transfer.address], size);
|
memcpy(Memory::GetPointer(addr), &mBbaMem[transfer.address], size);
|
||||||
|
|
||||||
|
@ -216,6 +220,7 @@ void CEXIETHERNET::DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
p.Do(mBbaMem);
|
p.Do(mBbaMem);
|
||||||
// TODO ... the rest...
|
// TODO ... the rest...
|
||||||
|
ERROR_LOG(SP1, "CEXIETHERNET::DoState not implemented!");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CEXIETHERNET::IsMXCommand(u32 const data)
|
bool CEXIETHERNET::IsMXCommand(u32 const data)
|
||||||
|
@ -236,16 +241,16 @@ char const * const CEXIETHERNET::GetRegisterName() const
|
||||||
{
|
{
|
||||||
switch (transfer.address)
|
switch (transfer.address)
|
||||||
{
|
{
|
||||||
STR_RETURN(EXI_ID)
|
STR_RETURN(EXI_ID)
|
||||||
STR_RETURN(REVISION_ID)
|
STR_RETURN(REVISION_ID)
|
||||||
STR_RETURN(INTERRUPT)
|
STR_RETURN(INTERRUPT)
|
||||||
STR_RETURN(INTERRUPT_MASK)
|
STR_RETURN(INTERRUPT_MASK)
|
||||||
STR_RETURN(DEVICE_ID)
|
STR_RETURN(DEVICE_ID)
|
||||||
STR_RETURN(ACSTART)
|
STR_RETURN(ACSTART)
|
||||||
STR_RETURN(HASH_READ)
|
STR_RETURN(HASH_READ)
|
||||||
STR_RETURN(HASH_WRITE)
|
STR_RETURN(HASH_WRITE)
|
||||||
STR_RETURN(HASH_STATUS)
|
STR_RETURN(HASH_STATUS)
|
||||||
STR_RETURN(RESET)
|
STR_RETURN(RESET)
|
||||||
default: return "unknown";
|
default: return "unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,45 +258,45 @@ char const * const CEXIETHERNET::GetRegisterName() const
|
||||||
{
|
{
|
||||||
switch (transfer.address)
|
switch (transfer.address)
|
||||||
{
|
{
|
||||||
STR_RETURN(BBA_NCRA)
|
STR_RETURN(BBA_NCRA)
|
||||||
STR_RETURN(BBA_NCRB)
|
STR_RETURN(BBA_NCRB)
|
||||||
STR_RETURN(BBA_LTPS)
|
STR_RETURN(BBA_LTPS)
|
||||||
STR_RETURN(BBA_LRPS)
|
STR_RETURN(BBA_LRPS)
|
||||||
STR_RETURN(BBA_IMR)
|
STR_RETURN(BBA_IMR)
|
||||||
STR_RETURN(BBA_IR)
|
STR_RETURN(BBA_IR)
|
||||||
STR_RETURN(BBA_BP)
|
STR_RETURN(BBA_BP)
|
||||||
STR_RETURN(BBA_TLBP)
|
STR_RETURN(BBA_TLBP)
|
||||||
STR_RETURN(BBA_TWP)
|
STR_RETURN(BBA_TWP)
|
||||||
STR_RETURN(BBA_IOB)
|
STR_RETURN(BBA_IOB)
|
||||||
STR_RETURN(BBA_TRP)
|
STR_RETURN(BBA_TRP)
|
||||||
STR_RETURN(BBA_RWP)
|
STR_RETURN(BBA_RWP)
|
||||||
STR_RETURN(BBA_RRP)
|
STR_RETURN(BBA_RRP)
|
||||||
STR_RETURN(BBA_RHBP)
|
STR_RETURN(BBA_RHBP)
|
||||||
STR_RETURN(BBA_RXINTT)
|
STR_RETURN(BBA_RXINTT)
|
||||||
STR_RETURN(BBA_NAFR_PAR0)
|
STR_RETURN(BBA_NAFR_PAR0)
|
||||||
STR_RETURN(BBA_NAFR_PAR1)
|
STR_RETURN(BBA_NAFR_PAR1)
|
||||||
STR_RETURN(BBA_NAFR_PAR2)
|
STR_RETURN(BBA_NAFR_PAR2)
|
||||||
STR_RETURN(BBA_NAFR_PAR3)
|
STR_RETURN(BBA_NAFR_PAR3)
|
||||||
STR_RETURN(BBA_NAFR_PAR4)
|
STR_RETURN(BBA_NAFR_PAR4)
|
||||||
STR_RETURN(BBA_NAFR_PAR5)
|
STR_RETURN(BBA_NAFR_PAR5)
|
||||||
STR_RETURN(BBA_NAFR_MAR0)
|
STR_RETURN(BBA_NAFR_MAR0)
|
||||||
STR_RETURN(BBA_NAFR_MAR1)
|
STR_RETURN(BBA_NAFR_MAR1)
|
||||||
STR_RETURN(BBA_NAFR_MAR2)
|
STR_RETURN(BBA_NAFR_MAR2)
|
||||||
STR_RETURN(BBA_NAFR_MAR3)
|
STR_RETURN(BBA_NAFR_MAR3)
|
||||||
STR_RETURN(BBA_NAFR_MAR4)
|
STR_RETURN(BBA_NAFR_MAR4)
|
||||||
STR_RETURN(BBA_NAFR_MAR5)
|
STR_RETURN(BBA_NAFR_MAR5)
|
||||||
STR_RETURN(BBA_NAFR_MAR6)
|
STR_RETURN(BBA_NAFR_MAR6)
|
||||||
STR_RETURN(BBA_NAFR_MAR7)
|
STR_RETURN(BBA_NAFR_MAR7)
|
||||||
STR_RETURN(BBA_NWAYC)
|
STR_RETURN(BBA_NWAYC)
|
||||||
STR_RETURN(BBA_NWAYS)
|
STR_RETURN(BBA_NWAYS)
|
||||||
STR_RETURN(BBA_GCA)
|
STR_RETURN(BBA_GCA)
|
||||||
STR_RETURN(BBA_MISC)
|
STR_RETURN(BBA_MISC)
|
||||||
STR_RETURN(BBA_TXFIFOCNT)
|
STR_RETURN(BBA_TXFIFOCNT)
|
||||||
STR_RETURN(BBA_WRTXFIFOD)
|
STR_RETURN(BBA_WRTXFIFOD)
|
||||||
STR_RETURN(BBA_MISC2)
|
STR_RETURN(BBA_MISC2)
|
||||||
STR_RETURN(BBA_SI_ACTRL)
|
STR_RETURN(BBA_SI_ACTRL)
|
||||||
STR_RETURN(BBA_SI_STATUS)
|
STR_RETURN(BBA_SI_STATUS)
|
||||||
STR_RETURN(BBA_SI_ACTRL2)
|
STR_RETURN(BBA_SI_ACTRL2)
|
||||||
default:
|
default:
|
||||||
if (transfer.address >= 0x100 &&
|
if (transfer.address >= 0x100 &&
|
||||||
transfer.address <= 0xfff)
|
transfer.address <= 0xfff)
|
||||||
|
@ -320,14 +325,14 @@ void CEXIETHERNET::MXCommandHandler(u32 data, u32 size)
|
||||||
case BBA_NCRA:
|
case BBA_NCRA:
|
||||||
if (data & NCRA_RESET)
|
if (data & NCRA_RESET)
|
||||||
{
|
{
|
||||||
WARN_LOG(SP1, "software reset");
|
DEBUG_LOG(SP1, "software reset");
|
||||||
//MXSoftReset();
|
//MXSoftReset();
|
||||||
Activate();
|
Activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mBbaMem[BBA_NCRA] & NCRA_SR) ^ (data & NCRA_SR))
|
if ((mBbaMem[BBA_NCRA] & NCRA_SR) ^ (data & NCRA_SR))
|
||||||
{
|
{
|
||||||
WARN_LOG(SP1, "%s rx", (data & NCRA_SR) ? "start" : "stop");
|
DEBUG_LOG(SP1, "%s rx", (data & NCRA_SR) ? "start" : "stop");
|
||||||
|
|
||||||
if (data & NCRA_SR)
|
if (data & NCRA_SR)
|
||||||
RecvStart();
|
RecvStart();
|
||||||
|
@ -338,7 +343,7 @@ void CEXIETHERNET::MXCommandHandler(u32 data, u32 size)
|
||||||
// Only start transfer if there isn't one currently running
|
// Only start transfer if there isn't one currently running
|
||||||
if (!(mBbaMem[BBA_NCRA] & (NCRA_ST0 | NCRA_ST1)))
|
if (!(mBbaMem[BBA_NCRA] & (NCRA_ST0 | NCRA_ST1)))
|
||||||
{
|
{
|
||||||
// TODO Might have to check TXDMA status as well?
|
// Technically transfer dma status is kept in TXDMA - not implemented
|
||||||
|
|
||||||
if (data & NCRA_ST0)
|
if (data & NCRA_ST0)
|
||||||
{
|
{
|
||||||
|
@ -347,7 +352,7 @@ void CEXIETHERNET::MXCommandHandler(u32 data, u32 size)
|
||||||
}
|
}
|
||||||
else if (data & NCRA_ST1)
|
else if (data & NCRA_ST1)
|
||||||
{
|
{
|
||||||
WARN_LOG(SP1, "start tx - direct fifo");
|
DEBUG_LOG(SP1, "start tx - direct fifo");
|
||||||
SendFromDirectFIFO();
|
SendFromDirectFIFO();
|
||||||
// Kind of a hack: send completes instantly, so we don't
|
// Kind of a hack: send completes instantly, so we don't
|
||||||
// actually write the "send in status" bit to the register
|
// actually write the "send in status" bit to the register
|
||||||
|
@ -371,12 +376,11 @@ void CEXIETHERNET::MXCommandHandler(u32 data, u32 size)
|
||||||
|
|
||||||
write_to_register:
|
write_to_register:
|
||||||
default:
|
default:
|
||||||
|
for (int i = size - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
for (int i = size - 1; i >= 0; i--)
|
mBbaMem[transfer.address++] = (data >> (i * 8)) & 0xff;
|
||||||
{
|
|
||||||
mBbaMem[transfer.address++] = (data >> (i * 8)) & 0xff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,6 +394,9 @@ void CEXIETHERNET::DirectFIFOWrite(u8 *data, u32 size)
|
||||||
memcpy(tx_fifo + *tx_fifo_count, data, size);
|
memcpy(tx_fifo + *tx_fifo_count, data, size);
|
||||||
|
|
||||||
*tx_fifo_count += size;
|
*tx_fifo_count += size;
|
||||||
|
// TODO not sure this mask is correct.
|
||||||
|
// However, BBA_TXFIFOCNT should never get even close to this amount,
|
||||||
|
// so it shouldn't matter
|
||||||
*tx_fifo_count &= (1 << 12) - 1;
|
*tx_fifo_count &= (1 << 12) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,7 +425,7 @@ void CEXIETHERNET::SendComplete()
|
||||||
mBbaMem[BBA_LTPS] = 0;
|
mBbaMem[BBA_LTPS] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 CEXIETHERNET::HashIndex(u8 *dest_eth_addr)
|
inline u8 CEXIETHERNET::HashIndex(u8 *dest_eth_addr)
|
||||||
{
|
{
|
||||||
// Calculate crc
|
// Calculate crc
|
||||||
u32 crc = 0xffffffff;
|
u32 crc = 0xffffffff;
|
||||||
|
@ -440,7 +447,7 @@ u8 CEXIETHERNET::HashIndex(u8 *dest_eth_addr)
|
||||||
return crc >> 26;
|
return crc >> 26;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CEXIETHERNET::RecvMACFilter()
|
inline bool CEXIETHERNET::RecvMACFilter()
|
||||||
{
|
{
|
||||||
static u8 const broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
static u8 const broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||||
|
|
||||||
|
@ -471,19 +478,19 @@ bool CEXIETHERNET::RecvMACFilter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PAGE_PTR(x) ((mBbaMem[x + 1] << 8) | mBbaMem[x])
|
|
||||||
|
|
||||||
void CEXIETHERNET::inc_rwp()
|
void CEXIETHERNET::inc_rwp()
|
||||||
{
|
{
|
||||||
u16 *rwp = (u16 *)&mBbaMem[BBA_RWP];
|
u16 *rwp = (u16 *)&mBbaMem[BBA_RWP];
|
||||||
|
|
||||||
if (*rwp + 1 == PAGE_PTR(BBA_RHBP))
|
if (*rwp + 1 == page_ptr(BBA_RHBP))
|
||||||
// TODO check if BP is used as well
|
// TODO check if BP is used as well
|
||||||
*rwp = PAGE_PTR(BBA_BP);
|
*rwp = page_ptr(BBA_BP);
|
||||||
else
|
else
|
||||||
(*rwp)++;
|
(*rwp)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function is on the critical path for recving data.
|
||||||
|
// Be very careful about calling into the logger and other slow things
|
||||||
bool CEXIETHERNET::RecvHandlePacket()
|
bool CEXIETHERNET::RecvHandlePacket()
|
||||||
{
|
{
|
||||||
u8 *write_ptr;
|
u8 *write_ptr;
|
||||||
|
@ -494,23 +501,22 @@ bool CEXIETHERNET::RecvHandlePacket()
|
||||||
if (!RecvMACFilter())
|
if (!RecvMACFilter())
|
||||||
goto wait_for_next;
|
goto wait_for_next;
|
||||||
|
|
||||||
|
#ifdef BBA_TACK_PAGE_PTRS
|
||||||
WARN_LOG(SP1, "RecvHandlePacket %x\n%s", mRecvBufferLength,
|
WARN_LOG(SP1, "RecvHandlePacket %x\n%s", mRecvBufferLength,
|
||||||
ArrayToString(mRecvBuffer, mRecvBufferLength, 0x100).c_str());
|
ArrayToString(mRecvBuffer, mRecvBufferLength, 0x100).c_str());
|
||||||
|
|
||||||
#define PTR_FROM_PAGE_PTR(x) &mBbaMem[PAGE_PTR(x) << 8]
|
WARN_LOG(SP1, "%x %x %x %x",
|
||||||
|
page_ptr(BBA_BP),
|
||||||
|
page_ptr(BBA_RRP),
|
||||||
|
page_ptr(BBA_RWP),
|
||||||
|
page_ptr(BBA_RHBP));
|
||||||
|
#endif
|
||||||
|
|
||||||
ERROR_LOG(SP1, "%x %x %x %x",
|
write_ptr = ptr_from_page_ptr(BBA_RWP);
|
||||||
PAGE_PTR(BBA_BP),
|
end_ptr = ptr_from_page_ptr(BBA_RHBP);
|
||||||
PAGE_PTR(BBA_RRP),
|
read_ptr = ptr_from_page_ptr(BBA_RRP);
|
||||||
PAGE_PTR(BBA_RWP),
|
|
||||||
PAGE_PTR(BBA_RHBP));
|
|
||||||
|
|
||||||
write_ptr = PTR_FROM_PAGE_PTR(BBA_RWP);
|
|
||||||
end_ptr = PTR_FROM_PAGE_PTR(BBA_RHBP);
|
|
||||||
read_ptr = PTR_FROM_PAGE_PTR(BBA_RRP);
|
|
||||||
|
|
||||||
descriptor = (Descriptor *)write_ptr;
|
descriptor = (Descriptor *)write_ptr;
|
||||||
//u8 *descriptor = write_ptr;
|
|
||||||
write_ptr += 4;
|
write_ptr += 4;
|
||||||
|
|
||||||
for (u32 i = 0, off = 4; i < mRecvBufferLength; ++i, ++off)
|
for (u32 i = 0, off = 4; i < mRecvBufferLength; ++i, ++off)
|
||||||
|
@ -525,7 +531,7 @@ bool CEXIETHERNET::RecvHandlePacket()
|
||||||
|
|
||||||
if (write_ptr == end_ptr)
|
if (write_ptr == end_ptr)
|
||||||
// TODO check if BP is used as well
|
// TODO check if BP is used as well
|
||||||
write_ptr = PTR_FROM_PAGE_PTR(BBA_BP);
|
write_ptr = ptr_from_page_ptr(BBA_BP);
|
||||||
|
|
||||||
if (write_ptr == read_ptr)
|
if (write_ptr == read_ptr)
|
||||||
{
|
{
|
||||||
|
@ -537,11 +543,13 @@ bool CEXIETHERNET::RecvHandlePacket()
|
||||||
if ((mRecvBufferLength + 4) % 256)
|
if ((mRecvBufferLength + 4) % 256)
|
||||||
inc_rwp();
|
inc_rwp();
|
||||||
|
|
||||||
ERROR_LOG(SP1, "%x %x %x %x",
|
#ifdef BBA_TACK_PAGE_PTRS
|
||||||
PAGE_PTR(BBA_BP),
|
WARN_LOG(SP1, "%x %x %x %x",
|
||||||
PAGE_PTR(BBA_RRP),
|
page_ptr(BBA_BP),
|
||||||
PAGE_PTR(BBA_RWP),
|
page_ptr(BBA_RRP),
|
||||||
PAGE_PTR(BBA_RHBP));
|
page_ptr(BBA_RWP),
|
||||||
|
page_ptr(BBA_RHBP));
|
||||||
|
#endif
|
||||||
|
|
||||||
// Update descriptor
|
// Update descriptor
|
||||||
descriptor->set(*(u16 *)&mBbaMem[BBA_RWP], 4 + mRecvBufferLength, 0);
|
descriptor->set(*(u16 *)&mBbaMem[BBA_RWP], 4 + mRecvBufferLength, 0);
|
||||||
|
@ -557,15 +565,13 @@ bool CEXIETHERNET::RecvHandlePacket()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERROR_LOG(SP1, "NOT raising recv interrupt");
|
// This occurs if software is still processing the last raised recv interrupt
|
||||||
|
WARN_LOG(SP1, "NOT raising recv interrupt");
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_for_next:
|
wait_for_next:
|
||||||
if (mBbaMem[BBA_NCRA] & NCRA_SR)
|
if (mBbaMem[BBA_NCRA] & NCRA_SR)
|
||||||
RecvStart();
|
RecvStart();
|
||||||
|
|
||||||
#undef PTR_FROM_PAGE_PTR
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#pragma optimize("",on)
|
|
||||||
|
|
|
@ -275,6 +275,16 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline u16 page_ptr(int const index) const
|
||||||
|
{
|
||||||
|
return ((u16)mBbaMem[index + 1] << 8) | mBbaMem[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline u8 *ptr_from_page_ptr(int const index) const
|
||||||
|
{
|
||||||
|
return &mBbaMem[page_ptr(index) << 8];
|
||||||
|
}
|
||||||
|
|
||||||
bool IsMXCommand(u32 const data);
|
bool IsMXCommand(u32 const data);
|
||||||
bool IsWriteCommand(u32 const data);
|
bool IsWriteCommand(u32 const data);
|
||||||
char const * const GetRegisterName() const;
|
char const * const GetRegisterName() const;
|
||||||
|
@ -302,6 +312,7 @@ public:
|
||||||
void RecvStop();
|
void RecvStop();
|
||||||
|
|
||||||
u8 *mRecvBuffer;
|
u8 *mRecvBuffer;
|
||||||
|
u32 mRecvBufferLength;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
HANDLE mHAdapter, mHRecvEvent, mHReadWait;
|
HANDLE mHAdapter, mHRecvEvent, mHReadWait;
|
||||||
|
@ -314,7 +325,6 @@ public:
|
||||||
volatile bool readEnabled;
|
volatile bool readEnabled;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u32 mRecvBufferLength;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue