convert Wifi and WifiAP
This commit is contained in:
parent
76976fef30
commit
2bd09eafeb
|
@ -1212,7 +1212,7 @@ int ClassifyAddress7(u32 addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WifiWrite32(u32 addr, u32 val)
|
/*void WifiWrite32(u32 addr, u32 val)
|
||||||
{
|
{
|
||||||
Wifi::Write(addr, val & 0xFFFF);
|
Wifi::Write(addr, val & 0xFFFF);
|
||||||
Wifi::Write(addr + 2, val >> 16);
|
Wifi::Write(addr + 2, val >> 16);
|
||||||
|
@ -1221,7 +1221,7 @@ void WifiWrite32(u32 addr, u32 val)
|
||||||
u32 WifiRead32(u32 addr)
|
u32 WifiRead32(u32 addr)
|
||||||
{
|
{
|
||||||
return (u32)Wifi::Read(addr) | ((u32)Wifi::Read(addr + 2) << 16);
|
return (u32)Wifi::Read(addr) | ((u32)Wifi::Read(addr + 2) << 16);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void VRAMWrite(u32 addr, T val)
|
void VRAMWrite(u32 addr, T val)
|
||||||
|
@ -1358,7 +1358,8 @@ void* GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x04800000:
|
// TODO: the wifi funcs also ought to check POWCNT
|
||||||
|
/*case 0x04800000:
|
||||||
if (addr < 0x04810000 && size >= 16)
|
if (addr < 0x04810000 && size >= 16)
|
||||||
{
|
{
|
||||||
switch (size | store)
|
switch (size | store)
|
||||||
|
@ -1369,7 +1370,7 @@ void* GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size)
|
||||||
case 33: return (void*)WifiWrite32;
|
case 33: return (void*)WifiWrite32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;*/
|
||||||
case 0x06000000:
|
case 0x06000000:
|
||||||
case 0x06800000:
|
case 0x06800000:
|
||||||
switch (size | store)
|
switch (size | store)
|
||||||
|
|
29
src/NDS.cpp
29
src/NDS.cpp
|
@ -181,6 +181,7 @@ u16 RCnt;
|
||||||
class SPU* SPU;
|
class SPU* SPU;
|
||||||
class SPIHost* SPI;
|
class SPIHost* SPI;
|
||||||
class RTC* RTC;
|
class RTC* RTC;
|
||||||
|
class Wifi* Wifi;
|
||||||
|
|
||||||
bool Running;
|
bool Running;
|
||||||
|
|
||||||
|
@ -222,11 +223,11 @@ bool Init()
|
||||||
SPU = new class SPU;
|
SPU = new class SPU;
|
||||||
SPI = new class SPIHost();
|
SPI = new class SPIHost();
|
||||||
RTC = new class RTC();
|
RTC = new class RTC();
|
||||||
|
Wifi = new class Wifi();
|
||||||
|
|
||||||
if (!NDSCart::Init()) return false;
|
if (!NDSCart::Init()) return false;
|
||||||
if (!GBACart::Init()) return false;
|
if (!GBACart::Init()) return false;
|
||||||
if (!GPU::Init()) return false;
|
if (!GPU::Init()) return false;
|
||||||
if (!Wifi::Init()) return false;
|
|
||||||
|
|
||||||
if (!DSi::Init()) return false;
|
if (!DSi::Init()) return false;
|
||||||
|
|
||||||
|
@ -253,11 +254,11 @@ void DeInit()
|
||||||
delete SPU; SPU = nullptr;
|
delete SPU; SPU = nullptr;
|
||||||
delete SPI; SPI = nullptr;
|
delete SPI; SPI = nullptr;
|
||||||
delete RTC; RTC = nullptr;
|
delete RTC; RTC = nullptr;
|
||||||
|
delete Wifi; Wifi = nullptr;
|
||||||
|
|
||||||
NDSCart::DeInit();
|
NDSCart::DeInit();
|
||||||
GBACart::DeInit();
|
GBACart::DeInit();
|
||||||
GPU::DeInit();
|
GPU::DeInit();
|
||||||
Wifi::DeInit();
|
|
||||||
|
|
||||||
DSi::DeInit();
|
DSi::DeInit();
|
||||||
|
|
||||||
|
@ -646,7 +647,7 @@ void Reset()
|
||||||
SPU->Reset();
|
SPU->Reset();
|
||||||
SPI->Reset();
|
SPI->Reset();
|
||||||
RTC->Reset();
|
RTC->Reset();
|
||||||
Wifi::Reset();
|
Wifi->Reset();
|
||||||
|
|
||||||
// TODO: move the SOUNDBIAS/degrade logic to SPU?
|
// TODO: move the SOUNDBIAS/degrade logic to SPU?
|
||||||
|
|
||||||
|
@ -848,7 +849,7 @@ bool DoSavestate(Savestate* file)
|
||||||
SPU->DoSavestate(file);
|
SPU->DoSavestate(file);
|
||||||
SPI->DoSavestate(file);
|
SPI->DoSavestate(file);
|
||||||
RTC->DoSavestate(file);
|
RTC->DoSavestate(file);
|
||||||
Wifi::DoSavestate(file);
|
Wifi->DoSavestate(file);
|
||||||
|
|
||||||
if (ConsoleType == 1)
|
if (ConsoleType == 1)
|
||||||
DSi::DoSavestate(file);
|
DSi::DoSavestate(file);
|
||||||
|
@ -858,7 +859,7 @@ bool DoSavestate(Savestate* file)
|
||||||
GPU::SetPowerCnt(PowerControl9);
|
GPU::SetPowerCnt(PowerControl9);
|
||||||
|
|
||||||
SPU->SetPowerCnt(PowerControl7 & 0x0001);
|
SPU->SetPowerCnt(PowerControl7 & 0x0001);
|
||||||
Wifi::SetPowerCnt(PowerControl7 & 0x0002);
|
Wifi->SetPowerCnt(PowerControl7 & 0x0002);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JIT_ENABLED
|
#ifdef JIT_ENABLED
|
||||||
|
@ -2542,8 +2543,8 @@ u8 ARM7Read8(u32 addr)
|
||||||
if (addr < 0x04810000)
|
if (addr < 0x04810000)
|
||||||
{
|
{
|
||||||
if (!(PowerControl7 & (1<<1))) return 0;
|
if (!(PowerControl7 & (1<<1))) return 0;
|
||||||
if (addr & 0x1) return Wifi::Read(addr-1) >> 8;
|
if (addr & 0x1) return Wifi->Read(addr-1) >> 8;
|
||||||
return Wifi::Read(addr) & 0xFF;
|
return Wifi->Read(addr) & 0xFF;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2609,7 +2610,7 @@ u16 ARM7Read16(u32 addr)
|
||||||
if (addr < 0x04810000)
|
if (addr < 0x04810000)
|
||||||
{
|
{
|
||||||
if (!(PowerControl7 & (1<<1))) return 0;
|
if (!(PowerControl7 & (1<<1))) return 0;
|
||||||
return Wifi::Read(addr);
|
return Wifi->Read(addr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2675,7 +2676,7 @@ u32 ARM7Read32(u32 addr)
|
||||||
if (addr < 0x04810000)
|
if (addr < 0x04810000)
|
||||||
{
|
{
|
||||||
if (!(PowerControl7 & (1<<1))) return 0;
|
if (!(PowerControl7 & (1<<1))) return 0;
|
||||||
return Wifi::Read(addr) | (Wifi::Read(addr+2) << 16);
|
return Wifi->Read(addr) | (Wifi->Read(addr+2) << 16);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2818,7 +2819,7 @@ void ARM7Write16(u32 addr, u16 val)
|
||||||
if (addr < 0x04810000)
|
if (addr < 0x04810000)
|
||||||
{
|
{
|
||||||
if (!(PowerControl7 & (1<<1))) return;
|
if (!(PowerControl7 & (1<<1))) return;
|
||||||
Wifi::Write(addr, val);
|
Wifi->Write(addr, val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2898,8 +2899,8 @@ void ARM7Write32(u32 addr, u32 val)
|
||||||
if (addr < 0x04810000)
|
if (addr < 0x04810000)
|
||||||
{
|
{
|
||||||
if (!(PowerControl7 & (1<<1))) return;
|
if (!(PowerControl7 & (1<<1))) return;
|
||||||
Wifi::Write(addr, val & 0xFFFF);
|
Wifi->Write(addr, val & 0xFFFF);
|
||||||
Wifi::Write(addr+2, val >> 16);
|
Wifi->Write(addr+2, val >> 16);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -4332,7 +4333,7 @@ void ARM7IOWrite16(u32 addr, u16 val)
|
||||||
u16 change = PowerControl7 ^ val;
|
u16 change = PowerControl7 ^ val;
|
||||||
PowerControl7 = val & 0x0003;
|
PowerControl7 = val & 0x0003;
|
||||||
SPU->SetPowerCnt(val & 0x0001);
|
SPU->SetPowerCnt(val & 0x0001);
|
||||||
Wifi::SetPowerCnt(val & 0x0002);
|
Wifi->SetPowerCnt(val & 0x0002);
|
||||||
if (change & 0x0002) UpdateWifiTimings();
|
if (change & 0x0002) UpdateWifiTimings();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -4462,7 +4463,7 @@ void ARM7IOWrite32(u32 addr, u32 val)
|
||||||
u16 change = PowerControl7 ^ val;
|
u16 change = PowerControl7 ^ val;
|
||||||
PowerControl7 = val & 0x0003;
|
PowerControl7 = val & 0x0003;
|
||||||
SPU->SetPowerCnt(val & 0x0001);
|
SPU->SetPowerCnt(val & 0x0001);
|
||||||
Wifi::SetPowerCnt(val & 0x0002);
|
Wifi->SetPowerCnt(val & 0x0002);
|
||||||
if (change & 0x0002) UpdateWifiTimings();
|
if (change & 0x0002) UpdateWifiTimings();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
class SPU;
|
class SPU;
|
||||||
class SPIHost;
|
class SPIHost;
|
||||||
class RTC;
|
class RTC;
|
||||||
|
class Wifi;
|
||||||
|
|
||||||
namespace NDS
|
namespace NDS
|
||||||
{
|
{
|
||||||
|
@ -253,6 +254,7 @@ extern u16 RCnt;
|
||||||
extern class SPU* SPU;
|
extern class SPU* SPU;
|
||||||
extern class SPIHost* SPI;
|
extern class SPIHost* SPI;
|
||||||
extern class RTC* RTC;
|
extern class RTC* RTC;
|
||||||
|
extern class Wifi* Wifi;
|
||||||
|
|
||||||
const u32 ARM7WRAMSize = 0x10000;
|
const u32 ARM7WRAMSize = 0x10000;
|
||||||
extern u8* ARM7WRAM;
|
extern u8* ARM7WRAM;
|
||||||
|
|
197
src/Wifi.cpp
197
src/Wifi.cpp
|
@ -27,91 +27,19 @@
|
||||||
using Platform::Log;
|
using Platform::Log;
|
||||||
using Platform::LogLevel;
|
using Platform::LogLevel;
|
||||||
|
|
||||||
namespace Wifi
|
|
||||||
{
|
|
||||||
|
|
||||||
//#define WIFI_LOG printf
|
//#define WIFI_LOG printf
|
||||||
#define WIFI_LOG(...) {}
|
#define WIFI_LOG(...) {}
|
||||||
|
|
||||||
#define PRINT_MAC(pf, mac) Log(LogLevel::Debug, "%s: %02X:%02X:%02X:%02X:%02X:%02X\n", pf, (mac)[0], (mac)[1], (mac)[2], (mac)[3], (mac)[4], (mac)[5]);
|
#define PRINT_MAC(pf, mac) Log(LogLevel::Debug, "%s: %02X:%02X:%02X:%02X:%02X:%02X\n", pf, (mac)[0], (mac)[1], (mac)[2], (mac)[3], (mac)[4], (mac)[5]);
|
||||||
|
|
||||||
u8 RAM[0x2000];
|
|
||||||
u16 IO[0x1000>>1];
|
|
||||||
|
|
||||||
#define IOPORT(x) IO[(x)>>1]
|
#define IOPORT(x) IO[(x)>>1]
|
||||||
#define IOPORT8(x) ((u8*)IO)[x]
|
#define IOPORT8(x) ((u8*)IO)[x]
|
||||||
|
|
||||||
// destination MACs for MP frames
|
// destination MACs for MP frames
|
||||||
const u8 MPCmdMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x00};
|
const u8 Wifi::MPCmdMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x00};
|
||||||
const u8 MPReplyMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x10};
|
const u8 Wifi::MPReplyMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x10};
|
||||||
const u8 MPAckMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x03};
|
const u8 Wifi::MPAckMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x03};
|
||||||
|
|
||||||
const int kTimerInterval = 8;
|
|
||||||
const u32 kTimeCheckMask = ~(kTimerInterval - 1);
|
|
||||||
|
|
||||||
bool Enabled;
|
|
||||||
bool PowerOn;
|
|
||||||
|
|
||||||
s32 TimerError;
|
|
||||||
|
|
||||||
u16 Random;
|
|
||||||
|
|
||||||
// general, always-on microsecond counter
|
|
||||||
u64 USTimestamp;
|
|
||||||
|
|
||||||
u64 USCounter;
|
|
||||||
u64 USCompare;
|
|
||||||
bool BlockBeaconIRQ14;
|
|
||||||
|
|
||||||
u32 CmdCounter;
|
|
||||||
|
|
||||||
u8 BBRegs[0x100];
|
|
||||||
u8 BBRegsRO[0x100];
|
|
||||||
|
|
||||||
u8 RFVersion;
|
|
||||||
u32 RFRegs[0x40];
|
|
||||||
|
|
||||||
struct TXSlot
|
|
||||||
{
|
|
||||||
bool Valid;
|
|
||||||
u16 Addr;
|
|
||||||
u16 Length;
|
|
||||||
u8 Rate;
|
|
||||||
u8 CurPhase;
|
|
||||||
int CurPhaseTime;
|
|
||||||
u32 HalfwordTimeMask;
|
|
||||||
};
|
|
||||||
|
|
||||||
TXSlot TXSlots[6];
|
|
||||||
u8 TXBuffer[0x2000];
|
|
||||||
|
|
||||||
u8 RXBuffer[2048];
|
|
||||||
u32 RXBufferPtr;
|
|
||||||
int RXTime;
|
|
||||||
u32 RXHalfwordTimeMask;
|
|
||||||
|
|
||||||
u32 ComStatus; // 0=waiting for packets 1=receiving 2=sending
|
|
||||||
u32 TXCurSlot;
|
|
||||||
u32 RXCounter;
|
|
||||||
|
|
||||||
int MPReplyTimer;
|
|
||||||
u16 MPClientMask, MPClientFail;
|
|
||||||
|
|
||||||
u8 MPClientReplies[15*1024];
|
|
||||||
|
|
||||||
u16 MPLastSeqno;
|
|
||||||
|
|
||||||
bool MPInited;
|
|
||||||
bool LANInited;
|
|
||||||
|
|
||||||
int USUntilPowerOn;
|
|
||||||
bool ForcePowerOn;
|
|
||||||
|
|
||||||
// MULTIPLAYER SYNC APPARATUS
|
|
||||||
bool IsMP;
|
|
||||||
bool IsMPClient;
|
|
||||||
u64 NextSync; // for clients: timestamp for next sync point
|
|
||||||
u64 RXTimestamp;
|
|
||||||
|
|
||||||
// multiplayer host TX sequence:
|
// multiplayer host TX sequence:
|
||||||
// 1. preamble
|
// 1. preamble
|
||||||
|
@ -148,9 +76,20 @@ u64 RXTimestamp;
|
||||||
// * TX errors (if applicable)
|
// * TX errors (if applicable)
|
||||||
|
|
||||||
|
|
||||||
bool Init()
|
bool MACEqual(u8* a, const u8* b)
|
||||||
{
|
{
|
||||||
NDS::RegisterEventFunc(NDS::Event_Wifi, 0, USTimer);
|
return (*(u32*)&a[0] == *(u32*)&b[0]) && (*(u16*)&a[4] == *(u16*)&b[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MACIsBroadcast(u8* a)
|
||||||
|
{
|
||||||
|
return (*(u32*)&a[0] == 0xFFFFFFFF) && (*(u16*)&a[4] == 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Wifi::Wifi()
|
||||||
|
{
|
||||||
|
NDS::RegisterEventFunc(NDS::Event_Wifi, 0, MemberEventFunc(Wifi, USTimer));
|
||||||
|
|
||||||
//MPInited = false;
|
//MPInited = false;
|
||||||
//LANInited = false;
|
//LANInited = false;
|
||||||
|
@ -161,24 +100,22 @@ bool Init()
|
||||||
Platform::LAN_Init();
|
Platform::LAN_Init();
|
||||||
LANInited = true;
|
LANInited = true;
|
||||||
|
|
||||||
WifiAP::Init();
|
WifiAP = new class WifiAP(this);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeInit()
|
Wifi::~Wifi()
|
||||||
{
|
{
|
||||||
if (MPInited)
|
if (MPInited)
|
||||||
Platform::MP_DeInit();
|
Platform::MP_DeInit();
|
||||||
if (LANInited)
|
if (LANInited)
|
||||||
Platform::LAN_DeInit();
|
Platform::LAN_DeInit();
|
||||||
|
|
||||||
WifiAP::DeInit();
|
delete WifiAP; WifiAP = nullptr;
|
||||||
|
|
||||||
NDS::UnregisterEventFunc(NDS::Event_Wifi, 0);
|
NDS::UnregisterEventFunc(NDS::Event_Wifi, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset()
|
void Wifi::Reset()
|
||||||
{
|
{
|
||||||
memset(RAM, 0, 0x2000);
|
memset(RAM, 0, 0x2000);
|
||||||
memset(IO, 0, 0x1000);
|
memset(IO, 0, 0x1000);
|
||||||
|
@ -277,10 +214,10 @@ void Reset()
|
||||||
NextSync = 0;
|
NextSync = 0;
|
||||||
RXTimestamp = 0;
|
RXTimestamp = 0;
|
||||||
|
|
||||||
WifiAP::Reset();
|
WifiAP->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoSavestate(Savestate* file)
|
void Wifi::DoSavestate(Savestate* file)
|
||||||
{
|
{
|
||||||
file->Section("WIFI");
|
file->Section("WIFI");
|
||||||
|
|
||||||
|
@ -355,7 +292,7 @@ void DoSavestate(Savestate* file)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ScheduleTimer(bool first)
|
void Wifi::ScheduleTimer(bool first)
|
||||||
{
|
{
|
||||||
if (first) TimerError = 0;
|
if (first) TimerError = 0;
|
||||||
|
|
||||||
|
@ -367,7 +304,7 @@ void ScheduleTimer(bool first)
|
||||||
NDS::ScheduleEvent(NDS::Event_Wifi, !first, delay, 0, 0);
|
NDS::ScheduleEvent(NDS::Event_Wifi, !first, delay, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdatePowerOn()
|
void Wifi::UpdatePowerOn()
|
||||||
{
|
{
|
||||||
bool on = Enabled;
|
bool on = Enabled;
|
||||||
|
|
||||||
|
@ -405,17 +342,14 @@ void UpdatePowerOn()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPowerCnt(u32 val)
|
void Wifi::SetPowerCnt(u32 val)
|
||||||
{
|
{
|
||||||
Enabled = val & (1<<1);
|
Enabled = val & (1<<1);
|
||||||
UpdatePowerOn();
|
UpdatePowerOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PowerDown();
|
void Wifi::SetIRQ(u32 irq)
|
||||||
void StartTX_Beacon();
|
|
||||||
|
|
||||||
void SetIRQ(u32 irq)
|
|
||||||
{
|
{
|
||||||
u32 oldflags = IOPORT(W_IF) & IOPORT(W_IE);
|
u32 oldflags = IOPORT(W_IF) & IOPORT(W_IE);
|
||||||
|
|
||||||
|
@ -426,7 +360,7 @@ void SetIRQ(u32 irq)
|
||||||
NDS::SetIRQ(1, NDS::IRQ_Wifi);
|
NDS::SetIRQ(1, NDS::IRQ_Wifi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIRQ13()
|
void Wifi::SetIRQ13()
|
||||||
{
|
{
|
||||||
SetIRQ(13);
|
SetIRQ(13);
|
||||||
|
|
||||||
|
@ -440,7 +374,7 @@ void SetIRQ13()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIRQ14(int source) // 0=USCOMPARE 1=BEACONCOUNT 2=forced
|
void Wifi::SetIRQ14(int source) // 0=USCOMPARE 1=BEACONCOUNT 2=forced
|
||||||
{
|
{
|
||||||
if (source != 2)
|
if (source != 2)
|
||||||
IOPORT(W_BeaconCount1) = IOPORT(W_BeaconInterval);
|
IOPORT(W_BeaconCount1) = IOPORT(W_BeaconInterval);
|
||||||
|
@ -469,7 +403,7 @@ void SetIRQ14(int source) // 0=USCOMPARE 1=BEACONCOUNT 2=forced
|
||||||
IOPORT(W_ListenCount)--;
|
IOPORT(W_ListenCount)--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIRQ15()
|
void Wifi::SetIRQ15()
|
||||||
{
|
{
|
||||||
SetIRQ(15);
|
SetIRQ(15);
|
||||||
|
|
||||||
|
@ -481,7 +415,7 @@ void SetIRQ15()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SetStatus(u32 status)
|
void Wifi::SetStatus(u32 status)
|
||||||
{
|
{
|
||||||
// TODO, eventually: states 2/4/7
|
// TODO, eventually: states 2/4/7
|
||||||
u16 rfpins[10] = {0x04, 0x84, 0, 0x46, 0, 0x84, 0x87, 0, 0x46, 0x04};
|
u16 rfpins[10] = {0x04, 0x84, 0, 0x46, 0, 0x84, 0x87, 0, 0x46, 0x04};
|
||||||
|
@ -490,7 +424,7 @@ void SetStatus(u32 status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PowerDown()
|
void Wifi::PowerDown()
|
||||||
{
|
{
|
||||||
IOPORT(W_TXReqRead) &= ~0x000F;
|
IOPORT(W_TXReqRead) &= ~0x000F;
|
||||||
IOPORT(W_PowerState) |= 0x0200;
|
IOPORT(W_PowerState) |= 0x0200;
|
||||||
|
@ -504,20 +438,14 @@ void PowerDown()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool MACEqual(const u8* a, const u8* b)
|
int Wifi::PreambleLen(int rate)
|
||||||
{
|
|
||||||
return (*(u32*)&a[0] == *(u32*)&b[0]) && (*(u16*)&a[4] == *(u16*)&b[4]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int PreambleLen(int rate)
|
|
||||||
{
|
{
|
||||||
if (rate == 1) return 192;
|
if (rate == 1) return 192;
|
||||||
if (IOPORT(W_Preamble) & 0x0004) return 96;
|
if (IOPORT(W_Preamble) & 0x0004) return 96;
|
||||||
return 192;
|
return 192;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 NumClients(u16 bitmask)
|
u32 Wifi::NumClients(u16 bitmask)
|
||||||
{
|
{
|
||||||
u32 ret = 0;
|
u32 ret = 0;
|
||||||
for (int i = 1; i < 16; i++)
|
for (int i = 1; i < 16; i++)
|
||||||
|
@ -527,14 +455,14 @@ u32 NumClients(u16 bitmask)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IncrementTXCount(TXSlot* slot)
|
void Wifi::IncrementTXCount(TXSlot* slot)
|
||||||
{
|
{
|
||||||
u8 cnt = RAM[slot->Addr + 0x4];
|
u8 cnt = RAM[slot->Addr + 0x4];
|
||||||
if (cnt < 0xFF) cnt++;
|
if (cnt < 0xFF) cnt++;
|
||||||
*(u16*)&RAM[slot->Addr + 0x4] = cnt;
|
*(u16*)&RAM[slot->Addr + 0x4] = cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReportMPReplyErrors(u16 clientfail)
|
void Wifi::ReportMPReplyErrors(u16 clientfail)
|
||||||
{
|
{
|
||||||
// TODO: do these trigger any IRQ?
|
// TODO: do these trigger any IRQ?
|
||||||
|
|
||||||
|
@ -547,7 +475,7 @@ void ReportMPReplyErrors(u16 clientfail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TXSendFrame(TXSlot* slot, int num)
|
void Wifi::TXSendFrame(TXSlot* slot, int num)
|
||||||
{
|
{
|
||||||
u32 noseqno = 0;
|
u32 noseqno = 0;
|
||||||
|
|
||||||
|
@ -597,7 +525,7 @@ void TXSendFrame(TXSlot* slot, int num)
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
Platform::MP_SendPacket(TXBuffer, 12+len, USTimestamp);
|
Platform::MP_SendPacket(TXBuffer, 12+len, USTimestamp);
|
||||||
if (!IsMP) WifiAP::SendPacket(TXBuffer, 12+len);
|
if (!IsMP) WifiAP->SendPacket(TXBuffer, 12+len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -617,7 +545,7 @@ void TXSendFrame(TXSlot* slot, int num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartTX_LocN(int nslot, int loc)
|
void Wifi::StartTX_LocN(int nslot, int loc)
|
||||||
{
|
{
|
||||||
TXSlot* slot = &TXSlots[nslot];
|
TXSlot* slot = &TXSlots[nslot];
|
||||||
|
|
||||||
|
@ -637,7 +565,7 @@ void StartTX_LocN(int nslot, int loc)
|
||||||
slot->CurPhaseTime = PreambleLen(slot->Rate);
|
slot->CurPhaseTime = PreambleLen(slot->Rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartTX_Cmd()
|
void Wifi::StartTX_Cmd()
|
||||||
{
|
{
|
||||||
TXSlot* slot = &TXSlots[1];
|
TXSlot* slot = &TXSlots[1];
|
||||||
|
|
||||||
|
@ -672,7 +600,7 @@ void StartTX_Cmd()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartTX_Beacon()
|
void Wifi::StartTX_Beacon()
|
||||||
{
|
{
|
||||||
TXSlot* slot = &TXSlots[4];
|
TXSlot* slot = &TXSlots[4];
|
||||||
|
|
||||||
|
@ -691,7 +619,7 @@ void StartTX_Beacon()
|
||||||
IOPORT(W_TXBusy) |= 0x0010;
|
IOPORT(W_TXBusy) |= 0x0010;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FireTX()
|
void Wifi::FireTX()
|
||||||
{
|
{
|
||||||
if (!(IOPORT(W_RXCnt) & 0x8000))
|
if (!(IOPORT(W_RXCnt) & 0x8000))
|
||||||
return;
|
return;
|
||||||
|
@ -736,7 +664,7 @@ void FireTX()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendMPDefaultReply()
|
void Wifi::SendMPDefaultReply()
|
||||||
{
|
{
|
||||||
u8 reply[12 + 28];
|
u8 reply[12 + 28];
|
||||||
|
|
||||||
|
@ -766,7 +694,7 @@ void SendMPDefaultReply()
|
||||||
WIFI_LOG("wifi: sent %d/40 bytes of MP default reply\n", txlen);
|
WIFI_LOG("wifi: sent %d/40 bytes of MP default reply\n", txlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendMPReply(u16 clienttime, u16 clientmask)
|
void Wifi::SendMPReply(u16 clienttime, u16 clientmask)
|
||||||
{
|
{
|
||||||
TXSlot* slot = &TXSlots[5];
|
TXSlot* slot = &TXSlots[5];
|
||||||
|
|
||||||
|
@ -827,7 +755,7 @@ void SendMPReply(u16 clienttime, u16 clientmask)
|
||||||
IOPORT(W_TXBusy) |= 0x0080;
|
IOPORT(W_TXBusy) |= 0x0080;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendMPAck(u16 cmdcount, u16 clientfail)
|
void Wifi::SendMPAck(u16 cmdcount, u16 clientfail)
|
||||||
{
|
{
|
||||||
u8 ack[12 + 32];
|
u8 ack[12 + 32];
|
||||||
|
|
||||||
|
@ -873,10 +801,7 @@ void SendMPAck(u16 cmdcount, u16 clientfail)
|
||||||
WIFI_LOG("wifi: sent %d/44 bytes of MP ack, %d %d\n", txlen, ComStatus, RXTime);
|
WIFI_LOG("wifi: sent %d/44 bytes of MP ack, %d %d\n", txlen, ComStatus, RXTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckRX(int type);
|
bool Wifi::ProcessTX(TXSlot* slot, int num)
|
||||||
void MPClientReplyRX(int client);
|
|
||||||
|
|
||||||
bool ProcessTX(TXSlot* slot, int num)
|
|
||||||
{
|
{
|
||||||
slot->CurPhaseTime -= kTimerInterval;
|
slot->CurPhaseTime -= kTimerInterval;
|
||||||
if (slot->CurPhaseTime > 0)
|
if (slot->CurPhaseTime > 0)
|
||||||
|
@ -1137,7 +1062,7 @@ bool ProcessTX(TXSlot* slot, int num)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void IncrementRXAddr(u16& addr, u16 inc = 2)
|
inline void Wifi::IncrementRXAddr(u16& addr, u16 inc)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < inc; i += 2)
|
for (u32 i = 0; i < inc; i += 2)
|
||||||
{
|
{
|
||||||
|
@ -1148,7 +1073,7 @@ inline void IncrementRXAddr(u16& addr, u16 inc = 2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartRX()
|
void Wifi::StartRX()
|
||||||
{
|
{
|
||||||
u16 framelen = *(u16*)&RXBuffer[8];
|
u16 framelen = *(u16*)&RXBuffer[8];
|
||||||
RXTime = framelen;
|
RXTime = framelen;
|
||||||
|
@ -1176,7 +1101,7 @@ void StartRX()
|
||||||
ComStatus |= 1;
|
ComStatus |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FinishRX()
|
void Wifi::FinishRX()
|
||||||
{
|
{
|
||||||
ComStatus &= ~0x1;
|
ComStatus &= ~0x1;
|
||||||
RXCounter = 0;
|
RXCounter = 0;
|
||||||
|
@ -1451,7 +1376,7 @@ void FinishRX()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MPClientReplyRX(int client)
|
void Wifi::MPClientReplyRX(int client)
|
||||||
{
|
{
|
||||||
if (IOPORT(W_PowerState) & 0x0300)
|
if (IOPORT(W_PowerState) & 0x0300)
|
||||||
return;
|
return;
|
||||||
|
@ -1492,7 +1417,7 @@ void MPClientReplyRX(int client)
|
||||||
StartRX();
|
StartRX();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
bool Wifi::CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
||||||
{
|
{
|
||||||
if (IOPORT(W_PowerState) & 0x0300)
|
if (IOPORT(W_PowerState) & 0x0300)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1517,7 +1442,7 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
||||||
{
|
{
|
||||||
rxlen = Platform::MP_RecvPacket(RXBuffer, ×tamp);
|
rxlen = Platform::MP_RecvPacket(RXBuffer, ×tamp);
|
||||||
if ((rxlen <= 0) && (!IsMP))
|
if ((rxlen <= 0) && (!IsMP))
|
||||||
rxlen = WifiAP::RecvPacket(RXBuffer);
|
rxlen = WifiAP->RecvPacket(RXBuffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1632,7 +1557,7 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MSTimer()
|
void Wifi::MSTimer()
|
||||||
{
|
{
|
||||||
if (IOPORT(W_USCompareCnt))
|
if (IOPORT(W_USCompareCnt))
|
||||||
{
|
{
|
||||||
|
@ -1656,7 +1581,7 @@ void MSTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void USTimer(u32 param)
|
void Wifi::USTimer(u32 param)
|
||||||
{
|
{
|
||||||
USTimestamp += kTimerInterval;
|
USTimestamp += kTimerInterval;
|
||||||
|
|
||||||
|
@ -1676,7 +1601,7 @@ void USTimer(u32 param)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(USTimestamp & 0x3FF & kTimeCheckMask))
|
if (!(USTimestamp & 0x3FF & kTimeCheckMask))
|
||||||
WifiAP::MSTimer();
|
WifiAP->MSTimer();
|
||||||
|
|
||||||
bool switchOffPowerSaving = false;
|
bool switchOffPowerSaving = false;
|
||||||
if (USUntilPowerOn < 0)
|
if (USUntilPowerOn < 0)
|
||||||
|
@ -1839,7 +1764,7 @@ void USTimer(u32 param)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RFTransfer_Type2()
|
void Wifi::RFTransfer_Type2()
|
||||||
{
|
{
|
||||||
u32 id = (IOPORT(W_RFData2) >> 2) & 0x1F;
|
u32 id = (IOPORT(W_RFData2) >> 2) & 0x1F;
|
||||||
|
|
||||||
|
@ -1856,7 +1781,7 @@ void RFTransfer_Type2()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RFTransfer_Type3()
|
void Wifi::RFTransfer_Type3()
|
||||||
{
|
{
|
||||||
u32 id = (IOPORT(W_RFData1) >> 8) & 0x3F;
|
u32 id = (IOPORT(W_RFData1) >> 8) & 0x3F;
|
||||||
|
|
||||||
|
@ -1873,7 +1798,7 @@ void RFTransfer_Type3()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
u16 Read(u32 addr)
|
u16 Wifi::Read(u32 addr)
|
||||||
{
|
{
|
||||||
if (addr >= 0x04810000)
|
if (addr >= 0x04810000)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1976,7 +1901,7 @@ u16 Read(u32 addr)
|
||||||
return IOPORT(addr&0xFFF);
|
return IOPORT(addr&0xFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Write(u32 addr, u16 val)
|
void Wifi::Write(u32 addr, u16 val)
|
||||||
{
|
{
|
||||||
if (addr >= 0x04810000)
|
if (addr >= 0x04810000)
|
||||||
return;
|
return;
|
||||||
|
@ -2331,14 +2256,12 @@ void Write(u32 addr, u16 val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
u8* GetMAC()
|
u8* Wifi::GetMAC()
|
||||||
{
|
{
|
||||||
return (u8*)&IOPORT(W_MACAddr0);
|
return (u8*)&IOPORT(W_MACAddr0);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* GetBSSID()
|
u8* Wifi::GetBSSID()
|
||||||
{
|
{
|
||||||
return (u8*)&IOPORT(W_BSSID0);
|
return (u8*)&IOPORT(W_BSSID0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
396
src/Wifi.h
396
src/Wifi.h
|
@ -21,178 +21,268 @@
|
||||||
|
|
||||||
#include "Savestate.h"
|
#include "Savestate.h"
|
||||||
|
|
||||||
namespace Wifi
|
class WifiAP;
|
||||||
|
|
||||||
|
class Wifi
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
W_ID = 0x000,
|
W_ID = 0x000,
|
||||||
|
|
||||||
W_ModeReset = 0x004,
|
W_ModeReset = 0x004,
|
||||||
W_ModeWEP = 0x006,
|
W_ModeWEP = 0x006,
|
||||||
W_TXStatCnt = 0x008,
|
W_TXStatCnt = 0x008,
|
||||||
W_IF = 0x010,
|
W_IF = 0x010,
|
||||||
W_IE = 0x012,
|
W_IE = 0x012,
|
||||||
|
|
||||||
W_MACAddr0 = 0x018,
|
W_MACAddr0 = 0x018,
|
||||||
W_MACAddr1 = 0x01A,
|
W_MACAddr1 = 0x01A,
|
||||||
W_MACAddr2 = 0x01C,
|
W_MACAddr2 = 0x01C,
|
||||||
W_BSSID0 = 0x020,
|
W_BSSID0 = 0x020,
|
||||||
W_BSSID1 = 0x022,
|
W_BSSID1 = 0x022,
|
||||||
W_BSSID2 = 0x024,
|
W_BSSID2 = 0x024,
|
||||||
W_AIDLow = 0x028,
|
W_AIDLow = 0x028,
|
||||||
W_AIDFull = 0x02A,
|
W_AIDFull = 0x02A,
|
||||||
|
|
||||||
W_TXRetryLimit = 0x02C,
|
W_TXRetryLimit = 0x02C,
|
||||||
W_RXCnt = 0x030,
|
W_RXCnt = 0x030,
|
||||||
W_WEPCnt = 0x032,
|
W_WEPCnt = 0x032,
|
||||||
|
|
||||||
W_PowerUS = 0x036,
|
W_PowerUS = 0x036,
|
||||||
W_PowerTX = 0x038,
|
W_PowerTX = 0x038,
|
||||||
W_PowerState = 0x03C,
|
W_PowerState = 0x03C,
|
||||||
W_PowerForce = 0x040,
|
W_PowerForce = 0x040,
|
||||||
W_PowerUnk = 0x48,
|
W_PowerUnk = 0x48,
|
||||||
|
|
||||||
W_Random = 0x044,
|
W_Random = 0x044,
|
||||||
|
|
||||||
W_RXBufBegin = 0x050,
|
W_RXBufBegin = 0x050,
|
||||||
W_RXBufEnd = 0x052,
|
W_RXBufEnd = 0x052,
|
||||||
W_RXBufWriteCursor = 0x054,
|
W_RXBufWriteCursor = 0x054,
|
||||||
W_RXBufWriteAddr = 0x056,
|
W_RXBufWriteAddr = 0x056,
|
||||||
W_RXBufReadAddr = 0x058,
|
W_RXBufReadAddr = 0x058,
|
||||||
W_RXBufReadCursor = 0x05A,
|
W_RXBufReadCursor = 0x05A,
|
||||||
W_RXBufCount = 0x05C,
|
W_RXBufCount = 0x05C,
|
||||||
W_RXBufDataRead = 0x060,
|
W_RXBufDataRead = 0x060,
|
||||||
W_RXBufGapAddr = 0x062,
|
W_RXBufGapAddr = 0x062,
|
||||||
W_RXBufGapSize = 0x064,
|
W_RXBufGapSize = 0x064,
|
||||||
|
|
||||||
W_TXBufWriteAddr = 0x068,
|
W_TXBufWriteAddr = 0x068,
|
||||||
W_TXBufCount = 0x06C,
|
W_TXBufCount = 0x06C,
|
||||||
W_TXBufDataWrite = 0x070,
|
W_TXBufDataWrite = 0x070,
|
||||||
W_TXBufGapAddr = 0x074,
|
W_TXBufGapAddr = 0x074,
|
||||||
W_TXBufGapSize = 0x076,
|
W_TXBufGapSize = 0x076,
|
||||||
|
|
||||||
W_TXSlotBeacon = 0x080,
|
W_TXSlotBeacon = 0x080,
|
||||||
W_TXBeaconTIM = 0x084,
|
W_TXBeaconTIM = 0x084,
|
||||||
W_ListenCount = 0x088,
|
W_ListenCount = 0x088,
|
||||||
W_BeaconInterval = 0x08C,
|
W_BeaconInterval = 0x08C,
|
||||||
W_ListenInterval = 0x08E,
|
W_ListenInterval = 0x08E,
|
||||||
W_TXSlotCmd = 0x090,
|
W_TXSlotCmd = 0x090,
|
||||||
W_TXSlotReply1 = 0x094,
|
W_TXSlotReply1 = 0x094,
|
||||||
W_TXSlotReply2 = 0x098,
|
W_TXSlotReply2 = 0x098,
|
||||||
W_TXSlotLoc1 = 0x0A0,
|
W_TXSlotLoc1 = 0x0A0,
|
||||||
W_TXSlotLoc2 = 0x0A4,
|
W_TXSlotLoc2 = 0x0A4,
|
||||||
W_TXSlotLoc3 = 0x0A8,
|
W_TXSlotLoc3 = 0x0A8,
|
||||||
W_TXReqReset = 0x0AC,
|
W_TXReqReset = 0x0AC,
|
||||||
W_TXReqSet = 0x0AE,
|
W_TXReqSet = 0x0AE,
|
||||||
W_TXReqRead = 0x0B0,
|
W_TXReqRead = 0x0B0,
|
||||||
W_TXSlotReset = 0x0B4,
|
W_TXSlotReset = 0x0B4,
|
||||||
W_TXBusy = 0x0B6,
|
W_TXBusy = 0x0B6,
|
||||||
W_TXStat = 0x0B8,
|
W_TXStat = 0x0B8,
|
||||||
W_Preamble = 0x0BC,
|
W_Preamble = 0x0BC,
|
||||||
W_CmdTotalTime = 0x0C0,
|
W_CmdTotalTime = 0x0C0,
|
||||||
W_CmdReplyTime = 0x0C4,
|
W_CmdReplyTime = 0x0C4,
|
||||||
W_RXFilter = 0x0D0,
|
W_RXFilter = 0x0D0,
|
||||||
W_RXLenCrop = 0x0DA,
|
W_RXLenCrop = 0x0DA,
|
||||||
W_RXFilter2 = 0x0E0,
|
W_RXFilter2 = 0x0E0,
|
||||||
|
|
||||||
W_USCountCnt = 0x0E8,
|
W_USCountCnt = 0x0E8,
|
||||||
W_USCompareCnt = 0x0EA,
|
W_USCompareCnt = 0x0EA,
|
||||||
W_CmdCountCnt = 0x0EE,
|
W_CmdCountCnt = 0x0EE,
|
||||||
|
|
||||||
W_USCount0 = 0x0F8,
|
W_USCount0 = 0x0F8,
|
||||||
W_USCount1 = 0x0FA,
|
W_USCount1 = 0x0FA,
|
||||||
W_USCount2 = 0x0FC,
|
W_USCount2 = 0x0FC,
|
||||||
W_USCount3 = 0x0FE,
|
W_USCount3 = 0x0FE,
|
||||||
W_USCompare0 = 0x0F0,
|
W_USCompare0 = 0x0F0,
|
||||||
W_USCompare1 = 0x0F2,
|
W_USCompare1 = 0x0F2,
|
||||||
W_USCompare2 = 0x0F4,
|
W_USCompare2 = 0x0F4,
|
||||||
W_USCompare3 = 0x0F6,
|
W_USCompare3 = 0x0F6,
|
||||||
|
|
||||||
W_ContentFree = 0x10C,
|
W_ContentFree = 0x10C,
|
||||||
W_PreBeacon = 0x110,
|
W_PreBeacon = 0x110,
|
||||||
W_CmdCount = 0x118,
|
W_CmdCount = 0x118,
|
||||||
W_BeaconCount1 = 0x11C,
|
W_BeaconCount1 = 0x11C,
|
||||||
W_BeaconCount2 = 0x134,
|
W_BeaconCount2 = 0x134,
|
||||||
|
|
||||||
W_BBCnt = 0x158,
|
W_BBCnt = 0x158,
|
||||||
W_BBWrite = 0x15A,
|
W_BBWrite = 0x15A,
|
||||||
W_BBRead = 0x15C,
|
W_BBRead = 0x15C,
|
||||||
W_BBBusy = 0x15E,
|
W_BBBusy = 0x15E,
|
||||||
W_BBMode = 0x160,
|
W_BBMode = 0x160,
|
||||||
W_BBPower = 0x168,
|
W_BBPower = 0x168,
|
||||||
|
|
||||||
W_RFData2 = 0x17C,
|
W_RFData2 = 0x17C,
|
||||||
W_RFData1 = 0x17E,
|
W_RFData1 = 0x17E,
|
||||||
W_RFBusy = 0x180,
|
W_RFBusy = 0x180,
|
||||||
W_RFCnt = 0x184,
|
W_RFCnt = 0x184,
|
||||||
|
|
||||||
W_TXHeaderCnt = 0x194,
|
W_TXHeaderCnt = 0x194,
|
||||||
W_RFPins = 0x19C,
|
W_RFPins = 0x19C,
|
||||||
|
|
||||||
W_RXStatIncIF = 0x1A8,
|
W_RXStatIncIF = 0x1A8,
|
||||||
W_RXStatIncIE = 0x1AA,
|
W_RXStatIncIE = 0x1AA,
|
||||||
W_RXStatHalfIF = 0x1AC,
|
W_RXStatHalfIF = 0x1AC,
|
||||||
W_RXStatHalfIE = 0x1AE,
|
W_RXStatHalfIE = 0x1AE,
|
||||||
W_TXErrorCount = 0x1C0,
|
W_TXErrorCount = 0x1C0,
|
||||||
W_RXCount = 0x1C4,
|
W_RXCount = 0x1C4,
|
||||||
|
|
||||||
W_CMDStat0 = 0x1D0,
|
W_CMDStat0 = 0x1D0,
|
||||||
W_CMDStat1 = 0x1D2,
|
W_CMDStat1 = 0x1D2,
|
||||||
W_CMDStat2 = 0x1D4,
|
W_CMDStat2 = 0x1D4,
|
||||||
W_CMDStat3 = 0x1D6,
|
W_CMDStat3 = 0x1D6,
|
||||||
W_CMDStat4 = 0x1D8,
|
W_CMDStat4 = 0x1D8,
|
||||||
W_CMDStat5 = 0x1DA,
|
W_CMDStat5 = 0x1DA,
|
||||||
W_CMDStat6 = 0x1DC,
|
W_CMDStat6 = 0x1DC,
|
||||||
W_CMDStat7 = 0x1DE,
|
W_CMDStat7 = 0x1DE,
|
||||||
|
|
||||||
W_TXSeqNo = 0x210,
|
W_TXSeqNo = 0x210,
|
||||||
W_RFStatus = 0x214,
|
W_RFStatus = 0x214,
|
||||||
W_IFSet = 0x21C,
|
W_IFSet = 0x21C,
|
||||||
W_RXTXAddr = 0x268,
|
W_RXTXAddr = 0x268,
|
||||||
|
};
|
||||||
|
|
||||||
|
Wifi();
|
||||||
|
~Wifi();
|
||||||
|
void Reset();
|
||||||
|
void DoSavestate(Savestate* file);
|
||||||
|
|
||||||
|
void SetPowerCnt(u32 val);
|
||||||
|
|
||||||
|
void USTimer(u32 param);
|
||||||
|
|
||||||
|
u16 Read(u32 addr);
|
||||||
|
void Write(u32 addr, u16 val);
|
||||||
|
|
||||||
|
u8* GetMAC();
|
||||||
|
u8* GetBSSID();
|
||||||
|
|
||||||
|
private:
|
||||||
|
u8 RAM[0x2000];
|
||||||
|
u16 IO[0x1000>>1];
|
||||||
|
|
||||||
|
static const u8 MPCmdMAC[6];
|
||||||
|
static const u8 MPReplyMAC[6];
|
||||||
|
static const u8 MPAckMAC[6];
|
||||||
|
|
||||||
|
static const int kTimerInterval = 8;
|
||||||
|
static const u32 kTimeCheckMask = ~(kTimerInterval - 1);
|
||||||
|
|
||||||
|
bool Enabled;
|
||||||
|
bool PowerOn;
|
||||||
|
|
||||||
|
s32 TimerError;
|
||||||
|
|
||||||
|
u16 Random;
|
||||||
|
|
||||||
|
// general, always-on microsecond counter
|
||||||
|
u64 USTimestamp;
|
||||||
|
|
||||||
|
u64 USCounter;
|
||||||
|
u64 USCompare;
|
||||||
|
bool BlockBeaconIRQ14;
|
||||||
|
|
||||||
|
u32 CmdCounter;
|
||||||
|
|
||||||
|
u8 BBRegs[0x100];
|
||||||
|
u8 BBRegsRO[0x100];
|
||||||
|
|
||||||
|
u8 RFVersion;
|
||||||
|
u32 RFRegs[0x40];
|
||||||
|
|
||||||
|
struct TXSlot
|
||||||
|
{
|
||||||
|
bool Valid;
|
||||||
|
u16 Addr;
|
||||||
|
u16 Length;
|
||||||
|
u8 Rate;
|
||||||
|
u8 CurPhase;
|
||||||
|
int CurPhaseTime;
|
||||||
|
u32 HalfwordTimeMask;
|
||||||
|
};
|
||||||
|
|
||||||
|
TXSlot TXSlots[6];
|
||||||
|
u8 TXBuffer[0x2000];
|
||||||
|
|
||||||
|
u8 RXBuffer[2048];
|
||||||
|
u32 RXBufferPtr;
|
||||||
|
int RXTime;
|
||||||
|
u32 RXHalfwordTimeMask;
|
||||||
|
|
||||||
|
u32 ComStatus; // 0=waiting for packets 1=receiving 2=sending
|
||||||
|
u32 TXCurSlot;
|
||||||
|
u32 RXCounter;
|
||||||
|
|
||||||
|
int MPReplyTimer;
|
||||||
|
u16 MPClientMask, MPClientFail;
|
||||||
|
|
||||||
|
u8 MPClientReplies[15*1024];
|
||||||
|
|
||||||
|
u16 MPLastSeqno;
|
||||||
|
|
||||||
|
bool MPInited;
|
||||||
|
bool LANInited;
|
||||||
|
|
||||||
|
int USUntilPowerOn;
|
||||||
|
bool ForcePowerOn;
|
||||||
|
|
||||||
|
// MULTIPLAYER SYNC APPARATUS
|
||||||
|
bool IsMP;
|
||||||
|
bool IsMPClient;
|
||||||
|
u64 NextSync; // for clients: timestamp for next sync point
|
||||||
|
u64 RXTimestamp;
|
||||||
|
|
||||||
|
class WifiAP* WifiAP;
|
||||||
|
|
||||||
|
void ScheduleTimer(bool first);
|
||||||
|
void UpdatePowerOn();
|
||||||
|
|
||||||
|
void SetIRQ(u32 irq);
|
||||||
|
void SetIRQ13();
|
||||||
|
void SetIRQ14(int source);
|
||||||
|
void SetIRQ15();
|
||||||
|
|
||||||
|
void SetStatus(u32 status);
|
||||||
|
void PowerDown();
|
||||||
|
|
||||||
|
int PreambleLen(int rate);
|
||||||
|
u32 NumClients(u16 bitmask);
|
||||||
|
void IncrementTXCount(TXSlot* slot);
|
||||||
|
void ReportMPReplyErrors(u16 clientfail);
|
||||||
|
|
||||||
|
void TXSendFrame(TXSlot* slot, int num);
|
||||||
|
void StartTX_LocN(int nslot, int loc);
|
||||||
|
void StartTX_Cmd();
|
||||||
|
void StartTX_Beacon();
|
||||||
|
void FireTX();
|
||||||
|
void SendMPDefaultReply();
|
||||||
|
void SendMPReply(u16 clienttime, u16 clientmask);
|
||||||
|
void SendMPAck(u16 cmdcount, u16 clientfail);
|
||||||
|
bool ProcessTX(TXSlot* slot, int num);
|
||||||
|
|
||||||
|
void IncrementRXAddr(u16& addr, u16 inc = 2);
|
||||||
|
void StartRX();
|
||||||
|
void FinishRX();
|
||||||
|
void MPClientReplyRX(int client);
|
||||||
|
bool CheckRX(int type);
|
||||||
|
|
||||||
|
void MSTimer();
|
||||||
|
|
||||||
|
void RFTransfer_Type2();
|
||||||
|
void RFTransfer_Type3();
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
Event_RXCheck = 0,
|
|
||||||
Event_IRQ15,
|
|
||||||
Event_MSTimer,
|
|
||||||
Event_RFWakeup,
|
|
||||||
Event_RX,
|
|
||||||
Event_TX,
|
|
||||||
Event_MPClientSync,
|
|
||||||
Event_RF,
|
|
||||||
Event_BB,
|
|
||||||
|
|
||||||
Event_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SchedEvent
|
|
||||||
{
|
|
||||||
void (*Func)(u32 param);
|
|
||||||
u64 Timestamp;
|
|
||||||
u32 Param;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
extern bool MPInited;
|
|
||||||
|
|
||||||
|
|
||||||
bool Init();
|
|
||||||
void DeInit();
|
|
||||||
void Reset();
|
|
||||||
void DoSavestate(Savestate* file);
|
|
||||||
|
|
||||||
void SetPowerCnt(u32 val);
|
|
||||||
|
|
||||||
void USTimer(u32 param);
|
|
||||||
|
|
||||||
u16 Read(u32 addr);
|
|
||||||
void Write(u32 addr, u16 val);
|
|
||||||
|
|
||||||
u8* GetMAC();
|
|
||||||
u8* GetBSSID();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,10 +30,9 @@
|
||||||
using Platform::Log;
|
using Platform::Log;
|
||||||
using Platform::LogLevel;
|
using Platform::LogLevel;
|
||||||
|
|
||||||
namespace WifiAP
|
|
||||||
{
|
|
||||||
|
|
||||||
const u8 APMac[6] = {AP_MAC};
|
const char* WifiAP::APName = "melonAP";
|
||||||
|
const u8 WifiAP::APMac[6] = {0x00, 0xF0, 0x77, 0x77, 0x77, 0x77};
|
||||||
|
|
||||||
#define PWRITE_8(p, v) *p++ = v;
|
#define PWRITE_8(p, v) *p++ = v;
|
||||||
#define PWRITE_16(p, v) *(u16*)p = v; p += 2;
|
#define PWRITE_16(p, v) *(u16*)p = v; p += 2;
|
||||||
|
@ -65,33 +64,19 @@ const u8 APMac[6] = {AP_MAC};
|
||||||
#define PALIGN_4(p, base) while (PLEN(p,base) & 0x3) *p++ = 0xFF;
|
#define PALIGN_4(p, base) while (PLEN(p,base) & 0x3) *p++ = 0xFF;
|
||||||
|
|
||||||
|
|
||||||
u64 USCounter;
|
bool MACEqual(u8* a, const u8* b);
|
||||||
|
bool MACIsBroadcast(u8* a);
|
||||||
u16 SeqNo;
|
|
||||||
|
|
||||||
bool BeaconDue;
|
|
||||||
|
|
||||||
u8 PacketBuffer[2048];
|
|
||||||
int PacketLen;
|
|
||||||
int RXNum;
|
|
||||||
|
|
||||||
u8 LANBuffer[2048];
|
|
||||||
|
|
||||||
// this is a lazy AP, we only keep track of one client
|
|
||||||
// 0=disconnected 1=authenticated 2=associated
|
|
||||||
int ClientStatus;
|
|
||||||
|
|
||||||
|
|
||||||
bool Init()
|
WifiAP::WifiAP(class Wifi* wifi) : Wifi(wifi)
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeInit()
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset()
|
WifiAP::~WifiAP()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WifiAP::Reset()
|
||||||
{
|
{
|
||||||
// random starting point for the counter
|
// random starting point for the counter
|
||||||
USCounter = 0x428888000ULL;
|
USCounter = 0x428888000ULL;
|
||||||
|
@ -107,18 +92,7 @@ void Reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool MACEqual(u8* a, u8* b)
|
void WifiAP::MSTimer()
|
||||||
{
|
|
||||||
return (*(u32*)&a[0] == *(u32*)&b[0]) && (*(u16*)&a[4] == *(u16*)&b[4]);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MACIsBroadcast(u8* a)
|
|
||||||
{
|
|
||||||
return (*(u32*)&a[0] == 0xFFFFFFFF) && (*(u16*)&a[4] == 0xFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MSTimer()
|
|
||||||
{
|
{
|
||||||
USCounter += 0x400;
|
USCounter += 0x400;
|
||||||
|
|
||||||
|
@ -131,7 +105,7 @@ void MSTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int HandleManagementFrame(u8* data, int len)
|
int WifiAP::HandleManagementFrame(u8* data, int len)
|
||||||
{
|
{
|
||||||
// TODO: perfect this
|
// TODO: perfect this
|
||||||
// noting that frames sent pre-auth/assoc don't have a proper BSSID
|
// noting that frames sent pre-auth/assoc don't have a proper BSSID
|
||||||
|
@ -199,8 +173,8 @@ int HandleManagementFrame(u8* data, int len)
|
||||||
PWRITE_16(p, 0x0021); // capability
|
PWRITE_16(p, 0x0021); // capability
|
||||||
PWRITE_8(p, 0x01); PWRITE_8(p, 0x02); PWRITE_8(p, 0x82); PWRITE_8(p, 0x84); // rates
|
PWRITE_8(p, 0x01); PWRITE_8(p, 0x02); PWRITE_8(p, 0x82); PWRITE_8(p, 0x84); // rates
|
||||||
PWRITE_8(p, 0x03); PWRITE_8(p, 0x01); PWRITE_8(p, 0x06); // current channel
|
PWRITE_8(p, 0x03); PWRITE_8(p, 0x01); PWRITE_8(p, 0x06); // current channel
|
||||||
PWRITE_8(p, 0x00); PWRITE_8(p, strlen(AP_NAME));
|
PWRITE_8(p, 0x00); PWRITE_8(p, strlen(APName));
|
||||||
memcpy(p, AP_NAME, strlen(AP_NAME)); p += strlen(AP_NAME);
|
memcpy(p, APName, strlen(APName)); p += strlen(APName);
|
||||||
|
|
||||||
PacketLen = PLEN(p, base);
|
PacketLen = PLEN(p, base);
|
||||||
RXNum = 1;
|
RXNum = 1;
|
||||||
|
@ -282,7 +256,7 @@ int HandleManagementFrame(u8* data, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int SendPacket(u8* data, int len)
|
int WifiAP::SendPacket(u8* data, int len)
|
||||||
{
|
{
|
||||||
data += 12;
|
data += 12;
|
||||||
|
|
||||||
|
@ -330,7 +304,7 @@ int SendPacket(u8* data, int len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RecvPacket(u8* data)
|
int WifiAP::RecvPacket(u8* data)
|
||||||
{
|
{
|
||||||
if (BeaconDue)
|
if (BeaconDue)
|
||||||
{
|
{
|
||||||
|
@ -353,8 +327,8 @@ int RecvPacket(u8* data)
|
||||||
PWRITE_8(p, 0x01); PWRITE_8(p, 0x02); PWRITE_8(p, 0x82); PWRITE_8(p, 0x84); // rates
|
PWRITE_8(p, 0x01); PWRITE_8(p, 0x02); PWRITE_8(p, 0x82); PWRITE_8(p, 0x84); // rates
|
||||||
PWRITE_8(p, 0x03); PWRITE_8(p, 0x01); PWRITE_8(p, 0x06); // current channel
|
PWRITE_8(p, 0x03); PWRITE_8(p, 0x01); PWRITE_8(p, 0x06); // current channel
|
||||||
PWRITE_8(p, 0x05); PWRITE_8(p, 0x04); PWRITE_8(p, 0); PWRITE_8(p, 0); PWRITE_8(p, 0); PWRITE_8(p, 0); // TIM
|
PWRITE_8(p, 0x05); PWRITE_8(p, 0x04); PWRITE_8(p, 0); PWRITE_8(p, 0); PWRITE_8(p, 0); PWRITE_8(p, 0); // TIM
|
||||||
PWRITE_8(p, 0x00); PWRITE_8(p, strlen(AP_NAME));
|
PWRITE_8(p, 0x00); PWRITE_8(p, strlen(APName));
|
||||||
memcpy(p, AP_NAME, strlen(AP_NAME)); p += strlen(AP_NAME);
|
memcpy(p, APName, strlen(APName)); p += strlen(APName);
|
||||||
|
|
||||||
PALIGN_4(p, base);
|
PALIGN_4(p, base);
|
||||||
PWRITE_32(p, 0xDEADBEEF); // checksum. doesn't matter for now
|
PWRITE_32(p, 0xDEADBEEF); // checksum. doesn't matter for now
|
||||||
|
@ -394,7 +368,7 @@ int RecvPacket(u8* data)
|
||||||
// check destination MAC
|
// check destination MAC
|
||||||
if (!MACIsBroadcast(&LANBuffer[0]))
|
if (!MACIsBroadcast(&LANBuffer[0]))
|
||||||
{
|
{
|
||||||
if (!MACEqual(&LANBuffer[0], Wifi::GetMAC()))
|
if (!MACEqual(&LANBuffer[0], Wifi->GetMAC()))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,5 +401,3 @@ int RecvPacket(u8* data)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
44
src/WifiAP.h
44
src/WifiAP.h
|
@ -21,24 +21,44 @@
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
namespace WifiAP
|
class Wifi;
|
||||||
|
|
||||||
|
class WifiAP
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
WifiAP(Wifi* wifi);
|
||||||
|
~WifiAP();
|
||||||
|
void Reset();
|
||||||
|
|
||||||
#define AP_MAC 0x00, 0xF0, 0x77, 0x77, 0x77, 0x77
|
static const char* APName;
|
||||||
#define AP_NAME "melonAP"
|
static const u8 APMac[6];
|
||||||
|
|
||||||
extern const u8 APMac[6];
|
void MSTimer();
|
||||||
|
|
||||||
bool Init();
|
// packet format: 12-byte TX header + original 802.11 frame
|
||||||
void DeInit();
|
int SendPacket(u8* data, int len);
|
||||||
void Reset();
|
int RecvPacket(u8* data);
|
||||||
|
|
||||||
void MSTimer();
|
private:
|
||||||
|
class Wifi* Wifi;
|
||||||
|
|
||||||
// packet format: 12-byte TX header + original 802.11 frame
|
u64 USCounter;
|
||||||
int SendPacket(u8* data, int len);
|
|
||||||
int RecvPacket(u8* data);
|
|
||||||
|
|
||||||
}
|
u16 SeqNo;
|
||||||
|
|
||||||
|
bool BeaconDue;
|
||||||
|
|
||||||
|
u8 PacketBuffer[2048];
|
||||||
|
int PacketLen;
|
||||||
|
int RXNum;
|
||||||
|
|
||||||
|
u8 LANBuffer[2048];
|
||||||
|
|
||||||
|
// this is a lazy AP, we only keep track of one client
|
||||||
|
// 0=disconnected 1=authenticated 2=associated
|
||||||
|
int ClientStatus;
|
||||||
|
|
||||||
|
int HandleManagementFrame(u8* data, int len);
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue