source: rtems/c/src/lib/libbsp/arm/nds/dswifi/arm7/source/wifi_arm7.c @ 311dfa6

4.104.114.95
Last change on this file since 311dfa6 was 311dfa6, checked in by Joel Sherrill <joel.sherrill@…>, on 04/16/08 at 18:37:33

2008-04-16 Matthieu Bucchianeri <mbucchia@…>

  • ChangeLog?, Makefile.am, README, bsp_specs, configure.ac, mk_libnds.sh, patch.libnds, preinstall.am, block/block.c, clock/clock.c, console/console.c, coproc/coproc.S, coproc/coproc.c, coproc/coproc.ld, dswifi/dswifi_license.txt, dswifi/makefile, dswifi/arm7/makefile, dswifi/arm7/source/wifi_arm7.c, dswifi/arm7/source/wifi_arm7.h, dswifi/arm9/makefile, dswifi/arm9/source/sgIP.c, dswifi/arm9/source/sgIP.h, dswifi/arm9/source/sgIP_ARP.c, dswifi/arm9/source/sgIP_ARP.h, dswifi/arm9/source/sgIP_Config.h, dswifi/arm9/source/sgIP_DHCP.c, dswifi/arm9/source/sgIP_DHCP.h, dswifi/arm9/source/sgIP_DNS.c, dswifi/arm9/source/sgIP_DNS.h, dswifi/arm9/source/sgIP_Hub.c, dswifi/arm9/source/sgIP_Hub.h, dswifi/arm9/source/sgIP_ICMP.c, dswifi/arm9/source/sgIP_ICMP.h, dswifi/arm9/source/sgIP_IP.c, dswifi/arm9/source/sgIP_IP.h, dswifi/arm9/source/sgIP_TCP.c, dswifi/arm9/source/sgIP_TCP.h, dswifi/arm9/source/sgIP_UDP.c, dswifi/arm9/source/sgIP_UDP.h, dswifi/arm9/source/sgIP_memblock.c, dswifi/arm9/source/sgIP_memblock.h, dswifi/arm9/source/sgIP_sockets.c, dswifi/arm9/source/sgIP_sockets.h, dswifi/arm9/source/wifi_arm9.c, dswifi/arm9/source/wifi_arm9.h, dswifi/common/source/dsregs.h, dswifi/common/source/spinlock.h, dswifi/common/source/spinlock.s, dswifi/common/source/wifi_shared.h, dswifi/include/dswifi7.h, dswifi/include/dswifi9.h, dswifi/include/dswifi_version.h, dswifi/include/netdb.h, dswifi/include/sgIP_errno.h, dswifi/include/netinet/in.h, fb/fb.c, fb/fb.h, include/bsp.h, include/my_ipc.h, include/tm27.h, include/types.h, include/sys/iosupport.h, irq/irq.c, irq/irq.h, libfat/gba/include/fat.h, libfat/include/fat.h, libfat/nds/include/fat.h, libfat/source/bit_ops.h, libfat/source/cache.c, libfat/source/cache.h, libfat/source/common.h, libfat/source/directory.c, libfat/source/directory.h, libfat/source/fatdir.c, libfat/source/fatdir.h, libfat/source/fatfile.c, libfat/source/fatfile.h, libfat/source/file_allocation_table.c, libfat/source/file_allocation_table.h, libfat/source/filetime.c, libfat/source/filetime.h, libfat/source/libfat.c, libfat/source/mem_allocate.h, libfat/source/partition.c, libfat/source/partition.h, libfat/source/disc_io/disc.c, libfat/source/disc_io/disc.h, libfat/source/disc_io/disc_io.h, libfat/source/disc_io/io_cf_common.c, libfat/source/disc_io/io_cf_common.h, libfat/source/disc_io/io_dldi.h, libfat/source/disc_io/io_dldi.s, libfat/source/disc_io/io_efa2.c, libfat/source/disc_io/io_efa2.h, libfat/source/disc_io/io_fcsr.c, libfat/source/disc_io/io_fcsr.h, libfat/source/disc_io/io_m3_common.c, libfat/source/disc_io/io_m3_common.h, libfat/source/disc_io/io_m3cf.c, libfat/source/disc_io/io_m3cf.h, libfat/source/disc_io/io_m3sd.c, libfat/source/disc_io/io_m3sd.h, libfat/source/disc_io/io_mpcf.c, libfat/source/disc_io/io_mpcf.h, libfat/source/disc_io/io_njsd.c, libfat/source/disc_io/io_njsd.h, libfat/source/disc_io/io_nmmc.c, libfat/source/disc_io/io_nmmc.h, libfat/source/disc_io/io_sc_common.c, libfat/source/disc_io/io_sc_common.h, libfat/source/disc_io/io_sccf.c, libfat/source/disc_io/io_sccf.h, libfat/source/disc_io/io_scsd.c, libfat/source/disc_io/io_scsd.h, libfat/source/disc_io/io_scsd_s.s, libfat/source/disc_io/io_sd_common.c, libfat/source/disc_io/io_sd_common.h, libnds/Makefile.arm7, libnds/Makefile.arm9, libnds/libnds_license.txt, libnds/basicARM7/source/defaultARM7.c, libnds/include/default_font_bin.h, libnds/include/gbfs.h, libnds/include/nds.h, libnds/include/nds/bios.h, libnds/include/nds/card.h, libnds/include/nds/dma.h, libnds/include/nds/interrupts.h, libnds/include/nds/ipc.h, libnds/include/nds/jtypes.h, libnds/include/nds/memory.h, libnds/include/nds/registers_alt.h, libnds/include/nds/reload.h, libnds/include/nds/system.h, libnds/include/nds/timers.h, libnds/include/nds/arm7/audio.h, libnds/include/nds/arm7/clock.h, libnds/include/nds/arm7/serial.h, libnds/include/nds/arm7/touch.h, libnds/include/nds/arm9/background.h, libnds/include/nds/arm9/boxtest.h, libnds/include/nds/arm9/cache.h, libnds/include/nds/arm9/console.h, libnds/include/nds/arm9/exceptions.h, libnds/include/nds/arm9/image.h, libnds/include/nds/arm9/input.h, libnds/include/nds/arm9/math.h, libnds/include/nds/arm9/ndsmotion.h, libnds/include/nds/arm9/pcx.h, libnds/include/nds/arm9/postest.h, libnds/include/nds/arm9/rumble.h, libnds/include/nds/arm9/sound.h, libnds/include/nds/arm9/sprite.h, libnds/include/nds/arm9/trig_lut.h, libnds/include/nds/arm9/video.h, libnds/include/nds/arm9/videoGL.h, libnds/source/arm7/audio.c, libnds/source/arm7/clock.c, libnds/source/arm7/microphone.c, libnds/source/arm7/spi.c, libnds/source/arm7/touch.c, libnds/source/arm7/userSettings.c, libnds/source/arm9/COS.bin, libnds/source/arm9/COS.s, libnds/source/arm9/SIN.bin, libnds/source/arm9/SIN.s, libnds/source/arm9/TAN.bin, libnds/source/arm9/TAN.s, libnds/source/arm9/boxtest.c, libnds/source/arm9/console.c, libnds/source/arm9/dcache.s, libnds/source/arm9/default_font.bin, libnds/source/arm9/default_font.s, libnds/source/arm9/exceptionHandler.S, libnds/source/arm9/exceptionHandler.s, libnds/source/arm9/exceptions.c, libnds/source/arm9/gurumeditation.c, libnds/source/arm9/icache.s, libnds/source/arm9/image.c, libnds/source/arm9/initSystem.c, libnds/source/arm9/keys.c, libnds/source/arm9/ndsmotion.c, libnds/source/arm9/pcx.c, libnds/source/arm9/rumble.c, libnds/source/arm9/sound.c, libnds/source/arm9/system.c, libnds/source/arm9/touch.c, libnds/source/arm9/video.c, libnds/source/arm9/videoGL.c, libnds/source/common/biosCalls.s, libnds/source/common/card.c, libnds/source/common/gbfs.c, libnds/source/common/interruptDispatcher.s, libnds/source/common/interrupts.c, rtc/rtc.c, sound/sound.c, sound/sound.h, start/start.S, startup/linkcmds, startup/start.c, timer/timer.c, tools/Makefile.am, tools/bin2s, tools/bin2s.c, tools/configure.ac, tools/runtest, tools/ndstool/include/arm7_sha1_homebrew.h, tools/ndstool/include/arm7_sha1_nintendo.h, tools/ndstool/include/banner.h, tools/ndstool/include/bigint.h, tools/ndstool/include/crc.h, tools/ndstool/include/default_icon.h, tools/ndstool/include/encryption.h, tools/ndstool/include/header.h, tools/ndstool/include/hook.h, tools/ndstool/include/little.h, tools/ndstool/include/loadme.h, tools/ndstool/include/logo.h, tools/ndstool/include/ndscreate.h, tools/ndstool/include/ndsextract.h, tools/ndstool/include/ndstool.h, tools/ndstool/include/ndstree.h, tools/ndstool/include/overlay.h, tools/ndstool/include/passme.h, tools/ndstool/include/passme_sram.h, tools/ndstool/include/passme_vhd1.h, tools/ndstool/include/passme_vhd2.h, tools/ndstool/include/raster.h, tools/ndstool/include/sha1.h, tools/ndstool/include/types.h, tools/ndstool/source/arm7_sha1_homebrew.c, tools/ndstool/source/arm7_sha1_nintendo.c, tools/ndstool/source/banner.cpp, tools/ndstool/source/bigint.cpp, tools/ndstool/source/compile_date.c, tools/ndstool/source/crc.cpp, tools/ndstool/source/default_icon.c, tools/ndstool/source/encryption.cpp, tools/ndstool/source/header.cpp, tools/ndstool/source/hook.cpp, tools/ndstool/source/loadme.c, tools/ndstool/source/logo.cpp, tools/ndstool/source/ndscodes.cpp, tools/ndstool/source/ndscreate.cpp, tools/ndstool/source/ndsextract.cpp, tools/ndstool/source/ndstool.cpp, tools/ndstool/source/ndstree.cpp, tools/ndstool/source/passme.cpp, tools/ndstool/source/passme_sram.c, tools/ndstool/source/raster.cpp, tools/ndstool/source/sha1.cpp, touchscreen/README.reco, touchscreen/parser.c, touchscreen/reco.c, touchscreen/reco.h, touchscreen/touchscreen.c, touchscreen/touchscreen.h, wifi/compat.c, wifi/compat.h, wifi/wifi.c: New files.
  • Property mode set to 100644
File size: 46.2 KB
Line 
1// DS Wifi interface code
2// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
3// wifi_arm7.c - arm7 wifi interface code
4/******************************************************************************
5DSWifi Lib and test materials are licenced under the MIT open source licence:
6Copyright (c) 2005-2006 Stephen Stair
7
8Permission is hereby granted, free of charge, to any person obtaining a copy of
9this software and associated documentation files (the "Software"), to deal in
10the Software without restriction, including without limitation the rights to
11use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12of the Software, and to permit persons to whom the Software is furnished to do
13so, subject to the following conditions:
14
15The above copyright notice and this permission notice shall be included in all
16copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24SOFTWARE.
25******************************************************************************/
26
27
28#include <nds.h>
29#include "dsregs.h"
30#include "wifi_arm7.h"
31
32#include "spinlock.h" // .h file with code for spinlocking in it.
33
34volatile Wifi_MainStruct * WifiData = 0;
35WifiSyncHandler synchandler = 0;
36int keepalive_time = 0;
37int chdata_save5 = 0;
38
39//////////////////////////////////////////////////////////////////////////
40//
41//  Flash support functions
42//
43char FlashData[512];
44void Read_Flash(int address, char * destination, int length) {
45        int i;
46        while(SPI_CR&0x80);
47        SPI_CR=0x8900;
48        SPI_DATA=3;
49        while(SPI_CR&0x80);
50        SPI_DATA=(address>>16)&255;
51        while(SPI_CR&0x80);
52        SPI_DATA=(address>>8)&255;
53        while(SPI_CR&0x80);
54        SPI_DATA=(address)&255;
55        while(SPI_CR&0x80);
56        for(i=0;i<length;i++) {
57                SPI_DATA=0;
58                while(SPI_CR&0x80);
59                destination[i]=SPI_DATA;
60        }
61        SPI_CR=0;
62}
63
64void InitFlashData() {
65        Read_Flash(0,FlashData,512);
66}
67
68int ReadFlashByte(int address) {
69        if(address<0 || address>511) return 0;
70        return FlashData[address];             
71}
72
73int ReadFlashBytes(int address, int numbytes) {
74        int dataout=0;
75        int i;
76        for(i=0;i<numbytes;i++) {
77                dataout |= ReadFlashByte(i+address)<<(i*8);
78        }
79        return dataout;
80}
81int ReadFlashHWord(int address) {
82        if(address<0 || address>510) return 0;
83        return ReadFlashBytes(address,2);
84}
85
86//////////////////////////////////////////////////////////////////////////
87//
88// WFC data loading
89//
90/*
91int crc16_slow(u8 * data, int length) {
92   int i,j,d, crc;
93   crc=0x0000;
94   for(i=0;i<length;i++) {
95      d=data[i];
96      for(j=0;j<8;j++) {
97         if(((d)^(crc>>15))&1) crc = (crc<<1)^0x8005; else crc=crc<<1;
98         d=d>>1;
99      }
100   }
101   crc &=0xFFFF;
102   return crc;
103}
104*/
105int crc16_slow(u8 * data, int length) {
106    int i,j, crc;
107    crc=0x0000;
108    for(i=0;i<length;i++) {
109        crc ^=data[i];
110        for(j=0;j<8;j++) {
111            if((crc)&1) crc = (crc>>1)^0xA001; else crc=crc>>1;
112        }
113    }
114    crc &=0xFFFF;
115    return crc;
116}
117
118void GetWfcSettings() {
119   u8 data[256];
120   int i,n, c;
121   unsigned long s;
122   c=0;
123   u32 wfcBase = ReadFlashBytes(0x20, 2) * 8 - 0x400;
124   for(i=0;i<3;i++) WifiData->wfc_enable[i]=0;
125   for(i=0;i<3;i++) {
126      Read_Flash( wfcBase +(i<<8),(char *)data,256);
127      // check for validity (crc16)
128          if(crc16_slow(data,256)==0x0000 && data[0xE7]==0x00) { // passed the test
129                  WifiData->wfc_enable[c] = 0x80 | (data[0xE6]&0x0F);
130                  WifiData->wfc_ap[c].channel=0;
131                  for(n=0;n<6;n++) WifiData->wfc_ap[c].bssid[n]=0;
132                  for(n=0;n<16;n++) WifiData->wfc_wepkey[c][n]=data[0x80+n];
133                  for(n=0;n<32;n++) WifiData->wfc_ap[c].ssid[n]=data[0x40+n];
134                  for(n=0;n<32;n++) if(!data[0x40+n]) break;
135                  WifiData->wfc_ap[c].ssid_len=n;
136                  WifiData->wfc_config[c][0]=((unsigned long *)(data+0xC0))[0];
137                  WifiData->wfc_config[c][1]=((unsigned long *)(data+0xC0))[1];
138                  WifiData->wfc_config[c][3]=((unsigned long *)(data+0xC0))[2];
139                  WifiData->wfc_config[c][4]=((unsigned long *)(data+0xC0))[3];
140                  s=0;
141                  for(n=0;n<data[0xD0];n++) {
142                        s |= 1<<(31-n);
143                  }
144                  s= (s<<24) | (s>>24) | ((s&0xFF00)<<8) | ((s&0xFF0000)>>8); // htonl
145                  WifiData->wfc_config[c][2]=s;
146                  c++;
147          }
148   }
149}
150
151
152//////////////////////////////////////////////////////////////////////////
153//
154//  Other support
155//
156
157int Wifi_BBRead(int a) {
158        while(W_BBSIOBUSY&1);
159        W_BBSIOCNT=a | 0x6000;
160        while(W_BBSIOBUSY&1);
161        return W_BBSIOREAD;
162}
163int Wifi_BBWrite(int a, int b) {
164        int i;
165        i=0x2710;
166        while((W_BBSIOBUSY&1)) {
167                if(!i--) return -1;
168        }
169        W_BBSIOWRITE=b;
170        W_BBSIOCNT=a | 0x5000;
171        i=0x2710;
172        while((W_BBSIOBUSY&1)) {
173                if(!i--) return 0;
174        }
175        return 0;
176}
177void Wifi_RFWrite(int writedata) {
178        while(W_RFSIOBUSY&1);
179        W_RFSIODATA1=writedata;
180        W_RFSIODATA2=writedata>>16;
181        while(W_RFSIOBUSY&1);
182}
183
184int PowerChip_ReadWrite(int cmd, int data) {
185        if(cmd&0x80) data=0;
186        while(SPI_CR&0x80);
187        SPI_CR=0x8802;
188        SPI_DATA=cmd;
189        while(SPI_CR&0x80);
190        SPI_CR=0x8002;
191        SPI_DATA=data;
192        while(SPI_CR&0x80);
193        data=SPI_DATA;
194        SPI_CR=0;
195        return data;
196}
197
198#define LED_LONGBLINK   1
199#define LED_SHORTBLINK  3
200#define LED_ON                  0
201int led_state=0;
202void SetLedState(int state) {
203        int i;
204        if(state>3 || state<0) return;
205        if(state!=led_state) {
206                led_state=state;
207                i=PowerChip_ReadWrite(0x80,0);
208                i=i&0xCF;
209                i |= state<<4;
210                PowerChip_ReadWrite(0,i);
211        }
212}
213
214void ProxySetLedState(int state) {
215        if(WifiData->flags9&WFLAG_ARM9_USELED) SetLedState(state);
216}
217
218//////////////////////////////////////////////////////////////////////////
219//
220//  Main functionality
221//
222
223int RF_Reglist[] = { 0x146, 0x148, 0x14A, 0x14C, 0x120, 0x122, 0x154, 0x144, 0x130, 0x132, 0x140, 0x142, 0x38, 0x124, 0x128, 0x150 };
224
225void Wifi_RFInit() {
226        int i,j;
227        int channel_extrabits;
228        int numchannels;
229        int channel_extrabytes;
230        int temp;
231        for(i=0;i<16;i++) {
232                WIFI_REG(RF_Reglist[i])=ReadFlashHWord(0x44+i*2);
233        }
234        numchannels=ReadFlashByte(0x42);
235        channel_extrabits=ReadFlashByte(0x41);
236        channel_extrabytes=(channel_extrabits+7)/8;
237        WIFI_REG(0x184)=((channel_extrabits>>7)<<8) | (channel_extrabits&0x7F);
238        j=0xCE;
239        if(ReadFlashByte(0x40)==3) {
240                for(i=0;i<numchannels;i++) {
241                        Wifi_RFWrite(ReadFlashByte(j++)|(i<<8)|0x50000);
242                }
243        } else if(ReadFlashByte(0x40)==2) {
244                for(i=0;i<numchannels;i++) {
245                        temp = ReadFlashBytes(j,channel_extrabytes);
246                        Wifi_RFWrite(temp);
247                        j+=channel_extrabytes;
248                        if( (temp>>18)==9 ) {
249                                chdata_save5 = temp&(~0x7C00);
250                        }
251                }
252        } else {
253                for(i=0;i<numchannels;i++) {
254                        Wifi_RFWrite(ReadFlashBytes(j,channel_extrabytes));
255                        j+=channel_extrabytes;
256                }
257        }
258}
259
260void Wifi_BBInit() {
261        int i;
262        WIFI_REG(0x160)=0x0100;
263        for(i=0;i<0x69;i++) {
264                Wifi_BBWrite(i,ReadFlashByte(0x64+i));
265        }
266}
267
268// 22 entry list
269int MAC_Reglist[] = { 0x04, 0x08, 0x0A, 0x12, 0x10, 0x254, 0xB4, 0x80, 0x2A, 0x28, 0xE8, 0xEA, 0xEE, 0xEC, 0x1A2, 0x1A0, 0x110, 0xBC, 0xD4, 0xD8, 0xDA, 0x76 };
270int MAC_Vallist[] = { 0, 0, 0, 0, 0xffff, 0, 0xffff, 0, 0, 0, 0, 0, 1, 0x3F03, 1, 0, 0x0800, 1, 3, 4, 0x0602, 0};
271void Wifi_MacInit() {
272        int i;
273        for(i=0;i<22;i++) {
274                WIFI_REG(MAC_Reglist[i]) = MAC_Vallist[i];
275        }
276}
277
278
279void Wifi_TxSetup() {
280/*      switch(WIFI_REG(0x8006)&7) {
281        case 0: //
282                // 4170,  4028, 4000
283                // TxqEndData, TxqEndManCtrl, TxqEndPsPoll
284                WIFI_REG(0x4024)=0xB6B8;
285                WIFI_REG(0x4026)=0x1D46;
286                WIFI_REG(0x416C)=0xB6B8;
287                WIFI_REG(0x416E)=0x1D46;
288                WIFI_REG(0x4790)=0xB6B8;
289                WIFI_REG(0x4792)=0x1D46;
290                WIFI_REG(0x80AE) = 1;
291                break;
292        case 1: //
293                // 4AA0, 4958, 4334
294                // TxqEndData, TxqEndManCtrl, TxqEndBroadCast
295                // 4238, 4000
296                WIFI_REG(0x4234)=0xB6B8;
297                WIFI_REG(0x4236)=0x1D46;
298                WIFI_REG(0x4330)=0xB6B8;
299                WIFI_REG(0x4332)=0x1D46;
300                WIFI_REG(0x4954)=0xB6B8;
301                WIFI_REG(0x4956)=0x1D46;
302                WIFI_REG(0x4A9C)=0xB6B8;
303                WIFI_REG(0x4A9E)=0x1D46;
304                WIFI_REG(0x50C0)=0xB6B8;
305                WIFI_REG(0x50C2)=0x1D46;
306                //...
307                break;
308        case 2:
309                // 45D8, 4490, 4468
310                // TxqEndData, TxqEndManCtrl, TxqEndPsPoll
311
312                WIFI_REG(0x4230)=0xB6B8;
313                WIFI_REG(0x4232)=0x1D46;
314                WIFI_REG(0x4464)=0xB6B8;
315                WIFI_REG(0x4466)=0x1D46;
316                WIFI_REG(0x448C)=0xB6B8;
317                WIFI_REG(0x448E)=0x1D46;
318                WIFI_REG(0x45D4)=0xB6B8;
319                WIFI_REG(0x45D6)=0x1D46;
320                WIFI_REG(0x4BF8)=0xB6B8;
321                WIFI_REG(0x4BFA)=0x1D46;
322*/
323                WIFI_REG(0x80AE)=0x000D;
324//      }
325}
326
327void Wifi_RxSetup() {
328        WIFI_REG(0x8030) = 0x8000;
329/*      switch(WIFI_REG(0x8006)&7) {
330        case 0:
331                WIFI_REG(0x8050) = 0x4794;
332                WIFI_REG(0x8056) = 0x03CA;
333                // 17CC ?
334                break;
335        case 1:
336                WIFI_REG(0x8050) = 0x50C4;
337                WIFI_REG(0x8056) = 0x0862;
338                // 0E9C ?
339                break;
340        case 2:
341                WIFI_REG(0x8050) = 0x4BFC;
342                WIFI_REG(0x8056) = 0x05FE;
343                // 1364 ?
344                break;
345        case 3:
346                WIFI_REG(0x8050) = 0x4794;
347                WIFI_REG(0x8056) = 0x03CA;
348                // 17CC ?
349                break;
350        }
351        */
352        WIFI_REG(0x8050) = 0x4C00;
353        WIFI_REG(0x8056) = 0x0600;
354
355        WIFI_REG(0x8052) = 0x5F60;
356        WIFI_REG(0x805A) = (WIFI_REG(0x8050)&0x3FFF)>>1;
357        WIFI_REG(0x8062) = 0x5F5E;
358        WIFI_REG(0x8030) = 0x8001;
359}
360
361
362void Wifi_WakeUp() {
363        u32 i;
364        WIFI_REG(0x8036)=0;
365
366        swiDelay( 67109 ); // 8ms delay
367
368        WIFI_REG(0x8168)=0;
369
370        i=Wifi_BBRead(1);
371        Wifi_BBWrite(1,i&0x7f);
372        Wifi_BBWrite(1,i);
373
374        swiDelay( 335544 ); // 40ms delay
375
376        Wifi_RFInit();
377}
378void Wifi_Shutdown() {
379        int a;
380        if(ReadFlashByte(0x40)==2) {
381                Wifi_RFWrite(0xC008);
382        }
383        a=Wifi_BBRead(0x1E);
384        Wifi_BBWrite(0x1E,a|0x3F);
385        WIFI_REG(0x168)=0x800D;
386        WIFI_REG(0x36)=1;
387}
388
389
390void Wifi_CopyMacAddr(volatile void * dest, volatile void * src) {
391        ((u16 *)dest)[0]=((u16 *)src)[0];
392        ((u16 *)dest)[1]=((u16 *)src)[1];
393        ((u16 *)dest)[2]=((u16 *)src)[2];
394}
395
396int Wifi_CmpMacAddr(volatile void * mac1,volatile  void * mac2) {
397        return (((u16 *)mac1)[0]==((u16 *)mac2)[0]) && (((u16 *)mac1)[1]==((u16 *)mac2)[1]) && (((u16 *)mac1)[2]==((u16 *)mac2)[2]);
398}
399
400//////////////////////////////////////////////////////////////////////////
401//
402//  MAC Copy functions
403//
404
405u16 inline Wifi_MACRead(u32 MAC_Base, u32 MAC_Offset) {
406        MAC_Base += MAC_Offset;
407        if(MAC_Base>=(WIFI_REG(0x52)&0x1FFE)) MAC_Base -= ((WIFI_REG(0x52)&0x1FFE)-(WIFI_REG(0x50)&0x1FFE));
408        return WIFI_REG(0x4000+MAC_Base);
409}
410
411void Wifi_MACCopy(u16 * dest, u32 MAC_Base, u32 MAC_Offset, u32 length) {
412        int endrange,subval;
413        int thislength;
414        endrange = (WIFI_REG(0x52)&0x1FFE);
415        subval=((WIFI_REG(0x52)&0x1FFE)-(WIFI_REG(0x50)&0x1FFE));
416        MAC_Base += MAC_Offset;
417        if(MAC_Base>=endrange) MAC_Base -= subval;
418        while(length>0) {
419                thislength=length;
420                if(thislength>(endrange-MAC_Base)) thislength=endrange-MAC_Base;
421                length-=thislength;
422                while(thislength>0) {
423                        *(dest++) = WIFI_REG(0x4000+MAC_Base);
424                        MAC_Base+=2;
425                        thislength-=2;
426                }
427                MAC_Base-=subval;
428        }
429}
430
431void Wifi_MACWrite(u16 * src, u32 MAC_Base, u32 MAC_Offset, u32 length) {
432        int endrange,subval;
433        int thislength;
434        endrange = (WIFI_REG(0x52)&0x1FFE);
435        subval=((WIFI_REG(0x52)&0x1FFE)-(WIFI_REG(0x50)&0x1FFE));
436        MAC_Base += MAC_Offset;
437        if(MAC_Base>=endrange) MAC_Base -= subval;
438        while(length>0) {
439                thislength=length;
440                if(length>(endrange-MAC_Base)) length=endrange-MAC_Base;
441                length-=thislength;
442                while(thislength>0) {
443                        WIFI_REG(0x4000+MAC_Base) = *(src++);
444                        MAC_Base+=2;
445                        thislength-=2;
446                }
447                MAC_Base-=subval;
448        }
449}
450int Wifi_QueueRxMacData(u32 base, u32 len) {
451        int buflen, temp,macofs, tempout;
452        macofs=0;
453        buflen=(WifiData->rxbufIn-WifiData->rxbufOut-1)*2;
454        if(buflen<0) buflen += WIFI_RXBUFFER_SIZE;
455        if(buflen<len) { WifiData->stats[WSTAT_RXQUEUEDLOST]++; return 0; }
456        WifiData->stats[WSTAT_RXQUEUEDPACKETS]++;
457        WifiData->stats[WSTAT_RXQUEUEDBYTES]+=len;
458        temp=WIFI_RXBUFFER_SIZE-(WifiData->rxbufOut*2);
459    tempout=WifiData->rxbufOut;
460        if(len>temp) {
461                Wifi_MACCopy((u16*)WifiData->rxbufData+tempout,base,macofs,temp);
462                macofs+=temp;
463                len-=temp;
464                tempout=0;
465        }
466        Wifi_MACCopy((u16*)WifiData->rxbufData+tempout,base,macofs,len);
467        tempout+=len/2;
468        if(tempout>=(WIFI_RXBUFFER_SIZE/2)) tempout-=(WIFI_RXBUFFER_SIZE/2);
469    WifiData->rxbufOut=tempout;
470   if(synchandler) synchandler();
471        return 1;
472}
473
474int Wifi_CheckTxBuf(s32 offset) {
475        offset+=WifiData->txbufIn;
476        if(offset>=WIFI_TXBUFFER_SIZE/2) offset-=WIFI_TXBUFFER_SIZE/2;
477        return WifiData->txbufData[offset];
478}
479
480// non-wrapping function.
481int Wifi_CopyFirstTxData(s32 macbase) {
482        int seglen, readbase,max, packetlen,length;
483        packetlen=Wifi_CheckTxBuf(5);
484        readbase=WifiData->txbufIn;
485        length = (packetlen+12-4+1)/2;
486        max=WifiData->txbufOut-WifiData->txbufIn;
487        if(max<0) max+=WIFI_TXBUFFER_SIZE/2;
488        if(max<length) return 0;
489        while(length>0) {
490                seglen=length;
491                if(readbase+seglen>WIFI_TXBUFFER_SIZE/2) seglen=WIFI_TXBUFFER_SIZE/2-readbase;
492                length-=seglen;
493                while(seglen--) { WIFI_REG(0x4000+macbase)=WifiData->txbufData[readbase++]; macbase+=2; }
494                if(readbase>=WIFI_TXBUFFER_SIZE/2) readbase-=WIFI_TXBUFFER_SIZE/2;
495        }
496        WifiData->txbufIn=readbase;
497
498        WifiData->stats[WSTAT_TXPACKETS]++;
499        WifiData->stats[WSTAT_TXBYTES]+=packetlen+12-4;
500        WifiData->stats[WSTAT_TXDATABYTES]+=packetlen-4;
501
502        return packetlen;
503}
504
505
506
507u16 arm7q[1024];
508u16 arm7qlen = 0;
509
510void Wifi_TxRaw(u16 * data, int datalen) {
511        datalen = (datalen+3)&(~3);
512        Wifi_MACWrite(data, 0, 0, datalen);
513//      WIFI_REG(0xB8)=0x0001;
514        WIFI_REG(0xA8)=0x8000;
515        WifiData->stats[WSTAT_TXPACKETS]++;
516        WifiData->stats[WSTAT_TXBYTES]+=datalen;
517        WifiData->stats[WSTAT_TXDATABYTES]+=datalen-12;
518}
519
520int Wifi_TxCheck() {
521        if(WIFI_REG(0xA8)&0x8000) return 0;
522        return 1;
523}
524
525
526//////////////////////////////////////////////////////////////////////////
527//
528//  Wifi Interrupts
529//
530
531void Wifi_Intr_RxEnd() {
532        int base;
533        int packetlen;
534        int full_packetlen;
535        int cut, temp;
536        int tIME;
537        tIME=REG_IME;
538        REG_IME=0;
539        cut=0;
540
541        while(WIFI_REG(0x54)!=WIFI_REG(0x5A)) {
542                base = WIFI_REG(0x5A)<<1;
543                packetlen=Wifi_MACRead(base,8);
544                full_packetlen=12+((packetlen+3)&(~3));
545                WifiData->stats[WSTAT_RXPACKETS]++;
546                WifiData->stats[WSTAT_RXBYTES]+=full_packetlen;
547                WifiData->stats[WSTAT_RXDATABYTES]+=full_packetlen-12;
548
549               
550                // process packet here
551                temp=Wifi_ProcessReceivedFrame(base,full_packetlen); // returns packet type
552                if(temp&WifiData->reqPacketFlags || WifiData->reqReqFlags&WFLAG_REQ_PROMISC) { // if packet type is requested, forward it to the rx queue
553                        keepalive_time=0;
554                        if(!Wifi_QueueRxMacData(base,full_packetlen)) {
555                                // failed, ignore for now.
556                        }
557                }
558
559                base += full_packetlen;
560                if(base>=(WIFI_REG(0x52)&0x1FFE)) base -= ((WIFI_REG(0x52)&0x1FFE)-(WIFI_REG(0x50)&0x1FFE));
561                WIFI_REG(0x5A)=base>>1;
562
563                if(cut++>5) break;
564        }
565        REG_IME=tIME;
566}
567
568#define CNT_STAT_START WSTAT_HW_1B0
569#define CNT_STAT_NUM 18
570u16 count_ofs_list[CNT_STAT_NUM] = {
571        0x1B0, 0x1B2, 0x1B4, 0x1B6, 0x1B8, 0x1BA, 0x1BC, 0x1BE, 0x1C0, 0x1C4, 0x1D0, 0x1D2, 0x1D4, 0x1D6, 0x1D8, 0x1DA, 0x1DC, 0x1DE
572};
573void Wifi_Intr_CntOverflow() {
574        int i;
575        int s,d;
576        s=CNT_STAT_START;
577        for(i=0;i<CNT_STAT_NUM;i++) {
578                d=WIFI_REG(count_ofs_list[i]);
579                WifiData->stats[s++]+=(d&0xFF);
580                WifiData->stats[s++]+=((d>>8)&0xFF);
581        }
582}
583
584void Wifi_Intr_StartTx() {
585        if(WifiData->reqReqFlags&WFLAG_REQ_PROMISC) { // attempt to ensure packet is received
586
587        }
588}
589
590void Wifi_Intr_TxEnd() { // assume that we can now tx something new.
591        if(arm7qlen) {
592                Wifi_TxRaw(arm7q, arm7qlen);
593                keepalive_time=0;
594                arm7qlen=0;
595                return;
596        }
597        if((WifiData->txbufOut!=WifiData->txbufIn) && (!(WifiData->curReqFlags&WFLAG_REQ_APCONNECT) || WifiData->authlevel==WIFI_AUTHLEVEL_ASSOCIATED)) {
598                if(Wifi_CopyFirstTxData(0)) {
599                        keepalive_time=0;
600                        if(WIFI_REG(0x4008)==0) { WIFI_REG(0x4008)=WifiData->maxrate7; } // if rate dne, fill it in.
601                        if(WIFI_REG(0x400C)&0x4000) { // wep is enabled, fill in the IV.
602                                WIFI_REG(0x4024) = (W_RANDOM ^ (W_RANDOM<<7) ^ (W_RANDOM<<15))&0xFFFF;
603                                WIFI_REG(0x4026) = ((W_RANDOM ^ (W_RANDOM>>7))&0xFF) | (WifiData->wepkeyid7<<14);
604                        }
605                        //      WIFI_REG(0xB8)=0x0001;
606                        WIFI_REG(0xA8)=0x8000;
607         WIFI_REG(0xAE)=0x000D;
608                }
609        }
610}
611
612void Wifi_Intr_TBTT() {
613        if(WIFI_REG(0xA8)&0x8000) {
614                WIFI_REG(0xAE)=0x000D;
615        }
616}
617
618void Wifi_Intr_DoNothing() {
619}
620
621
622
623void Wifi_Interrupt() {
624        int wIF;
625        if(!WifiData) return;
626        if(!(WifiData->flags7&WFLAG_ARM7_RUNNING)) return;
627        do {
628        REG_IF=0x01000000; // now that we've cleared the wireless IF, kill the bit in regular IF.
629        wIF= W_IE & W_IF;
630        if(wIF& 0x0001) { W_IF=0x0001;  Wifi_Intr_RxEnd();  } // 0) Rx End
631        if(wIF& 0x0002) { W_IF=0x0002;  Wifi_Intr_TxEnd();  } // 1) Tx End
632        if(wIF& 0x0004) { W_IF=0x0004;  Wifi_Intr_DoNothing();  } // 2) Rx Cntup
633        if(wIF& 0x0008) { W_IF=0x0008;  Wifi_Intr_DoNothing();  } // 3) Tx Err
634        if(wIF& 0x0010) { W_IF=0x0010;  Wifi_Intr_CntOverflow();  } // 4) Count Overflow
635        if(wIF& 0x0020) { W_IF=0x0020;  Wifi_Intr_CntOverflow();  } // 5) AckCount Overflow
636        if(wIF& 0x0040) { W_IF=0x0040;  Wifi_Intr_DoNothing();  } // 6) Start Rx
637        if(wIF& 0x0080) { W_IF=0x0080;  Wifi_Intr_StartTx();  } // 7) Start Tx
638        if(wIF& 0x0100) { W_IF=0x0100;  Wifi_Intr_DoNothing();  } // 8)
639        if(wIF& 0x0200) { W_IF=0x0200;  Wifi_Intr_DoNothing();  } // 9)
640        if(wIF& 0x0400) { W_IF=0x0400;  Wifi_Intr_DoNothing();  } //10)
641        if(wIF& 0x0800) { W_IF=0x0800;  Wifi_Intr_DoNothing();  } //11) RF Wakeup
642        if(wIF& 0x1000) { W_IF=0x1000;  Wifi_Intr_DoNothing();  } //12) MP End
643        if(wIF& 0x2000) { W_IF=0x2000;  Wifi_Intr_DoNothing();  } //13) ACT End
644        if(wIF& 0x4000) { W_IF=0x4000;  Wifi_Intr_TBTT();  } //14) TBTT
645        if(wIF& 0x8000) { W_IF=0x8000;  Wifi_Intr_DoNothing();  } //15) PreTBTT
646        wIF= W_IE & W_IF;
647        } while(wIF);
648
649}
650
651
652
653
654
655
656void Wifi_Update() {
657        int i;
658        if(!WifiData) return;
659   WifiData->random ^=(W_RANDOM ^ (W_RANDOM<<11) ^ (W_RANDOM<<22));
660   WifiData->stats[WSTAT_ARM7_UPDATES]++;
661   WifiData->stats[WSTAT_DEBUG]=WIFI_REG(0xA8);
662   if(WIFI_REG(0xA8)&0x8000) {
663      WIFI_REG(0xAE)=0x000D;
664   }
665        // check flags, to see if we need to change anything
666        switch(WifiData->curMode) {
667        case WIFIMODE_DISABLED:
668                ProxySetLedState(LED_ON);
669                if(WifiData->reqMode!=WIFIMODE_DISABLED) {
670                        Wifi_Start();
671                        WifiData->curMode=WIFIMODE_NORMAL;
672                }
673                break;
674        case WIFIMODE_NORMAL: // main switcher function
675                ProxySetLedState(LED_LONGBLINK);
676                if(WifiData->reqMode==WIFIMODE_DISABLED) {
677                        Wifi_Stop();
678                        WifiData->curMode=WIFIMODE_DISABLED;
679                        break;
680                }
681                if(WifiData->reqMode==WIFIMODE_SCAN) {
682                        WifiData->counter7=WIFI_REG(0xFA); // timer hword 2 (each tick is 65.5ms)
683                        WifiData->curMode=WIFIMODE_SCAN;
684                        break;
685                }
686                if((WifiData->reqReqFlags ^ WifiData->curReqFlags) & WFLAG_REQ_APCONNECT) {
687                        if(WifiData->curReqFlags& WFLAG_REQ_APCONNECT) { // already connected; disconnect
688                                WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT;
689                        } else { // not connected - connect!
690                                if(WifiData->reqReqFlags&WFLAG_REQ_APCOPYVALUES) {
691                                        WifiData->wepkeyid7=WifiData->wepkeyid9;
692                                        WifiData->wepmode7=WifiData->wepmode9;
693                                        WifiData->apchannel7=WifiData->apchannel9;
694                                        Wifi_CopyMacAddr(WifiData->bssid7,WifiData->bssid9);
695                                        Wifi_CopyMacAddr(WifiData->apmac7,WifiData->apmac9);
696                                        for(i=0;i<20;i++) WifiData->wepkey7[i]=WifiData->wepkey9[i];
697                                        for(i=0;i<34;i++) WifiData->ssid7[i]=WifiData->ssid9[i];
698                                        for(i=0;i<16;i++) WifiData->baserates7[i]=WifiData->baserates9[i];
699                                        if(WifiData->reqReqFlags&WFLAG_REQ_APADHOC) WifiData->curReqFlags |= WFLAG_REQ_APADHOC; else WifiData->curReqFlags &= ~WFLAG_REQ_APADHOC;
700                                }
701            Wifi_SetWepKey((void *)WifiData->wepkey7);
702                                Wifi_SetWepMode(WifiData->wepmode7);
703                                // latch BSSID
704                                W_BSSID[0]= ((u16 *)WifiData->bssid7)[0];
705                                W_BSSID[1]= ((u16 *)WifiData->bssid7)[1];
706                                W_BSSID[2]= ((u16 *)WifiData->bssid7)[2];
707                                //WIFI_REG(0xD0) &= ~0x0400;
708                                WIFI_REG(0xD0) |= 0x0400;
709                                WifiData->reqChannel=WifiData->apchannel7;
710                                Wifi_SetChannel(WifiData->apchannel7);
711                                if(WifiData->curReqFlags&WFLAG_REQ_APADHOC) {
712                                        WifiData->authlevel=WIFI_AUTHLEVEL_ASSOCIATED;
713                                } else {
714                                        Wifi_SendOpenSystemAuthPacket();
715                                        WifiData->authlevel=WIFI_AUTHLEVEL_DISCONNECTED;
716                                }
717            WifiData->txbufIn=WifiData->txbufOut; // empty tx buffer.
718                                WifiData->curReqFlags |= WFLAG_REQ_APCONNECT;
719                WifiData->counter7=WIFI_REG(0xFA); // timer hword 2 (each tick is 65.5ms)
720                                WifiData->curMode=WIFIMODE_ASSOCIATE;
721                                WifiData->authctr=0;
722                        }
723                }
724                break;
725        case WIFIMODE_SCAN:
726                ProxySetLedState(LED_LONGBLINK);
727                if(WifiData->reqMode!=WIFIMODE_SCAN) {
728                        WifiData->curMode=WIFIMODE_NORMAL;
729                        break;
730                }
731                if(((u16)(WIFI_REG(0xFA)-WifiData->counter7))>6) { // jump ship!
732                        WifiData->counter7=WIFI_REG(0xFA);
733                        WifiData->reqChannel++;
734         {
735            int i;
736            for(i=0;i<WIFI_MAX_AP;i++) {
737               if(WifiData->aplist[i].flags & WFLAG_APDATA_ACTIVE) {
738                  WifiData->aplist[i].timectr++;
739                  if(WifiData->aplist[i].timectr>WIFI_AP_TIMEOUT) {
740                     WifiData->aplist[i].rssi=0;
741                     WifiData->aplist[i].rssi_past[0]=WifiData->aplist[i].rssi_past[1]=
742                        WifiData->aplist[i].rssi_past[2]=WifiData->aplist[i].rssi_past[3]=
743                        WifiData->aplist[i].rssi_past[4]=WifiData->aplist[i].rssi_past[5]=
744                        WifiData->aplist[i].rssi_past[6]=WifiData->aplist[i].rssi_past[7]=0; // update rssi later.
745                  }
746               }
747            }
748         }
749                        if(WifiData->reqChannel==14) WifiData->reqChannel=1;
750                }
751                break;
752        case WIFIMODE_ASSOCIATE:
753                ProxySetLedState(LED_LONGBLINK);
754                if(WifiData->authlevel==WIFI_AUTHLEVEL_ASSOCIATED) {
755                        WifiData->curMode=WIFIMODE_ASSOCIATED;
756                        break;
757                }
758                if(((u16)(WIFI_REG(0xFA)-WifiData->counter7))>20) { // ~1 second, reattempt connect stage
759                        WifiData->counter7=WIFI_REG(0xFA);
760                        WifiData->authctr++;
761                        if(WifiData->authctr>WIFI_MAX_ASSOC_RETRY) {
762                                WifiData->curMode=WIFIMODE_CANNOTASSOCIATE;
763                                break;
764                        }
765                        switch(WifiData->authlevel) {
766                        case WIFI_AUTHLEVEL_DISCONNECTED: // send auth packet
767                                if(!(WifiData->curReqFlags&WFLAG_REQ_APADHOC)) {
768                                        Wifi_SendOpenSystemAuthPacket();
769                                        break;
770                                }
771                                WifiData->authlevel=WIFI_AUTHLEVEL_ASSOCIATED;
772                                break;
773                        case WIFI_AUTHLEVEL_DEASSOCIATED:
774                        case WIFI_AUTHLEVEL_AUTHENTICATED: // send assoc packet
775                                Wifi_SendAssocPacket();
776                                break;
777                        case WIFI_AUTHLEVEL_ASSOCIATED:
778                                WifiData->curMode=WIFIMODE_ASSOCIATED;
779                                break;
780                        }
781                }
782                if(!(WifiData->reqReqFlags & WFLAG_REQ_APCONNECT)) {
783                        WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT;
784                        WifiData->curMode=WIFIMODE_NORMAL;
785                        break;
786                }
787                break;
788        case WIFIMODE_ASSOCIATED:
789                ProxySetLedState(LED_SHORTBLINK);
790                keepalive_time++;
791                if(keepalive_time>WIFI_KEEPALIVE_COUNT) {
792                        keepalive_time=0;
793                        Wifi_SendNullFrame();
794                }
795                if((u16)(WIFI_REG(0xFA)-WifiData->pspoll_period)>WIFI_PS_POLL_CONST) {
796                        WifiData->pspoll_period=WIFI_REG(0xFA);
797                //      Wifi_SendPSPollFrame();
798                }
799                if(!(WifiData->reqReqFlags & WFLAG_REQ_APCONNECT)) {
800         W_BSSID[0]= ((u16 *)WifiData->bssid7)[0];
801         W_BSSID[1]= ((u16 *)WifiData->bssid7)[1];
802         W_BSSID[2]= ((u16 *)WifiData->bssid7)[2];
803         //WIFI_REG(0xD0) &= ~0x0400;
804         WifiData->curMode=WIFIMODE_NORMAL;
805         WifiData->authlevel=WIFI_AUTHLEVEL_DISCONNECTED;
806                        if(WifiData->curReqFlags &WFLAG_REQ_APCONNECT) { // deassociate, then return
807                                WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT;
808                        } else { // not connected for some reason, return.
809                                WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT;
810                                WifiData->curMode=WIFIMODE_ASSOCIATE;
811                        }
812         break;
813                }
814                if(WifiData->authlevel!=WIFI_AUTHLEVEL_ASSOCIATED) {
815                        WifiData->curMode=WIFIMODE_ASSOCIATE;
816                        break;
817                }
818                break;
819        case WIFIMODE_CANNOTASSOCIATE:
820                ProxySetLedState(LED_LONGBLINK);
821                if(!(WifiData->reqReqFlags & WFLAG_REQ_APCONNECT)) {
822                        WifiData->curReqFlags &=~WFLAG_REQ_APCONNECT;
823                        WifiData->curMode=WIFIMODE_NORMAL;
824                        break;
825                }
826                break;
827
828
829        }
830        if(WifiData->curChannel!=WifiData->reqChannel) {
831                Wifi_SetChannel(WifiData->reqChannel);
832        }
833        // check Rx
834        Wifi_Intr_RxEnd();
835        // check if we need to tx anything
836        if(Wifi_TxCheck()) Wifi_Intr_TxEnd(); // easiest way to do so at the moment.
837}
838
839
840
841
842//////////////////////////////////////////////////////////////////////////
843//
844//  Wifi User-called Functions
845//
846void erasemem(void * mem, int length) {
847        int i;
848        char * m = (char *)mem;
849        for(i=0;i<length;i++)
850                m[i]=0;
851}
852
853
854void Wifi_Init(u32 wifidata) {
855        WifiData = (Wifi_MainStruct *)wifidata;
856
857        POWERCNT7 |= 2; // enable power for the wifi
858        *((volatile u16 *)0x04000206) = 0x30; // ???
859
860    InitFlashData();
861
862        // reset/shutdown wifi:
863        WIFI_REG(0x4)=0xffff;
864        Wifi_Stop();
865        Wifi_Shutdown(); // power off wifi
866
867        WifiData->curChannel=1;
868        WifiData->reqChannel=1;
869        WifiData->curMode=WIFIMODE_DISABLED;
870        WifiData->reqMode=WIFIMODE_DISABLED;
871        WifiData->reqPacketFlags=WFLAG_PACKET_ALL & (~WFLAG_PACKET_BEACON);
872        WifiData->curReqFlags=0;
873        WifiData->reqReqFlags=0;
874        WifiData->maxrate7=0x0A;
875
876        int i;
877        for(i=0x4000;i<0x6000;i+=2) WIFI_REG(i)=0;
878
879
880   // load in the WFC data.
881   GetWfcSettings();
882
883        for(i=0;i<6;i++)  WifiData->MacAddr[i]=ReadFlashByte(0x36+i);
884
885        W_IE=0;
886        Wifi_WakeUp();
887
888        Wifi_MacInit();
889        Wifi_RFInit();
890        Wifi_BBInit();
891
892        // Set Default Settings
893        W_MACADDR[0]=((u16 *)WifiData->MacAddr)[0];
894        W_MACADDR[1]=((u16 *)WifiData->MacAddr)[1];
895        W_MACADDR[2]=((u16 *)WifiData->MacAddr)[2];
896
897        W_RETRLIMIT=7;
898        Wifi_SetMode(2);
899        Wifi_SetWepMode(WEPMODE_NONE);
900
901
902        Wifi_SetChannel(1);
903
904        Wifi_BBWrite(0x13, 0x00);
905        Wifi_BBWrite(0x35, 0x1F);
906
907//      Wifi_Shutdown();
908   WifiData->random ^=(W_RANDOM ^ (W_RANDOM<<11) ^ (W_RANDOM<<22));
909
910        WifiData->flags7 |= WFLAG_ARM7_ACTIVE;
911}
912
913void Wifi_Deinit() {
914        Wifi_Stop();
915        POWERCNT7 &= ~2;
916}
917
918void Wifi_Start() {
919        int i, tIME;
920        tIME=REG_IME;
921        REG_IME=0;
922        Wifi_Stop();
923
924//      Wifi_WakeUp();
925
926        WIFI_REG(0x8032) = 0x8000;
927        WIFI_REG(0x8134) = 0xFFFF;
928        WIFI_REG(0x802A) = 0;
929        W_AIDS           = 0;
930        WIFI_REG(0x80E8) = 1;
931        WIFI_REG(0x8038) = 0x0000;
932        WIFI_REG(0x20) = 0x0000;
933        WIFI_REG(0x22) = 0x0000;
934        WIFI_REG(0x24) = 0x0000;
935
936        Wifi_TxSetup();
937        Wifi_RxSetup();
938
939        WIFI_REG(0x8030) = 0x8000;
940/*
941        switch(WIFI_REG(0x8006)&7) {
942        case 0: // infrastructure mode?
943                W_IF=0xFFFF;
944                W_IE=0x003F;
945                WIFI_REG(0x81AE)=0x1fff;
946                //WIFI_REG(0x81AA)=0x0400;
947                WIFI_REG(0x80D0)=0xffff;
948                WIFI_REG(0x80E0)=0x0008;
949                WIFI_REG(0x8008)=0;
950                WIFI_REG(0x800A)=0;
951                WIFI_REG(0x80E8)=0;
952                WIFI_REG(0x8004)=1;
953                //SetStaState(0x40);
954                break;
955        case 1: // ad-hoc mode? -- beacons are required to be created!
956                W_IF=0xFFF;
957                W_IE=0x703F;
958                WIFI_REG(0x81AE)=0x1fff;
959                WIFI_REG(0x81AA)=0; // 0x400
960                WIFI_REG(0x80D0)=0x0301;
961                WIFI_REG(0x80E0)=0x000D;
962                WIFI_REG(0x8008)=0xE000;
963                WIFI_REG(0x800A)=0;
964                WIFI_REG(0x8004)=1;
965                //??
966                WIFI_REG(0x80EA)=1;
967                WIFI_REG(0x80AE)=2;
968                break;
969        case 2: // DS comms mode?
970        */
971                W_IF=0xFFFF;
972                //W_IE=0xE03F;
973                W_IE=0x40B3;
974                WIFI_REG(0x81AE)=0x1fff;
975                WIFI_REG(0x81AA)=0; //0x68
976                W_BSSID[0]=0xFFFF;
977                W_BSSID[1]=0xFFFF;
978                W_BSSID[2]=0xFFFF;
979                WIFI_REG(0x80D0)=0x0181; // 0x181
980                WIFI_REG(0x80E0)=0x000B;
981                WIFI_REG(0x8008)=0;
982                WIFI_REG(0x800A)=0;
983                WIFI_REG(0x8004)=1;
984                WIFI_REG(0x80E8)=1;
985                WIFI_REG(0x80EA)=1;
986                //SetStaState(0x20);
987        /*
988                break;
989        case 3:
990        case 4:
991                break;
992        }
993        */
994
995        WIFI_REG(0x8048)=0x0000;
996        Wifi_DisableTempPowerSave();
997        //WIFI_REG(0x80AE)=0x0002;
998        W_POWERSTATE |= 2;
999        WIFI_REG(0xAC) = 0xFFFF;
1000        i=0xFA0;
1001        while(i!=0 && !(WIFI_REG(0x819C)&0x80)) i--;
1002        WifiData->flags7 |=WFLAG_ARM7_RUNNING;
1003        REG_IME=tIME;
1004}
1005
1006void Wifi_Stop() {
1007        int tIME;
1008        tIME=REG_IME;
1009        WifiData->flags7 &= ~WFLAG_ARM7_RUNNING;
1010        W_IE=0;
1011        WIFI_REG(0x8004) = 0;
1012        WIFI_REG(0x80EA) = 0;
1013        WIFI_REG(0x80E8) = 0;
1014        WIFI_REG(0x8008) = 0;
1015        WIFI_REG(0x800A) = 0;
1016
1017        WIFI_REG(0x80AC) = 0xFFFF;
1018        WIFI_REG(0x80B4) = 0xFFFF;
1019//      Wifi_Shutdown();
1020        REG_IME=tIME;
1021}
1022
1023void Wifi_SetChannel(int channel) {
1024        int i,n,l;
1025        if(channel<1 || channel>13) return;
1026    channel-=1;
1027
1028    switch(ReadFlashByte(0x40)) {
1029    case 2:
1030    case 5:
1031        Wifi_RFWrite(ReadFlashBytes(0xf2+channel*6,3));
1032        Wifi_RFWrite(ReadFlashBytes(0xf5+channel*6,3));
1033
1034                swiDelay( 12583 ); // 1500 us delay
1035
1036                if(chdata_save5 & 0x10000)
1037                {
1038                        if(chdata_save5 & 0x8000) break;
1039                        n = ReadFlashByte(0x154+channel);
1040                        Wifi_RFWrite( chdata_save5 | ((n&0x1F)<<10) );
1041                } else {
1042                        Wifi_BBWrite(0x1E, ReadFlashByte(0x146+channel));
1043                }
1044
1045        break;
1046    case 3:
1047        n=ReadFlashByte(0x42);
1048        n+=0xCF;
1049                l=ReadFlashByte(n-1);
1050        for(i=0;i<l;i++) {
1051            Wifi_BBWrite(ReadFlashByte(n),ReadFlashByte(n+channel+1));
1052            n+=15;
1053        }
1054        for(i=0;i<ReadFlashByte(0x43);i++) {
1055            Wifi_RFWrite( (ReadFlashByte(n)<<8) | ReadFlashByte(n+channel+1) | 0x050000 );
1056            n+=15;
1057        }
1058               
1059                swiDelay( 12583 ); // 1500 us delay
1060       
1061                break;
1062    default:
1063        break;
1064    }
1065        WifiData->curChannel=channel+1;
1066}
1067void Wifi_SetWepKey(void * wepkey) {
1068        int i;
1069        for(i=0;i<16;i++) {
1070                W_WEPKEY0[i]=((u16 *)wepkey)[i];
1071                W_WEPKEY1[i]=((u16 *)wepkey)[i];
1072                W_WEPKEY2[i]=((u16 *)wepkey)[i];
1073                W_WEPKEY3[i]=((u16 *)wepkey)[i];
1074        }
1075}
1076
1077void Wifi_SetWepMode(int wepmode) {
1078        if(wepmode<0 || wepmode>7) return;
1079   if(wepmode==0) {
1080      WIFI_REG(0x32)=0x0000;
1081   } else {
1082      WIFI_REG(0x32)=0x8000;
1083   }
1084   if(wepmode==0) wepmode=1;
1085        W_MODE_WEP = (W_MODE_WEP & 0xFFC7) | (wepmode<<3);
1086}
1087
1088void Wifi_SetBeaconPeriod(int beacon_period) {
1089        if(beacon_period<0x10 || beacon_period>0x3E7) return;
1090        WIFI_REG(0x8C)=beacon_period;
1091}
1092
1093void Wifi_SetMode(int wifimode) {
1094        if(wifimode>3 || wifimode<0) return;
1095        W_MODE_WEP = (W_MODE_WEP& 0xfff8) | wifimode;
1096}
1097void Wifi_SetPreambleType(int preamble_type) {
1098        if(preamble_type>1 || preamble_type<0) return;
1099        WIFI_REG(0x80BC) = (WIFI_REG(0x80BC) & 0xFFBF) | (preamble_type<<6);
1100}
1101void Wifi_DisableTempPowerSave() {
1102        WIFI_REG(0x8038) &= ~2;
1103        WIFI_REG(0x8048) = 0;
1104}
1105
1106
1107
1108
1109
1110//////////////////////////////////////////////////////////////////////////
1111//
1112//  802.11b system, tied in a bit with the :
1113
1114
1115int Wifi_TxQueue(u16 * data, int datalen) {
1116        int i,j;
1117        if(arm7qlen) {
1118                if(Wifi_TxCheck()) {
1119                        Wifi_TxRaw(arm7q,arm7qlen);
1120                        arm7qlen=0;
1121                        j=(datalen+1)>>1;
1122                        if(j>1024) return 0;
1123                        for(i=0;i<j;i++) arm7q[i]=data[i];
1124                        arm7qlen=datalen;
1125                        return 1;
1126                }
1127                return 0;
1128        }
1129        if(Wifi_TxCheck()) {
1130                Wifi_TxRaw(data,datalen);
1131                return 1;
1132        }
1133        arm7qlen=0;
1134        j=(datalen+1)>>1;
1135        if(j>1024) return 0;
1136        for(i=0;i<j;i++) arm7q[i]=data[i];
1137        arm7qlen=datalen;
1138        return 1;
1139}
1140
1141int Wifi_GenMgtHeader(u8 * data, u16 headerflags) {
1142        // tx header
1143        ((u16 *)data)[0]=0;
1144        ((u16 *)data)[1]=0;
1145        ((u16 *)data)[2]=0;
1146        ((u16 *)data)[3]=0;
1147        ((u16 *)data)[4]=0;
1148        ((u16 *)data)[5]=0;
1149        // fill in most header fields
1150        ((u16 *)data)[7]=0x0000;
1151        Wifi_CopyMacAddr(data+16,WifiData->apmac7);
1152        Wifi_CopyMacAddr(data+22,WifiData->MacAddr);
1153        Wifi_CopyMacAddr(data+28,WifiData->bssid7);
1154        ((u16 *)data)[17]=0;
1155
1156        // fill in wep-specific stuff
1157        if(headerflags&0x4000) {
1158                ((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.
1159                ((u16 *)data)[6]=headerflags;
1160                return 28+12;
1161        } else {
1162                ((u16 *)data)[6]=headerflags;
1163                return 24+12;
1164        }
1165}
1166
1167int Wifi_SendOpenSystemAuthPacket() {
1168        // max size is 12+24+4+6 = 46
1169        u8 data[64];
1170        int i;
1171        i=Wifi_GenMgtHeader(data,0x00B0);
1172
1173        ((u16 *)(data+i))[0]=0; // Authentication algorithm number (0=open system)
1174        ((u16 *)(data+i))[1]=1; // Authentication sequence number
1175        ((u16 *)(data+i))[2]=0; // Authentication status code (reserved for this message, =0)
1176
1177        ((u16 *)data)[4]=0x000A;
1178        ((u16 *)data)[5]=i+6-12+4;
1179
1180        return Wifi_TxQueue((u16 *)data, i+6);
1181}
1182
1183int Wifi_SendSharedKeyAuthPacket() {
1184        // max size is 12+24+4+6 = 46
1185        u8 data[64];
1186        int i;
1187        i=Wifi_GenMgtHeader(data,0x00B0);
1188
1189        ((u16 *)(data+i))[0]=1; // Authentication algorithm number (1=shared key)
1190        ((u16 *)(data+i))[1]=1; // Authentication sequence number
1191        ((u16 *)(data+i))[2]=0; // Authentication status code (reserved for this message, =0)
1192
1193        ((u16 *)data)[4]=0x000A;
1194        ((u16 *)data)[5]=i+6-12+4;
1195
1196        return Wifi_TxQueue((u16 *)data, i+6);
1197}
1198
1199int Wifi_SendSharedKeyAuthPacket2(int challenge_length, u8 * challenge_Text) {
1200        // max size is 12+24+4+6 = 46
1201        u8 data[320];
1202        int i,j;
1203        i=Wifi_GenMgtHeader(data,0x40B0);
1204
1205        ((u16 *)(data+i))[0]=1; // Authentication algorithm number (1=shared key)
1206        ((u16 *)(data+i))[1]=3; // Authentication sequence number
1207        ((u16 *)(data+i))[2]=0; // Authentication status code (reserved for this message, =0)
1208
1209    data[i+6]=0x10; // 16=challenge text block
1210    data[i+7]=challenge_length;
1211
1212        for(j=0;j<challenge_length;j++) {
1213                data[i+j+8]=challenge_Text[j];
1214        }
1215
1216        ((u16 *)data)[4]=0x000A;
1217        ((u16 *)data)[5]=i+8+challenge_length-12+4 +4;
1218
1219        return Wifi_TxQueue((u16 *)data, i+8+challenge_length);
1220}
1221
1222
1223int Wifi_SendAssocPacket() { // uses arm7 data in our struct
1224        // max size is 12+24+4+34+4 = 66
1225        u8 data[96];
1226        int i,j,numrates;
1227
1228        i=Wifi_GenMgtHeader(data,0x0000);
1229
1230        if(WifiData->wepmode7) {
1231                ((u16 *)(data+i))[0]=0x0031; // CAPS info
1232        } else {
1233                ((u16 *)(data+i))[0]=0x0021; // CAPS info
1234        }
1235       
1236        ((u16 *)(data+i))[1]=WIFI_REG(0x8E); // Listen interval
1237        i+=4;
1238        data[i++]=0; // SSID element
1239        data[i++]=WifiData->ssid7[0];
1240        for(j=0;j<WifiData->ssid7[0];j++) data[i++]=WifiData->ssid7[1+j];
1241
1242        if((WifiData->baserates7[0]&0x7f)!=2) {
1243                for(j=1;j<16;j++) WifiData->baserates7[i]=WifiData->baserates7[j-1];
1244        }
1245        WifiData->baserates7[0]=0x82;
1246        if((WifiData->baserates7[1]&0x7f)!=4) {
1247                for(j=2;j<16;j++) WifiData->baserates7[j]=WifiData->baserates7[j-1];
1248        }
1249        WifiData->baserates7[1]=0x04;
1250       
1251        WifiData->baserates7[15]=0;
1252        for(j=0;j<16;j++) if(WifiData->baserates7[j]==0) break;
1253        numrates=j;
1254        for(j=2;j<numrates;j++) WifiData->baserates7[j] &= 0x7F;
1255
1256        data[i++]=1; // rate set
1257        data[i++]=numrates;
1258        for(j=0;j<numrates;j++) data[i++]=WifiData->baserates7[j];
1259
1260        // reset header fields with needed data
1261        ((u16 *)data)[4]=0x000A;
1262        ((u16 *)data)[5]=i-12+4;
1263
1264        return Wifi_TxQueue((u16 *)data, i);
1265}
1266
1267int Wifi_SendNullFrame() {
1268        // max size is 12+16 = 28
1269        u8 data[32];
1270        // tx header
1271        ((u16 *)data)[0]=0;
1272        ((u16 *)data)[1]=0;
1273        ((u16 *)data)[2]=0;
1274        ((u16 *)data)[3]=0;
1275        ((u16 *)data)[4]=WifiData->maxrate7;
1276        ((u16 *)data)[5]=18+4;
1277        // fill in packet header fields
1278        ((u16 *)data)[6]=0x0148;
1279        ((u16 *)data)[7]=0;
1280        Wifi_CopyMacAddr(data+16,WifiData->apmac7);
1281        Wifi_CopyMacAddr(data+22,WifiData->MacAddr);
1282
1283        return Wifi_TxQueue((u16 *)data, 30);
1284}
1285
1286int Wifi_SendPSPollFrame() {
1287        // max size is 12+16 = 28
1288        u8 data[32];
1289        // tx header
1290        ((u16 *)data)[0]=0;
1291        ((u16 *)data)[1]=0;
1292        ((u16 *)data)[2]=0;
1293        ((u16 *)data)[3]=0;
1294        ((u16 *)data)[4]=WifiData->maxrate7;
1295        ((u16 *)data)[5]=16+4;
1296        // fill in packet header fields
1297        ((u16 *)data)[6]=0x01A4;
1298        ((u16 *)data)[7]=0xC000 | W_AIDS;
1299        Wifi_CopyMacAddr(data+16,WifiData->apmac7);
1300        Wifi_CopyMacAddr(data+22,WifiData->MacAddr);
1301
1302        return Wifi_TxQueue((u16 *)data, 28);
1303}
1304
1305int Wifi_ProcessReceivedFrame(int macbase, int framelen) {
1306        Wifi_RxHeader packetheader;
1307        u16 control_802;
1308        Wifi_MACCopy((u16 *)&packetheader,macbase,0,12);
1309        control_802=Wifi_MACRead(macbase,12);
1310        switch((control_802>>2)&0x3F) {
1311                // Management Frames
1312                case 0x20: // 1000 00 Beacon
1313        case 0x14: // 0101 00 Probe Response // process probe responses too.
1314                        // mine data from the beacon...
1315                        {
1316                                u8 data[512];
1317                                u8 wepmode,fromsta;
1318                                u8 segtype,seglen;
1319                                u8 channel;
1320                                u8 wpamode;
1321                                u8 rateset[16];
1322                                u16 ptr_ssid;
1323                                u16 maxrate;
1324                                u16 curloc;
1325                                u32 datalen;
1326                                u16 i,j,compatible;
1327                                datalen=packetheader.byteLength;
1328                                if(datalen>512) datalen=512;
1329                                Wifi_MACCopy((u16 *)data,macbase,12,(datalen+1)&~1);
1330                                wepmode=0;
1331                                maxrate=0;
1332                                if(((u16 *)data)[5+12]&0x0010) { // capability info, WEP bit
1333                                        wepmode=1;
1334                                }
1335                                fromsta=Wifi_CmpMacAddr(data+10, data+16);
1336                                curloc=12+24; // 12 fixed bytes, 24 802.11 header
1337                                compatible=1;
1338                                ptr_ssid=0;
1339                                channel=WifiData->curChannel;
1340                                wpamode=0;
1341                                do {
1342                                        if(curloc>=datalen) break;
1343                                        segtype=data[curloc++];
1344                                        seglen=data[curloc++];
1345                                        switch(segtype) {
1346                                        case 0: // SSID element
1347                                                ptr_ssid=curloc-2;
1348                                                break;
1349                                        case 1: // rate set (make sure we're compatible)
1350                                                compatible=0;
1351                                                maxrate=0;
1352                                                j=0;
1353                                                for(i=0;i<seglen;i++) {
1354                                                        if((data[curloc+i]&0x7F)>maxrate) maxrate=data[curloc+i]&0x7F;
1355                                                        if(j<15 && data[curloc+i]&0x80) rateset[j++]=data[curloc+i];
1356                                                }
1357                                                for(i=0;i<seglen;i++) {
1358                                                        if(data[curloc+i]==0x82 || data[curloc+i]==0x84) compatible=1;  // 1-2mbit, fully compatible
1359                                                        else if(data[curloc+i]==0x8B || data[curloc+i]==0x96) compatible=2; // 5.5,11mbit, have to fake our way in.
1360                                                        else if(data[curloc+i]&0x80) { compatible=0; break; }
1361                                                }
1362                                                rateset[j]=0;
1363                                                break;
1364                                        case 3: // DS set (current channel)
1365                                                channel=data[curloc];
1366                                                break;
1367                                        case 48: // RSN(A) field- WPA enabled.
1368                                                wpamode=1;
1369                                                break;
1370
1371                                        } // don't care about the others.
1372                                        curloc+=seglen;
1373                                } while(curloc<datalen);
1374                                if(wpamode==1) compatible=0;
1375                                if(1) {
1376                                        seglen=0;
1377                                        segtype=255;
1378                                        for(i=0;i<WIFI_MAX_AP;i++) {
1379                                                if(     Wifi_CmpMacAddr(WifiData->aplist[i].bssid,data+16)) {
1380                                                        seglen++;
1381                                                        if(Spinlock_Acquire(WifiData->aplist[i])==SPINLOCK_OK) {
1382                                                                WifiData->aplist[i].timectr=0;
1383                                                                WifiData->aplist[i].flags=WFLAG_APDATA_ACTIVE | (wepmode?WFLAG_APDATA_WEP:0) | (fromsta?0:WFLAG_APDATA_ADHOC);
1384                                                                if(compatible==1) WifiData->aplist[i].flags |= WFLAG_APDATA_COMPATIBLE;
1385                                                                if(compatible==2) WifiData->aplist[i].flags |= WFLAG_APDATA_EXTCOMPATIBLE;
1386                                                                if(wpamode==1) WifiData->aplist[i].flags |= WFLAG_APDATA_WPA;
1387                                                                WifiData->aplist[i].maxrate=maxrate;
1388
1389                                                                Wifi_CopyMacAddr(WifiData->aplist[i].macaddr,data+10); // src: +10
1390                                                                if(ptr_ssid) {
1391                                                                        WifiData->aplist[i].ssid_len=data[ptr_ssid+1];
1392                                                                        if(WifiData->aplist[i].ssid_len>32) WifiData->aplist[i].ssid_len=32;
1393                                                                        for(j=0;j<WifiData->aplist[i].ssid_len;j++) {
1394                                                                                WifiData->aplist[i].ssid[j]=data[ptr_ssid+2+j];
1395                                                                        }
1396                                                                        WifiData->aplist[i].ssid[j]=0;
1397                                                                }
1398                                                                if(WifiData->curChannel==channel) { // only use RSSI when we're on the right channel
1399                                                                        if(WifiData->aplist[i].rssi_past[0]==0) { // min rssi is 2, heh.
1400                                                                                WifiData->aplist[i].rssi_past[0]=WifiData->aplist[i].rssi_past[1]=
1401                                                                                        WifiData->aplist[i].rssi_past[2]=WifiData->aplist[i].rssi_past[3]=
1402                                                                                        WifiData->aplist[i].rssi_past[4]=WifiData->aplist[i].rssi_past[5]=
1403                                                                                        WifiData->aplist[i].rssi_past[6]=WifiData->aplist[i].rssi_past[7]=packetheader.rssi_&255;
1404                                                                        } else {
1405                                                                                for(j=0;j<7;j++) {
1406                                                                                        WifiData->aplist[i].rssi_past[j]=WifiData->aplist[i].rssi_past[j+1];
1407                                                                                }
1408                                                                                WifiData->aplist[i].rssi_past[7]=packetheader.rssi_&255;
1409                                                                        }
1410                                                                }
1411                                                                WifiData->aplist[i].channel=channel;
1412                                                                for(j=0;j<16;j++) WifiData->aplist[i].base_rates[j]=rateset[j];
1413                                                                Spinlock_Release(WifiData->aplist[i]);
1414                                                        } else {
1415                                                                // couldn't update beacon - oh well :\ there'll be other beacons.
1416                                                        }
1417                                                } else {
1418                                                        if(WifiData->aplist[i].flags & WFLAG_APDATA_ACTIVE) {
1419                                                        //      WifiData->aplist[i].timectr++;
1420                                                        } else {
1421                                                                if(segtype==255) segtype=i;
1422                                                        }
1423                                                }
1424                                        }
1425                                        if(seglen==0) { // we couldn't find an existing record
1426                                                if(segtype==255) {
1427                                                        j=0;
1428                                                        for(i=0;i<WIFI_MAX_AP;i++) {
1429                                                                if(WifiData->aplist[i].timectr>j) {
1430                                                                        j=WifiData->aplist[i].timectr;
1431                                                                        segtype=i;
1432                                                                }
1433                                                        }
1434                                                }
1435                                                // stuff new data in
1436                                                i=segtype;
1437                                                if(Spinlock_Acquire(WifiData->aplist[i])==SPINLOCK_OK) {
1438                                                        Wifi_CopyMacAddr(WifiData->aplist[i].bssid,data+16); // bssid: +16
1439                                                        Wifi_CopyMacAddr(WifiData->aplist[i].macaddr,data+10); // src: +10
1440                                                        WifiData->aplist[i].timectr=0;
1441                                                        WifiData->aplist[i].flags=WFLAG_APDATA_ACTIVE | (wepmode?WFLAG_APDATA_WEP:0) | (fromsta?0:WFLAG_APDATA_ADHOC);
1442                                                        if(compatible==1) WifiData->aplist[i].flags |= WFLAG_APDATA_COMPATIBLE;
1443                                                        if(compatible==2) WifiData->aplist[i].flags |= WFLAG_APDATA_EXTCOMPATIBLE;
1444                                                        if(wpamode==1) WifiData->aplist[i].flags |= WFLAG_APDATA_WPA;
1445                                                        WifiData->aplist[i].maxrate=maxrate;
1446
1447                                                        if(ptr_ssid) {
1448                                                                WifiData->aplist[i].ssid_len=data[ptr_ssid+1];
1449                                                                if(WifiData->aplist[i].ssid_len>32) WifiData->aplist[i].ssid_len=32;
1450                                                                for(j=0;j<WifiData->aplist[i].ssid_len;j++) {
1451                                                                        WifiData->aplist[i].ssid[j]=data[ptr_ssid+2+j];
1452                                                                }
1453                                                                WifiData->aplist[i].ssid[j]=0;
1454                                                        }
1455                                                        if(WifiData->curChannel==channel) { // only use RSSI when we're on the right channel
1456                                                                WifiData->aplist[i].rssi_past[0]=WifiData->aplist[i].rssi_past[1]=
1457                                                                        WifiData->aplist[i].rssi_past[2]=WifiData->aplist[i].rssi_past[3]=
1458                                                                        WifiData->aplist[i].rssi_past[4]=WifiData->aplist[i].rssi_past[5]=
1459                                                                        WifiData->aplist[i].rssi_past[6]=WifiData->aplist[i].rssi_past[7]=packetheader.rssi_&255;
1460                                                        } else {
1461                                                                WifiData->aplist[i].rssi_past[0]=WifiData->aplist[i].rssi_past[1]=
1462                                                                        WifiData->aplist[i].rssi_past[2]=WifiData->aplist[i].rssi_past[3]=
1463                                                                        WifiData->aplist[i].rssi_past[4]=WifiData->aplist[i].rssi_past[5]=
1464                                                                        WifiData->aplist[i].rssi_past[6]=WifiData->aplist[i].rssi_past[7]=0; // update rssi later.
1465                                                        }
1466                                                        WifiData->aplist[i].channel=channel;
1467                                                        for(j=0;j<16;j++) WifiData->aplist[i].base_rates[j]=rateset[j];
1468
1469                                                        Spinlock_Release(WifiData->aplist[i]);
1470                                                } else {
1471                                                        // couldn't update beacon - oh well :\ there'll be other beacons.
1472                                                }
1473                                        }
1474                                }
1475                        }
1476            if(((control_802>>2)&0x3F)==0x14) return WFLAG_PACKET_MGT;
1477                        return WFLAG_PACKET_BEACON;
1478                case 0x04: // 0001 00 Assoc Response
1479                case 0x0C: // 0011 00 Reassoc Response
1480                        // we might have been associated, let's check.
1481                        {
1482                                int datalen,i;
1483                                u8 data[64];
1484                                datalen=packetheader.byteLength;
1485                                if(datalen>64) datalen=64;
1486                                Wifi_MACCopy((u16 *)data,macbase,12,(datalen+1)&~1);
1487
1488                                if(Wifi_CmpMacAddr(data+4,WifiData->MacAddr)) { // packet is indeed sent to us.
1489                                        if(Wifi_CmpMacAddr(data+16,WifiData->bssid7)) { // packet is indeed from the base station we're trying to associate to.
1490                                                if(((u16 *)(data+24))[1]==0) { // status code, 0==success
1491                                                        W_AIDS=((u16 *)(data+24))[2];
1492                                                        WIFI_REG(0x2A)=((u16 *)(data+24))[2];
1493                                                        // set max rate
1494                                                        WifiData->maxrate7=0xA;
1495                                                        for(i=0;i<((u8 *)(data+24))[7];i++) {
1496                                                                if(((u8 *)(data+24))[8+i]==0x84 || ((u8 *)(data+24))[8+i]==0x04) {
1497                                                                        WifiData->maxrate7=0x14;
1498                                                                }
1499                                                        }
1500                                                        if(WifiData->authlevel==WIFI_AUTHLEVEL_AUTHENTICATED || WifiData->authlevel==WIFI_AUTHLEVEL_DEASSOCIATED) {
1501                                                                WifiData->authlevel=WIFI_AUTHLEVEL_ASSOCIATED;
1502                                                                WifiData->authctr=0;
1503                                                               
1504
1505                                                               
1506                                                        }
1507                                                } else { // status code = failure!
1508                                                        WifiData->curMode=WIFIMODE_CANNOTASSOCIATE;
1509                                                }
1510                                        }
1511                                }
1512                        }
1513
1514
1515                        return WFLAG_PACKET_MGT;
1516                case 0x00: // 0000 00 Assoc Request 
1517                case 0x08: // 0010 00 Reassoc Request
1518                case 0x10: // 0100 00 Probe Request
1519                case 0x24: // 1001 00 ATIM
1520                case 0x28: // 1010 00 Disassociation
1521                        return WFLAG_PACKET_MGT;
1522                case 0x2C: // 1011 00 Authentication
1523                        // check auth response to ensure we're in
1524                        {
1525                                int datalen;
1526                                u8 data[384];
1527                                datalen=packetheader.byteLength;
1528                                if(datalen>384) datalen=384;
1529                                Wifi_MACCopy((u16 *)data,macbase,12,(datalen+1)&~1);
1530
1531                                if(Wifi_CmpMacAddr(data+4,WifiData->MacAddr)) { // packet is indeed sent to us.
1532                                        if(Wifi_CmpMacAddr(data+16,WifiData->bssid7)) { // packet is indeed from the base station we're trying to associate to.
1533                        if(((u16 *)(data+24))[0]==0) { // open system auth
1534                            if(((u16 *)(data+24))[1]==2) { // seq 2, should be final sequence
1535                                if(((u16 *)(data+24))[2]==0) { // status code: successful
1536                                                                if(WifiData->authlevel==WIFI_AUTHLEVEL_DISCONNECTED) {
1537                                                                        WifiData->authlevel=WIFI_AUTHLEVEL_AUTHENTICATED;
1538                                                                        WifiData->authctr=0;
1539                                                                        Wifi_SendAssocPacket();
1540                                                                }
1541                                } else { // status code: rejected, try something else
1542                                    Wifi_SendSharedKeyAuthPacket();
1543                                }
1544                            }
1545                        } else if(((u16 *)(data+24))[0]==1) { // shared key auth
1546                            if(((u16 *)(data+24))[1]==2) { // seq 2, challenge text
1547                                if(((u16 *)(data+24))[2]==0) { // status code: successful
1548                                    // scrape challenge text and send challenge reply
1549                                    if(data[24+6]==0x10) { // 16 = challenge text - this value must be 0x10 or else!
1550                                        Wifi_SendSharedKeyAuthPacket2(data[24+7],data+24+8);                                       
1551                                    }
1552                                } else { // rejected, just give up.
1553                                    WifiData->curMode=WIFIMODE_CANNOTASSOCIATE;
1554                                }
1555                            } else if(((u16 *)(data+24))[1]==4) { // seq 4, accept/deny
1556                                if(((u16 *)(data+24))[2]==0) { // status code: successful
1557                                    if(WifiData->authlevel==WIFI_AUTHLEVEL_DISCONNECTED) {
1558                                        WifiData->authlevel=WIFI_AUTHLEVEL_AUTHENTICATED;
1559                                        WifiData->authctr=0;
1560                                        Wifi_SendAssocPacket();
1561                                    }
1562                                } else { // status code: rejected. Cry in the corner.
1563                                    WifiData->curMode=WIFIMODE_CANNOTASSOCIATE;
1564                                }
1565                            }
1566                        }
1567                                        }
1568                                }
1569                        }
1570                        return WFLAG_PACKET_MGT;
1571                case 0x30: // 1100 00 Deauthentication
1572                        {
1573                                int datalen;
1574                                u8 data[64];
1575                                datalen=packetheader.byteLength;
1576                                if(datalen>64) datalen=64;
1577                                Wifi_MACCopy((u16 *)data,macbase,12,(datalen+1)&~1);
1578
1579                                if(Wifi_CmpMacAddr(data+4,WifiData->MacAddr)) { // packet is indeed sent to us.
1580                                        if(Wifi_CmpMacAddr(data+16,WifiData->bssid7)) { // packet is indeed from the base station we're trying to associate to.
1581                                                // bad things! they booted us!.
1582                                                // back to square 1.
1583                                                if(WifiData->curReqFlags&WFLAG_REQ_APADHOC){
1584                                                        WifiData->authlevel=WIFI_AUTHLEVEL_AUTHENTICATED;
1585                                                        Wifi_SendAssocPacket();
1586                                                } else {
1587                                                        WifiData->authlevel=WIFI_AUTHLEVEL_DISCONNECTED;
1588                                                        Wifi_SendOpenSystemAuthPacket();
1589                                                }
1590                                        }
1591                                }
1592                        }
1593                        return WFLAG_PACKET_MGT;
1594                // Control Frames
1595                case 0x29: // 1010 01 PowerSave Poll
1596                case 0x2D: // 1011 01 RTS
1597                case 0x31: // 1100 01 CTS
1598                case 0x35: // 1101 01 ACK
1599                case 0x39: // 1110 01 CF-End
1600                case 0x3D: // 1111 01 CF-End+CF-Ack
1601                        return WFLAG_PACKET_CTRL;
1602                // Data Frames
1603                case 0x02: // 0000 10 Data
1604                case 0x06: // 0001 10 Data + CF-Ack
1605                case 0x0A: // 0010 10 Data + CF-Poll
1606                case 0x0E: // 0011 10 Data + CF-Ack + CF-Poll
1607                        // We like data!
1608
1609                        return WFLAG_PACKET_DATA;
1610                case 0x12: // 0100 10 Null Function
1611                case 0x16: // 0101 10 CF-Ack
1612                case 0x1A: // 0110 10 CF-Poll
1613                case 0x1E: // 0111 10 CF-Ack + CF-Poll
1614                        return WFLAG_PACKET_DATA;
1615                default: // ignore!
1616                return 0;
1617        }
1618}
1619int Wifi_CreateTxFrame(int frametype, void * dest, int destlen) {
1620        switch(frametype) {
1621
1622        default:
1623                return 0;
1624        }
1625}
1626
1627//////////////////////////////////////////////////////////////////////////
1628// sync functions
1629
1630void Wifi_Sync() {
1631   Wifi_Update();
1632}
1633void Wifi_SetSyncHandler(WifiSyncHandler sh) {
1634   synchandler=sh;
1635}
1636
1637
Note: See TracBrowser for help on using the repository browser.