Index: if_wi.c =================================================================== RCS file: /share/cvsup/FreeBSD/current/usr/src/sys/i386/isa/if_wi.c,v retrieving revision 1.29 diff -u -r1.29 if_wi.c --- if_wi.c 2000/11/30 18:52:31 1.29 +++ if_wi.c 2000/12/11 04:46:37 @@ -231,10 +231,34 @@ struct wi_ltv_gen gen; struct ifnet *ifp; int error; + u_int32_t flags; sc = device_get_softc(dev); ifp = &sc->arpcom.ac_if; + /* + * XXX: quick hack to support Prism II chip. + * Currently, we need to set a flags in pccard.conf to specify + * which type chip is used. + * + * We need to replace this code in a future. + * It is better to use CIS than using a flag. + */ + flags = device_get_flags(dev); +#define WI_FLAGS_PRISM2 0x10000 + if (flags & WI_FLAGS_PRISM2) { + sc->wi_prism2 = 1; + if (bootverbose) { + device_printf(dev, "found PrismII chip\n"); + } + } + else { + sc->wi_prism2 = 0; + if (bootverbose) { + device_printf(dev, "found Lucent chip\n"); + } + } + error = wi_alloc(dev); if (error) { device_printf(dev, "wi_alloc() failed! (%d)\n", error); @@ -320,6 +344,12 @@ wi_read_record(sc, &gen); sc->wi_has_wep = gen.wi_val; + if (bootverbose) { + device_printf(sc->dev, + __FUNCTION__ ":wi_has_wep = %d\n", + sc->wi_has_wep); + } + bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats)); wi_init(sc); @@ -589,7 +619,21 @@ { int i, s = 0; + /* wait for the busy bit to clear */ + for (i = 0; i < WI_TIMEOUT; i++) { + if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) { + break; + } + DELAY(10*1000); /* 10 m sec */ + } + + if (i == WI_TIMEOUT) { + return(ETIMEDOUT); + } + CSR_WRITE_2(sc, WI_PARAM0, val); + CSR_WRITE_2(sc, WI_PARAM1, 0); + CSR_WRITE_2(sc, WI_PARAM2, 0); CSR_WRITE_2(sc, WI_COMMAND, cmd); for (i = 0; i < WI_TIMEOUT; i++) { @@ -621,11 +665,12 @@ static void wi_reset(sc) struct wi_softc *sc; { +#ifdef foo wi_cmd(sc, WI_CMD_INI, 0); DELAY(100000); wi_cmd(sc, WI_CMD_INI, 0); +#endif DELAY(100000); -#ifdef foo if (wi_cmd(sc, WI_CMD_INI, 0)) device_printf(sc->dev, "init failed\n"); CSR_WRITE_2(sc, WI_INT_EN, 0); @@ -633,7 +678,7 @@ /* Calibrate timer. */ WI_SETVAL(WI_RID_TICK_TIME, 8); -#endif + return; } @@ -646,6 +691,23 @@ { u_int16_t *ptr; int i, len, code; + struct wi_ltv_gen *oltv, p2ltv; + + oltv = ltv; + if (sc->wi_prism2) { + switch (ltv->wi_type) { + case WI_RID_ENCRYPTION: + p2ltv.wi_type = WI_RID_P2_ENCRYPTION; + p2ltv.wi_len = 2; + ltv = &p2ltv; + break; + case WI_RID_TX_CRYPT_KEY: + p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; + p2ltv.wi_len = 2; + ltv = &p2ltv; + break; + } + } /* Tell the NIC to enter record read mode. */ if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type)) @@ -675,6 +737,35 @@ for (i = 0; i < ltv->wi_len - 1; i++) ptr[i] = CSR_READ_2(sc, WI_DATA1); + if (sc->wi_prism2) { + switch (oltv->wi_type) { + case WI_RID_TX_RATE: + case WI_RID_CUR_TX_RATE: + switch (ltv->wi_val) { + case 1: oltv->wi_val = 1; break; + case 2: oltv->wi_val = 2; break; + case 3: oltv->wi_val = 6; break; + case 4: oltv->wi_val = 5; break; + case 7: oltv->wi_val = 7; break; + case 8: oltv->wi_val = 11; break; + case 15: oltv->wi_val = 3; break; + default: oltv->wi_val = 0x100 + ltv->wi_val; break; + } + break; + case WI_RID_ENCRYPTION: + oltv->wi_len = 2; + if (ltv->wi_val & 0x01) + oltv->wi_val = 1; + else + oltv->wi_val = 0; + break; + case WI_RID_TX_CRYPT_KEY: + oltv->wi_len = 2; + oltv->wi_val = ltv->wi_val; + break; + } + } + return(0); } @@ -687,6 +778,59 @@ { u_int16_t *ptr; int i; + struct wi_ltv_gen p2ltv; + + if (sc->wi_prism2) { + switch (ltv->wi_type) { + case WI_RID_TX_RATE: + p2ltv.wi_type = WI_RID_TX_RATE; + p2ltv.wi_len = 2; + switch (ltv->wi_val) { + case 1: p2ltv.wi_val = 1; break; + case 2: p2ltv.wi_val = 2; break; + case 3: p2ltv.wi_val = 15; break; + case 5: p2ltv.wi_val = 4; break; + case 6: p2ltv.wi_val = 3; break; + case 7: p2ltv.wi_val = 7; break; + case 11: p2ltv.wi_val = 8; break; + default: return EINVAL; + } + ltv = &p2ltv; + break; + case WI_RID_ENCRYPTION: + p2ltv.wi_type = WI_RID_P2_ENCRYPTION; + p2ltv.wi_len = 2; + if (ltv->wi_val) + p2ltv.wi_val = 0x03; + else + p2ltv.wi_val = 0x90; + ltv = &p2ltv; + break; + case WI_RID_TX_CRYPT_KEY: + p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY; + p2ltv.wi_len = 2; + p2ltv.wi_val = ltv->wi_val; + ltv = &p2ltv; + break; + case WI_RID_DEFLT_CRYPT_KEYS: + { + int error; + struct wi_ltv_str ws; + struct wi_ltv_keys *wk = (struct wi_ltv_keys *)ltv; + for (i = 0; i < 4; i++) { + ws.wi_len = 4; + ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i; + memcpy(ws.wi_str, &wk->wi_keys[i].wi_keydat, 5); + ws.wi_str[5] = '\0'; + error = wi_write_record(sc, + (struct wi_ltv_gen *)&ws); + if (error) + return error; + } + return 0; + } + } + } if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1)) return(EIO); @@ -1362,7 +1506,8 @@ rid = 0; sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, - 0, ~0, 1, RF_ACTIVE); + 0, ~0, (1 << 6), + rman_make_alignment_flags(1 << 6) | RF_ACTIVE); if (!sc->iobase) { device_printf(dev, "No I/O space?!\n"); return (ENXIO); Index: if_wireg.h =================================================================== RCS file: /share/cvsup/FreeBSD/current/usr/src/sys/i386/isa/if_wireg.h,v retrieving revision 1.9 diff -u -r1.9 if_wireg.h --- if_wireg.h 2000/10/13 20:33:24 1.9 +++ if_wireg.h 2000/12/11 04:48:15 @@ -66,6 +66,13 @@ #define WI_RID_DEFLT_CRYPT_KEYS 0xFCB0 #define WI_RID_TX_CRYPT_KEY 0xFCB1 #define WI_RID_WEP_AVAIL 0xFD4F +#define WI_RID_P2_TX_CRYPT_KEY 0xFC23 +#define WI_RID_P2_CRYPT_KEY0 0xFC24 +#define WI_RID_P2_CRYPT_KEY1 0xFC25 +#define WI_RID_P2_CRYPT_KEY2 0xFC26 +#define WI_RID_P2_CRYPT_KEY3 0xFC27 +#define WI_RID_P2_ENCRYPTION 0xFC28 +#define WI_RID_CUR_TX_RATE 0xFD44 /* current TX rate */ struct wi_key { u_int16_t wi_keylen; u_int8_t wi_keydat[14]; @@ -118,6 +125,7 @@ #endif struct callout_handle wi_stat_ch; struct mtx wi_mtx; + int wi_prism2; /* set to 1 if it uses a Prism II chip */ }; #define WI_LOCK(_sc) mtx_enter(&(_sc)->wi_mtx, MTX_DEF)