00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 #define __WLANDRV_C__
00080
00081 #include <compiler.h>
00082 #include <stdio.h>
00083 #include <stddef.h>
00084 #include <string.h>
00085
00086 #include <sys/timer.h>
00087 #include <sys/thread.h>
00088 #include <sys/event.h>
00089 #include <errno.h>
00090 #include <netinet/if_ether.h>
00091 #include <net/ether.h>
00092 #include <net/if_var.h>
00093 #include <dev/irqreg.h>
00094
00095 #include <dev/wlantypes.h>
00096 #include <dev/pcmcia.h>
00097 #include <dev/wlancfg.h>
00098 #include <dev/wlan.h>
00099 #include <dev/wlandrv.h>
00100
00101
00102
00103
00104 #if (_DEBUG >= 1)
00105 #define Debug(_x) if (bDebugState ) printf _x
00106 #define Debug2(_x) if (bDebugState > 1) printf _x
00107 #define panic printf
00108 #else
00109 #define Debug(_x)
00110 #define Debug2(_x)
00111 #define panic
00112 #endif
00113
00114 #define WI_LOCK(sc) NutEventWait(&hDeviceSemaphore,0)
00115 #define WI_UNLOCK(sc) NutEventPost(&hDeviceSemaphore)
00116
00117 #define ieee80211_new_state(_a,_b,_c) _a->ic_state=_b
00118 #define isset(_a,_b) (*_a & (1<<_b))
00119
00120 #define CSR_WRITE_2(_a,_b,_c) pcmcia_WriteReg(_b,_c)
00121 #define CSR_READ_2(_a,_b) pcmcia_ReadReg(_b)
00122
00123
00124
00125
00126 #define WLAN_MIN_ETHERNET_FRAME_LEN 60
00127 #define WLAN_MAX_ETHERNET_FRAME_LEN 1514
00128 #define WLAN_ETHERNET_HEADER_LEN 14
00129
00130
00131
00132
00133 #define WI_INTRS (WI_EV_RX | WI_EV_ALLOC | WI_EV_INFO)
00134
00135 struct wi_card_ident {
00136 u_int16_t card_id;
00137 char *card_name;
00138 u_int8_t firm_type;
00139 };
00140
00141 struct ieee80211_frame_addr4 {
00142 u_int8_t i_fc[2];
00143 u_int8_t i_dur[2];
00144 u_int8_t i_addr1[IEEE80211_ADDR_LEN];
00145 u_int8_t i_addr2[IEEE80211_ADDR_LEN];
00146 u_int8_t i_addr3[IEEE80211_ADDR_LEN];
00147 u_int8_t i_seq[2];
00148 u_int8_t i_addr4[IEEE80211_ADDR_LEN];
00149 };
00150
00151
00152
00153
00154 struct wi_frame {
00155 u_int16_t wi_status;
00156 u_int16_t wi_rx_tstamp1;
00157 u_int16_t wi_rx_tstamp0;
00158 u_int8_t wi_rx_silence;
00159 u_int8_t wi_rx_signal;
00160 u_int8_t wi_rx_rate;
00161 u_int8_t wi_rx_flow;
00162 u_int8_t wi_tx_rtry;
00163 u_int8_t wi_tx_rate;
00164 u_int16_t wi_tx_ctl;
00165 struct ieee80211_frame_addr4 wi_whdr;
00166 u_int16_t wi_dat_len;
00167 struct ether_header wi_ehdr;
00168 };
00169
00170
00171
00172
00173 struct wi_ssid {
00174 u_int16_t wi_len;
00175 u_int8_t wi_ssid[32];
00176 };
00177
00178
00179
00180
00181 typedef struct {
00182 u_int16_t DSAPSSAP;
00183 u_int16_t Control;
00184 u_int16_t MustZero;
00185 u_int16_t Type;
00186 } LLCS_SNAP_HEADER;
00187
00188
00189
00190
00191
00192
00193
00194
00195 static HANDLE hDeviceSemaphore;
00196 static BYTE bDebugState = 0;
00197
00198 struct wi_card_ident wi_card_ident[] = {
00199
00200
00201
00202 #if (WLAN_SUPPORT_LUCENT >= 1)
00203 {WI_NIC_LUCENT_ID, WI_NIC_LUCENT_STR, WI_LUCENT},
00204 {WI_NIC_SONY_ID, WI_NIC_SONY_STR, WI_LUCENT},
00205 {WI_NIC_LUCENT_EMB_ID, WI_NIC_LUCENT_EMB_STR, WI_LUCENT},
00206 #endif
00207
00208 #if (WLAN_SUPPORT_INTERSIL >= 1)
00209 {WI_NIC_EVB2_ID, WI_NIC_EVB2_STR, WI_INTERSIL},
00210 {WI_NIC_HWB3763_ID, WI_NIC_HWB3763_STR, WI_INTERSIL},
00211 {WI_NIC_HWB3163_ID, WI_NIC_HWB3163_STR, WI_INTERSIL},
00212 {WI_NIC_HWB3163B_ID, WI_NIC_HWB3163B_STR, WI_INTERSIL},
00213 {WI_NIC_EVB3_ID, WI_NIC_EVB3_STR, WI_INTERSIL},
00214 {WI_NIC_HWB1153_ID, WI_NIC_HWB1153_STR, WI_INTERSIL},
00215 {WI_NIC_P2_SST_ID, WI_NIC_P2_SST_STR, WI_INTERSIL},
00216 {WI_NIC_EVB2_SST_ID, WI_NIC_EVB2_SST_STR, WI_INTERSIL},
00217 {WI_NIC_3842_EVA_ID, WI_NIC_3842_EVA_STR, WI_INTERSIL},
00218 {WI_NIC_3842_PCMCIA_AMD_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL},
00219 {WI_NIC_3842_PCMCIA_SST_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL},
00220 {WI_NIC_3842_PCMCIA_ATL_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL},
00221 {WI_NIC_3842_PCMCIA_ATS_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL},
00222 {WI_NIC_3842_MINI_AMD_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL},
00223 {WI_NIC_3842_MINI_SST_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL},
00224 {WI_NIC_3842_MINI_ATL_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL},
00225 {WI_NIC_3842_MINI_ATS_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL},
00226 {WI_NIC_3842_PCI_AMD_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL},
00227 {WI_NIC_3842_PCI_SST_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL},
00228 {WI_NIC_3842_PCI_ATS_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL},
00229 {WI_NIC_3842_PCI_ATL_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL},
00230 {WI_NIC_P3_PCMCIA_AMD_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL},
00231 {WI_NIC_P3_PCMCIA_SST_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL},
00232 {WI_NIC_P3_PCMCIA_ATL_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL},
00233 {WI_NIC_P3_PCMCIA_ATS_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL},
00234 {WI_NIC_P3_MINI_AMD_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL},
00235 {WI_NIC_P3_MINI_SST_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL},
00236 {WI_NIC_P3_MINI_ATL_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL},
00237 {WI_NIC_P3_MINI_ATS_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL},
00238 #endif
00239 {0, NULL, 0},
00240 };
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 static void DELAY(u_int32_t delay_us)
00251 {
00252 delay_us = delay_us / 1000;
00253 delay_us++;
00254 NutSleep(delay_us);
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264 void DumpWlanData(BYTE * pBuffer, WORD wBufferSize)
00265 {
00266 u_int16_t x, MaxX = 16;
00267 u_int16_t y, MaxY;
00268 u_int16_t Size;
00269
00270 if (bDebugState != 0) {
00271 Size = 0;
00272 MaxY = (wBufferSize / 16) + 1;
00273 for (y = 0; y < MaxY; y++) {
00274 Debug(("%04X: ", (y * 16)));
00275 for (x = 0; x < MaxX; x++) {
00276 Debug(("%02X ", pBuffer[Size]));
00277 Size++;
00278
00279 if (Size >= wBufferSize) {
00280 Debug(("\r\n"));
00281 return;
00282 }
00283 }
00284 Debug(("\r\n"));
00285 }
00286 }
00287 }
00288
00289
00290
00291
00292 static int wi_cmd(struct wi_softc *sc, int cmd, int val0, int val1, int val2)
00293 {
00294 unsigned long i;
00295 unsigned int s = 0;
00296 static volatile int count = 0;
00297
00298 if (sc->wi_gone) {
00299 return (ENODEV);
00300 }
00301
00302
00303
00304
00305
00306 count++;
00307
00308
00309
00310
00311 for (i = sc->wi_cmd_count; i > 0; i--) {
00312 if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) {
00313 break;
00314 }
00315 DELAY(1 * 1000);
00316 }
00317 if (i == 0) {
00318 Debug(("wi_cmd: busy bit won't clear.\n"));
00319 sc->wi_gone = 1;
00320 count--;
00321 return (ETIMEDOUT);
00322 }
00323
00324 CSR_WRITE_2(sc, WI_PARAM0, val0);
00325 CSR_WRITE_2(sc, WI_PARAM1, val1);
00326 CSR_WRITE_2(sc, WI_PARAM2, val2);
00327 CSR_WRITE_2(sc, WI_COMMAND, cmd);
00328
00329 if (cmd == WI_CMD_INI) {
00330
00331
00332
00333
00334 DELAY(250UL * 1000UL);
00335 }
00336 for (i = 0; i < WI_TIMEOUT; i++) {
00337
00338
00339
00340
00341 s = CSR_READ_2(sc, WI_EVENT_STAT);
00342 if (s & WI_EV_CMD) {
00343
00344
00345
00346 s = CSR_READ_2(sc, WI_STATUS);
00347 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
00348 if (s & WI_STAT_CMD_RESULT) {
00349 count--;
00350 return (EIO);
00351 }
00352 break;
00353 }
00354 DELAY(WI_DELAY);
00355 }
00356
00357 count--;
00358 if (i == WI_TIMEOUT) {
00359 Debug(("timeout in wi_cmd 0x%04x; event status 0x%04x\n", cmd, s));
00360 if (s == 0xffff) {
00361 sc->wi_gone = 1;
00362 }
00363 return (ETIMEDOUT);
00364 }
00365 return (0);
00366 }
00367
00368
00369
00370
00371 void wi_stop(struct wi_softc *sc, int disable)
00372 {
00373 struct ieee80211com *ic = &sc->sc_ic;
00374
00375 DELAY(100000);
00376
00377 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
00378 if (sc->sc_enabled && !sc->wi_gone) {
00379 CSR_WRITE_2(sc, WI_INT_EN, 0);
00380 wi_cmd(sc, WI_CMD_DISABLE | sc->sc_portnum, 0, 0, 0);
00381 if (disable) {
00382 sc->sc_enabled = 0;
00383 }
00384 } else {
00385 if (sc->wi_gone && disable) {
00386 sc->sc_enabled = 0;
00387 }
00388 }
00389
00390 sc->sc_tx_timer = 0;
00391 sc->sc_scan_timer = 0;
00392 }
00393
00394
00395
00396
00397 static int wi_seek_bap(struct wi_softc *sc, int id, int off)
00398 {
00399 long i;
00400 unsigned int status;
00401
00402 CSR_WRITE_2(sc, WI_SEL0, id);
00403 CSR_WRITE_2(sc, WI_OFF0, off);
00404
00405 for (i = 0;; i++) {
00406 status = CSR_READ_2(sc, WI_OFF0);
00407 if ((status & WI_OFF_BUSY) == 0) {
00408 break;
00409 }
00410 if (i == WI_TIMEOUT) {
00411 Debug(("timeout in wi_seek to %x/%x\n", id, off));
00412 sc->sc_bap_off = WI_OFF_ERR;
00413 if (status == 0xffff) {
00414 sc->wi_gone = 1;
00415 }
00416 return ETIMEDOUT;
00417 }
00418 DELAY(1);
00419 }
00420 if (status & WI_OFF_ERR) {
00421 Debug(("failed in wi_seek to %x/%x\n", id, off));
00422 sc->sc_bap_off = WI_OFF_ERR;
00423 return EIO;
00424 }
00425 sc->sc_bap_id = id;
00426 sc->sc_bap_off = off;
00427 return 0;
00428 }
00429
00430
00431
00432
00433 static int wi_read_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen)
00434 {
00435 u_int16_t *ptr;
00436 int i, error, cnt;
00437
00438 if (buflen == 0) {
00439 return 0;
00440 }
00441 if (id != sc->sc_bap_id || off != sc->sc_bap_off) {
00442 if ((error = wi_seek_bap(sc, id, off)) != 0) {
00443 return error;
00444 }
00445 }
00446 cnt = (buflen + 1) / 2;
00447 ptr = (u_int16_t *) buf;
00448 for (i = 0; i < cnt; i++) {
00449 *ptr++ = CSR_READ_2(sc, WI_DATA0);
00450 }
00451 sc->sc_bap_off += cnt * 2;
00452 return 0;
00453 }
00454
00455
00456
00457
00458 static int wi_write_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen)
00459 {
00460 u_int16_t *ptr;
00461 int i, error, cnt;
00462
00463 if (buflen == 0) {
00464 return 0;
00465 }
00466 #ifdef WI_HERMES_AUTOINC_WAR
00467 again:
00468 #endif
00469 if (id != sc->sc_bap_id || off != sc->sc_bap_off) {
00470 if ((error = wi_seek_bap(sc, id, off)) != 0) {
00471 return error;
00472 }
00473 }
00474 cnt = (buflen + 1) / 2;
00475 ptr = (u_int16_t *) buf;
00476 for (i = 0; i < cnt; i++) {
00477 CSR_WRITE_2(sc, WI_DATA0, ptr[i]);
00478 }
00479 sc->sc_bap_off += cnt * 2;
00480
00481 #ifdef WI_HERMES_AUTOINC_WAR
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 if ((sc->sc_flags & WI_FLAGS_BUG_AUTOINC) && (id & 0xf000) == 0) {
00496 CSR_WRITE_2(sc, WI_DATA0, 0x1234);
00497 CSR_WRITE_2(sc, WI_DATA0, 0x5678);
00498 wi_seek_bap(sc, id, sc->sc_bap_off);
00499 sc->sc_bap_off = WI_OFF_ERR;
00500 if (CSR_READ_2(sc, WI_DATA0) != 0x1234 || CSR_READ_2(sc, WI_DATA0) != 0x5678) {
00501 Debug(("detect auto increment bug, try again\n"));
00502 goto again;
00503 }
00504 }
00505 #endif
00506 return 0;
00507 }
00508
00509
00510
00511
00512 static int wi_read_rid(struct wi_softc *sc, int rid, void *buf, int *buflenp)
00513 {
00514 int error, len;
00515 u_int16_t ltbuf[2];
00516
00517
00518
00519
00520 error = wi_cmd(sc, WI_CMD_ACCESS | WI_ACCESS_READ, rid, 0, 0);
00521 if (error) {
00522 return error;
00523 }
00524
00525 error = wi_read_bap(sc, rid, 0, ltbuf, sizeof(ltbuf));
00526 if (error) {
00527 return error;
00528 }
00529
00530 if (le16toh(ltbuf[1]) != (u_int16_t) rid) {
00531 Debug(("record read mismatch, rid=%x, got=%x\n", rid, le16toh(ltbuf[1])));
00532 return EIO;
00533 }
00534 len = (le16toh(ltbuf[0]) - 1) * 2;
00535 if (*buflenp < len) {
00536 Debug(("record buffer is too small, rid=%x, size=%d, len=%d\n", rid, *buflenp, len));
00537 return ENOSPC;
00538 }
00539 *buflenp = len;
00540 return wi_read_bap(sc, rid, sizeof(ltbuf), buf, len);
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550 static int wi_write_rid(struct wi_softc *sc, int rid, void *buf, int buflen)
00551 {
00552 int error;
00553 u_int16_t ltbuf[2];
00554
00555 ltbuf[0] = htole16((buflen + 1) / 2 + 1);
00556 ltbuf[1] = htole16(rid);
00557
00558 error = wi_write_bap(sc, rid, 0, ltbuf, sizeof(ltbuf));
00559 if (error) {
00560 return error;
00561 }
00562 error = wi_write_bap(sc, rid, sizeof(ltbuf), buf, buflen);
00563 if (error) {
00564 return error;
00565 }
00566
00567 return wi_cmd(sc, WI_CMD_ACCESS | WI_ACCESS_WRITE, rid, 0, 0);
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 static int wi_write_val(struct wi_softc *sc, int rid, u_int16_t val)
00579 {
00580 val = htole16(val);
00581 return wi_write_rid(sc, rid, &val, sizeof(val));
00582 }
00583
00584
00585
00586
00587 static int wi_write_txrate(struct wi_softc *sc)
00588 {
00589 struct ieee80211com *ic = &sc->sc_ic;
00590 int i;
00591 u_int16_t rate;
00592
00593 if (ic->ic_fixed_rate < 0) {
00594 rate = 0;
00595 } else {
00596 rate = (ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL) / 2;
00597 }
00598
00599
00600
00601
00602
00603 switch (sc->sc_firmware_type) {
00604 case WI_LUCENT:
00605 switch (rate) {
00606 case 0:
00607 rate = 3;
00608 break;
00609
00610
00611
00612 case 5:
00613 rate = 4;
00614 break;
00615 case 11:
00616 rate = 5;
00617 break;
00618 default:
00619 break;
00620 }
00621 break;
00622 default:
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 for (i = 8; i > 0; i >>= 1) {
00634 if ((int) rate >= i) {
00635 break;
00636 }
00637 }
00638 if (i == 0) {
00639 rate = 0xf;
00640 } else {
00641 rate = i;
00642 }
00643 break;
00644 }
00645 return wi_write_val(sc, WI_RID_TX_RATE, rate);
00646 }
00647
00648
00649
00650
00651 static int wi_reset(struct wi_softc *sc)
00652 {
00653
00654 int i;
00655 int error = 0;
00656 int tries;
00657
00658
00659
00660
00661 if (sc->sc_firmware_type == WI_SYMBOL && sc->sc_reset) {
00662 return (0);
00663 }
00664 if (sc->sc_firmware_type == WI_SYMBOL) {
00665 tries = 1;
00666 } else {
00667 tries = 3;
00668 }
00669
00670 for (i = 0; i < tries; i++) {
00671 if ((error = wi_cmd(sc, WI_CMD_INI, 0, 0, 0)) == 0) {
00672 break;
00673 }
00674 DELAY(WI_DELAY * 1000);
00675 }
00676 sc->sc_reset = 1;
00677
00678 if (i == tries) {
00679 Debug(("init failed\n"));
00680 return (error);
00681 }
00682
00683 CSR_WRITE_2(sc, WI_INT_EN, 0);
00684 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
00685
00686
00687
00688
00689 wi_write_val(sc, WI_RID_TICK_TIME, 8);
00690
00691 return (0);
00692 }
00693
00694
00695
00696
00697 static void WLANInterrupt(void *p)
00698 {
00699 NUTDEVICE *dev = (NUTDEVICE *) p;
00700 struct wi_softc *sc = (struct wi_softc *) dev->dev_dcb;
00701
00702 if ((sc->wi_gone == 1) || (sc->sc_enabled == 0)) {
00703 CSR_WRITE_2(sc, WI_INT_EN, 0);
00704 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
00705 return;
00706 }
00707
00708
00709
00710
00711
00712 CSR_WRITE_2(sc, WI_INT_EN, 0);
00713
00714 sc->EventStatus = CSR_READ_2(sc, WI_EVENT_STAT);
00715
00716 NutEventPostFromIrq(&sc->InterruptEvent);
00717 }
00718
00719
00720
00721
00722 static void wi_tx_intr(struct wi_softc *sc)
00723 {
00724
00725 int fid, cur;
00726
00727 if (sc->wi_gone) {
00728 return;
00729 }
00730
00731 fid = CSR_READ_2(sc, WI_ALLOC_FID);
00732 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
00733
00734 cur = sc->sc_txcur;
00735 if (sc->sc_txd[cur].d_fid != fid) {
00736 #if (WLAN_ENABLE_TX_FRAME_DUMP >= 1)
00737 Debug(("bad alloc %x != %x, cur %d nxt %d\n", fid, sc->sc_txd[cur].d_fid, cur, sc->sc_txnext));
00738 #endif
00739 return;
00740 }
00741 sc->sc_tx_timer = 0;
00742 sc->sc_txd[cur].d_len = 0;
00743 sc->sc_txcur = cur = (cur + 1) % sc->sc_ntxbuf;
00744 if (sc->sc_txd[cur].d_len == 0) {
00745
00746 } else {
00747 if (wi_cmd(sc, WI_CMD_TX | WI_RECLAIM, sc->sc_txd[cur].d_fid, 0, 0)) {
00748 Debug(("xmit failed\n"));
00749 sc->sc_txd[cur].d_len = 0;
00750 } else {
00751 sc->sc_tx_timer = 5;
00752
00753 }
00754 }
00755 }
00756
00757
00758
00759
00760 static void wi_info_intr(struct wi_softc *sc)
00761 {
00762 struct ieee80211com *ic = &sc->sc_ic;
00763
00764
00765 int fid;
00766 u_int16_t ltbuf[2];
00767 u_int16_t stat;
00768
00769
00770 fid = CSR_READ_2(sc, WI_INFO_FID);
00771 wi_read_bap(sc, fid, 0, ltbuf, sizeof(ltbuf));
00772
00773 switch (le16toh(ltbuf[1])) {
00774
00775 case WI_INFO_LINK_STAT:
00776 wi_read_bap(sc, fid, sizeof(ltbuf), &stat, sizeof(stat));
00777 #if (WLAN_ENABLE_LINK_STATUS >= 1)
00778 Debug(("wi_info_intr: LINK_STAT 0x%x\n", le16toh(stat)));
00779 #endif
00780
00781 switch (le16toh(stat)) {
00782 case WI_INFO_LINK_STAT_CONNECTED:
00783 sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
00784 if (ic->ic_state == IEEE80211_S_RUN && ic->ic_opmode != IEEE80211_M_IBSS) {
00785 break;
00786 }
00787
00788
00789
00790 case WI_INFO_LINK_STAT_AP_CHG:
00791 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
00792 break;
00793 case WI_INFO_LINK_STAT_AP_INR:
00794 sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
00795 break;
00796 case WI_INFO_LINK_STAT_AP_OOR:
00797 if (sc->sc_firmware_type == WI_SYMBOL && sc->sc_scan_timer > 0) {
00798 if (wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_HOST_SCAN_RESULTS, 0, 0)
00799 != 0) {
00800 sc->sc_scan_timer = 0;
00801 }
00802 break;
00803 }
00804 if (ic->ic_opmode == IEEE80211_M_STA) {
00805 sc->sc_flags |= WI_FLAGS_OUTRANGE;
00806 }
00807 break;
00808 case WI_INFO_LINK_STAT_DISCONNECTED:
00809 case WI_INFO_LINK_STAT_ASSOC_FAILED:
00810 if (ic->ic_opmode == IEEE80211_M_STA) {
00811 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
00812 }
00813 break;
00814 }
00815 break;
00816
00817 case WI_INFO_COUNTERS:
00818 #if 0 //@@MF later
00819
00820
00821
00822
00823
00824
00825
00826
00827 len = min(le16toh(ltbuf[0]) - 1, sizeof(sc->sc_stats) / 4);
00828 ptr = (u_int32_t *) & sc->sc_stats;
00829 off = sizeof(ltbuf);
00830 for (i = 0; i < len; i++, off += 2, ptr++) {
00831 wi_read_bap(sc, fid, off, &stat, sizeof(stat));
00832 #ifdef WI_HERMES_STATS_WAR
00833 if (stat & 0xf000) {
00834 stat = ~stat;
00835 }
00836 #endif
00837 *ptr += stat;
00838 }
00839 ifp->if_collisions = sc->sc_stats.wi_tx_single_retries + sc->sc_stats.wi_tx_multi_retries + sc->sc_stats.wi_tx_retry_limit;
00840 #endif
00841 break;
00842
00843 #if 0 //@@MF later
00844 case WI_INFO_SCAN_RESULTS:
00845 case WI_INFO_HOST_SCAN_RESULTS:
00846 wi_scan_result(sc, fid, le16toh(ltbuf[0]));
00847 break;
00848 #endif
00849
00850 default:
00851 Debug(("wi_info_intr: got fid %x type %x len %d\n", fid, le16toh(ltbuf[1]), le16toh(ltbuf[0])));
00852 break;
00853 }
00854 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
00855 }
00856
00857
00858
00859
00860 static NETBUF *wi_rx_intr(struct wi_softc *sc)
00861 {
00862
00863 struct wi_frame frmhdr;
00864 int fid, len, off;
00865 u_int16_t status;
00866 int error;
00867
00868 NETBUF *nb = 0;
00869 LLCS_SNAP_HEADER *pLLCSSNAPHeader;
00870 ETHERHDR LABBuffer;
00871 ETHERHDR MAC802_3;
00872 u_int8_t *pFrameBuffer = 0;
00873 u_int8_t *pBytePointer;
00874 int copy_size = 0;
00875 int size;
00876 int IPFrame = 0;
00877
00878 if (sc->wi_gone) {
00879 Debug(("wi_rx_intr gone\r\n"));
00880 return (0);
00881 }
00882
00883 fid = CSR_READ_2(sc, WI_RX_FID);
00884
00885
00886
00887
00888 if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr))) {
00889 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
00890 Debug(("wi_rx_intr: read fid %x failed\n", fid));
00891 return 0;
00892 }
00893
00894
00895
00896
00897 status = le16toh(frmhdr.wi_status);
00898 if (status & WI_STAT_ERRSTAT) {
00899 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
00900 Debug(("wi_rx_intr: fid %x error status %x\n", fid, status));
00901 return 0;
00902 }
00903
00904
00905
00906
00907 memcpy(MAC802_3.ether_dhost, frmhdr.wi_ehdr.ether_dhost, IEEE80211_ADDR_LEN);
00908 memcpy(MAC802_3.ether_shost, frmhdr.wi_ehdr.ether_shost, IEEE80211_ADDR_LEN);
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918 len = le16toh(frmhdr.wi_dat_len);
00919 off = sizeof(frmhdr);
00920
00921
00922
00923
00924
00925 if (len > WLAN_MAX_ETHERNET_FRAME_LEN) {
00926 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
00927 Debug(("wi_rx_intr: oversized packet\n"));
00928 return (0);
00929 }
00930
00931
00932
00933
00934 error = wi_read_bap(sc, fid, off, &LABBuffer, sizeof(LABBuffer));
00935 off += sizeof(LABBuffer);
00936
00937 if (error == 0) {
00938
00939
00940
00941 pLLCSSNAPHeader = (LLCS_SNAP_HEADER *) & LABBuffer;
00942 if ((pLLCSSNAPHeader->DSAPSSAP == 0xAAAA) && (pLLCSSNAPHeader->Control == 0x0003) && (pLLCSSNAPHeader->MustZero == 0x0000)) {
00943
00944 if ((pLLCSSNAPHeader->Type == 0x0608) || (pLLCSSNAPHeader->Type == 0x0008)) {
00945
00946 #if (WLAN_ENABLE_RX_FRAME_DUMP >= 1)
00947 Debug(("RFC1024 IP-Frame\n"));
00948 #endif
00949
00950 IPFrame = 1;
00951 MAC802_3.ether_type = pLLCSSNAPHeader->Type;
00952
00953
00954
00955
00956
00957
00958
00959 len -= 6;
00960
00961
00962
00963
00964
00965 len += 12;
00966
00967
00968
00969
00970
00971 len += 1;
00972 len &= ~1;
00973
00974
00975
00976
00977 nb = NutNetBufAlloc(0, NBAF_DATALINK, len);
00978 if (nb != 0) {
00979 pFrameBuffer = nb->nb_dl.vp;
00980
00981
00982
00983
00984 copy_size = len;
00985
00986
00987
00988
00989 memcpy(pFrameBuffer, &MAC802_3, sizeof(MAC802_3));
00990 pFrameBuffer += sizeof(MAC802_3);
00991 copy_size -= sizeof(MAC802_3);
00992
00993
00994
00995
00996 pBytePointer = (BYTE *) & LABBuffer;
00997
00998
00999
01000 pBytePointer += sizeof(LLCS_SNAP_HEADER);
01001
01002
01003
01004 size = sizeof(LABBuffer) - sizeof(LLCS_SNAP_HEADER);
01005 memcpy(pFrameBuffer, pBytePointer, size);
01006
01007
01008
01009 pFrameBuffer += size;
01010 copy_size -= size;
01011 } else {
01012 IPFrame = 0;
01013 }
01014 }
01015 } else {
01016
01017
01018
01019 if ((LABBuffer.ether_type == 0x0608) || (LABBuffer.ether_type == 0x0008)) {
01020
01021 #if (WLAN_ENABLE_RX_FRAME_DUMP >= 1)
01022 Debug(("RFC894 IP-Frame\n"));
01023 #endif
01024
01025 IPFrame = 1;
01026
01027
01028
01029
01030
01031 len += 1;
01032 len &= ~1;
01033
01034
01035
01036
01037
01038 nb = NutNetBufAlloc(0, NBAF_DATALINK, len);
01039 if (nb != 0) {
01040 pFrameBuffer = nb->nb_dl.vp;
01041
01042
01043
01044
01045 copy_size = len;
01046
01047
01048
01049
01050 memcpy(pFrameBuffer, &LABBuffer, sizeof(LABBuffer));
01051 pFrameBuffer += sizeof(LABBuffer);
01052 copy_size -= sizeof(LABBuffer);
01053 } else {
01054 IPFrame = 0;
01055 }
01056 }
01057 }
01058
01059
01060
01061
01062 if (IPFrame == 1) {
01063 error = wi_read_bap(sc, fid, off, pFrameBuffer, copy_size);
01064 if (error != 0) {
01065 NutNetBufFree(nb);
01066 nb = NULL;
01067 } else {
01068 #if (WLAN_ENABLE_RX_FRAME_DUMP >= 1)
01069 Debug(("RxFrame: %d\n", len));
01070 DumpWlanData(nb->nb_dl.vp, nb->nb_dl.sz);
01071 #endif
01072 }
01073 }
01074 }
01075
01076
01077
01078
01079 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
01080
01081 return (nb);
01082 }
01083
01084
01085
01086
01087 THREAD(RxThread, arg)
01088 {
01089 NUTDEVICE *dev;
01090 IFNET *ifn;
01091 NETBUF *nb;
01092 struct wi_softc *sc;
01093 u_int16_t EventStatus;
01094
01095 dev = arg;
01096 ifn = (IFNET *) dev->dev_icb;
01097 sc = (struct wi_softc *) dev->dev_dcb;
01098
01099 for (;;) {
01100
01101
01102
01103
01104 NutEventWait(&sc->InterruptEvent, 2000);
01105 EventStatus = sc->EventStatus;
01106
01107
01108
01109
01110
01111
01112 sc->EventStatus = 0;
01113
01114 if (EventStatus != 0) {
01115 if (EventStatus & WI_EV_RX) {
01116 WI_LOCK(sc);
01117 nb = wi_rx_intr(sc);
01118 WI_UNLOCK(sc);
01119
01120 if (nb != 0) {
01121 (*ifn->if_recv) (dev, nb);
01122 }
01123 }
01124
01125 if (EventStatus & WI_EV_ALLOC) {
01126 WI_LOCK(sc);
01127 wi_tx_intr(sc);
01128 WI_UNLOCK(sc);
01129 }
01130
01131 if (EventStatus & WI_EV_INFO) {
01132 WI_LOCK(sc);
01133 wi_info_intr(sc);
01134 WI_UNLOCK(sc);
01135 }
01136
01137 if (EventStatus & WI_EV_TX_EXC) {
01138 Debug(("WI_EV_TX_EXC\n"));
01139 }
01140
01141
01142 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
01143 } else {
01144
01145
01146
01147 if ((sc->sc_enabled == 1) && (sc->wi_gone == 1)) {
01148
01149
01150
01151 Debug(("Houston, we have a problem...\n"));
01152 sc->wi_gone = 0;
01153 wlandrv_Init(dev);
01154 }
01155 }
01156 }
01157 }
01158
01159
01160
01161
01162 static int wi_alloc_fid(struct wi_softc *sc, int len, int *idp)
01163 {
01164 unsigned long i;
01165
01166
01167 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) {
01168 Debug(("failed to allocate %d bytes on NIC\n", len));
01169 return ENOMEM;
01170 }
01171
01172 for (i = 0; i < WI_TIMEOUT; i++) {
01173 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC) {
01174 break;
01175 }
01176 if (i == WI_TIMEOUT) {
01177 Debug(("timeout in alloc\n"));
01178 return ETIMEDOUT;
01179 }
01180 DELAY(1);
01181 }
01182 *idp = CSR_READ_2(sc, WI_ALLOC_FID);
01183 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
01184 return 0;
01185 }
01186
01187
01188
01189
01190 static int wi_write_ssid(struct wi_softc *sc, int rid, u_int8_t * buf, int buflen)
01191 {
01192 struct wi_ssid ssid;
01193
01194 if (buflen > IEEE80211_NWID_LEN) {
01195 return ENOBUFS;
01196 }
01197 memset(&ssid, 0, sizeof(ssid));
01198 ssid.wi_len = htole16(buflen);
01199 memcpy(ssid.wi_ssid, buf, buflen);
01200 return wi_write_rid(sc, rid, &ssid, sizeof(ssid));
01201 }
01202
01203
01204
01205
01206 static void wi_read_nicid(struct wi_softc *sc)
01207 {
01208 struct wi_card_ident *id;
01209 char *p;
01210 int len;
01211 u_int16_t ver[4];
01212
01213
01214
01215
01216 memset(ver, 0, sizeof(ver));
01217 len = sizeof(ver);
01218 wi_read_rid(sc, WI_RID_CARD_ID, ver, &len);
01219 Debug(("using "));
01220
01221 sc->sc_firmware_type = WI_NOTYPE;
01222 for (id = wi_card_ident; id->card_name != NULL; id++) {
01223 if (le16toh(ver[0]) == id->card_id) {
01224 Debug(("%s", id->card_name));
01225 sc->sc_firmware_type = id->firm_type;
01226 break;
01227 }
01228 }
01229 if (sc->sc_firmware_type == WI_NOTYPE) {
01230 if (le16toh(ver[0]) & 0x8000) {
01231 Debug(("Unknown PRISM2 chip"));
01232 sc->sc_firmware_type = WI_INTERSIL;
01233 } else {
01234 Debug(("Unknown Lucent chip"));
01235 sc->sc_firmware_type = WI_LUCENT;
01236 }
01237 }
01238
01239
01240
01241
01242 if (sc->sc_firmware_type != WI_LUCENT) {
01243 memset(ver, 0, sizeof(ver));
01244 len = sizeof(ver);
01245 wi_read_rid(sc, WI_RID_PRI_IDENTITY, ver, &len);
01246 sc->sc_pri_firmware_ver = le16toh(ver[2]) * 10000 + le16toh(ver[3]) * 100 + le16toh(ver[1]);
01247 }
01248
01249
01250
01251
01252 memset(ver, 0, sizeof(ver));
01253 len = sizeof(ver);
01254 wi_read_rid(sc, WI_RID_STA_IDENTITY, ver, &len);
01255 sc->sc_sta_firmware_ver = le16toh(ver[2]) * 10000 + le16toh(ver[3]) * 100 + le16toh(ver[1]);
01256 if (sc->sc_firmware_type == WI_INTERSIL && (sc->sc_sta_firmware_ver == 10102 || sc->sc_sta_firmware_ver == 20102)) {
01257 char ident[12];
01258 memset(ident, 0, sizeof(ident));
01259 len = sizeof(ident);
01260
01261
01262
01263 if (wi_read_rid(sc, WI_RID_SYMBOL_IDENTITY, ident, &len) == 0 &&
01264 *(p = (char *) ident) >= 'A' && p[2] == '.' && p[5] == '-' && p[8] == '\0') {
01265 sc->sc_firmware_type = WI_SYMBOL;
01266 sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 +
01267 (p[3] - '0') * 1000 + (p[4] - '0') * 100 + (p[6] - '0') * 10 + (p[7] - '0');
01268 }
01269 }
01270 Debug(("\n"));
01271 Debug(("%s Firmware: ",
01272 sc->sc_firmware_type == WI_LUCENT ? "Lucent" : (sc->sc_firmware_type == WI_SYMBOL ? "Symbol" : "Intersil")));
01273 if (sc->sc_firmware_type != WI_LUCENT) {
01274 Debug(("Primary (%ld.%ld.%ld), ",
01275 sc->sc_pri_firmware_ver / 10000, (sc->sc_pri_firmware_ver % 10000) / 100, sc->sc_pri_firmware_ver % 100));
01276 }
01277 Debug(("Station (%ld.%ld.%ld)\n",
01278 sc->sc_sta_firmware_ver / 10000, (sc->sc_sta_firmware_ver % 10000) / 100, sc->sc_sta_firmware_ver % 100));
01279 }
01280
01281
01282
01283
01284 static int wi_write_wep(struct wi_softc *sc)
01285 {
01286 struct ieee80211com *ic = &sc->sc_ic;
01287 int error = 0;
01288 int i, keylen;
01289 u_int16_t val;
01290 struct wi_key wkey[IEEE80211_WEP_NKID];
01291
01292 switch (sc->sc_firmware_type) {
01293 #if (WLAN_SUPPORT_LUCENT >= 1)
01294 case WI_LUCENT:
01295 val = (ic->ic_flags & IEEE80211_F_WEPON) ? 1 : 0;
01296 error = wi_write_val(sc, WI_RID_ENCRYPTION, val);
01297 if (error)
01298 break;
01299 error = wi_write_val(sc, WI_RID_TX_CRYPT_KEY, ic->ic_wep_txkey);
01300 if (error)
01301 break;
01302 memset(wkey, 0, sizeof(wkey));
01303 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
01304 keylen = ic->ic_nw_keys[i].wk_len;
01305 wkey[i].wi_keylen = htole16(keylen);
01306 memcpy(wkey[i].wi_keydat, ic->ic_nw_keys[i].wk_key, keylen);
01307 }
01308 error = wi_write_rid(sc, WI_RID_DEFLT_CRYPT_KEYS, wkey, sizeof(wkey));
01309 break;
01310 #endif
01311
01312 #if ((WLAN_SUPPORT_INTERSIL >= 1) || (WLAN_SUPPORT_SYMBOL >= 1))
01313 case WI_INTERSIL:
01314 case WI_SYMBOL:
01315 if (ic->ic_flags & IEEE80211_F_WEPON) {
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325 if (sc->sc_firmware_type == WI_INTERSIL && sc->sc_sta_firmware_ver < 802) {
01326
01327
01328
01329 wi_write_val(sc, WI_RID_PROMISC, 1);
01330 }
01331 wi_write_val(sc, WI_RID_CNFAUTHMODE, sc->sc_cnfauthmode);
01332 val = PRIVACY_INVOKED | EXCLUDE_UNENCRYPTED;
01333
01334
01335
01336 if (sc->sc_firmware_type == WI_INTERSIL && ic->ic_opmode == IEEE80211_M_HOSTAP) {
01337 val |= HOST_ENCRYPT;
01338 }
01339 } else {
01340 wi_write_val(sc, WI_RID_CNFAUTHMODE, IEEE80211_AUTH_OPEN);
01341 val = HOST_ENCRYPT | HOST_DECRYPT;
01342 }
01343 error = wi_write_val(sc, WI_RID_P2_ENCRYPTION, val);
01344 if (error) {
01345 break;
01346 }
01347 error = wi_write_val(sc, WI_RID_P2_TX_CRYPT_KEY, ic->ic_wep_txkey);
01348 if (error) {
01349 break;
01350 }
01351
01352
01353
01354
01355
01356
01357 keylen = ic->ic_nw_keys[ic->ic_wep_txkey].wk_len;
01358 if (keylen > IEEE80211_WEP_KEYLEN) {
01359 keylen = 13;
01360 } else {
01361 keylen = IEEE80211_WEP_KEYLEN;
01362 }
01363 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
01364 error = wi_write_rid(sc, WI_RID_P2_CRYPT_KEY0 + i, ic->ic_nw_keys[i].wk_key, keylen);
01365 if (error) {
01366 break;
01367 }
01368 }
01369 break;
01370 #endif
01371 }
01372 return error;
01373 }
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385 int wlandrv_ProbeDevice(void)
01386 {
01387 int error = -1;
01388 u_int16_t Value;
01389
01390
01391
01392
01393 RESET_EN_PORT |= RESET_BIT;
01394 RESET_PORT |= RESET_BIT;
01395
01396 NutSleep(100);
01397
01398
01399
01400
01401 RESET_PORT &= ~RESET_BIT;
01402
01403 NutSleep(500);
01404
01405
01406
01407
01408 pcmcia_WriteMem(WI_COR_OFFSET, WI_COR_VALUE);
01409 NutSleep(100);
01410
01411
01412
01413
01414 pcmcia_WriteReg(WI_HFA384X_SWSUPPORT0_OFF, WI_PRISM2STA_MAGIC);
01415 Value = pcmcia_ReadReg(WI_HFA384X_SWSUPPORT0_OFF);
01416 if (Value == WI_PRISM2STA_MAGIC) {
01417
01418
01419
01420 error = 0;
01421 }
01422
01423 return (error);
01424 }
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434 int wlandrv_Attach(device_t dev)
01435 {
01436 struct wi_softc *sc = device_get_softc(dev);
01437 struct ieee80211com *ic = &sc->sc_ic;
01438 struct ieee80211_rateset *rs;
01439 int i, nrates, buflen;
01440 u_int16_t val;
01441 u_int8_t ratebuf[2 + IEEE80211_RATE_SIZE];
01442
01443
01444
01445 int error;
01446
01447 bDebugState = 2;
01448
01449 sc->wi_cmd_count = 500;
01450 ic->ic_fixed_rate = -1;
01451
01452
01453
01454
01455
01456 if (wi_reset(sc) != 0) {
01457 return ENXIO;
01458 }
01459
01460
01461
01462
01463
01464
01465
01466 buflen = IEEE80211_ADDR_LEN;
01467 error = wi_read_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, &buflen);
01468 if (error != 0) {
01469 buflen = IEEE80211_ADDR_LEN;
01470 error = wi_read_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, &buflen);
01471 }
01472 if (error != 0) {
01473 Debug(("mac read failed %d\n", error));
01474 return (error);
01475 }
01476 Debug(("802.11 address: %02X-%02X-%02X-%02X-%02X-%02X\n",
01477 ic->ic_myaddr[0], ic->ic_myaddr[1], ic->ic_myaddr[2], ic->ic_myaddr[3], ic->ic_myaddr[4], ic->ic_myaddr[5]));
01478
01479
01480
01481
01482 wi_read_nicid(sc);
01483
01484 ic->ic_opmode = IEEE80211_M_STA;
01485 ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_AHDEMO;
01486 ic->ic_state = IEEE80211_S_INIT;
01487
01488
01489
01490
01491 buflen = sizeof(val);
01492 if (wi_read_rid(sc, WI_RID_CHANNEL_LIST, &val, &buflen) != 0) {
01493 val = htole16(0x1fff);
01494 }
01495 if (val == 0) {
01496 Debug(("wi_attach: no available channels listed!"));
01497 }
01498 ic->ChannelList = (val << 1);
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508 buflen = sizeof(val);
01509 if (wi_read_rid(sc, WI_RID_OWN_CHNL, &val, &buflen) == 0) {
01510 val = le16toh(val);
01511 i = (1 << val);
01512
01513 if ((val > 16) || ((ic->ChannelList & i) == 0)) {
01514 Debug(("wi_attach: invalid own channel %d!", val));
01515 }
01516 ic->ic_ibss_chan = val;
01517 } else {
01518 Debug(("WI_RID_OWN_CHNL failed, using first channel!\n"));
01519 ic->ic_ibss_chan = 1;
01520 }
01521
01522
01523
01524
01525 switch (sc->sc_firmware_type) {
01526 #if (WLAN_SUPPORT_LUCENT >= 1)
01527 case WI_LUCENT:
01528 sc->sc_ntxbuf = 1;
01529 sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE;
01530
01531 #ifdef WI_HERMES_AUTOINC_WAR
01532
01533
01534
01535 if (sc->sc_sta_firmware_ver < 40000) {
01536 sc->sc_flags |= WI_FLAGS_BUG_AUTOINC;
01537 }
01538 #endif
01539 if (sc->sc_sta_firmware_ver >= 60000) {
01540 sc->sc_flags |= WI_FLAGS_HAS_MOR;
01541 }
01542 if (sc->sc_sta_firmware_ver >= 60006) {
01543 ic->ic_caps |= IEEE80211_C_IBSS;
01544 ic->ic_caps |= IEEE80211_C_MONITOR;
01545 }
01546 sc->sc_ibss_port = htole16(1);
01547
01548 sc->sc_min_rssi = WI_LUCENT_MIN_RSSI;
01549 sc->sc_max_rssi = WI_LUCENT_MAX_RSSI;
01550 sc->sc_dbm_offset = WI_LUCENT_DBM_OFFSET;
01551 break;
01552 #endif
01553
01554 #if (WLAN_SUPPORT_INTERSIL >= 1)
01555 case WI_INTERSIL:
01556 sc->sc_ntxbuf = WI_NTXBUF;
01557 sc->sc_flags |= WI_FLAGS_HAS_FRAGTHR;
01558 sc->sc_flags |= WI_FLAGS_HAS_ROAMING;
01559 sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE;
01560
01561
01562
01563 if (sc->sc_sta_firmware_ver < 10000) {
01564 sc->wi_cmd_count = 5000;
01565 }
01566 if (sc->sc_sta_firmware_ver > 10101) {
01567 sc->sc_flags |= WI_FLAGS_HAS_DBMADJUST;
01568 }
01569 if (sc->sc_sta_firmware_ver >= 800) {
01570 ic->ic_caps |= IEEE80211_C_IBSS;
01571 ic->ic_caps |= IEEE80211_C_MONITOR;
01572 }
01573
01574
01575
01576
01577
01578 if (sc->sc_sta_firmware_ver >= 803) {
01579 ic->ic_caps |= IEEE80211_C_HOSTAP;
01580 }
01581 sc->sc_ibss_port = htole16(0);
01582
01583 sc->sc_min_rssi = WI_PRISM_MIN_RSSI;
01584 sc->sc_max_rssi = WI_PRISM_MAX_RSSI;
01585 sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET;
01586 break;
01587 #endif
01588
01589 #if (WLAN_SUPPORT_SYMBOL >= 1)
01590 case WI_SYMBOL:
01591 sc->sc_ntxbuf = 1;
01592 sc->sc_flags |= WI_FLAGS_HAS_DIVERSITY;
01593 if (sc->sc_sta_firmware_ver >= 25000) {
01594 ic->ic_caps |= IEEE80211_C_IBSS;
01595 }
01596 sc->sc_ibss_port = htole16(4);
01597
01598 sc->sc_min_rssi = WI_PRISM_MIN_RSSI;
01599 sc->sc_max_rssi = WI_PRISM_MAX_RSSI;
01600 sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET;
01601 break;
01602 #endif
01603 }
01604
01605
01606
01607
01608 buflen = sizeof(val);
01609 if (wi_read_rid(sc, WI_RID_WEP_AVAIL, &val, &buflen) == 0 && val != htole16(0)) {
01610 ic->ic_caps |= IEEE80211_C_WEP;
01611 }
01612
01613
01614
01615
01616 buflen = sizeof(ratebuf);
01617 rs = &ic->ic_sup_rates[IEEE80211_MODE_11B];
01618 if (wi_read_rid(sc, WI_RID_DATA_RATES, ratebuf, &buflen) == 0) {
01619 nrates = le16toh(*(u_int16_t *) ratebuf);
01620 if (nrates > IEEE80211_RATE_MAXSIZE) {
01621 nrates = IEEE80211_RATE_MAXSIZE;
01622 }
01623 rs->rs_nrates = 0;
01624 for (i = 0; i < nrates; i++) {
01625 if (ratebuf[2 + i]) {
01626 rs->rs_rates[rs->rs_nrates++] = ratebuf[2 + i];
01627 }
01628 }
01629 } else {
01630
01631
01632
01633 rs->rs_nrates = 0;
01634 }
01635
01636 buflen = sizeof(val);
01637 if ((sc->sc_flags & WI_FLAGS_HAS_DBMADJUST) && wi_read_rid(sc, WI_RID_DBM_ADJUST, &val, &buflen) == 0) {
01638 sc->sc_dbm_offset = le16toh(val);
01639 }
01640
01641 sc->sc_max_datalen = 2304;
01642 sc->sc_system_scale = 1;
01643 sc->sc_cnfauthmode = IEEE80211_AUTH_OPEN;
01644 sc->sc_roaming_mode = WI_DEFAULT_ROAMING;
01645
01646 sc->sc_portnum = WI_DEFAULT_PORT;
01647 sc->sc_authtype = WI_DEFAULT_AUTHTYPE;
01648
01649
01650
01651
01652 NutEventPost(&hDeviceSemaphore);
01653
01654 return (0);
01655 }
01656
01657
01658
01659
01660 void wlandrv_Init(device_t dev)
01661 {
01662 struct wi_softc *sc = device_get_softc(dev);
01663 struct ieee80211com *ic = &sc->sc_ic;
01664 int i;
01665 int error = 0, wasenabled;
01666
01667 WI_LOCK(sc);
01668
01669 if (sc->wi_gone) {
01670 WI_UNLOCK(sc);
01671 return;
01672 }
01673
01674 if ((wasenabled = sc->sc_enabled)) {
01675 wi_stop(sc, 1);
01676 }
01677 wi_reset(sc);
01678
01679
01680
01681
01682 ic->ic_flags &= ~IEEE80211_F_IBSSON;
01683 sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
01684 switch (ic->ic_opmode) {
01685 case IEEE80211_M_STA:
01686 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_BSS);
01687 break;
01688 case IEEE80211_M_IBSS:
01689 wi_write_val(sc, WI_RID_PORTTYPE, sc->sc_ibss_port);
01690 ic->ic_flags |= IEEE80211_F_IBSSON;
01691 break;
01692 case IEEE80211_M_AHDEMO:
01693 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC);
01694 break;
01695 case IEEE80211_M_HOSTAP:
01696
01697
01698
01699
01700 if (sc->sc_firmware_type == WI_INTERSIL && ic->ic_des_esslen == 0) {
01701 ic->ic_des_essid[0] = ' ';
01702 ic->ic_des_esslen = 1;
01703 }
01704 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_HOSTAP);
01705 break;
01706 case IEEE80211_M_MONITOR:
01707
01708 #if 0 // @@MF this mode is not working with my card
01709 if (sc->sc_firmware_type == WI_LUCENT) {
01710 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC);
01711 }
01712 error = wi_cmd(sc, WI_CMD_DEBUG | (WI_TEST_MONITOR << 8), 0, 0, 0);
01713 #endif
01714 break;
01715 }
01716
01717
01718
01719
01720 if (sc->sc_firmware_type == WI_LUCENT && (ic->ic_flags & IEEE80211_F_IBSSON) && ic->ic_des_esslen > 0) {
01721 wi_write_val(sc, WI_RID_CREATE_IBSS, 1);
01722 } else {
01723 wi_write_val(sc, WI_RID_CREATE_IBSS, 0);
01724 }
01725
01726 #if 0 //@@MF later
01727 wi_write_val(sc, WI_RID_MAX_SLEEP, ic->ic_lintval);
01728 #endif
01729
01730 wi_write_ssid(sc, WI_RID_DESIRED_SSID, ic->ic_des_essid, ic->ic_des_esslen);
01731 wi_write_val(sc, WI_RID_OWN_CHNL, ic->ic_ibss_chan);
01732 wi_write_ssid(sc, WI_RID_OWN_SSID, ic->ic_des_essid, ic->ic_des_esslen);
01733
01734 wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, IEEE80211_ADDR_LEN);
01735
01736 wi_write_val(sc, WI_RID_PM_ENABLED, (ic->ic_flags & IEEE80211_F_PMGTON) ? 1 : 0);
01737
01738
01739
01740
01741 wi_write_val(sc, WI_RID_MAX_DATALEN, sc->sc_max_datalen);
01742
01743 #if 0 //@@MF later
01744 wi_write_val(sc, WI_RID_RTS_THRESH, ic->ic_rtsthreshold);
01745 if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR) {
01746 wi_write_val(sc, WI_RID_FRAG_THRESH, ic->ic_fragthreshold);
01747 }
01748 #endif
01749
01750
01751
01752
01753 if (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE) {
01754 wi_write_val(sc, WI_RID_SYSTEM_SCALE, sc->sc_system_scale);
01755 }
01756 if (sc->sc_flags & WI_FLAGS_HAS_ROAMING) {
01757 wi_write_val(sc, WI_RID_ROAMING_MODE, sc->sc_roaming_mode);
01758 }
01759 if (sc->sc_flags & WI_FLAGS_HAS_MOR) {
01760 wi_write_val(sc, WI_RID_MICROWAVE_OVEN, sc->sc_microwave_oven);
01761 }
01762 wi_write_txrate(sc);
01763
01764 #if 0 //@@MF later
01765
01766
01767
01768 wi_write_ssid(sc, WI_RID_NODENAME, sc->sc_nodename, sc->sc_nodelen);
01769 #endif
01770
01771 #if 0 //@@MF later
01772
01773
01774
01775 if (ic->ic_opmode == IEEE80211_M_HOSTAP && sc->sc_firmware_type == WI_INTERSIL) {
01776 wi_write_val(sc, WI_RID_OWN_BEACON_INT, ic->ic_lintval);
01777 wi_write_val(sc, WI_RID_BASIC_RATE, 0x03);
01778 wi_write_val(sc, WI_RID_SUPPORT_RATE, 0x0f);
01779 wi_write_val(sc, WI_RID_DTIM_PERIOD, 1);
01780 }
01781 #endif
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791 if ((ic->ic_opmode != IEEE80211_M_HOSTAP) && (sc->PromiscuousMode != 0)) {
01792 wi_write_val(sc, WI_RID_PROMISC, 1);
01793 } else {
01794 wi_write_val(sc, WI_RID_PROMISC, 0);
01795 }
01796
01797
01798
01799
01800 if (ic->ic_caps & IEEE80211_C_WEP) {
01801 wi_write_wep(sc);
01802 }
01803 #if 0 //@@MF later
01804
01805
01806
01807 wi_write_multi(sc);
01808 #endif
01809
01810
01811
01812
01813 if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled) {
01814 sc->sc_buflen = IEEE80211_MAX_LEN + sizeof(struct wi_frame);
01815 if (sc->sc_firmware_type == WI_SYMBOL) {
01816 sc->sc_buflen = 1585;
01817 }
01818 for (i = 0; i < sc->sc_ntxbuf; i++) {
01819 error = wi_alloc_fid(sc, sc->sc_buflen, &sc->sc_txd[i].d_fid);
01820 if (error) {
01821 Debug(("tx buffer allocation failed (error %u)\n", error));
01822 goto out;
01823 }
01824 sc->sc_txd[i].d_len = 0;
01825 }
01826 }
01827 sc->sc_txcur = sc->sc_txnext = 0;
01828
01829
01830
01831
01832 wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0);
01833
01834 sc->sc_enabled = 1;
01835 if (ic->ic_opmode == IEEE80211_M_AHDEMO || ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_opmode == IEEE80211_M_HOSTAP) {
01836 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
01837 }
01838
01839
01840
01841
01842 if (sc->InterruptInitDone == 0) {
01843 sc->InterruptInitDone = 1;
01844
01845
01846
01847 PORTE |= 0x80;
01848 error = NutRegisterIrqHandler(&sig_INTERRUPT7, WLANInterrupt, dev);
01849 if (error == FALSE) {
01850 EICR |= 0x80;
01851 sbi(EIMSK, INT7);
01852
01853
01854
01855
01856 NutThreadCreate("rxi7", RxThread, dev, 640);
01857 }
01858 }
01859
01860
01861
01862
01863
01864
01865 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
01866
01867 if (!wasenabled && ic->ic_opmode == IEEE80211_M_HOSTAP && sc->sc_firmware_type == WI_INTERSIL) {
01868
01869
01870
01871 wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0);
01872 wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0);
01873 }
01874 #if 0 //@@MF later
01875
01876
01877
01878 if (ic->ic_opmode == IEEE80211_M_STA && ((ic->ic_flags & IEEE80211_F_DESBSSID) || ic->ic_des_chan != IEEE80211_CHAN_ANYC)) {
01879 memset(&join, 0, sizeof(join));
01880 if (ic->ic_flags & IEEE80211_F_DESBSSID)
01881 IEEE80211_ADDR_COPY(&join.wi_bssid, ic->ic_des_bssid);
01882 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC)
01883 join.wi_chan = htole16(ieee80211_chan2ieee(ic, ic->ic_des_chan));
01884
01885
01886
01887 if (sc->sc_firmware_type != WI_LUCENT)
01888 wi_write_rid(sc, WI_RID_JOIN_REQ, &join, sizeof(join));
01889 }
01890 #endif
01891
01892 WI_UNLOCK(sc);
01893 return;
01894 out:
01895 if (error) {
01896 Debug(("interface not running\n"));
01897 wi_stop(sc, 1);
01898 }
01899 WI_UNLOCK(sc);
01900 Debug(("wi_init: return %d\n", error));
01901 return;
01902 }
01903
01904
01905
01906
01907 int wlandrv_PutPacket(NUTDEVICE * dev, NETBUF * nb)
01908 {
01909 int error = -1;
01910 struct wi_softc *sc = (struct wi_softc *) dev->dev_dcb;
01911 struct wi_frame frmhdr;
01912 LLCS_SNAP_HEADER LLCSSNAPHeader;
01913 ETHERHDR *pMAC8023Header;
01914 int cur, fid, off, len;
01915
01916 if (sc->wi_gone) {
01917 Debug(("wlandrv_PutPacket gone\r\n"));
01918 return (-1);
01919 }
01920
01921
01922
01923
01924
01925 len = nb->nb_dl.sz + nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz;
01926 if (len > 1518) {
01927 return (-1);
01928 } else {
01929 WI_LOCK(sc);
01930
01931
01932
01933
01934 #if (WLAN_ENABLE_TX_FRAME_DUMP >= 1)
01935 Debug(("TxFrame: %d\n", len));
01936 DumpWlanData(nb->nb_dl.vp, len);
01937 #endif
01938
01939
01940
01941
01942
01943 len = len - sizeof(ETHERHDR);
01944
01945
01946
01947
01948 len += sizeof(LLCS_SNAP_HEADER);
01949
01950
01951
01952
01953
01954 memset(&frmhdr, 0, sizeof(frmhdr));
01955
01956
01957
01958
01959 pMAC8023Header = (ETHERHDR *) nb->nb_dl.vp;
01960 frmhdr.wi_dat_len = len;
01961 memcpy(frmhdr.wi_ehdr.ether_dhost, pMAC8023Header->ether_dhost, IEEE80211_ADDR_LEN);
01962 memcpy(frmhdr.wi_ehdr.ether_shost, pMAC8023Header->ether_shost, IEEE80211_ADDR_LEN);
01963 frmhdr.wi_ehdr.ether_type = SWAP(len);
01964
01965
01966
01967
01968 LLCSSNAPHeader.DSAPSSAP = 0xAAAA;
01969 LLCSSNAPHeader.Control = 0x0003;
01970 LLCSSNAPHeader.MustZero = 0x0000;
01971 LLCSSNAPHeader.Type = pMAC8023Header->ether_type;
01972
01973
01974
01975
01976 cur = sc->sc_txcur;
01977 fid = sc->sc_txd[cur].d_fid;
01978
01979
01980
01981
01982 error = wi_write_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr));
01983 if (error == 0) {
01984 off = sizeof(frmhdr);
01985
01986
01987
01988
01989 error = wi_write_bap(sc, fid, off, &LLCSSNAPHeader, sizeof(LLCSSNAPHeader));
01990 if (error == 0) {
01991 off += sizeof(LLCSSNAPHeader);
01992
01993
01994
01995
01996 if ((error == 0) && (nb->nb_nw.sz != 0)) {
01997 error = wi_write_bap(sc, fid, off, nb->nb_nw.vp, nb->nb_nw.sz);
01998 off += nb->nb_nw.sz;
01999 }
02000 if ((error == 0) && (nb->nb_tp.sz != 0)) {
02001 error = wi_write_bap(sc, fid, off, nb->nb_tp.vp, nb->nb_tp.sz);
02002 off += nb->nb_tp.sz;
02003 }
02004 if ((error == 0) && (nb->nb_ap.sz != 0)) {
02005 error = wi_write_bap(sc, fid, off, nb->nb_ap.vp, nb->nb_ap.sz);
02006 }
02007 if (error == 0) {
02008
02009
02010
02011 error = wi_cmd(sc, WI_CMD_TX | WI_RECLAIM, fid, 0, 0);
02012 if (error != 0) {
02013 Debug(("xmit failed\n"));
02014 sc->sc_txd[cur].d_len = 0;
02015 }
02016
02017 sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf;
02018 }
02019 }
02020 }
02021
02022 WI_UNLOCK(sc);
02023 }
02024
02025 return (error);
02026 }
02027
02028
02029
02030
02031 int wlandrv_IOCTL(NUTDEVICE * dev, int req, void *conf)
02032 {
02033 int error = 0;
02034 int len;
02035 int i;
02036 u_int16_t DataBuffer[6];
02037 struct wi_softc *sc = (struct wi_softc *) dev->dev_dcb;
02038 struct ieee80211com *ic = &sc->sc_ic;
02039 WLAN_CONFIG *pWLANConfig;
02040 WLAN_STATUS *pWLANStatus;
02041 u_int8_t BSSIDAddress[6];
02042
02043 if ((sc->wi_gone) || (conf == 0)) {
02044 error = -1;
02045 } else {
02046
02047 switch (req) {
02048
02049
02050
02051 case WLAN_IOCTL_GET_MAC_ADDRESS:{
02052 memcpy(conf, ic->ic_myaddr, IEEE80211_ADDR_LEN);
02053 break;
02054 }
02055
02056
02057
02058
02059 case WLAN_IOCTL_SET_CONFIG:{
02060 pWLANConfig = (WLAN_CONFIG *) conf;
02061
02062 if ((pWLANConfig != NULL) && (pWLANConfig->Size == sizeof(WLAN_CONFIG))) {
02063 WI_LOCK(sc);
02064
02065
02066 wi_stop(sc, 1);
02067
02068
02069 switch (pWLANConfig->Mode) {
02070 case WLAN_MODE_STOP:{
02071 WI_UNLOCK(sc);
02072 return (0);
02073 break;
02074 }
02075 case WLAN_MODE_STATION:{
02076 ic->ic_opmode = IEEE80211_M_STA;
02077 break;
02078 }
02079 case WLAN_MODE_ADHOC:{
02080 ic->ic_opmode = IEEE80211_M_IBSS;
02081 break;
02082 }
02083 default:{
02084 error = -1;
02085 break;
02086 }
02087 }
02088
02089 if (error == 0) {
02090
02091 len = strlen(pWLANConfig->Networkname);
02092 memcpy(ic->ic_des_essid, pWLANConfig->Networkname, len);
02093 ic->ic_des_esslen = len;
02094
02095
02096 switch (pWLANConfig->UseWEP) {
02097 case WLAN_USE_NO_WEP:{
02098 ic->ic_flags &= ~IEEE80211_F_WEPON;
02099 break;
02100 }
02101 case WLAN_USE_64BIT_WEP:
02102 case WLAN_USE_128BIT_WEP:{
02103 ic->ic_flags |= IEEE80211_F_WEPON;
02104 break;
02105 }
02106 default:{
02107 error = -1;
02108 break;
02109 }
02110 }
02111
02112
02113 ic->ic_wep_txkey = pWLANConfig->UseWEPTxKey;
02114
02115
02116 for (i = 0; i < WLAN_WEP_MAX_KEY_COUNT; i++) {
02117 ic->ic_nw_keys[i].wk_len = pWLANConfig->WEPKey[i].KeyLen;
02118 memcpy(ic->ic_nw_keys[i].wk_key, pWLANConfig->WEPKey[i].Key, WLAN_WEP_MAX_KEY_SIZE);
02119 }
02120 }
02121
02122 WI_UNLOCK(sc);
02123
02124 if (error == 0) {
02125 wlandrv_Init(dev);
02126 }
02127 } else {
02128 error = -1;
02129 }
02130 break;
02131 }
02132
02133
02134
02135
02136 case WLAN_IOCTL_GET_STATUS:{
02137 pWLANStatus = (WLAN_STATUS *) conf;
02138
02139 if ((pWLANStatus != NULL) && (pWLANStatus->Size == sizeof(WLAN_STATUS))) {
02140 WI_LOCK(sc);
02141
02142 memset(pWLANStatus, 0x00, sizeof(WLAN_STATUS));
02143 pWLANStatus->Size = sizeof(WLAN_STATUS);
02144
02145
02146
02147
02148 memset(DataBuffer, 0, sizeof(DataBuffer));
02149 len = sizeof(DataBuffer);
02150 error = wi_read_rid(sc, WI_RID_PORT_STAT, DataBuffer, &len);
02151 if (error == 0) {
02152 pWLANStatus->PortStatus = (u_int8_t) DataBuffer[0];
02153 }
02154
02155
02156
02157
02158 memset(BSSIDAddress, 0, sizeof(BSSIDAddress));
02159 len = sizeof(BSSIDAddress);
02160 error = wi_read_rid(sc, WI_RID_CURRENT_BSSID, BSSIDAddress, &len);
02161 if (error == 0) {
02162 memcpy(pWLANStatus->BSSIDAddress, BSSIDAddress, IEEE80211_ADDR_LEN);
02163 }
02164
02165
02166
02167
02168 memset(DataBuffer, 0, sizeof(DataBuffer));
02169 len = sizeof(DataBuffer);
02170 error = wi_read_rid(sc, WI_RID_CURRENT_CHAN, DataBuffer, &len);
02171 if (error == 0) {
02172 pWLANStatus->Channel = (u_int8_t) DataBuffer[0];
02173 }
02174
02175
02176
02177
02178 memset(DataBuffer, 0, sizeof(DataBuffer));
02179 len = sizeof(DataBuffer);
02180 error = wi_read_rid(sc, WI_RID_CUR_TX_RATE, DataBuffer, &len);
02181 if (error == 0) {
02182 pWLANStatus->TxRate = (u_int8_t) DataBuffer[0];
02183 }
02184
02185
02186
02187
02188 memset(DataBuffer, 0, sizeof(DataBuffer));
02189 len = sizeof(DataBuffer);
02190 error = wi_read_rid(sc, WI_RID_DBM_COMMS_QUAL, DataBuffer, &len);
02191 if (error == 0) {
02192 pWLANStatus->Quality = DataBuffer[0];
02193 pWLANStatus->Signal = DataBuffer[1];
02194 pWLANStatus->Noise = DataBuffer[2];
02195 }
02196
02197 WI_UNLOCK(sc);
02198 } else {
02199 error = -1;
02200 }
02201
02202 break;
02203 }
02204
02205
02206 default:{
02207 error = -1;
02208 break;
02209 }
02210 }
02211 }
02212
02213
02214 return (error);
02215 }