diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pcmcia/if_wi.c | 260 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_wireg.h | 26 |
2 files changed, 258 insertions, 28 deletions
diff --git a/sys/dev/pcmcia/if_wi.c b/sys/dev/pcmcia/if_wi.c index b74bd77518f..8a739fcfd47 100644 --- a/sys/dev/pcmcia/if_wi.c +++ b/sys/dev/pcmcia/if_wi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wi.c,v 1.27 2001/03/19 20:24:59 niklas Exp $ */ +/* $OpenBSD: if_wi.c,v 1.28 2001/04/04 20:13:11 mickey Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -133,7 +133,7 @@ u_int32_t widebug = WIDEBUG; #if !defined(lint) && !defined(__OpenBSD__) static const char rcsid[] = - "$OpenBSD: if_wi.c,v 1.27 2001/03/19 20:24:59 niklas Exp $"; + "$OpenBSD: if_wi.c,v 1.28 2001/04/04 20:13:11 mickey Exp $"; #endif /* lint */ #ifdef foo @@ -181,6 +181,157 @@ struct cfattach wi_ca = { wi_pcmcia_detach, wi_pcmcia_activate }; +static const struct wi_pcmcia_product { + u_int32_t pp_vendor; + u_int32_t pp_product; + const char *pp_cisinfo[4]; + const char *pp_name; + int pp_prism2; +} wi_pcmcia_products[] = { + { PCMCIA_VENDOR_LUCENT, + PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE, + PCMCIA_CIS_LUCENT_WAVELAN_IEEE, + "WaveLAN/IEEE", + 0 }, + + { PCMCIA_VENDOR_3COM, + PCMCIA_PRODUCT_3COM_3CRWE737A, + PCMCIA_CIS_3COM_3CRWE737A, + "3Com AirConnect Wireless LAN", + 1 }, + + { PCMCIA_VENDOR_COREGA, + PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCC_11, + PCMCIA_CIS_COREGA_WIRELESS_LAN_PCC_11, + "Corega Wireless LAN PCC-11", + 1 }, + + { PCMCIA_VENDOR_COREGA, + PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCCA_11, + PCMCIA_CIS_COREGA_WIRELESS_LAN_PCCA_11, + "Corega Wireless LAN PCCA-11", + 1 }, + + { PCMCIA_VENDOR_INTERSIL, + PCMCIA_PRODUCT_INTERSIL_PRISM2, + PCMCIA_CIS_INTERSIL_PRISM2, + "Intersil Prism II", + 1 }, + + { PCMCIA_VENDOR_SAMSUNG, + PCMCIA_PRODUCT_SAMSUNG_SWL_2000N, + PCMCIA_CIS_SAMSUNG_SWL_2000N, + "Samsung MagicLAN SWL-2000N", + 1 }, + + { PCMCIA_VENDOR_LUCENT, + PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE, + PCMCIA_CIS_SMC_2632W, + "SMC 2632 EZ Connect Wireless PC Card", + 1 }, + + { PCMCIA_VENDOR_LUCENT, + PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE, + PCMCIA_CIS_NANOSPEED_PRISM2, + "NANOSPEED ROOT-RZ2000 WLAN Card", + 1 }, + + { PCMCIA_VENDOR_ELSA, + PCMCIA_PRODUCT_ELSA_XI300_IEEE, + PCMCIA_CIS_ELSA_XI300_IEEE, + "XI300 Wireless LAN", + 1 }, + + { PCMCIA_VENDOR_COMPAQ, + PCMCIA_PRODUCT_COMPAQ_NC5004, + PCMCIA_CIS_COMPAQ_NC5004, + "Compaq Agency NC5004 Wireless Card", + 1 }, + + { PCMCIA_VENDOR_CONTEC, + PCMCIA_PRODUCT_CONTEC_FX_DS110_PCC, + PCMCIA_CIS_CONTEC_FX_DS110_PCC, + "Contec FLEXLAN/FX-DS110-PCC", + 1 }, + + { PCMCIA_VENDOR_TDK, + PCMCIA_PRODUCT_TDK_LAK_CD011WL, + PCMCIA_CIS_TDK_LAK_CD011WL, + "TDK LAK-CD011WL", + 1 }, + + { PCMCIA_VENDOR_LUCENT, + PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE, + PCMCIA_CIS_NEC_CMZ_RT_WP, + "NEC Wireless Card CMZ-RT-WP", + 1 }, + + { PCMCIA_VENDOR_LUCENT, + PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE, + PCMCIA_CIS_NTT_ME_WLAN, + "NTT-ME 11Mbps Wireless LAN PC Card", + 1 }, + + { PCMCIA_VENDOR_LUCENT, + PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE, + PCMCIA_CIS_NTT_ME_WLAN, + "Addtron AWP-100", + 0 }, + + { PCMCIA_VENDOR_LUCENT, + PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE, + PCMCIA_CIS_CABLETRON_ROAMABOUT, + "Cabletron RoamAbout", + 0 }, + + { PCMCIA_VENDOR_IODATA2, + PCMCIA_PRODUCT_IODATA2_WNB11PCM, + PCMCIA_CIS_IODATA2_WNB11PCM, + "I-O DATA WN-B11/PCM", + 1 }, + + { 0, + 0, + { NULL, NULL, NULL, NULL }, + NULL, + 0 } +}; + +static const struct wi_pcmcia_product *wi_lookup __P((struct pcmcia_attach_args *pa)); + +const struct wi_pcmcia_product * +wi_lookup(pa) + struct pcmcia_attach_args *pa; +{ + const struct wi_pcmcia_product *pp; + + /* + * match by CIS information first + * XXX: Farallon SkyLINE 11mb uses PRISM II but vendor ID + * and product ID is the same as Lucent WaveLAN + */ + for (pp = wi_pcmcia_products; pp->pp_name != NULL; pp++) { + if (pa->card->cis1_info[0] != NULL && + pp->pp_cisinfo[0] != NULL && + strcmp(pa->card->cis1_info[0], pp->pp_cisinfo[0]) == 0 && + pa->card->cis1_info[1] != NULL && + pp->pp_cisinfo[1] != NULL && + strcmp(pa->card->cis1_info[1], pp->pp_cisinfo[1]) == 0) + return pp; + } + + /* match by vendor/product id */ + for (pp = wi_pcmcia_products; pp->pp_name != NULL; pp++) { + if (pa->manufacturer != PCMCIA_VENDOR_INVALID && + pa->manufacturer == pp->pp_vendor && + pa->product != PCMCIA_PRODUCT_INVALID && + pa->product == pp->pp_product) + return pp; + } + + return NULL; +} + int wi_pcmcia_match(parent, match, aux) struct device *parent; @@ -188,24 +339,9 @@ wi_pcmcia_match(parent, match, aux) { struct pcmcia_attach_args *pa = aux; - if (pa->pf->function != PCMCIA_FUNCTION_NETWORK) - return (0); - - switch (pa->manufacturer) { - case PCMCIA_VENDOR_LUCENT: - /* XXX Per-productid checking here. */ - return (1); - - case PCMCIA_VENDOR_ELSA: - switch (pa->product) { - case PCMCIA_PRODUCT_ELSA_XI300_IEEE: - return (1); - } - return (0); - - default: - return (0); - } + if (wi_lookup(pa) != NULL) + return 1; + return 0; } void @@ -217,6 +353,7 @@ wi_pcmcia_attach(parent, self, aux) struct pcmcia_attach_args *pa = aux; struct pcmcia_function *pf = pa->pf; struct pcmcia_config_entry *cfe = pf->cfe_head.sqh_first; + const struct wi_pcmcia_product *pp; struct wi_ltv_macaddr mac; struct wi_ltv_gen gen; struct ifnet *ifp; @@ -249,6 +386,13 @@ wi_pcmcia_attach(parent, self, aux) sc->wi_btag = sc->sc_pcioh.iot; sc->wi_bhandle = sc->sc_pcioh.ioh; + pp = wi_lookup(pa); + if (pp == NULL) { + /* should not happen */ + sc->sc_prism2 = 0; + } else + sc->sc_prism2 = pp->pp_prism2; + /* Make sure interrupts are disabled. */ CSR_WRITE_2(sc, WI_INT_EN, 0); CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); @@ -724,6 +868,23 @@ wi_read_record(sc, ltv) { u_int16_t *ptr; int i, len, code; + struct wi_ltv_gen *oltv, p2ltv; + + if (sc->sc_prism2) { + oltv = ltv; + 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)) @@ -753,6 +914,35 @@ wi_read_record(sc, ltv) for (i = 0; i < ltv->wi_len - 1; i++) ptr[i] = CSR_READ_2(sc, WI_DATA1); + if (sc->sc_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); } @@ -766,6 +956,36 @@ wi_write_record(sc, ltv) { u_int16_t *ptr; int i; + struct wi_ltv_gen *oltv; + + if (sc->sc_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; + } + } if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1)) return(EIO); diff --git a/sys/dev/pcmcia/if_wireg.h b/sys/dev/pcmcia/if_wireg.h index 68e85eb4e90..3b0f61996de 100644 --- a/sys/dev/pcmcia/if_wireg.h +++ b/sys/dev/pcmcia/if_wireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wireg.h,v 1.9 2001/03/19 20:25:00 niklas Exp $ */ +/* $OpenBSD: if_wireg.h,v 1.10 2001/04/04 20:13:12 mickey Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -60,14 +60,21 @@ struct wi_counters { /* * Encryption controls. We can enable or disable encryption as - * well as specify up to 4 encryption keys. We can also specify + * well as specify up to 4 encryption keys. We can also specify * which of the four keys will be used for transmit encryption. */ -#define WI_RID_ENCRYPTION 0xFC20 -#define WI_RID_AUTHTYPE 0xFC21 -#define WI_RID_DEFLT_CRYPT_KEYS 0xFCB0 -#define WI_RID_TX_CRYPT_KEY 0xFCB1 -#define WI_RID_WEP_AVAIL 0xFD4F +#define WI_RID_ENCRYPTION 0xFC20 +#define WI_RID_AUTHTYPE 0xFC21 +#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_MICROWAVE_OVEN 0xFC25 +#define WI_RID_P2_CRYPT_KEY2 0xFC26 +#define WI_RID_P2_CRYPT_KEY3 0xFC27 +#define WI_RID_P2_ENCRYPTION 0xFC28 +#define WI_RID_DEFLT_CRYPT_KEYS 0xFCB0 +#define WI_RID_TX_CRYPT_KEY 0xFCB1 +#define WI_RID_WEP_AVAIL 0xFD4F struct wi_key { u_int16_t wi_keylen; u_int8_t wi_keydat[14]; @@ -115,6 +122,7 @@ struct wi_softc { int sc_io_window; struct pcmcia_function *sc_pf; struct timeout sc_timo; + int sc_prism2; }; #define WI_TIMEOUT 50000 /* XXX just a guess at a good value. */ @@ -138,7 +146,7 @@ struct wi_softc { #define WI_DEFAULT_AP_DENSITY 1 #define WI_DEFAULT_RTS_THRESH 2347 - + #define WI_DEFAULT_DATALEN 2304 #define WI_DEFAULT_CREATE_IBSS 0 @@ -438,6 +446,8 @@ struct wi_ltv_commqual { u_int16_t wi_noise_lvl; }; +#define WI_RID_CUR_TX_RATE 0xFD44 /* current TX rate */ + /* * Actual system scale thresholds (0xFD46). */ |