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