00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 FILE_LICENCE ( GPL2_OR_LATER );
00017
00018 #include <etherboot.h>
00019 #include <nic.h>
00020 #include <gpxe/pci.h>
00021 #include <gpxe/ethernet.h>
00022
00023
00024
00025
00026
00027
00028 static const char hardcoded_ssid[] = "";
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #define MAX_JOIN_INFO_COUNT 2
00040
00041
00042
00043
00044
00045 #ifndef WLAN_HOSTIF
00046 #define WLAN_HOSTIF WLAN_PLX
00047 #endif
00048
00049
00050
00051
00052
00053
00054 #define __LINUX_WLAN__
00055 #undef __KERNEL__
00056 #define __I386__
00057 #include "wlan_compat.h"
00058 #include "p80211hdr.h"
00059 #include "hfa384x.h"
00060 #define BAP_TIMEOUT ( 5000 )
00061
00062
00063
00064
00065
00066 #include <errno.h>
00067 #define __le16_to_cpu(x) (x)
00068 #define __le32_to_cpu(x) (x)
00069 #define __cpu_to_le16(x) (x)
00070 #define __cpu_to_le32(x) (x)
00071
00072 #define hfa384x2host_16(n) (__le16_to_cpu((UINT16)(n)))
00073 #define hfa384x2host_32(n) (__le32_to_cpu((UINT32)(n)))
00074 #define host2hfa384x_16(n) (__cpu_to_le16((UINT16)(n)))
00075 #define host2hfa384x_32(n) (__cpu_to_le32((UINT32)(n)))
00076
00077
00078
00079
00080
00081
00082 #define PLX_LOCAL_CONFIG_REGISTER_BASE ( PCI_BASE_ADDRESS_1 )
00083 #define PLX_LOCAL_ADDRESS_SPACE_0_BASE ( PCI_BASE_ADDRESS_2 )
00084 #define PLX_LOCAL_ADDRESS_SPACE_1_BASE ( PCI_BASE_ADDRESS_3 )
00085 #define PLX_LOCAL_ADDRESS_SPACE_2_BASE ( PCI_BASE_ADDRESS_4 )
00086 #define PLX_LOCAL_ADDRESS_SPACE_3_BASE ( PCI_BASE_ADDRESS_5 )
00087
00088 #define PRISM2_PLX_ATTR_MEM_BASE ( PLX_LOCAL_ADDRESS_SPACE_0_BASE )
00089 #define PRISM2_PLX_IO_BASE ( PLX_LOCAL_ADDRESS_SPACE_1_BASE )
00090
00091 #define PRISM2_PCI_MEM_BASE ( PCI_BASE_ADDRESS_0 )
00092
00093
00094
00095
00096
00097
00098 #define CISTPL_VERS_1 ( 0x15 )
00099 #define CISTPL_END ( 0xff )
00100
00101 #define CIS_STEP ( 2 )
00102 #define CISTPL_HEADER_LEN ( 2 * CIS_STEP )
00103 #define CISTPL_LEN_OFF ( 1 * CIS_STEP )
00104 #define CISTPL_VERS_1_STR_OFF ( 4 * CIS_STEP )
00105
00106
00107
00108
00109
00110
00111 #define COR_OFFSET ( 0x3e0 )
00112 #define COR_VALUE ( 0x41 )
00113
00114
00115
00116
00117
00118
00119
00120 typedef struct hfa384x
00121 {
00122 UINT32 iobase;
00123 void *membase;
00124 UINT16 lastcmd;
00125 UINT16 status;
00126 UINT16 resp0;
00127 UINT16 resp1;
00128 UINT16 resp2;
00129 UINT8 bssid[WLAN_BSSID_LEN];
00130 } hfa384x_t;
00131
00132
00133 static hfa384x_t hw_global = {
00134 0, 0, 0, 0, 0, 0, 0, {0,0,0,0,0,0}
00135 };
00136
00137
00138
00139
00140
00141
00142 typedef struct wlan_llc
00143 {
00144 UINT8 dsap;
00145 UINT8 ssap;
00146 UINT8 ctl;
00147 } wlan_llc_t;
00148
00149 static const wlan_llc_t wlan_llc_snap = { 0xaa, 0xaa, 0x03 };
00150
00151 #define WLAN_IEEE_OUI_LEN 3
00152 typedef struct wlan_snap
00153 {
00154 UINT8 oui[WLAN_IEEE_OUI_LEN];
00155 UINT16 type;
00156 } wlan_snap_t;
00157
00158 typedef struct wlan_80211hdr
00159 {
00160 wlan_llc_t llc;
00161 wlan_snap_t snap;
00162 } wlan_80211hdr_t;
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 static inline UINT16 hfa384x_getreg( hfa384x_t *hw, UINT reg )
00176 {
00177 #if (WLAN_HOSTIF == WLAN_PLX)
00178 return inw ( hw->iobase + reg );
00179 #elif (WLAN_HOSTIF == WLAN_PCI)
00180 return readw ( hw->membase + reg );
00181 #endif
00182 }
00183
00184
00185 static inline void hfa384x_setreg( hfa384x_t *hw, UINT16 val, UINT reg )
00186 {
00187 #if (WLAN_HOSTIF == WLAN_PLX)
00188 outw ( val, hw->iobase + reg );
00189 #elif (WLAN_HOSTIF == WLAN_PCI)
00190 writew ( val, hw->membase + reg );
00191 #endif
00192 return;
00193 }
00194
00195
00196
00197
00198
00199 static inline UINT16 hfa384x_getreg_noswap( hfa384x_t *hw, UINT reg )
00200 {
00201 return hfa384x_getreg ( hw, reg );
00202 }
00203 static inline void hfa384x_setreg_noswap( hfa384x_t *hw, UINT16 val, UINT reg )
00204 {
00205 hfa384x_setreg ( hw, val, reg );
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 static int hfa384x_docmd_wait( hfa384x_t *hw, UINT16 cmd, UINT16 parm0, UINT16 parm1, UINT16 parm2)
00231 {
00232 UINT16 reg = 0;
00233 UINT16 counter = 0;
00234
00235
00236 counter = 0;
00237 reg = hfa384x_getreg(hw, HFA384x_CMD);
00238 while ( HFA384x_CMD_ISBUSY(reg) && (counter < 10) ) {
00239 reg = hfa384x_getreg(hw, HFA384x_CMD);
00240 counter++;
00241 udelay(10);
00242 }
00243 if (HFA384x_CMD_ISBUSY(reg)) {
00244 printf("hfa384x_cmd timeout(1), reg=0x%0hx.\n", reg);
00245 return -ETIMEDOUT;
00246 }
00247
00248
00249 hfa384x_setreg(hw, parm0, HFA384x_PARAM0);
00250 hfa384x_setreg(hw, parm1, HFA384x_PARAM1);
00251 hfa384x_setreg(hw, parm2, HFA384x_PARAM2);
00252 hw->lastcmd = cmd;
00253 hfa384x_setreg(hw, cmd, HFA384x_CMD);
00254
00255
00256 counter = 0;
00257 reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
00258
00259
00260
00261
00262 while ( !HFA384x_EVSTAT_ISCMD(reg) && (counter < 5000)) {
00263 reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
00264 counter++;
00265 udelay(200);
00266 }
00267 if ( ! HFA384x_EVSTAT_ISCMD(reg) ) {
00268 printf("hfa384x_cmd timeout(2), reg=0x%0hx.\n", reg);
00269 return -ETIMEDOUT;
00270 }
00271
00272
00273 hw->status = hfa384x_getreg(hw, HFA384x_STATUS);
00274 hw->resp0 = hfa384x_getreg(hw, HFA384x_RESP0);
00275 hw->resp1 = hfa384x_getreg(hw, HFA384x_RESP1);
00276 hw->resp2 = hfa384x_getreg(hw, HFA384x_RESP2);
00277 hfa384x_setreg(hw, HFA384x_EVACK_CMD, HFA384x_EVACK);
00278 return HFA384x_STATUS_RESULT_GET(hw->status);
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 static int hfa384x_prepare_bap(hfa384x_t *hw, UINT16 id, UINT16 offset)
00293 {
00294 int result = 0;
00295 UINT16 reg;
00296 UINT16 i;
00297
00298
00299 if ( (offset > HFA384x_BAP_OFFSET_MAX) || (offset % 2) ) {
00300 result = -EINVAL;
00301 } else {
00302
00303 hfa384x_setreg(hw, id, HFA384x_SELECT0);
00304 udelay(10);
00305 hfa384x_setreg(hw, offset, HFA384x_OFFSET0);
00306
00307 i = 0;
00308 do {
00309 reg = hfa384x_getreg(hw, HFA384x_OFFSET0);
00310 if ( i > 0 ) udelay(2);
00311 i++;
00312 } while ( i < BAP_TIMEOUT && HFA384x_OFFSET_ISBUSY(reg));
00313 if ( i >= BAP_TIMEOUT ) {
00314
00315 result = reg;
00316 } else if ( HFA384x_OFFSET_ISERR(reg) ){
00317
00318 result = reg;
00319 }
00320 }
00321 return result;
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 static int hfa384x_copy_from_bap(hfa384x_t *hw, UINT16 id, UINT16 offset,
00337 void *buf, UINT len)
00338 {
00339 int result = 0;
00340 UINT8 *d = (UINT8*)buf;
00341 UINT16 i;
00342 UINT16 reg = 0;
00343
00344
00345 result = hfa384x_prepare_bap ( hw, id, offset );
00346 if ( result == 0 ) {
00347
00348 for ( i = 0; i < (len & 0xfffe); i+=2 ) {
00349 *(UINT16*)(&(d[i])) = hfa384x_getreg_noswap(hw, HFA384x_DATA0);
00350 }
00351
00352 if ( len % 2 ){
00353 reg = hfa384x_getreg_noswap(hw, HFA384x_DATA0);
00354 d[len-1] = ((UINT8*)(®))[0];
00355 }
00356 }
00357 if (result) {
00358 printf ( "copy_from_bap(%#hx, %#hx, %d) failed, result=%#hx\n", id, offset, len, result);
00359 }
00360 return result;
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375 static int hfa384x_copy_to_bap(hfa384x_t *hw, UINT16 id, UINT16 offset,
00376 void *buf, UINT len)
00377 {
00378 int result = 0;
00379 UINT8 *d = (UINT8*)buf;
00380 UINT16 i;
00381 UINT16 savereg;
00382
00383
00384 result = hfa384x_prepare_bap ( hw, id, offset );
00385 if ( result == 0 ) {
00386
00387 for ( i = 0; i < (len & 0xfffe); i+=2 ) {
00388 hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), HFA384x_DATA0);
00389 }
00390
00391 if ( len % 2 ){
00392 savereg = hfa384x_getreg_noswap(hw, HFA384x_DATA0);
00393 result = hfa384x_prepare_bap ( hw, id, offset + (len & 0xfffe) );
00394 if ( result == 0 ) {
00395 ((UINT8*)(&savereg))[0] = d[len-1];
00396 hfa384x_setreg_noswap(hw, savereg, HFA384x_DATA0);
00397 }
00398 }
00399 }
00400 if (result) {
00401 printf ( "copy_to_bap(%#hx, %#hx, %d) failed, result=%#hx\n", id, offset, len, result);
00402 }
00403 return result;
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418 static inline int hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid)
00419 {
00420 return hfa384x_docmd_wait(hw, HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ACCESS) | HFA384x_CMD_WRITE_SET(write), rid, 0, 0);
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 static int hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len)
00438 {
00439 int result = 0;
00440 hfa384x_rec_t rec;
00441
00442
00443 result = hfa384x_cmd_access( hw, 0, rid);
00444 if ( result ) {
00445 printf("Call to hfa384x_cmd_access failed\n");
00446 return -1;
00447 }
00448
00449 result = hfa384x_copy_from_bap( hw, rid, 0, &rec, sizeof(rec));
00450 if ( result ) {
00451 return -1;
00452 }
00453
00454 if ( ((hfa384x2host_16(rec.reclen)-1)*2) != len ) {
00455 printf ( "RID len mismatch, rid=%#hx hlen=%d fwlen=%d\n", rid, len, (hfa384x2host_16(rec.reclen)-1)*2);
00456 return -1;
00457 }
00458
00459 result = hfa384x_copy_from_bap( hw, rid, sizeof(rec), buf, len);
00460 return result;
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 #if 0
00476 static int hfa384x_drvr_getconfig16(hfa384x_t *hw, UINT16 rid, void *val)
00477 {
00478 int result = 0;
00479 result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT16));
00480 if ( result == 0 ) {
00481 *((UINT16*)val) = hfa384x2host_16(*((UINT16*)val));
00482 }
00483 return result;
00484 }
00485 #endif
00486 #if 0
00487 static int hfa384x_drvr_getconfig32(hfa384x_t *hw, UINT16 rid, void *val)
00488 {
00489 int result = 0;
00490 result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT32));
00491 if ( result == 0 ) {
00492 *((UINT32*)val) = hfa384x2host_32(*((UINT32*)val));
00493 }
00494 return result;
00495 }
00496 #endif
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510 static int hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len)
00511 {
00512 int result = 0;
00513 hfa384x_rec_t rec;
00514
00515 rec.rid = host2hfa384x_16(rid);
00516 rec.reclen = host2hfa384x_16((len/2) + 1);
00517
00518 result = hfa384x_copy_to_bap( hw, rid, 0, &rec, sizeof(rec));
00519 if ( result ) {
00520 printf("Failure writing record header\n");
00521 return -1;
00522 }
00523
00524 if ( len > 0 ) {
00525 result = hfa384x_copy_to_bap( hw, rid, sizeof(rec), buf, len);
00526 if ( result ) {
00527 printf("Failure writing record data\n");
00528 return -1;
00529 }
00530 }
00531
00532 result = hfa384x_cmd_access( hw, 1, rid);
00533 return result;
00534 }
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 static int hfa384x_drvr_setconfig16(hfa384x_t *hw, UINT16 rid, UINT16 *val)
00548 {
00549 UINT16 value;
00550 value = host2hfa384x_16(*val);
00551 return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(UINT16));
00552 }
00553 #if 0
00554 static int hfa384x_drvr_setconfig32(hfa384x_t *hw, UINT16 rid, UINT32 *val)
00555 {
00556 UINT32 value;
00557 value = host2hfa384x_32(*val);
00558 return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(UINT32));
00559 }
00560 #endif
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 static int hfa384x_wait_for_event(hfa384x_t *hw, UINT16 event_mask, UINT16 event_ack, int wait, int timeout, const char *descr)
00580 {
00581 UINT16 reg;
00582 int count = 0;
00583
00584 do {
00585 reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
00586 if ( count > 0 ) udelay(wait);
00587 count++;
00588 } while ( !(reg & event_mask) && count < timeout);
00589 if ( count >= timeout ) {
00590 printf("hfa384x: Timed out waiting for %s\n", descr);
00591 return 0;
00592 }
00593
00594 hfa384x_setreg(hw, reg & ( event_mask | event_ack ), HFA384x_EVACK);
00595 return reg;
00596 }
00597
00598
00599
00600
00601 static int prism2_poll(struct nic *nic, int retrieve)
00602 {
00603 UINT16 reg;
00604 UINT16 rxfid;
00605 UINT16 result;
00606 hfa384x_rx_frame_t rxdesc;
00607 hfa384x_t *hw = &hw_global;
00608
00609
00610 reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
00611 if ( ! HFA384x_EVSTAT_ISRX(reg) ) {
00612
00613 return 0;
00614 }
00615
00616 if ( ! retrieve ) return 1;
00617
00618
00619 hfa384x_setreg(hw, HFA384x_EVACK_RX_SET(1), HFA384x_EVACK);
00620
00621 rxfid = hfa384x_getreg(hw, HFA384x_RXFID);
00622
00623 result = hfa384x_copy_from_bap(hw, rxfid, 0, &rxdesc, sizeof(rxdesc));
00624 if ( result ) {
00625 return 0;
00626 }
00627
00628 rxdesc.status = hfa384x2host_16(rxdesc.status);
00629 rxdesc.time = hfa384x2host_32(rxdesc.time);
00630 rxdesc.data_len = hfa384x2host_16(rxdesc.data_len);
00631
00632
00633 nic->packetlen = rxdesc.data_len;
00634 if ( nic->packetlen > 0 ) {
00635
00636
00637
00638
00639
00640
00641 result = hfa384x_copy_from_bap(hw, rxfid, HFA384x_RX_DATA_OFF,
00642 nic->packet + ETH_HLEN - sizeof(wlan_80211hdr_t), nic->packetlen);
00643 if ( result ) {
00644 return 0;
00645 }
00646 }
00647 return 1;
00648 }
00649
00650
00651
00652
00653 static void prism2_transmit(
00654 struct nic *nic,
00655 const char *d,
00656 unsigned int t,
00657 unsigned int s,
00658 const char *p)
00659 {
00660 hfa384x_t *hw = &hw_global;
00661 hfa384x_tx_frame_t txdesc;
00662 wlan_80211hdr_t p80211hdr = { wlan_llc_snap, {{0,0,0},0} };
00663 UINT16 fid;
00664 UINT16 status;
00665 int result;
00666
00667
00668 result = hfa384x_docmd_wait(hw, HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ALLOC), HFA384x_DRVR_TXBUF_MAX, 0, 0);
00669 if (result != 0) {
00670 printf("hfa384x: Tx FID allocate command failed: Aborting transmit..\n");
00671 return;
00672 }
00673 if ( !hfa384x_wait_for_event(hw, HFA384x_EVSTAT_ALLOC, HFA384x_EVACK_INFO, 10, 50, "Tx FID to be allocated\n" ) ) return;
00674 fid = hfa384x_getreg(hw, HFA384x_ALLOCFID);
00675
00676
00677 memset(&txdesc, 0, sizeof(txdesc));
00678 txdesc.tx_control = host2hfa384x_16( HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
00679 HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1) );
00680 txdesc.frame_control = host2ieee16( WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) |
00681 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY) |
00682 WLAN_SET_FC_TODS(1) );
00683 memcpy(txdesc.address1, hw->bssid, WLAN_ADDR_LEN);
00684 memcpy(txdesc.address2, nic->node_addr, WLAN_ADDR_LEN);
00685 memcpy(txdesc.address3, d, WLAN_ADDR_LEN);
00686 txdesc.data_len = host2hfa384x_16( sizeof(txdesc) + sizeof(p80211hdr) + s );
00687
00688
00689 p80211hdr.snap.type = htons(t);
00690
00691
00692 result = hfa384x_copy_to_bap(hw, fid, 0, &txdesc, sizeof(txdesc));
00693 if ( result ) return;
00694 result = hfa384x_copy_to_bap( hw, fid, sizeof(txdesc), &p80211hdr, sizeof(p80211hdr) );
00695 if ( result ) return;
00696 result = hfa384x_copy_to_bap( hw, fid, sizeof(txdesc) + sizeof(p80211hdr), (UINT8*)p, s );
00697 if ( result ) return;
00698
00699
00700 result = hfa384x_docmd_wait(hw, HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_TX), fid, 0, 0);
00701 if ( result != 0 ) {
00702 printf("hfa384x: Transmit failed with result %#hx.\n", result);
00703 return;
00704 }
00705
00706
00707 result = hfa384x_wait_for_event(hw, HFA384x_EVSTAT_TXEXC | HFA384x_EVSTAT_TX, HFA384x_EVACK_INFO,
00708 200, 500, "Tx to complete\n" );
00709 if ( !result ) return;
00710 if ( HFA384x_EVSTAT_ISTXEXC(result) ) {
00711 fid = hfa384x_getreg(hw, HFA384x_TXCOMPLFID);
00712 printf ( "Tx exception occurred with fid %#hx\n", fid );
00713 result = hfa384x_copy_from_bap(hw, fid, 0, &status, sizeof(status));
00714 if ( result ) return;
00715 printf("hfa384x: Tx error occurred (status %#hx):\n", status);
00716 if ( HFA384x_TXSTATUS_ISACKERR(status) ) { printf(" ...acknowledgement error\n"); }
00717 if ( HFA384x_TXSTATUS_ISFORMERR(status) ) { printf(" ...format error\n"); }
00718 if ( HFA384x_TXSTATUS_ISDISCON(status) ) { printf(" ...disconnected error\n"); }
00719 if ( HFA384x_TXSTATUS_ISAGEDERR(status) ) { printf(" ...AGED error\n"); }
00720 if ( HFA384x_TXSTATUS_ISRETRYERR(status) ) { printf(" ...retry error\n"); }
00721 return;
00722 }
00723 }
00724
00725
00726
00727
00728 static void prism2_disable ( struct nic *nic __unused ) {
00729
00730 }
00731
00732
00733
00734
00735 static void prism2_irq(struct nic *nic __unused, irq_action_t action __unused)
00736 {
00737 switch ( action ) {
00738 case DISABLE :
00739 break;
00740 case ENABLE :
00741 break;
00742 case FORCE :
00743 break;
00744 }
00745 }
00746
00747
00748
00749
00750 static struct nic_operations prism2_operations = {
00751 .connect = dummy_connect,
00752 .poll = prism2_poll,
00753 .transmit = prism2_transmit,
00754 .irq = prism2_irq,
00755 };
00756
00757
00758
00759
00760
00761 static int prism2_probe ( struct nic *nic, hfa384x_t *hw ) {
00762 int result;
00763 UINT16 tmp16 = 0;
00764 UINT16 infofid;
00765 hfa384x_InfFrame_t inf;
00766 char ssid[HFA384x_RID_CNFDESIREDSSID_LEN];
00767 int info_count = 0;
00768
00769 nic->irqno = 0;
00770
00771
00772 result = hfa384x_docmd_wait(hw, HFA384x_CMDCODE_INIT, 0,0,0);
00773 if ( result ) printf ( "Initialize command returned %#hx\n", result );
00774 hfa384x_setreg(hw, 0, HFA384x_INTEN);
00775 hfa384x_setreg(hw, 0xffff, HFA384x_EVACK);
00776
00777 DBG ( "MAC address %s\n", eth_ntoa ( nic->node_addr ) );
00778
00779
00780 hfa384x_drvr_getconfig ( hw, HFA384x_RID_CNFOWNMACADDR, nic->node_addr, HFA384x_RID_CNFOWNMACADDR_LEN );
00781
00782
00783
00784 tmp16 = WLAN_DATA_MAXLEN;
00785 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, &tmp16);
00786 if ( result ) printf ( "Set Max Data Length command returned %#hx\n", result );
00787 tmp16 = 0x000f;
00788 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, &tmp16);
00789 if ( result ) printf ( "Set Transmit Rate command returned %#hx\n", result );
00790 tmp16 = HFA384x_CNFAUTHENTICATION_OPENSYSTEM;
00791 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, &tmp16);
00792 if ( result ) printf ( "Set Authentication Type command returned %#hx\n", result );
00793
00794 memset(ssid, 0, HFA384x_RID_CNFDESIREDSSID_LEN);
00795 for ( tmp16=0; tmp16<sizeof(hardcoded_ssid); tmp16++ ) { ssid[2+tmp16] = hardcoded_ssid[tmp16]; }
00796 ssid[0] = sizeof(hardcoded_ssid) - 1;
00797 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID, ssid, HFA384x_RID_CNFDESIREDSSID_LEN);
00798 if ( result ) printf ( "Set SSID command returned %#hx\n", result );
00799 tmp16 = 1;
00800 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, &tmp16);
00801 if ( result ) printf ( "Set port type command returned %#hx\n", result );
00802
00803 result = hfa384x_docmd_wait(hw, HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) | HFA384x_CMD_MACPORT_SET(0), 0,0,0);
00804 if ( result ) printf ( "Enable command returned %#hx\n", result );
00805
00806 do {
00807
00808
00809
00810 info_count++;
00811 if ( info_count > MAX_JOIN_INFO_COUNT ) {
00812 printf ( "Too many failed attempts - aborting\n" );
00813 return 0;
00814 }
00815
00816
00817 if ( sizeof(hardcoded_ssid) == 1 ) {
00818
00819 printf ( "Attempting to autojoin to any available access point (attempt %d)...", info_count );
00820 } else {
00821 printf ( "Attempting to autojoin to SSID %s (attempt %d)...", &ssid[2], info_count );
00822 }
00823
00824 if ( !hfa384x_wait_for_event(hw, HFA384x_EVSTAT_INFO, 0, 1000, 2000, "Info event" ) ) return 0;
00825 printf("done\n");
00826 infofid = hfa384x_getreg(hw, HFA384x_INFOFID);
00827
00828 result = hfa384x_copy_from_bap( hw, infofid, 0, &inf.framelen, sizeof(UINT16));
00829 if ( result ) return 0;
00830 inf.framelen = hfa384x2host_16(inf.framelen);
00831
00832 result = hfa384x_copy_from_bap( hw, infofid, sizeof(UINT16),
00833 &(inf.infotype), inf.framelen * sizeof(UINT16));
00834 if ( result ) return 0;
00835 if ( inf.infotype != HFA384x_IT_LINKSTATUS ) {
00836
00837 printf ( "Unexpected info frame type %#hx (not LinkStatus type)\n", inf.infotype );
00838 return 0;
00839 }
00840 inf.info.linkstatus.linkstatus = hfa384x2host_16(inf.info.linkstatus.linkstatus);
00841 if ( inf.info.linkstatus.linkstatus != HFA384x_LINK_CONNECTED ) {
00842
00843 printf ( "Link not connected (status %#hx)\n", inf.info.linkstatus.linkstatus );
00844 }
00845 } while ( inf.info.linkstatus.linkstatus != HFA384x_LINK_CONNECTED );
00846
00847
00848 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CURRENTBSSID, hw->bssid, WLAN_BSSID_LEN);
00849
00850 DBG ( "Link connected (BSSID %s - ", eth_ntoa ( hw->bssid ) );
00851 DBG ( " MAC address %s)\n", eth_ntoa (nic->node_addr ) );
00852
00853
00854 nic->nic_op = &prism2_operations;
00855 return 1;
00856 }
00857