diff options
Diffstat (limited to 'c/src/lib/libbsp/arm/nds/dswifi/arm7/source/wifi_arm7.c')
-rw-r--r-- | c/src/lib/libbsp/arm/nds/dswifi/arm7/source/wifi_arm7.c | 1637 |
1 files changed, 0 insertions, 1637 deletions
diff --git a/c/src/lib/libbsp/arm/nds/dswifi/arm7/source/wifi_arm7.c b/c/src/lib/libbsp/arm/nds/dswifi/arm7/source/wifi_arm7.c deleted file mode 100644 index d743a5b4c0..0000000000 --- a/c/src/lib/libbsp/arm/nds/dswifi/arm7/source/wifi_arm7.c +++ /dev/null @@ -1,1637 +0,0 @@ -// DS Wifi interface code -// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org -// wifi_arm7.c - arm7 wifi interface code -/****************************************************************************** -DSWifi Lib and test materials are licenced under the MIT open source licence: -Copyright (c) 2005-2006 Stephen Stair - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -******************************************************************************/ - - -#include <nds.h> -#include "dsregs.h" -#include "wifi_arm7.h" - -#include "spinlock.h" // .h file with code for spinlocking in it. - -volatile Wifi_MainStruct * WifiData = 0; -WifiSyncHandler synchandler = 0; -int keepalive_time = 0; -int chdata_save5 = 0; - -////////////////////////////////////////////////////////////////////////// -// -// Flash support functions -// -char FlashData[512]; -void Read_Flash(int address, char * destination, int length) { - int i; - while(SPI_CR&0x80); - SPI_CR=0x8900; - SPI_DATA=3; - while(SPI_CR&0x80); - SPI_DATA=(address>>16)&255; - while(SPI_CR&0x80); - SPI_DATA=(address>>8)&255; - while(SPI_CR&0x80); - SPI_DATA=(address)&255; - while(SPI_CR&0x80); - for(i=0;i<length;i++) { - SPI_DATA=0; - while(SPI_CR&0x80); - destination[i]=SPI_DATA; - } - SPI_CR=0; -} - -void InitFlashData() { - Read_Flash(0,FlashData,512); -} - -int ReadFlashByte(int address) { - if(address<0 || address>511) return 0; - return FlashData[address]; -} - -int ReadFlashBytes(int address, int numbytes) { - int dataout=0; - int i; - for(i=0;i<numbytes;i++) { - dataout |= ReadFlashByte(i+address)<<(i*8); - } - return dataout; -} -int ReadFlashHWord(int address) { - if(address<0 || address>510) return 0; - return ReadFlashBytes(address,2); -} - -////////////////////////////////////////////////////////////////////////// -// -// WFC data loading -// -/* -int crc16_slow(u8 * data, int length) { - int i,j,d, crc; - crc=0x0000; - for(i=0;i<length;i++) { - d=data[i]; - for(j=0;j<8;j++) { - if(((d)^(crc>>15))&1) crc = (crc<<1)^0x8005; else crc=crc<<1; - d=d>>1; - } - } - crc &=0xFFFF; - return crc; -} -*/ -int crc16_slow(u8 * data, int length) { - int i,j, crc; - crc=0x0000; - for(i=0;i<length;i++) { - crc ^=data[i]; - for(j=0;j<8;j++) { - if((crc)&1) crc = (crc>>1)^0xA001; else crc=crc>>1; - } - } - crc &=0xFFFF; - return crc; -} - -void GetWfcSettings(void) { - u8 data[256]; - int i,n, c; - unsigned long s; - c=0; - u32 wfcBase = ReadFlashBytes(0x20, 2) * 8 - 0x400; - for(i=0;i<3;i++) WifiData->wfc_enable[i]=0; - for(i=0;i<3;i++) { - Read_Flash( wfcBase +(i<<8),(char *)data,256); - // check for validity (crc16) - if(crc16_slow(data,256)==0x0000 && data[0xE7]==0x00) { // passed the test - WifiData->wfc_enable[c] = 0x80 | (data[0xE6]&0x0F); - WifiData->wfc_ap[c].channel=0; - for(n=0;n<6;n++) WifiData->wfc_ap[c].bssid[n]=0; - for(n=0;n<16;n++) WifiData->wfc_wepkey[c][n]=data[0x80+n]; - for(n=0;n<32;n++) WifiData->wfc_ap[c].ssid[n]=data[0x40+n]; - for(n=0;n<32;n++) if(!data[0x40+n]) break; - WifiData->wfc_ap[c].ssid_len=n; - WifiData->wfc_config[c][0]=((unsigned long *)(data+0xC0))[0]; - WifiData->wfc_config[c][1]=((unsigned long *)(data+0xC0))[1]; - WifiData->wfc_config[c][3]=((unsigned long *)(data+0xC0))[2]; - WifiData->wfc_config[c][4]=((unsigned long *)(data+0xC0))[3]; - s=0; - for(n=0;n<data[0xD0];n++) { - s |= 1<<(31-n); - } - s= (s<<24) | (s>>24) | ((s&0xFF00)<<8) | ((s&0xFF0000)>>8); // htonl - WifiData->wfc_config[c][2]=s; - c++; - } - } -} - - -////////////////////////////////////////////////////////////////////////// -// -// Other support -// - -int Wifi_BBRead(int a) { - while(W_BBSIOBUSY&1); - W_BBSIOCNT=a | 0x6000; - while(W_BBSIOBUSY&1); - return W_BBSIOREAD; -} -int Wifi_BBWrite(int a, int b) { - int i; - i=0x2710; - while((W_BBSIOBUSY&1)) { - if(!i--) return -1; - } - W_BBSIOWRITE=b; - W_BBSIOCNT=a | 0x5000; - i=0x2710; - while((W_BBSIOBUSY&1)) { - if(!i--) return 0; - } - return 0; -} -void Wifi_RFWrite(int writedata) { - while(W_RFSIOBUSY&1); - W_RFSIODATA1=writedata; - W_RFSIODATA2=writedata>>16; - while(W_RFSIOBUSY&1); -} - -int PowerChip_ReadWrite(int cmd, int data) { - if(cmd&0x80) data=0; - while(SPI_CR&0x80); - SPI_CR=0x8802; - SPI_DATA=cmd; - while(SPI_CR&0x80); - SPI_CR=0x8002; - SPI_DATA=data; - while(SPI_CR&0x80); - data=SPI_DATA; - SPI_CR=0; - return data; -} - -#define LED_LONGBLINK 1 -#define LED_SHORTBLINK 3 -#define LED_ON 0 -int led_state=0; -void SetLedState(int state) { - int i; - if(state>3 || state<0) return; - if(state!=led_state) { - led_state=state; - i=PowerChip_ReadWrite(0x80,0); - i=i&0xCF; - i |= state<<4; - PowerChip_ReadWrite(0,i); - } -} - -void ProxySetLedState(int state) { - if(WifiData->flags9&WFLAG_ARM9_USELED) SetLedState(state); -} - -////////////////////////////////////////////////////////////////////////// -// -// Main functionality -// - -int RF_Reglist[] = { 0x146, 0x148, 0x14A, 0x14C, 0x120, 0x122, 0x154, 0x144, 0x130, 0x132, 0x140, 0x142, 0x38, 0x124, 0x128, 0x150 }; - -void Wifi_RFInit() { - int i,j; - int channel_extrabits; - int numchannels; - int channel_extrabytes; - int temp; - for(i=0;i<16;i++) { - WIFI_REG(RF_Reglist[i])=ReadFlashHWord(0x44+i*2); - } - numchannels=ReadFlashByte(0x42); - channel_extrabits=ReadFlashByte(0x41); - channel_extrabytes=(channel_extrabits+7)/8; - WIFI_REG(0x184)=((channel_extrabits>>7)<<8) | (channel_extrabits&0x7F); - j=0xCE; - if(ReadFlashByte(0x40)==3) { - for(i=0;i<numchannels;i++) { - Wifi_RFWrite(ReadFlashByte(j++)|(i<<8)|0x50000); - } - } else if(ReadFlashByte(0x40)==2) { - for(i=0;i<numchannels;i++) { - temp = ReadFlashBytes(j,channel_extrabytes); - Wifi_RFWrite(temp); - j+=channel_extrabytes; - if( (temp>>18)==9 ) { - chdata_save5 = temp&(~0x7C00); - } - } - } else { - for(i=0;i<numchannels;i++) { - Wifi_RFWrite(ReadFlashBytes(j,channel_extrabytes)); - j+=channel_extrabytes; - } - } -} - -void Wifi_BBInit() { - int i; - WIFI_REG(0x160)=0x0100; - for(i=0;i<0x69;i++) { - Wifi_BBWrite(i,ReadFlashByte(0x64+i)); - } -} - -// 22 entry list -int MAC_Reglist[] = { 0x04, 0x08, 0x0A, 0x12, 0x10, 0x254, 0xB4, 0x80, 0x2A, 0x28, 0xE8, 0xEA, 0xEE, 0xEC, 0x1A2, 0x1A0, 0x110, 0xBC, 0xD4, 0xD8, 0xDA, 0x76 }; -int MAC_Vallist[] = { 0, 0, 0, 0, 0xffff, 0, 0xffff, 0, 0, 0, 0, 0, 1, 0x3F03, 1, 0, 0x0800, 1, 3, 4, 0x0602, 0}; -void Wifi_MacInit() { - int i; - for(i=0;i<22;i++) { - WIFI_REG(MAC_Reglist[i]) = MAC_Vallist[i]; - } -} - - -void Wifi_TxSetup() { -/* switch(WIFI_REG(0x8006)&7) { - case 0: // - // 4170, 4028, 4000 - // TxqEndData, TxqEndManCtrl, TxqEndPsPoll - WIFI_REG(0x4024)=0xB6B8; - WIFI_REG(0x4026)=0x1D46; - WIFI_REG(0x416C)=0xB6B8; - WIFI_REG(0x416E)=0x1D46; - WIFI_REG(0x4790)=0xB6B8; - WIFI_REG(0x4792)=0x1D46; - WIFI_REG(0x80AE) = 1; - break; - case 1: // - // 4AA0, 4958, 4334 - // TxqEndData, TxqEndManCtrl, TxqEndBroadCast - // 4238, 4000 - WIFI_REG(0x4234)=0xB6B8; - WIFI_REG(0x4236)=0x1D46; - WIFI_REG(0x4330)=0xB6B8; - WIFI_REG(0x4332)=0x1D46; - WIFI_REG(0x4954)=0xB6B8; - WIFI_REG(0x4956)=0x1D46; - WIFI_REG(0x4A9C)=0xB6B8; - WIFI_REG(0x4A9E)=0x1D46; - WIFI_REG(0x50C0)=0xB6B8; - WIFI_REG(0x50C2)=0x1D46; - //... - break; - case 2: - // 45D8, 4490, 4468 - // TxqEndData, TxqEndManCtrl, TxqEndPsPoll - - WIFI_REG(0x4230)=0xB6B8; - WIFI_REG(0x4232)=0x1D46; - WIFI_REG(0x4464)=0xB6B8; - WIFI_REG(0x4466)=0x1D46; - WIFI_REG(0x448C)=0xB6B8; - WIFI_REG(0x448E)=0x1D46; - WIFI_REG(0x45D4)=0xB6B8; - WIFI_REG(0x45D6)=0x1D46; - WIFI_REG(0x4BF8)=0xB6B8; - WIFI_REG(0x4BFA)=0x1D46; -*/ - WIFI_REG(0x80AE)=0x000D; -// } -} - -void Wifi_RxSetup() { - WIFI_REG(0x8030) = 0x8000; -/* switch(WIFI_REG(0x8006)&7) { - case 0: - WIFI_REG(0x8050) = 0x4794; - WIFI_REG(0x8056) = 0x03CA; - // 17CC ? - break; - case 1: - WIFI_REG(0x8050) = 0x50C4; - WIFI_REG(0x8056) = 0x0862; - // 0E9C ? - break; - case 2: - WIFI_REG(0x8050) = 0x4BFC; - WIFI_REG(0x8056) = 0x05FE; - // 1364 ? - break; - case 3: - WIFI_REG(0x8050) = 0x4794; - WIFI_REG(0x8056) = 0x03CA; - // 17CC ? - break; - } - */ - WIFI_REG(0x8050) = 0x4C00; - WIFI_REG(0x8056) = 0x0600; - - WIFI_REG(0x8052) = 0x5F60; - WIFI_REG(0x805A) = (WIFI_REG(0x8050)&0x3FFF)>>1; - WIFI_REG(0x8062) = 0x5F5E; - WIFI_REG(0x8030) = 0x8001; -} - - -void Wifi_WakeUp() { - u32 i; - WIFI_REG(0x8036)=0; - - swiDelay( 67109 ); // 8ms delay - - WIFI_REG(0x8168)=0; - - i=Wifi_BBRead(1); - Wifi_BBWrite(1,i&0x7f); - Wifi_BBWrite(1,i); - - swiDelay( 335544 ); // 40ms delay - - Wifi_RFInit(); -} -void Wifi_Shutdown() { - int a; - if(ReadFlashByte(0x40)==2) { - Wifi_RFWrite(0xC008); - } - a=Wifi_BBRead(0x1E); - Wifi_BBWrite(0x1E,a|0x3F); - WIFI_REG(0x168)=0x800D; - WIFI_REG(0x36)=1; -} - - -void Wifi_CopyMacAddr(volatile void * dest, volatile void * src) { - ((u16 *)dest)[0]=((u16 *)src)[0]; - ((u16 *)dest)[1]=((u16 *)src)[1]; - ((u16 *)dest)[2]=((u16 *)src)[2]; -} - -int Wifi_CmpMacAddr(volatile void * mac1,volatile void * mac2) { - return (((u16 *)mac1)[0]==((u16 *)mac2)[0]) && (((u16 *)mac1)[1]==((u16 *)mac2)[1]) && (((u16 *)mac1)[2]==((u16 *)mac2)[2]); -} - -////////////////////////////////////////////////////////////////////////// -// -// MAC Copy functions -// - -u16 inline Wifi_MACRead(u32 MAC_Base, u32 MAC_Offset) { - MAC_Base += MAC_Offset; - if(MAC_Base>=(WIFI_REG(0x52)&0x1FFE)) MAC_Base -= ((WIFI_REG(0x52)&0x1FFE)-(WIFI_REG(0x50)&0x1FFE)); - return WIFI_REG(0x4000+MAC_Base); -} - -void Wifi_MACCopy(u16 * dest, u32 MAC_Base, u32 MAC_Offset, u32 length) { - int endrange,subval; - int thislength; - endrange = (WIFI_REG(0x52)&0x1FFE); - subval=((WIFI_REG(0x52)&0x1FFE)-(WIFI_REG(0x50)&0x1FFE)); - MAC_Base += MAC_Offset; - if(MAC_Base>=endrange) MAC_Base -= subval; - while(length>0) { - thislength=length; - if(thislength>(endrange-MAC_Base)) thislength=endrange-MAC_Base; - length-=thislength; - while(thislength>0) { - *(dest++) = WIFI_REG(0x4000+MAC_Base); - MAC_Base+=2; - thislength-=2; - } - MAC_Base-=subval; - } -} - -void Wifi_MACWrite(u16 * src, u32 MAC_Base, u32 MAC_Offset, u32 length) { - int endrange,subval; - int thislength; - endrange = (WIFI_REG(0x52)&0x1FFE); - subval=((WIFI_REG(0x52)&0x1FFE)-(WIFI_REG(0x50)&0x1FFE)); - MAC_Base += MAC_Offset; - if(MAC_Base>=endrange) MAC_Base -= subval; - while(length>0) { - thislength=length; - if(length>(endrange-MAC_Base)) length=endrange-MAC_Base; - length-=thislength; - while(thislength>0) { - WIFI_REG(0x4000+MAC_Base) = *(src++); - MAC_Base+=2; - thislength-=2; - } - MAC_Base-=subval; - } -} -int Wifi_QueueRxMacData(u32 base, u32 len) { - int buflen, temp,macofs, tempout; - macofs=0; - buflen=(WifiData->rxbufIn-WifiData->rxbufOut-1)*2; - if(buflen<0) buflen += WIFI_RXBUFFER_SIZE; - if(buflen<len) { WifiData->stats[WSTAT_RXQUEUEDLOST]++; return 0; } - WifiData->stats[WSTAT_RXQUEUEDPACKETS]++; - WifiData->stats[WSTAT_RXQUEUEDBYTES]+=len; - temp=WIFI_RXBUFFER_SIZE-(WifiData->rxbufOut*2); - tempout=WifiData->rxbufOut; - if(len>temp) { - Wifi_MACCopy((u16*)WifiData->rxbufData+tempout,base,macofs,temp); - macofs+=temp; - len-=temp; - tempout=0; - } - Wifi_MACCopy((u16*)WifiData->rxbufData+tempout,base,macofs,len); - tempout+=len/2; - if(tempout>=(WIFI_RXBUFFER_SIZE/2)) tempout-=(WIFI_RXBUFFER_SIZE/2); - WifiData->rxbufOut=tempout; - if(synchandler) synchandler(); - return 1; -} - -int Wifi_CheckTxBuf(s32 offset) { - offset+=WifiData->txbufIn; - if(offset>=WIFI_TXBUFFER_SIZE/2) offset-=WIFI_TXBUFFER_SIZE/2; - return WifiData->txbufData[offset]; -} - -// non-wrapping function. -int Wifi_CopyFirstTxData(s32 macbase) { - int seglen, readbase,max, packetlen,length; - packetlen=Wifi_CheckTxBuf(5); - readbase=WifiData->txbufIn; - length = (packetlen+12-4+1)/2; - max=WifiData->txbufOut-WifiData->txbufIn; - if(max<0) max+=WIFI_TXBUFFER_SIZE/2; - if(max<length) return 0; - while(length>0) { - seglen=length; - if(readbase+seglen>WIFI_TXBUFFER_SIZE/2) seglen=WIFI_TXBUFFER_SIZE/2-readbase; - length-=seglen; - while(seglen--) { WIFI_REG(0x4000+macbase)=WifiData->txbufData[readbase++]; macbase+=2; } - if(readbase>=WIFI_TXBUFFER_SIZE/2) readbase-=WIFI_TXBUFFER_SIZE/2; - } - WifiData->txbufIn=readbase; - - WifiData->stats[WSTAT_TXPACKETS]++; - WifiData->stats[WSTAT_TXBYTES]+=packetlen+12-4; - WifiData->stats[WSTAT_TXDATABYTES]+=packetlen-4; - - return packetlen; -} - - - -u16 arm7q[1024]; -u16 arm7qlen = 0; - -void Wifi_TxRaw(u16 * data, int datalen) { - datalen = (datalen+3)&(~3); - Wifi_MACWrite(data, 0, 0, datalen); -// WIFI_REG(0xB8)=0x0001; - WIFI_REG(0xA8)=0x8000; - WifiData->stats[WSTAT_TXPACKETS]++; - WifiData->stats[WSTAT_TXBYTES]+=datalen; - WifiData->stats[WSTAT_TXDATABYTES]+=datalen-12; -} - -int Wifi_TxCheck(void) { - if(WIFI_REG(0xA8)&0x8000) return 0; - return 1; -} - - -////////////////////////////////////////////////////////////////////////// -// -// Wifi Interrupts -// - -void Wifi_Intr_RxEnd(void) { - int base; - int packetlen; - int full_packetlen; - int cut, temp; - int tIME; - tIME=REG_IME; - REG_IME=0; - cut=0; - - while(WIFI_REG(0x54)!=WIFI_REG(0x5A)) { - base = WIFI_REG(0x5A)<<1; - packetlen=Wifi_MACRead(base,8); - full_packetlen=12+((packetlen+3)&(~3)); - WifiData->stats[WSTAT_RXPACKETS]++; - WifiData->stats[WSTAT_RXBYTES]+=full_packetlen; - WifiData->stats[WSTAT_RXDATABYTES]+=full_packetlen-12; - - - // process packet here - temp=Wifi_ProcessReceivedFrame(base,full_packetlen); // returns packet type - if(temp&WifiData->reqPacketFlags || WifiData->reqReqFlags&WFLAG_REQ_PROMISC) { // if packet type is requested, forward it to the rx queue - keepalive_time=0; - if(!Wifi_QueueRxMacData(base,full_packetlen)) { - // failed, ignore for now. - } - } - - base += full_packetlen; - if(base>=(WIFI_REG(0x52)&0x1FFE)) base -= ((WIFI_REG(0x52)&0x1FFE)-(WIFI_REG(0x50)&0x1FFE)); - WIFI_REG(0x5A)=base>>1; - - if(cut++>5) break; - } - REG_IME=tIME; -} - -#define CNT_STAT_START WSTAT_HW_1B0 -#define CNT_STAT_NUM 18 -u16 count_ofs_list[CNT_STAT_NUM] = { - 0x1B0, 0x1B2, 0x1B4, 0x1B6, 0x1B8, 0x1BA, 0x1BC, 0x1BE, 0x1C0, 0x1C4, 0x1D0, 0x1D2, 0x1D4, 0x1D6, 0x1D8, 0x1DA, 0x1DC, 0x1DE -}; -void Wifi_Intr_CntOverflow(void) { - int i; - int s,d; - s=CNT_STAT_START; - for(i=0;i<CNT_STAT_NUM;i++) { - d=WIFI_REG(count_ofs_list[i]); - WifiData->stats[s++]+=(d&0xFF); - WifiData->stats[s++]+=((d>>8)&0xFF); - } -} - -void Wifi_Intr_StartTx(void) { - if(WifiData->reqReqFlags&WFLAG_REQ_PROMISC) { // attempt to ensure packet is received - - } -} - -void Wifi_Intr_TxEnd(void) { // assume that we can now tx something new. - if(arm7qlen) { - Wifi_TxRaw(arm7q, arm7qlen); - keepalive_time=0; - arm7qlen=0; - return; - } - if((WifiData->txbufOut!=WifiData->txbufIn) && (!(WifiData->curReqFlags&WFLAG_REQ_APCONNECT) || WifiData->authlevel==WIFI_AUTHLEVEL_ASSOCIATED)) { - if(Wifi_CopyFirstTxData(0)) { - keepalive_time=0; - if(WIFI_REG(0x4008)==0) { WIFI_REG(0x4008)=WifiData->maxrate7; } // if rate dne, fill it in. - if(WIFI_REG(0x400C)&0x4000) { // wep is enabled, fill in the IV. - WIFI_REG(0x4024) = (W_RANDOM ^ (W_RANDOM<<7) ^ (W_RANDOM<<15))&0xFFFF; - WIFI_REG(0x4026) = ((W_RANDOM ^ (W_RANDOM>>7))&0xFF) | (WifiData->wepkeyid7<<14); - } - // WIFI_REG(0xB8)=0x0001; - WIFI_REG(0xA8)=0x8000; - WIFI_REG(0xAE)=0x000D; - } - } -} - -void Wifi_Intr_TBTT(void) { - if(WIFI_REG(0xA8)&0x8000) { - WIFI_REG(0xAE)=0x000D; - } -} - -void Wifi_Intr_DoNothing(void) { -} - - - -void Wifi_Interrupt(void) { - int wIF; - if(!WifiData) return; - if(!(WifiData->flags7&WFLAG_ARM7_RUNNING)) return; - do { - REG_IF=0x01000000; // now that we've cleared the wireless IF, kill the bit in regular IF. - wIF= W_IE & W_IF; - if(wIF& 0x0001) { W_IF=0x0001; Wifi_Intr_RxEnd(); } // 0) Rx End - if(wIF& 0x0002) { W_IF=0x0002; Wifi_Intr_TxEnd(); } // 1) Tx End - if(wIF& 0x0004) { W_IF=0x0004; Wifi_Intr_DoNothing(); } // 2) Rx Cntup - if(wIF& 0x0008) { W_IF=0x0008; Wifi_Intr_DoNothing(); } // 3) Tx Err - if(wIF& 0x0010) { W_IF=0x0010; Wifi_Intr_CntOverflow(); } // 4) Count Overflow - if(wIF& 0x0020) { W_IF=0x0020; Wifi_Intr_CntOverflow(); } // 5) AckCount Overflow - if(wIF& 0x0040) { W_IF=0x0040; Wifi_Intr_DoNothing(); } // 6) Start Rx - if(wIF& 0x0080) { W_IF=0x0080; Wifi_Intr_StartTx(); } // 7) Start Tx - if(wIF& 0x0100) { W_IF=0x0100; Wifi_Intr_DoNothing(); } // 8) - if(wIF& 0x0200) { W_IF=0x0200; Wifi_Intr_DoNothing(); } // 9) - if(wIF& 0x0400) { W_IF=0x0400; Wifi_Intr_DoNothing(); } //10) - if(wIF& 0x0800) { W_IF=0x0800; Wifi_Intr_DoNothing(); } //11) RF Wakeup - if(wIF& 0x1000) { W_IF=0x1000; Wifi_Intr_DoNothing(); } //12) MP End - if(wIF& 0x2000) { W_IF=0x2000; Wifi_Intr_DoNothing(); } //13) ACT End - if(wIF& 0x4000) { W_IF=0x4000; Wifi_Intr_TBTT(); } //14) TBTT - if(wIF& 0x8000) { W_IF=0x8000; Wifi_Intr_DoNothing(); } //15) PreTBTT - wIF= W_IE & W_IF; - } while(wIF); - -} - - - - - - -void Wifi_Update(void) { - int i; - if(!WifiData) return; - WifiData->random ^=(W_RANDOM ^ (W_RANDOM<<11) ^ (W_RANDOM<<22)); - WifiData->stats[WSTAT_ARM7_UPDATES]++; - WifiData->stats[WSTAT_DEBUG]=WIFI_REG(0xA8); - if(WIFI_REG(0xA8)&0x8000) { - WIFI_REG(0xAE)=0x000D; - } - // check flags, to see if we need to change anything - switch(WifiData->curMode) { - case WIFIMODE_DISABLED: - ProxySetLedState(LED_ON); - if(WifiData->reqMode!=WIFIMODE_DISABLED) { - Wifi_Start(); - WifiData->curMode=WIFIMODE_NORMAL; - } - break; - case WIFIMODE_NORMAL: // main switcher function - ProxySetLedState(LED_LONGBLINK); - if(WifiData->reqMode==WIFIMODE_DISABLED) { - Wifi_Stop(); - WifiData->curMode=WIFIMODE_DISABLED; - break; - } - if(WifiData->reqMode==WIFIMODE_SCAN) { - WifiData->counter7=WIFI_REG(0xFA); // timer hword 2 (each tick is 65.5ms) - WifiData->curMode=WIFIMODE_SCAN; - break; - } - if((WifiData->reqReqFlags ^ WifiData->curReqFlags) & WFLAG_REQ_APCONNECT) { - if(WifiData->curReqFlags& WFLAG_REQ_APCONNECT) { // already connected; disconnect - WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT; - } else { // not connected - connect! - if(WifiData->reqReqFlags&WFLAG_REQ_APCOPYVALUES) { - WifiData->wepkeyid7=WifiData->wepkeyid9; - WifiData->wepmode7=WifiData->wepmode9; - WifiData->apchannel7=WifiData->apchannel9; - Wifi_CopyMacAddr(WifiData->bssid7,WifiData->bssid9); - Wifi_CopyMacAddr(WifiData->apmac7,WifiData->apmac9); - for(i=0;i<20;i++) WifiData->wepkey7[i]=WifiData->wepkey9[i]; - for(i=0;i<34;i++) WifiData->ssid7[i]=WifiData->ssid9[i]; - for(i=0;i<16;i++) WifiData->baserates7[i]=WifiData->baserates9[i]; - if(WifiData->reqReqFlags&WFLAG_REQ_APADHOC) WifiData->curReqFlags |= WFLAG_REQ_APADHOC; else WifiData->curReqFlags &= ~WFLAG_REQ_APADHOC; - } - Wifi_SetWepKey((void *)WifiData->wepkey7); - Wifi_SetWepMode(WifiData->wepmode7); - // latch BSSID - W_BSSID[0]= ((u16 *)WifiData->bssid7)[0]; - W_BSSID[1]= ((u16 *)WifiData->bssid7)[1]; - W_BSSID[2]= ((u16 *)WifiData->bssid7)[2]; - //WIFI_REG(0xD0) &= ~0x0400; - WIFI_REG(0xD0) |= 0x0400; - WifiData->reqChannel=WifiData->apchannel7; - Wifi_SetChannel(WifiData->apchannel7); - if(WifiData->curReqFlags&WFLAG_REQ_APADHOC) { - WifiData->authlevel=WIFI_AUTHLEVEL_ASSOCIATED; - } else { - Wifi_SendOpenSystemAuthPacket(); - WifiData->authlevel=WIFI_AUTHLEVEL_DISCONNECTED; - } - WifiData->txbufIn=WifiData->txbufOut; // empty tx buffer. - WifiData->curReqFlags |= WFLAG_REQ_APCONNECT; - WifiData->counter7=WIFI_REG(0xFA); // timer hword 2 (each tick is 65.5ms) - WifiData->curMode=WIFIMODE_ASSOCIATE; - WifiData->authctr=0; - } - } - break; - case WIFIMODE_SCAN: - ProxySetLedState(LED_LONGBLINK); - if(WifiData->reqMode!=WIFIMODE_SCAN) { - WifiData->curMode=WIFIMODE_NORMAL; - break; - } - if(((u16)(WIFI_REG(0xFA)-WifiData->counter7))>6) { // jump ship! - WifiData->counter7=WIFI_REG(0xFA); - WifiData->reqChannel++; - { - int i; - for(i=0;i<WIFI_MAX_AP;i++) { - if(WifiData->aplist[i].flags & WFLAG_APDATA_ACTIVE) { - WifiData->aplist[i].timectr++; - if(WifiData->aplist[i].timectr>WIFI_AP_TIMEOUT) { - WifiData->aplist[i].rssi=0; - WifiData->aplist[i].rssi_past[0]=WifiData->aplist[i].rssi_past[1]= - WifiData->aplist[i].rssi_past[2]=WifiData->aplist[i].rssi_past[3]= - WifiData->aplist[i].rssi_past[4]=WifiData->aplist[i].rssi_past[5]= - WifiData->aplist[i].rssi_past[6]=WifiData->aplist[i].rssi_past[7]=0; // update rssi later. - } - } - } - } - if(WifiData->reqChannel==14) WifiData->reqChannel=1; - } - break; - case WIFIMODE_ASSOCIATE: - ProxySetLedState(LED_LONGBLINK); - if(WifiData->authlevel==WIFI_AUTHLEVEL_ASSOCIATED) { - WifiData->curMode=WIFIMODE_ASSOCIATED; - break; - } - if(((u16)(WIFI_REG(0xFA)-WifiData->counter7))>20) { // ~1 second, reattempt connect stage - WifiData->counter7=WIFI_REG(0xFA); - WifiData->authctr++; - if(WifiData->authctr>WIFI_MAX_ASSOC_RETRY) { - WifiData->curMode=WIFIMODE_CANNOTASSOCIATE; - break; - } - switch(WifiData->authlevel) { - case WIFI_AUTHLEVEL_DISCONNECTED: // send auth packet - if(!(WifiData->curReqFlags&WFLAG_REQ_APADHOC)) { - Wifi_SendOpenSystemAuthPacket(); - break; - } - WifiData->authlevel=WIFI_AUTHLEVEL_ASSOCIATED; - break; - case WIFI_AUTHLEVEL_DEASSOCIATED: - case WIFI_AUTHLEVEL_AUTHENTICATED: // send assoc packet - Wifi_SendAssocPacket(); - break; - case WIFI_AUTHLEVEL_ASSOCIATED: - WifiData->curMode=WIFIMODE_ASSOCIATED; - break; - } - } - if(!(WifiData->reqReqFlags & WFLAG_REQ_APCONNECT)) { - WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT; - WifiData->curMode=WIFIMODE_NORMAL; - break; - } - break; - case WIFIMODE_ASSOCIATED: - ProxySetLedState(LED_SHORTBLINK); - keepalive_time++; - if(keepalive_time>WIFI_KEEPALIVE_COUNT) { - keepalive_time=0; - Wifi_SendNullFrame(); - } - if((u16)(WIFI_REG(0xFA)-WifiData->pspoll_period)>WIFI_PS_POLL_CONST) { - WifiData->pspoll_period=WIFI_REG(0xFA); - // Wifi_SendPSPollFrame(); - } - if(!(WifiData->reqReqFlags & WFLAG_REQ_APCONNECT)) { - W_BSSID[0]= ((u16 *)WifiData->bssid7)[0]; - W_BSSID[1]= ((u16 *)WifiData->bssid7)[1]; - W_BSSID[2]= ((u16 *)WifiData->bssid7)[2]; - //WIFI_REG(0xD0) &= ~0x0400; - WifiData->curMode=WIFIMODE_NORMAL; - WifiData->authlevel=WIFI_AUTHLEVEL_DISCONNECTED; - if(WifiData->curReqFlags &WFLAG_REQ_APCONNECT) { // deassociate, then return - WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT; - } else { // not connected for some reason, return. - WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT; - WifiData->curMode=WIFIMODE_ASSOCIATE; - } - break; - } - if(WifiData->authlevel!=WIFI_AUTHLEVEL_ASSOCIATED) { - WifiData->curMode=WIFIMODE_ASSOCIATE; - break; - } - break; - case WIFIMODE_CANNOTASSOCIATE: - ProxySetLedState(LED_LONGBLINK); - if(!(WifiData->reqReqFlags & WFLAG_REQ_APCONNECT)) { - WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT; - WifiData->curMode=WIFIMODE_NORMAL; - break; - } - break; - - - } - if(WifiData->curChannel!=WifiData->reqChannel) { - Wifi_SetChannel(WifiData->reqChannel); - } - // check Rx - Wifi_Intr_RxEnd(); - // check if we need to tx anything - if(Wifi_TxCheck()) Wifi_Intr_TxEnd(); // easiest way to do so at the moment. -} - - - - -////////////////////////////////////////////////////////////////////////// -// -// Wifi User-called Functions -// -void erasemem(void * mem, int length) { - int i; - char * m = (char *)mem; - for(i=0;i<length;i++) - m[i]=0; -} - - -void Wifi_Init(u32 wifidata) { - WifiData = (Wifi_MainStruct *)wifidata; - - POWERCNT7 |= 2; // enable power for the wifi - *((volatile u16 *)0x04000206) = 0x30; // ??? - - InitFlashData(); - - // reset/shutdown wifi: - WIFI_REG(0x4)=0xffff; - Wifi_Stop(); - Wifi_Shutdown(); // power off wifi - - WifiData->curChannel=1; - WifiData->reqChannel=1; - WifiData->curMode=WIFIMODE_DISABLED; - WifiData->reqMode=WIFIMODE_DISABLED; - WifiData->reqPacketFlags=WFLAG_PACKET_ALL & (~WFLAG_PACKET_BEACON); - WifiData->curReqFlags=0; - WifiData->reqReqFlags=0; - WifiData->maxrate7=0x0A; - - int i; - for(i=0x4000;i<0x6000;i+=2) WIFI_REG(i)=0; - - - // load in the WFC data. - GetWfcSettings(); - - for(i=0;i<6;i++) WifiData->MacAddr[i]=ReadFlashByte(0x36+i); - - W_IE=0; - Wifi_WakeUp(); - - Wifi_MacInit(); - Wifi_RFInit(); - Wifi_BBInit(); - - // Set Default Settings - W_MACADDR[0]=((u16 *)WifiData->MacAddr)[0]; - W_MACADDR[1]=((u16 *)WifiData->MacAddr)[1]; - W_MACADDR[2]=((u16 *)WifiData->MacAddr)[2]; - - W_RETRLIMIT=7; - Wifi_SetMode(2); - Wifi_SetWepMode(WEPMODE_NONE); - - - Wifi_SetChannel(1); - - Wifi_BBWrite(0x13, 0x00); - Wifi_BBWrite(0x35, 0x1F); - -// Wifi_Shutdown(); - WifiData->random ^=(W_RANDOM ^ (W_RANDOM<<11) ^ (W_RANDOM<<22)); - - WifiData->flags7 |= WFLAG_ARM7_ACTIVE; -} - -void Wifi_Deinit() { - Wifi_Stop(); - POWERCNT7 &= ~2; -} - -void Wifi_Start() { - int i, tIME; - tIME=REG_IME; - REG_IME=0; - Wifi_Stop(); - -// Wifi_WakeUp(); - - WIFI_REG(0x8032) = 0x8000; - WIFI_REG(0x8134) = 0xFFFF; - WIFI_REG(0x802A) = 0; - W_AIDS = 0; - WIFI_REG(0x80E8) = 1; - WIFI_REG(0x8038) = 0x0000; - WIFI_REG(0x20) = 0x0000; - WIFI_REG(0x22) = 0x0000; - WIFI_REG(0x24) = 0x0000; - - Wifi_TxSetup(); - Wifi_RxSetup(); - - WIFI_REG(0x8030) = 0x8000; -/* - switch(WIFI_REG(0x8006)&7) { - case 0: // infrastructure mode? - W_IF=0xFFFF; - W_IE=0x003F; - WIFI_REG(0x81AE)=0x1fff; - //WIFI_REG(0x81AA)=0x0400; - WIFI_REG(0x80D0)=0xffff; - WIFI_REG(0x80E0)=0x0008; - WIFI_REG(0x8008)=0; - WIFI_REG(0x800A)=0; - WIFI_REG(0x80E8)=0; - WIFI_REG(0x8004)=1; - //SetStaState(0x40); - break; - case 1: // ad-hoc mode? -- beacons are required to be created! - W_IF=0xFFF; - W_IE=0x703F; - WIFI_REG(0x81AE)=0x1fff; - WIFI_REG(0x81AA)=0; // 0x400 - WIFI_REG(0x80D0)=0x0301; - WIFI_REG(0x80E0)=0x000D; - WIFI_REG(0x8008)=0xE000; - WIFI_REG(0x800A)=0; - WIFI_REG(0x8004)=1; - //?? - WIFI_REG(0x80EA)=1; - WIFI_REG(0x80AE)=2; - break; - case 2: // DS comms mode? - */ - W_IF=0xFFFF; - //W_IE=0xE03F; - W_IE=0x40B3; - WIFI_REG(0x81AE)=0x1fff; - WIFI_REG(0x81AA)=0; //0x68 - W_BSSID[0]=0xFFFF; - W_BSSID[1]=0xFFFF; - W_BSSID[2]=0xFFFF; - WIFI_REG(0x80D0)=0x0181; // 0x181 - WIFI_REG(0x80E0)=0x000B; - WIFI_REG(0x8008)=0; - WIFI_REG(0x800A)=0; - WIFI_REG(0x8004)=1; - WIFI_REG(0x80E8)=1; - WIFI_REG(0x80EA)=1; - //SetStaState(0x20); - /* - break; - case 3: - case 4: - break; - } - */ - - WIFI_REG(0x8048)=0x0000; - Wifi_DisableTempPowerSave(); - //WIFI_REG(0x80AE)=0x0002; - W_POWERSTATE |= 2; - WIFI_REG(0xAC) = 0xFFFF; - i=0xFA0; - while(i!=0 && !(WIFI_REG(0x819C)&0x80)) i--; - WifiData->flags7 |=WFLAG_ARM7_RUNNING; - REG_IME=tIME; -} - -void Wifi_Stop() { - int tIME; - tIME=REG_IME; - WifiData->flags7 &= ~WFLAG_ARM7_RUNNING; - W_IE=0; - WIFI_REG(0x8004) = 0; - WIFI_REG(0x80EA) = 0; - WIFI_REG(0x80E8) = 0; - WIFI_REG(0x8008) = 0; - WIFI_REG(0x800A) = 0; - - WIFI_REG(0x80AC) = 0xFFFF; - WIFI_REG(0x80B4) = 0xFFFF; -// Wifi_Shutdown(); - REG_IME=tIME; -} - -void Wifi_SetChannel(int channel) { - int i,n,l; - if(channel<1 || channel>13) return; - channel-=1; - - switch(ReadFlashByte(0x40)) { - case 2: - case 5: - Wifi_RFWrite(ReadFlashBytes(0xf2+channel*6,3)); - Wifi_RFWrite(ReadFlashBytes(0xf5+channel*6,3)); - - swiDelay( 12583 ); // 1500 us delay - - if(chdata_save5 & 0x10000) - { - if(chdata_save5 & 0x8000) break; - n = ReadFlashByte(0x154+channel); - Wifi_RFWrite( chdata_save5 | ((n&0x1F)<<10) ); - } else { - Wifi_BBWrite(0x1E, ReadFlashByte(0x146+channel)); - } - - break; - case 3: - n=ReadFlashByte(0x42); - n+=0xCF; - l=ReadFlashByte(n-1); - for(i=0;i<l;i++) { - Wifi_BBWrite(ReadFlashByte(n),ReadFlashByte(n+channel+1)); - n+=15; - } - for(i=0;i<ReadFlashByte(0x43);i++) { - Wifi_RFWrite( (ReadFlashByte(n)<<8) | ReadFlashByte(n+channel+1) | 0x050000 ); - n+=15; - } - - swiDelay( 12583 ); // 1500 us delay - - break; - default: - break; - } - WifiData->curChannel=channel+1; -} -void Wifi_SetWepKey(void * wepkey) { - int i; - for(i=0;i<16;i++) { - W_WEPKEY0[i]=((u16 *)wepkey)[i]; - W_WEPKEY1[i]=((u16 *)wepkey)[i]; - W_WEPKEY2[i]=((u16 *)wepkey)[i]; - W_WEPKEY3[i]=((u16 *)wepkey)[i]; - } -} - -void Wifi_SetWepMode(int wepmode) { - if(wepmode<0 || wepmode>7) return; - if(wepmode==0) { - WIFI_REG(0x32)=0x0000; - } else { - WIFI_REG(0x32)=0x8000; - } - if(wepmode==0) wepmode=1; - W_MODE_WEP = (W_MODE_WEP & 0xFFC7) | (wepmode<<3); -} - -void Wifi_SetBeaconPeriod(int beacon_period) { - if(beacon_period<0x10 || beacon_period>0x3E7) return; - WIFI_REG(0x8C)=beacon_period; -} - -void Wifi_SetMode(int wifimode) { - if(wifimode>3 || wifimode<0) return; - W_MODE_WEP = (W_MODE_WEP& 0xfff8) | wifimode; -} -void Wifi_SetPreambleType(int preamble_type) { - if(preamble_type>1 || preamble_type<0) return; - WIFI_REG(0x80BC) = (WIFI_REG(0x80BC) & 0xFFBF) | (preamble_type<<6); -} -void Wifi_DisableTempPowerSave() { - WIFI_REG(0x8038) &= ~2; - WIFI_REG(0x8048) = 0; -} - - - - - -////////////////////////////////////////////////////////////////////////// -// -// 802.11b system, tied in a bit with the : - - -int Wifi_TxQueue(u16 * data, int datalen) { - int i,j; - if(arm7qlen) { - if(Wifi_TxCheck()) { - Wifi_TxRaw(arm7q,arm7qlen); - arm7qlen=0; - j=(datalen+1)>>1; - if(j>1024) return 0; - for(i=0;i<j;i++) arm7q[i]=data[i]; - arm7qlen=datalen; - return 1; - } - return 0; - } - if(Wifi_TxCheck()) { - Wifi_TxRaw(data,datalen); - return 1; - } - arm7qlen=0; - j=(datalen+1)>>1; - if(j>1024) return 0; - for(i=0;i<j;i++) arm7q[i]=data[i]; - arm7qlen=datalen; - return 1; -} - -int Wifi_GenMgtHeader(u8 * data, u16 headerflags) { - // tx header - ((u16 *)data)[0]=0; - ((u16 *)data)[1]=0; - ((u16 *)data)[2]=0; - ((u16 *)data)[3]=0; - ((u16 *)data)[4]=0; - ((u16 *)data)[5]=0; - // fill in most header fields - ((u16 *)data)[7]=0x0000; - Wifi_CopyMacAddr(data+16,WifiData->apmac7); - Wifi_CopyMacAddr(data+22,WifiData->MacAddr); - Wifi_CopyMacAddr(data+28,WifiData->bssid7); - ((u16 *)data)[17]=0; - - // fill in wep-specific stuff - if(headerflags&0x4000) { - ((u32 *)data)[9]=((W_RANDOM ^ (W_RANDOM<<7) ^ (W_RANDOM<<15))&0x0FFF) | (WifiData->wepkeyid7<<30); // I'm lazy and certainly haven't done this to spec. - ((u16 *)data)[6]=headerflags; - return 28+12; - } else { - ((u16 *)data)[6]=headerflags; - return 24+12; - } -} - -int Wifi_SendOpenSystemAuthPacket() { - // max size is 12+24+4+6 = 46 - u8 data[64]; - int i; - i=Wifi_GenMgtHeader(data,0x00B0); - - ((u16 *)(data+i))[0]=0; // Authentication algorithm number (0=open system) - ((u16 *)(data+i))[1]=1; // Authentication sequence number - ((u16 *)(data+i))[2]=0; // Authentication status code (reserved for this message, =0) - - ((u16 *)data)[4]=0x000A; - ((u16 *)data)[5]=i+6-12+4; - - return Wifi_TxQueue((u16 *)data, i+6); -} - -int Wifi_SendSharedKeyAuthPacket(void) { - // max size is 12+24+4+6 = 46 - u8 data[64]; - int i; - i=Wifi_GenMgtHeader(data,0x00B0); - - ((u16 *)(data+i))[0]=1; // Authentication algorithm number (1=shared key) - ((u16 *)(data+i))[1]=1; // Authentication sequence number - ((u16 *)(data+i))[2]=0; // Authentication status code (reserved for this message, =0) - - ((u16 *)data)[4]=0x000A; - ((u16 *)data)[5]=i+6-12+4; - - return Wifi_TxQueue((u16 *)data, i+6); -} - -int Wifi_SendSharedKeyAuthPacket2(int challenge_length, u8 * challenge_Text) { - // max size is 12+24+4+6 = 46 - u8 data[320]; - int i,j; - i=Wifi_GenMgtHeader(data,0x40B0); - - ((u16 *)(data+i))[0]=1; // Authentication algorithm number (1=shared key) - ((u16 *)(data+i))[1]=3; // Authentication sequence number - ((u16 *)(data+i))[2]=0; // Authentication status code (reserved for this message, =0) - - data[i+6]=0x10; // 16=challenge text block - data[i+7]=challenge_length; - - for(j=0;j<challenge_length;j++) { - data[i+j+8]=challenge_Text[j]; - } - - ((u16 *)data)[4]=0x000A; - ((u16 *)data)[5]=i+8+challenge_length-12+4 +4; - - return Wifi_TxQueue((u16 *)data, i+8+challenge_length); -} - - -int Wifi_SendAssocPacket() { // uses arm7 data in our struct - // max size is 12+24+4+34+4 = 66 - u8 data[96]; - int i,j,numrates; - - i=Wifi_GenMgtHeader(data,0x0000); - - if(WifiData->wepmode7) { - ((u16 *)(data+i))[0]=0x0031; // CAPS info - } else { - ((u16 *)(data+i))[0]=0x0021; // CAPS info - } - - ((u16 *)(data+i))[1]=WIFI_REG(0x8E); // Listen interval - i+=4; - data[i++]=0; // SSID element - data[i++]=WifiData->ssid7[0]; - for(j=0;j<WifiData->ssid7[0];j++) data[i++]=WifiData->ssid7[1+j]; - - if((WifiData->baserates7[0]&0x7f)!=2) { - for(j=1;j<16;j++) WifiData->baserates7[i]=WifiData->baserates7[j-1]; - } - WifiData->baserates7[0]=0x82; - if((WifiData->baserates7[1]&0x7f)!=4) { - for(j=2;j<16;j++) WifiData->baserates7[j]=WifiData->baserates7[j-1]; - } - WifiData->baserates7[1]=0x04; - - WifiData->baserates7[15]=0; - for(j=0;j<16;j++) if(WifiData->baserates7[j]==0) break; - numrates=j; - for(j=2;j<numrates;j++) WifiData->baserates7[j] &= 0x7F; - - data[i++]=1; // rate set - data[i++]=numrates; - for(j=0;j<numrates;j++) data[i++]=WifiData->baserates7[j]; - - // reset header fields with needed data - ((u16 *)data)[4]=0x000A; - ((u16 *)data)[5]=i-12+4; - - return Wifi_TxQueue((u16 *)data, i); -} - -int Wifi_SendNullFrame() { - // max size is 12+16 = 28 - u8 data[32]; - // tx header - ((u16 *)data)[0]=0; - ((u16 *)data)[1]=0; - ((u16 *)data)[2]=0; - ((u16 *)data)[3]=0; - ((u16 *)data)[4]=WifiData->maxrate7; - ((u16 *)data)[5]=18+4; - // fill in packet header fields - ((u16 *)data)[6]=0x0148; - ((u16 *)data)[7]=0; - Wifi_CopyMacAddr(data+16,WifiData->apmac7); - Wifi_CopyMacAddr(data+22,WifiData->MacAddr); - - return Wifi_TxQueue((u16 *)data, 30); -} - -int Wifi_SendPSPollFrame() { - // max size is 12+16 = 28 - u8 data[32]; - // tx header - ((u16 *)data)[0]=0; - ((u16 *)data)[1]=0; - ((u16 *)data)[2]=0; - ((u16 *)data)[3]=0; - ((u16 *)data)[4]=WifiData->maxrate7; - ((u16 *)data)[5]=16+4; - // fill in packet header fields - ((u16 *)data)[6]=0x01A4; - ((u16 *)data)[7]=0xC000 | W_AIDS; - Wifi_CopyMacAddr(data+16,WifiData->apmac7); - Wifi_CopyMacAddr(data+22,WifiData->MacAddr); - - return Wifi_TxQueue((u16 *)data, 28); -} - -int Wifi_ProcessReceivedFrame(int macbase, int framelen) { - Wifi_RxHeader packetheader; - u16 control_802; - Wifi_MACCopy((u16 *)&packetheader,macbase,0,12); - control_802=Wifi_MACRead(macbase,12); - switch((control_802>>2)&0x3F) { - // Management Frames - case 0x20: // 1000 00 Beacon - case 0x14: // 0101 00 Probe Response // process probe responses too. - // mine data from the beacon... - { - u8 data[512]; - u8 wepmode,fromsta; - u8 segtype,seglen; - u8 channel; - u8 wpamode; - u8 rateset[16]; - u16 ptr_ssid; - u16 maxrate; - u16 curloc; - u32 datalen; - u16 i,j,compatible; - datalen=packetheader.byteLength; - if(datalen>512) datalen=512; - Wifi_MACCopy((u16 *)data,macbase,12,(datalen+1)&~1); - wepmode=0; - maxrate=0; - if(((u16 *)data)[5+12]&0x0010) { // capability info, WEP bit - wepmode=1; - } - fromsta=Wifi_CmpMacAddr(data+10, data+16); - curloc=12+24; // 12 fixed bytes, 24 802.11 header - compatible=1; - ptr_ssid=0; - channel=WifiData->curChannel; - wpamode=0; - do { - if(curloc>=datalen) break; - segtype=data[curloc++]; - seglen=data[curloc++]; - switch(segtype) { - case 0: // SSID element - ptr_ssid=curloc-2; - break; - case 1: // rate set (make sure we're compatible) - compatible=0; - maxrate=0; - j=0; - for(i=0;i<seglen;i++) { - if((data[curloc+i]&0x7F)>maxrate) maxrate=data[curloc+i]&0x7F; - if(j<15 && data[curloc+i]&0x80) rateset[j++]=data[curloc+i]; - } - for(i=0;i<seglen;i++) { - if(data[curloc+i]==0x82 || data[curloc+i]==0x84) compatible=1; // 1-2mbit, fully compatible - else if(data[curloc+i]==0x8B || data[curloc+i]==0x96) compatible=2; // 5.5,11mbit, have to fake our way in. - else if(data[curloc+i]&0x80) { compatible=0; break; } - } - rateset[j]=0; - break; - case 3: // DS set (current channel) - channel=data[curloc]; - break; - case 48: // RSN(A) field- WPA enabled. - wpamode=1; - break; - - } // don't care about the others. - curloc+=seglen; - } while(curloc<datalen); - if(wpamode==1) compatible=0; - if(1) { - seglen=0; - segtype=255; - for(i=0;i<WIFI_MAX_AP;i++) { - if( Wifi_CmpMacAddr(WifiData->aplist[i].bssid,data+16)) { - seglen++; - if(Spinlock_Acquire(WifiData->aplist[i])==SPINLOCK_OK) { - WifiData->aplist[i].timectr=0; - WifiData->aplist[i].flags=WFLAG_APDATA_ACTIVE | (wepmode?WFLAG_APDATA_WEP:0) | (fromsta?0:WFLAG_APDATA_ADHOC); - if(compatible==1) WifiData->aplist[i].flags |= WFLAG_APDATA_COMPATIBLE; - if(compatible==2) WifiData->aplist[i].flags |= WFLAG_APDATA_EXTCOMPATIBLE; - if(wpamode==1) WifiData->aplist[i].flags |= WFLAG_APDATA_WPA; - WifiData->aplist[i].maxrate=maxrate; - - Wifi_CopyMacAddr(WifiData->aplist[i].macaddr,data+10); // src: +10 - if(ptr_ssid) { - WifiData->aplist[i].ssid_len=data[ptr_ssid+1]; - if(WifiData->aplist[i].ssid_len>32) WifiData->aplist[i].ssid_len=32; - for(j=0;j<WifiData->aplist[i].ssid_len;j++) { - WifiData->aplist[i].ssid[j]=data[ptr_ssid+2+j]; - } - WifiData->aplist[i].ssid[j]=0; - } - if(WifiData->curChannel==channel) { // only use RSSI when we're on the right channel - if(WifiData->aplist[i].rssi_past[0]==0) { // min rssi is 2, heh. - WifiData->aplist[i].rssi_past[0]=WifiData->aplist[i].rssi_past[1]= - WifiData->aplist[i].rssi_past[2]=WifiData->aplist[i].rssi_past[3]= - WifiData->aplist[i].rssi_past[4]=WifiData->aplist[i].rssi_past[5]= - WifiData->aplist[i].rssi_past[6]=WifiData->aplist[i].rssi_past[7]=packetheader.rssi_&255; - } else { - for(j=0;j<7;j++) { - WifiData->aplist[i].rssi_past[j]=WifiData->aplist[i].rssi_past[j+1]; - } - WifiData->aplist[i].rssi_past[7]=packetheader.rssi_&255; - } - } - WifiData->aplist[i].channel=channel; - for(j=0;j<16;j++) WifiData->aplist[i].base_rates[j]=rateset[j]; - Spinlock_Release(WifiData->aplist[i]); - } else { - // couldn't update beacon - oh well :\ there'll be other beacons. - } - } else { - if(WifiData->aplist[i].flags & WFLAG_APDATA_ACTIVE) { - // WifiData->aplist[i].timectr++; - } else { - if(segtype==255) segtype=i; - } - } - } - if(seglen==0) { // we couldn't find an existing record - if(segtype==255) { - j=0; - for(i=0;i<WIFI_MAX_AP;i++) { - if(WifiData->aplist[i].timectr>j) { - j=WifiData->aplist[i].timectr; - segtype=i; - } - } - } - // stuff new data in - i=segtype; - if(Spinlock_Acquire(WifiData->aplist[i])==SPINLOCK_OK) { - Wifi_CopyMacAddr(WifiData->aplist[i].bssid,data+16); // bssid: +16 - Wifi_CopyMacAddr(WifiData->aplist[i].macaddr,data+10); // src: +10 - WifiData->aplist[i].timectr=0; - WifiData->aplist[i].flags=WFLAG_APDATA_ACTIVE | (wepmode?WFLAG_APDATA_WEP:0) | (fromsta?0:WFLAG_APDATA_ADHOC); - if(compatible==1) WifiData->aplist[i].flags |= WFLAG_APDATA_COMPATIBLE; - if(compatible==2) WifiData->aplist[i].flags |= WFLAG_APDATA_EXTCOMPATIBLE; - if(wpamode==1) WifiData->aplist[i].flags |= WFLAG_APDATA_WPA; - WifiData->aplist[i].maxrate=maxrate; - - if(ptr_ssid) { - WifiData->aplist[i].ssid_len=data[ptr_ssid+1]; - if(WifiData->aplist[i].ssid_len>32) WifiData->aplist[i].ssid_len=32; - for(j=0;j<WifiData->aplist[i].ssid_len;j++) { - WifiData->aplist[i].ssid[j]=data[ptr_ssid+2+j]; - } - WifiData->aplist[i].ssid[j]=0; - } - if(WifiData->curChannel==channel) { // only use RSSI when we're on the right channel - WifiData->aplist[i].rssi_past[0]=WifiData->aplist[i].rssi_past[1]= - WifiData->aplist[i].rssi_past[2]=WifiData->aplist[i].rssi_past[3]= - WifiData->aplist[i].rssi_past[4]=WifiData->aplist[i].rssi_past[5]= - WifiData->aplist[i].rssi_past[6]=WifiData->aplist[i].rssi_past[7]=packetheader.rssi_&255; - } else { - WifiData->aplist[i].rssi_past[0]=WifiData->aplist[i].rssi_past[1]= - WifiData->aplist[i].rssi_past[2]=WifiData->aplist[i].rssi_past[3]= - WifiData->aplist[i].rssi_past[4]=WifiData->aplist[i].rssi_past[5]= - WifiData->aplist[i].rssi_past[6]=WifiData->aplist[i].rssi_past[7]=0; // update rssi later. - } - WifiData->aplist[i].channel=channel; - for(j=0;j<16;j++) WifiData->aplist[i].base_rates[j]=rateset[j]; - - Spinlock_Release(WifiData->aplist[i]); - } else { - // couldn't update beacon - oh well :\ there'll be other beacons. - } - } - } - } - if(((control_802>>2)&0x3F)==0x14) return WFLAG_PACKET_MGT; - return WFLAG_PACKET_BEACON; - case 0x04: // 0001 00 Assoc Response - case 0x0C: // 0011 00 Reassoc Response - // we might have been associated, let's check. - { - int datalen,i; - u8 data[64]; - datalen=packetheader.byteLength; - if(datalen>64) datalen=64; - Wifi_MACCopy((u16 *)data,macbase,12,(datalen+1)&~1); - - if(Wifi_CmpMacAddr(data+4,WifiData->MacAddr)) { // packet is indeed sent to us. - if(Wifi_CmpMacAddr(data+16,WifiData->bssid7)) { // packet is indeed from the base station we're trying to associate to. - if(((u16 *)(data+24))[1]==0) { // status code, 0==success - W_AIDS=((u16 *)(data+24))[2]; - WIFI_REG(0x2A)=((u16 *)(data+24))[2]; - // set max rate - WifiData->maxrate7=0xA; - for(i=0;i<((u8 *)(data+24))[7];i++) { - if(((u8 *)(data+24))[8+i]==0x84 || ((u8 *)(data+24))[8+i]==0x04) { - WifiData->maxrate7=0x14; - } - } - if(WifiData->authlevel==WIFI_AUTHLEVEL_AUTHENTICATED || WifiData->authlevel==WIFI_AUTHLEVEL_DEASSOCIATED) { - WifiData->authlevel=WIFI_AUTHLEVEL_ASSOCIATED; - WifiData->authctr=0; - - - - } - } else { // status code = failure! - WifiData->curMode=WIFIMODE_CANNOTASSOCIATE; - } - } - } - } - - - return WFLAG_PACKET_MGT; - case 0x00: // 0000 00 Assoc Request - case 0x08: // 0010 00 Reassoc Request - case 0x10: // 0100 00 Probe Request - case 0x24: // 1001 00 ATIM - case 0x28: // 1010 00 Disassociation - return WFLAG_PACKET_MGT; - case 0x2C: // 1011 00 Authentication - // check auth response to ensure we're in - { - int datalen; - u8 data[384]; - datalen=packetheader.byteLength; - if(datalen>384) datalen=384; - Wifi_MACCopy((u16 *)data,macbase,12,(datalen+1)&~1); - - if(Wifi_CmpMacAddr(data+4,WifiData->MacAddr)) { // packet is indeed sent to us. - if(Wifi_CmpMacAddr(data+16,WifiData->bssid7)) { // packet is indeed from the base station we're trying to associate to. - if(((u16 *)(data+24))[0]==0) { // open system auth - if(((u16 *)(data+24))[1]==2) { // seq 2, should be final sequence - if(((u16 *)(data+24))[2]==0) { // status code: successful - if(WifiData->authlevel==WIFI_AUTHLEVEL_DISCONNECTED) { - WifiData->authlevel=WIFI_AUTHLEVEL_AUTHENTICATED; - WifiData->authctr=0; - Wifi_SendAssocPacket(); - } - } else { // status code: rejected, try something else - Wifi_SendSharedKeyAuthPacket(); - } - } - } else if(((u16 *)(data+24))[0]==1) { // shared key auth - if(((u16 *)(data+24))[1]==2) { // seq 2, challenge text - if(((u16 *)(data+24))[2]==0) { // status code: successful - // scrape challenge text and send challenge reply - if(data[24+6]==0x10) { // 16 = challenge text - this value must be 0x10 or else! - Wifi_SendSharedKeyAuthPacket2(data[24+7],data+24+8); - } - } else { // rejected, just give up. - WifiData->curMode=WIFIMODE_CANNOTASSOCIATE; - } - } else if(((u16 *)(data+24))[1]==4) { // seq 4, accept/deny - if(((u16 *)(data+24))[2]==0) { // status code: successful - if(WifiData->authlevel==WIFI_AUTHLEVEL_DISCONNECTED) { - WifiData->authlevel=WIFI_AUTHLEVEL_AUTHENTICATED; - WifiData->authctr=0; - Wifi_SendAssocPacket(); - } - } else { // status code: rejected. Cry in the corner. - WifiData->curMode=WIFIMODE_CANNOTASSOCIATE; - } - } - } - } - } - } - return WFLAG_PACKET_MGT; - case 0x30: // 1100 00 Deauthentication - { - int datalen; - u8 data[64]; - datalen=packetheader.byteLength; - if(datalen>64) datalen=64; - Wifi_MACCopy((u16 *)data,macbase,12,(datalen+1)&~1); - - if(Wifi_CmpMacAddr(data+4,WifiData->MacAddr)) { // packet is indeed sent to us. - if(Wifi_CmpMacAddr(data+16,WifiData->bssid7)) { // packet is indeed from the base station we're trying to associate to. - // bad things! they booted us!. - // back to square 1. - if(WifiData->curReqFlags&WFLAG_REQ_APADHOC){ - WifiData->authlevel=WIFI_AUTHLEVEL_AUTHENTICATED; - Wifi_SendAssocPacket(); - } else { - WifiData->authlevel=WIFI_AUTHLEVEL_DISCONNECTED; - Wifi_SendOpenSystemAuthPacket(); - } - } - } - } - return WFLAG_PACKET_MGT; - // Control Frames - case 0x29: // 1010 01 PowerSave Poll - case 0x2D: // 1011 01 RTS - case 0x31: // 1100 01 CTS - case 0x35: // 1101 01 ACK - case 0x39: // 1110 01 CF-End - case 0x3D: // 1111 01 CF-End+CF-Ack - return WFLAG_PACKET_CTRL; - // Data Frames - case 0x02: // 0000 10 Data - case 0x06: // 0001 10 Data + CF-Ack - case 0x0A: // 0010 10 Data + CF-Poll - case 0x0E: // 0011 10 Data + CF-Ack + CF-Poll - // We like data! - - return WFLAG_PACKET_DATA; - case 0x12: // 0100 10 Null Function - case 0x16: // 0101 10 CF-Ack - case 0x1A: // 0110 10 CF-Poll - case 0x1E: // 0111 10 CF-Ack + CF-Poll - return WFLAG_PACKET_DATA; - default: // ignore! - return 0; - } -} -int Wifi_CreateTxFrame(int frametype, void * dest, int destlen) { - switch(frametype) { - - default: - return 0; - } -} - -////////////////////////////////////////////////////////////////////////// -// sync functions - -void Wifi_Sync() { - Wifi_Update(); -} -void Wifi_SetSyncHandler(WifiSyncHandler sh) { - synchandler=sh; -} - - |