00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <avr/io.h>
00019 #include <avr/interrupt.h>
00020 #include <string.h>
00021
00022 #include "global.h"
00023 #include "timer.h"
00024 #include "rprintf.h"
00025 #include "debug.h"
00026
00027 #include "net.h"
00028 #include "prism2.h"
00029
00030
00031 #include "prism2conf.h"
00032
00033 u16 TxHeader[34];
00034
00035 void nicInit(void)
00036 {
00037 prism2Init();
00038 }
00039
00040 void nicSend(unsigned int len, unsigned char* packet)
00041 {
00042 u16 i;
00043 u16 txfid;
00044 u08 stat;
00045
00046 prism2Command(PRISM2_CMD_ALLOC, len+44+14+6);
00047
00048 while( !(prism2Read16(PRISM2_REG_EVSTAT) & PRISM2_EVENT_ALLOC) );
00049
00050 txfid = prism2Read16(PRISM2_REG_ALLOCFID);
00051
00052 prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_ALLOC);
00053
00054
00055
00056
00057
00058
00059
00060 len-=14;
00061
00062
00063
00064 prism2SetupTxHeader(TxHeader);
00065
00066
00067 for(i=0;i<6;++i)
00068 TxHeader[23+i] = packet[i*2+1]<<8 | packet[i*2];
00069
00070 TxHeader[29] = htons(len+8);
00071
00072 TxHeader[33] = packet[13]<<8 | packet[12];
00073
00074
00075
00076
00077
00078
00079 prism2WriteBAP0(txfid, 0, TxHeader, 34);
00080
00081 prism2WriteBAP0(txfid, 68, (u16*)&packet[14], (len+1)>>1);
00082
00083 stat = prism2Command(PRISM2_CMD_TX, txfid);
00084 if(stat)
00085 rprintf("Transmit failed: 0x%x\r\n", stat);
00086
00087 prism2EventCheck();
00088 }
00089
00090 void nicGetMacAddress(u08* macaddr)
00091 {
00092 prism2GetMacAddress(macaddr);
00093 }
00094
00095 void nicSetMacAddress(u08* macaddr)
00096 {
00097
00098 }
00099
00100 void nicRegDump(void)
00101 {
00102 prism2CardRegDump();
00103 prism2RegDump();
00104 }
00105
00106 void prism2SetupTxHeader(u16* header)
00107 {
00108 u16 i;
00109
00110
00111 for(i=0;i<22;i++)
00112 header[i] = 0x00;
00113
00114
00115 header[5] = (0<<8) | 0;
00116
00117
00118
00119
00120
00121
00122
00123 header[6] = 0x0004;
00124
00125
00126
00127
00128
00129
00130 TxHeader[30] = 0xAAAA;
00131 TxHeader[31] = 0x0003;
00132 TxHeader[32] = 0x0000;
00133
00134
00135 }
00136
00137 void prism2EventCheck(void)
00138 {
00139 unsigned int evstat_data;
00140
00141 evstat_data = prism2Read16(PRISM2_REG_EVSTAT);
00142
00143 if(evstat_data & PRISM2_EVENT_TX)
00144 {
00145 prism2Write16(PRISM2_REG_EVACK,PRISM2_EVENT_TX);
00146 }
00147
00148 if(evstat_data & PRISM2_EVENT_TXEXEC)
00149 {
00150 prism2Write16(PRISM2_REG_EVACK,PRISM2_EVENT_TXEXEC);
00151 }
00152
00153 if(evstat_data & PRISM2_EVENT_ALLOC)
00154 {
00155 prism2Write16(PRISM2_REG_EVACK, 0x0002);
00156 }
00157
00158 if(evstat_data & PRISM2_EVENT_CMD)
00159 {
00160 prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_CMD);
00161 }
00162
00163 if(evstat_data & PRISM2_EVENT_INFO)
00164 {
00165 prism2Read16(PRISM2_REG_INFOFID);
00166 prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_INFO);
00167 }
00168
00169 if(evstat_data & PRISM2_EVENT_INFDROP)
00170 {
00171 prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_INFDROP);
00172 }
00173
00174 if(evstat_data & PRISM2_EVENT_WTERR)
00175 {
00176 prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_WTERR);
00177 }
00178 }
00179
00180
00181 unsigned int nicPoll(unsigned int maxlen, unsigned char* packet)
00182 {
00183 u16 rxfid=0;
00184 u16 packetLength=0;
00185
00186
00187 if(prism2Read16(PRISM2_REG_EVSTAT) & PRISM2_EVENT_RX)
00188 {
00189
00190
00191 rxfid = prism2Read16(PRISM2_REG_RXFID);
00192
00193 prism2ReadBAP0(rxfid, 44, &packetLength, 1);
00194 }
00195
00196
00197 if( !packetLength )
00198 return 0;
00199
00200
00201 if( packetLength > maxlen )
00202 {
00203
00204 prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_RX);
00205 return 0;
00206 }
00207
00208
00209
00210
00211
00212 prism2ReadBAP0(rxfid, 46, (u16*)&packet[0], 6);
00213
00214
00215 prism2ReadBAP0(rxfid, 46+12+8, (u16*)&packet[12], packetLength-6);
00216
00217 prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_RX);
00218
00219 return packetLength;
00220 }
00221
00222 void prism2InitPorts(void)
00223 {
00224 #if NIC_CONNECTION == MEMORY_MAPPED
00225
00226 sbi(MCUSR, SRE);
00227 #else
00228
00229 outb(PRISM2_ADDRESS_DDR, PRISM2_ADDRESS_MASK);
00230 outb(PRISM2_HADDRESS_DDR, PRISM2_HADDRESS_MASK);
00231
00232
00233 outb(PRISM2_DATA_DDR, 0x00);
00234 outb(PRISM2_DATA_PORT, 0xFF);
00235
00236
00237 sbi( PRISM2_CONTROL_PORT, PRISM2_CONTROL_IORD );
00238 sbi( PRISM2_CONTROL_PORT, PRISM2_CONTROL_IOWR );
00239 sbi( PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMRD );
00240 sbi( PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMWR );
00241
00242 sbi( PRISM2_CONTROL_DDR, PRISM2_CONTROL_IORD );
00243 sbi( PRISM2_CONTROL_DDR, PRISM2_CONTROL_IOWR );
00244 sbi( PRISM2_CONTROL_DDR, PRISM2_CONTROL_MEMRD );
00245 sbi( PRISM2_CONTROL_DDR, PRISM2_CONTROL_MEMWR );
00246 #endif
00247
00248 sbi( PRISM2_RESET_DDR, PRISM2_RESET_PIN );
00249
00250
00251 sbi(DDRB, 6);
00252 cbi(PORTB, 6);
00253
00254 cbi(DDRB, 7);
00255 sbi(PORTB, 7);
00256 }
00257
00258 void prism2Init(void)
00259 {
00260 u08 result;
00261 u16 buffer[20];
00262
00263
00264 prism2InitPorts();
00265
00266
00267 sbi( PRISM2_RESET_PORT, PRISM2_RESET_PIN );
00268
00269 delay_ms(10);
00270
00271 cbi( PRISM2_RESET_PORT, PRISM2_RESET_PIN );
00272 delay_ms(100);
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 prism2WriteMem(0x3E0+PCMCIA_ATTR_COR, prism2ReadMem(0x3E0+PCMCIA_ATTR_COR) | 0x01);
00291
00292
00293 rprintf("Prism2 Initializing...\r\n");
00294 if( (result = prism2Command(PRISM2_CMD_INIT,0)) )
00295 {
00296 rprintf("Prism2 Initialization Failure\r\n");
00297 rprintf("Result Code = %x\r\n",result);
00298 }
00299
00300 rprintf("Prism2 Initialized\r\n");
00301
00302
00303 prism2SetSSID("airdrop");
00304
00305
00306 buffer[0] = 0x0002;
00307 buffer[1] = PRISM2_RID_CNFMAXDATALEN;
00308 buffer[2] = 0x05DC;
00309 prism2WriteRID(PRISM2_RID_CNFMAXDATALEN, 0, buffer, 3);
00310
00311
00312 buffer[0] = 0x0002;
00313 buffer[1] = PRISM2_RID_CNFPORTTYPE;
00314
00315 buffer[2] = 0x0001;
00316 prism2WriteRID(PRISM2_RID_CNFPORTTYPE, 0, buffer, 3);
00317
00318
00319
00320
00321
00322
00323
00324
00325 prism2Command(PRISM2_CMD_ENABLE_MAC0,0);
00326 }
00327
00328 void prism2Off(void)
00329 {
00330
00331 prism2Command(PRISM2_CMD_DISABLE_MAC0,0);
00332
00333 delay_ms(100);
00334
00335 prism2Command(PRISM2_CMD_INIT,0);
00336 }
00337
00338 void prism2GetMacAddress(u08* macaddr)
00339 {
00340 u16 buffer[5];
00341
00342
00343 prism2ReadRID(PRISM2_RID_CNFOWNMACADDR, 0, buffer, 5);
00344
00345 *macaddr++ = buffer[2];
00346 *macaddr++ = buffer[2]>>8;
00347 *macaddr++ = buffer[3];
00348 *macaddr++ = buffer[3]>>8;
00349 *macaddr++ = buffer[4];
00350 *macaddr++ = buffer[4]>>8;
00351 }
00352
00353 void prism2SetSSID(u08* ssid)
00354 {
00355 u16 buffer[12];
00356
00357
00358 buffer[0] = 0x0012;
00359 buffer[1] = PRISM2_RID_CNFDESIREDSSID;
00360 buffer[2] = strlen(ssid);
00361
00362 strcpy((unsigned char*)&buffer[3], ssid);
00363
00364 prism2WriteRID(PRISM2_RID_CNFDESIREDSSID, 0, buffer, buffer[0]);
00365 }
00366
00367 void prism2SetWEPKey(u08* wepkey)
00368 {
00369 u16 buffer[9];
00370
00371
00372 buffer[0] = 0x0008;
00373 buffer[1] = PRISM2_RID_CNFWEPDEFAULTKEY0;
00374
00375 strncpy((unsigned char*)&buffer[2], wepkey, 13);
00376 buffer[8] &= 0x00FF;
00377
00378 prism2WriteRID(PRISM2_RID_CNFWEPDEFAULTKEY0, 0, buffer, buffer[0]);
00379
00380
00381 buffer[0] = 0x0002;
00382 buffer[1] = PRISM2_RID_CNFWEPFLAGS;
00383 buffer[2] = 0x0001;
00384 prism2WriteRID(PRISM2_RID_CNFWEPFLAGS, 0, buffer, buffer[0]);
00385
00386 buffer[0] = 0x0002;
00387 buffer[1] = 0xfc2a;
00388 buffer[2] = 0x0001;
00389 prism2WriteRID(0xfc2a, 0, buffer, buffer[0]);
00390
00391 buffer[0] = 0x0002;
00392 buffer[1] = 0xfc23;
00393 buffer[2] = 0x0000;
00394 prism2WriteRID(0xfc23, 0, buffer, buffer[0]);
00395
00396 }
00397
00398 u08 prism2Command(u16 cmd, u16 param0)
00399 {
00400 u16 result;
00401
00402
00403
00404 while(prism2Read16(PRISM2_REG_CMD) & PRISM2_CMD_BUSY);
00405
00406
00407 prism2Write16(PRISM2_REG_PARAM0, param0);
00408 prism2Write16(PRISM2_REG_CMD, cmd);
00409
00410
00411
00412 while(prism2Read16(PRISM2_REG_CMD) & PRISM2_CMD_BUSY);
00413
00414
00415
00416 while(!(prism2Read16(PRISM2_REG_EVSTAT) & PRISM2_EVENT_CMD));
00417
00418
00419 result = prism2Read16(PRISM2_REG_STATUS)>>8;
00420
00421
00422
00423
00424
00425 prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_CMD);
00426
00427
00428 return result;
00429 }
00430
00431 u08 prism2ReadRID(u16 id, u16 offset, u16* data, u16 len)
00432 {
00433 prism2Command(PRISM2_CMD_ACCESS_RD, id);
00434 return prism2ReadBAP0(id, offset, data, len);
00435 }
00436
00437 u08 prism2WriteRID(u16 id, u16 offset, u16* data, u16 len)
00438 {
00439 u08 result;
00440 result = prism2WriteBAP0(id, offset, data, len);
00441 prism2Command(PRISM2_CMD_ACCESS_WR, id);
00442 return result;
00443 }
00444
00445 u08 prism2ReadBAP0(u16 id, u16 offset, u16* data, u16 len)
00446 {
00447
00448
00449 while( prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_BUSY);
00450
00451 prism2Write16(PRISM2_REG_BAP0SEL, id);
00452
00453 prism2Write16(PRISM2_REG_BAP0OFFSET, offset);
00454
00455
00456 while( prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_BUSY);
00457
00458 if(prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_ERROR)
00459 return -1;
00460
00461
00462 while(len--)
00463 *data++ = prism2Read16(PRISM2_REG_BAP0DATA);
00464
00465 return 0;
00466 }
00467
00468 u08 prism2WriteBAP0(u16 id, u16 offset, u16* data, u16 len)
00469 {
00470
00471
00472 while( prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_BUSY);
00473
00474 prism2Write16(PRISM2_REG_BAP0SEL, id);
00475
00476 prism2Write16(PRISM2_REG_BAP0OFFSET, offset);
00477
00478
00479 while( prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_BUSY);
00480
00481 if(prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_ERROR)
00482 return -1;
00483
00484
00485 while(len--)
00486 prism2Write16(PRISM2_REG_BAP0DATA, *data++);
00487
00488 return 0;
00489 }
00490
00491 void prism2Write(unsigned short address, unsigned char data)
00492 {
00493 cli();
00494
00495 outb(PRISM2_HADDRESS_PORT, (address>>8) | (inb(PRISM2_HADDRESS_PORT)&~PRISM2_HADDRESS_MASK));
00496 outb(PRISM2_ADDRESS_PORT, address | (inb(PRISM2_ADDRESS_PORT)&~PRISM2_ADDRESS_MASK));
00497
00498 outb(PRISM2_DATA_DDR, 0xFF);
00499
00500 outb(PRISM2_DATA_PORT, data);
00501
00502 cbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_IOWR);
00503
00504 PRISM2_IO_ACCESS_DELAY;
00505
00506 sbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_IOWR);
00507
00508 outb(PRISM2_DATA_DDR, 0x00);
00509 outb(PRISM2_DATA_PORT, 0xFF);
00510 sei();
00511 }
00512
00513 unsigned char prism2Read(unsigned short address)
00514 {
00515 unsigned char data;
00516 cli();
00517
00518 outb(PRISM2_HADDRESS_PORT, (address>>8) | (inb(PRISM2_HADDRESS_PORT)&~PRISM2_HADDRESS_MASK));
00519 outb(PRISM2_ADDRESS_PORT, address | (inb(PRISM2_ADDRESS_PORT)&~PRISM2_ADDRESS_MASK));
00520
00521 outb(PRISM2_DATA_DDR, 0x00);
00522 outb(PRISM2_DATA_PORT, 0xFF);
00523
00524 cbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_IORD);
00525
00526 PRISM2_IO_ACCESS_DELAY;
00527
00528 data = inb( PRISM2_DATA_PIN );
00529
00530 sbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_IORD);
00531
00532 sei();
00533 return data;
00534 }
00535
00536 void prism2Write16(unsigned short address, unsigned short data)
00537 {
00538 prism2Write(address, data);
00539 prism2Write(address+1, data>>8);
00540 }
00541
00542 unsigned short prism2Read16(unsigned short address)
00543 {
00544 return prism2Read(address) | (prism2Read(address+1)<<8);
00545 }
00546
00547 void prism2WriteMem(unsigned short address, unsigned short data)
00548 {
00549 cli();
00550
00551 outb(PRISM2_HADDRESS_PORT, (address>>8) | (inb(PRISM2_HADDRESS_PORT)&~PRISM2_HADDRESS_MASK));
00552 outb(PRISM2_ADDRESS_PORT, address | (inb(PRISM2_ADDRESS_PORT)&~PRISM2_ADDRESS_MASK));
00553
00554 outb(PRISM2_DATA_DDR, 0xFF);
00555
00556 outb(PRISM2_DATA_PORT, data);
00557
00558 cbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMWR);
00559
00560 PRISM2_MEM_ACCESS_DELAY;
00561
00562 sbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMWR);
00563
00564 outb(PRISM2_DATA_DDR, 0x00);
00565 outb(PRISM2_DATA_PORT, 0xFF);
00566 sei();
00567 }
00568
00569 unsigned short prism2ReadMem(unsigned short address)
00570 {
00571 unsigned char data;
00572 cli();
00573
00574 outb(PRISM2_HADDRESS_PORT, (address>>8) | (inb(PRISM2_HADDRESS_PORT)&~PRISM2_HADDRESS_MASK));
00575 outb(PRISM2_ADDRESS_PORT, address | (inb(PRISM2_ADDRESS_PORT)&~PRISM2_ADDRESS_MASK));
00576
00577 outb(PRISM2_DATA_DDR, 0x00);
00578 outb(PRISM2_DATA_PORT, 0xFF);
00579
00580 cbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMRD);
00581
00582 PRISM2_MEM_ACCESS_DELAY;
00583
00584 data = inb( PRISM2_DATA_PIN );
00585
00586 sbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMRD);
00587 sei();
00588
00589 return data;
00590 }
00591
00592 void prism2CardRegDump(void)
00593 {
00594 u16 i;
00595 u08 buffer[0x100];
00596
00597 rprintfProgStrM("Card Config Registers\r\n");
00598 rprintfProgStrM("-------------------------------\r\n");
00599
00600 rprintf("CIS : \r\n");
00601 for(i=0; i<0x100; i++)
00602 buffer[i] = prism2ReadMem(i<<1);
00603 debugPrintHexTable(0x100, buffer);
00604
00605 rprintfCRLF();
00606
00607 rprintf("COR : "); rprintfu08(prism2ReadMem(0x3E0+PCMCIA_ATTR_COR)); rprintfCRLF();
00608 rprintf("CSR : "); rprintfu08(prism2ReadMem(0x3E0+PCMCIA_ATTR_CSR)); rprintfCRLF();
00609 rprintf("PRR : "); rprintfu08(prism2ReadMem(0x3E0+PCMCIA_ATTR_PRR)); rprintfCRLF();
00610 rprintf("SCR : "); rprintfu08(prism2ReadMem(0x3E0+PCMCIA_ATTR_SCR)); rprintfCRLF();
00611 }
00612
00613 void prism2RegDump(void)
00614 {
00615 rprintfProgStrM("Prism2 Registers\r\n");
00616 rprintfProgStrM("CMD : "); rprintfu16(prism2Read16(PRISM2_REG_CMD)); rprintfCRLF();
00617 rprintfProgStrM("PARAM0 : "); rprintfu16(prism2Read16(PRISM2_REG_PARAM0)); rprintfCRLF();
00618 rprintfProgStrM("PARAM1 : "); rprintfu16(prism2Read16(PRISM2_REG_PARAM1)); rprintfCRLF();
00619 rprintfProgStrM("PARAM2 : "); rprintfu16(prism2Read16(PRISM2_REG_PARAM2)); rprintfCRLF();
00620 rprintfProgStrM("STATUS : "); rprintfu16(prism2Read16(PRISM2_REG_STATUS)); rprintfCRLF();
00621 rprintfProgStrM("RESP0 : "); rprintfu16(prism2Read16(PRISM2_REG_RESP0)); rprintfCRLF();
00622 rprintfProgStrM("RESP1 : "); rprintfu16(prism2Read16(PRISM2_REG_RESP1)); rprintfCRLF();
00623 rprintfProgStrM("RESP2 : "); rprintfu16(prism2Read16(PRISM2_REG_RESP2)); rprintfCRLF();
00624
00625 rprintfProgStrM("INFOFID : "); rprintfu16(prism2Read16(PRISM2_REG_INFOFID)); rprintfCRLF();
00626 rprintfProgStrM("RXFID : "); rprintfu16(prism2Read16(PRISM2_REG_RXFID)); rprintfCRLF();
00627 rprintfProgStrM("ALLOCFID: "); rprintfu16(prism2Read16(PRISM2_REG_ALLOCFID)); rprintfCRLF();
00628 rprintfProgStrM("TXFID : "); rprintfu16(prism2Read16(PRISM2_REG_TXFID)); rprintfCRLF();
00629
00630 rprintfProgStrM("BAP0SEL : "); rprintfu16(prism2Read16(PRISM2_REG_BAP0SEL)); rprintfCRLF();
00631 rprintfProgStrM("BAP0OFFS: "); rprintfu16(prism2Read16(PRISM2_REG_BAP0OFFSET)); rprintfCRLF();
00632 rprintfProgStrM("BAP0DATA: "); rprintfu16(prism2Read16(PRISM2_REG_BAP0DATA)); rprintfCRLF();
00633
00634 rprintfProgStrM("BAP1SEL : "); rprintfu16(prism2Read16(PRISM2_REG_BAP1SEL)); rprintfCRLF();
00635 rprintfProgStrM("BAP1OFFS: "); rprintfu16(prism2Read16(PRISM2_REG_BAP1OFFSET)); rprintfCRLF();
00636 rprintfProgStrM("BAP1DATA: "); rprintfu16(prism2Read16(PRISM2_REG_BAP1DATA)); rprintfCRLF();
00637
00638 rprintfProgStrM("EVSTAT : "); rprintfu16(prism2Read16(PRISM2_REG_EVSTAT)); rprintfCRLF();
00639 rprintfProgStrM("INTEN : "); rprintfu16(prism2Read16(PRISM2_REG_INTEN)); rprintfCRLF();
00640 rprintfProgStrM("EVACK : "); rprintfu16(prism2Read16(PRISM2_REG_EVACK)); rprintfCRLF();
00641
00642 rprintfProgStrM("SWSUP0 : "); rprintfu16(prism2Read16(PRISM2_REG_SWSUP0)); rprintfCRLF();
00643 rprintfProgStrM("SWSUP0 : "); rprintfu16(prism2Read16(PRISM2_REG_SWSUP1)); rprintfCRLF();
00644 rprintfProgStrM("SWSUP0 : "); rprintfu16(prism2Read16(PRISM2_REG_SWSUP2)); rprintfCRLF();
00645
00646 rprintfProgStrM("AUXPAGE : "); rprintfu16(prism2Read16(PRISM2_REG_AUXPAGE)); rprintfCRLF();
00647 rprintfProgStrM("AUXOFFS : "); rprintfu16(prism2Read16(PRISM2_REG_AUXOFFSET)); rprintfCRLF();
00648 rprintfProgStrM("AUXDATA : "); rprintfu16(prism2Read16(PRISM2_REG_AUXDATA)); rprintfCRLF();
00649
00650 delay_ms(25);
00651 }