diff options
-rw-r--r-- | sys/dev/ic/if_wi.c | 127 | ||||
-rw-r--r-- | sys/dev/ic/if_wivar.h | 15 |
2 files changed, 92 insertions, 50 deletions
diff --git a/sys/dev/ic/if_wi.c b/sys/dev/ic/if_wi.c index 04dea2b55d2..4995fa2bb44 100644 --- a/sys/dev/ic/if_wi.c +++ b/sys/dev/ic/if_wi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wi.c,v 1.51 2002/04/10 19:25:07 millert Exp $ */ +/* $OpenBSD: if_wi.c,v 1.52 2002/04/11 00:08:25 millert Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -124,7 +124,7 @@ u_int32_t widebug = WIDEBUG; #if !defined(lint) && !defined(__OpenBSD__) static const char rcsid[] = - "$OpenBSD: if_wi.c,v 1.51 2002/04/10 19:25:07 millert Exp $"; + "$OpenBSD: if_wi.c,v 1.52 2002/04/11 00:08:25 millert Exp $"; #endif /* lint */ #ifdef foo @@ -175,13 +175,6 @@ struct cfdriver wi_cd = { NULL, "wi", DV_IFNET }; -/* Map of firmware type to IBBS port type */ -int ibss_portmap[] = { - 1, /* WI_LUCENT */ - 0, /* WI_INTERSIL */ - 4, /* WI_SYMBOL */ -}; - int wi_attach(sc) struct wi_softc *sc; @@ -254,12 +247,43 @@ wi_attach(sc) sc->wi_channel = 3; /* + * Set flags based on firmware version. + */ + switch (sc->sc_firmware_type) { + case WI_LUCENT: + sc->wi_flags |= WI_FLAGS_HAS_ROAMING; + if (sc->sc_sta_firmware_ver >= 60000) + sc->wi_flags |= WI_FLAGS_HAS_MOR; + if (sc->sc_sta_firmware_ver >= 60006) { + sc->wi_flags |= WI_FLAGS_HAS_IBSS; + sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS; + } + sc->wi_ibss_port = htole16(1); + break; + case WI_INTERSIL: + sc->wi_flags |= WI_FLAGS_HAS_ROAMING; + if (sc->sc_sta_firmware_ver >= 800) { + sc->wi_flags |= WI_FLAGS_HAS_IBSS; + sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS; + } + sc->wi_ibss_port = htole16(0); + break; + case WI_SYMBOL: + sc->wi_flags |= WI_FLAGS_HAS_DIVERSITY; + /* XXX - Symbol does not seem to support IBSS creation. */ + if (sc->sc_sta_firmware_ver >= 20000) + sc->wi_flags |= WI_FLAGS_HAS_IBSS; + sc->wi_ibss_port = htole16(4); + break; + } + + /* * Find out if we support WEP on this card. */ gen.wi_type = WI_RID_WEP_AVAIL; gen.wi_len = 2; - if (wi_read_record(sc, &gen) == 0) - sc->wi_has_wep = letoh16(gen.wi_val); + if (wi_read_record(sc, &gen) == 0 && gen.wi_val != htole16(0)) + sc->wi_flags |= WI_FLAGS_HAS_WEP; timeout_set(&sc->sc_timo, wi_inquire, sc); bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats)); @@ -277,8 +301,10 @@ wi_attach(sc) #define ADD(m, c) ifmedia_add(&sc->sc_media, (m), (c), NULL) ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0); ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_ADHOC, 0), 0); - ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_IBSS, 0), 0); - if (sc->sc_firmware_type != WI_SYMBOL) + if (sc->wi_flags & WI_FLAGS_HAS_IBSS) + ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_IBSS, + 0), 0); + if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_IBSSMASTER, 0), 0); if (sc->sc_firmware_type == WI_INTERSIL) @@ -288,9 +314,10 @@ wi_attach(sc) ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0); ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, IFM_IEEE80211_ADHOC, 0), 0); - ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, - IFM_IEEE80211_IBSS, 0), 0); - if (sc->sc_firmware_type != WI_SYMBOL) + if (sc->wi_flags & WI_FLAGS_HAS_IBSS) + ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, + IFM_IEEE80211_IBSS, 0), 0); + if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, IFM_IEEE80211_IBSSMASTER, 0), 0); if (sc->sc_firmware_type == WI_INTERSIL) @@ -301,9 +328,10 @@ wi_attach(sc) ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0); ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, IFM_IEEE80211_ADHOC, 0), 0); - ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, - IFM_IEEE80211_IBSS, 0), 0); - if (sc->sc_firmware_type != WI_SYMBOL) + if (sc->wi_flags & WI_FLAGS_HAS_IBSS) + ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, + IFM_IEEE80211_IBSS, 0), 0); + if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, IFM_IEEE80211_IBSSMASTER, 0), 0); if (sc->sc_firmware_type == WI_INTERSIL) @@ -314,9 +342,10 @@ wi_attach(sc) ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0); ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, IFM_IEEE80211_ADHOC, 0), 0); - ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, - IFM_IEEE80211_IBSS, 0), 0); - if (sc->sc_firmware_type != WI_SYMBOL) + if (sc->wi_flags & WI_FLAGS_HAS_IBSS) + ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, + IFM_IEEE80211_IBSS, 0), 0); + if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, IFM_IEEE80211_IBSSMASTER, 0), 0); if (sc->sc_firmware_type == WI_INTERSIL) @@ -327,9 +356,10 @@ wi_attach(sc) ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0); ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, IFM_IEEE80211_ADHOC, 0), 0); - ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, - IFM_IEEE80211_IBSS, 0), 0); - if (sc->sc_firmware_type != WI_SYMBOL) + if (sc->wi_flags & WI_FLAGS_HAS_IBSS) + ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, + IFM_IEEE80211_IBSS, 0), 0); + if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, IFM_IEEE80211_IBSSMASTER, 0), 0); if (sc->sc_firmware_type == WI_INTERSIL) @@ -744,11 +774,12 @@ wi_cor_reset(sc) DPRINTF(WID_RESET, ("wi_cor_reset: sc %p\n", sc)); /* - * Do a soft reset of the card. This is required by Symbol cards - * and shouldn't hurt others. We don't do this on Lucent cards - * because it messes up some old Lucent firmware revisions. + * Do a soft reset of the card; this is required for Symbol cards. + * This shouldn't hurt other cards but there have been reports + * of the COR reset messing up old Lucent firmware revisions so + * we only soft reset Symbol cards for now. */ - if (sc->sc_firmware_type != WI_LUCENT) { + if (sc->sc_firmware_type == WI_SYMBOL) { cor_value = bus_space_read_2(sc->wi_ltag, sc->wi_lhandle, sc->wi_cor_offset); bus_space_write_1(sc->wi_ltag, sc->wi_lhandle, @@ -819,7 +850,7 @@ wi_read_record(sc, ltv) CSR_READ_RAW_2(sc, WI_DATA1, ptr, (ltv->wi_len-1)*2); if (ltv->wi_type == WI_RID_PORTTYPE && sc->wi_ptype == WI_PORTTYPE_IBSS - && letoh16(ltv->wi_val) == ibss_portmap[sc->sc_firmware_type]) { + && ltv->wi_val == sc->wi_ibss_port) { /* * Convert vendor IBSS port type to WI_PORTTYPE_IBSS. * Since Lucent uses port type 1 for BSS *and* IBSS we @@ -879,7 +910,7 @@ wi_write_record(sc, ltv) /* Convert WI_PORTTYPE_IBSS to vendor IBSS port type. */ p2ltv.wi_type = WI_RID_PORTTYPE; p2ltv.wi_len = 2; - p2ltv.wi_val = htole16(ibss_portmap[sc->sc_firmware_type]); + p2ltv.wi_val = sc->wi_ibss_port; ltv = &p2ltv; } else if (sc->sc_firmware_type != WI_LUCENT) { int v; @@ -1389,13 +1420,19 @@ wi_ioctl(ifp, command, data) break; case WI_RID_SYMBOL_DIVERSITY: case WI_RID_ROAMING_MODE: - /* Only Symbol cards support antenna diversity */ - if (wreq.wi_type == WI_RID_SYMBOL_DIVERSITY && - sc->sc_firmware_type != WI_SYMBOL) - break; - /* Symbol cards use 0xFC2D for something else. */ - if (wreq.wi_type == WI_RID_ROAMING_MODE && - sc->sc_firmware_type == WI_SYMBOL) + case WI_RID_CREATE_IBSS: + case WI_RID_MICROWAVE_OVEN: + /* + * Check for features that may not be supported. + */ + if ((wreq.wi_type == WI_RID_SYMBOL_DIVERSITY && + !(sc->wi_flags & WI_FLAGS_HAS_DIVERSITY)) || + (wreq.wi_type == WI_RID_ROAMING_MODE && + !(sc->wi_flags & WI_FLAGS_HAS_ROAMING)) || + (wreq.wi_type == WI_RID_CREATE_IBSS && + !(sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)) || + (wreq.wi_type == WI_RID_MICROWAVE_OVEN && + !(sc->wi_flags & WI_FLAGS_HAS_MOR))) break; /* FALLTHROUGH */ default: @@ -1518,11 +1555,11 @@ wi_init(sc) WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep); /* Set Roaming Mode unless this is a Symbol card. */ - if (sc->sc_firmware_type != WI_SYMBOL) + if (sc->wi_flags & WI_FLAGS_HAS_ROAMING) WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming); /* Set Antenna Diversity if this is a Symbol card. */ - if (sc->sc_firmware_type == WI_SYMBOL) + if (sc->wi_flags & WI_FLAGS_HAS_DIVERSITY) WI_SETVAL(WI_RID_SYMBOL_DIVERSITY, sc->wi_diversity); /* Specify the network name */ @@ -1562,7 +1599,7 @@ wi_init(sc) WI_SETVAL(WI_RID_PROMISC, 0); /* Configure WEP. */ - if (sc->wi_has_wep) { + if (sc->wi_flags & WI_FLAGS_HAS_WEP) { WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep); WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key); sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1; @@ -2212,8 +2249,8 @@ wi_media_change(ifp) break; case IFM_IEEE80211_IBSSMASTER: case IFM_IEEE80211_IBSSMASTER|IFM_IEEE80211_IBSS: - if (sc->sc_firmware_type == WI_SYMBOL) - return (EINVAL); /* not working on Symbol */ + if (!(sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)) + return (EINVAL); sc->wi_create_ibss = 1; /* FALLTHROUGH */ case IFM_IEEE80211_IBSS: @@ -2279,7 +2316,7 @@ wi_set_nwkey(sc, nwkey) struct wi_req wreq; struct wi_ltv_keys *wk = (struct wi_ltv_keys *)&wreq; - if (!sc->wi_has_wep) + if (!(sc->wi_flags & WI_FLAGS_HAS_WEP)) return ENODEV; if (nwkey->i_defkid <= 0 || nwkey->i_defkid > IEEE80211_WEP_NKID) return EINVAL; @@ -2341,7 +2378,7 @@ wi_get_nwkey(sc, nwkey) int i, len, error; struct wi_ltv_keys *wk = &sc->wi_keys; - if (!sc->wi_has_wep) + if (!(sc->wi_flags & WI_FLAGS_HAS_WEP)) return ENODEV; nwkey->i_wepon = sc->wi_use_wep; nwkey->i_defkid = sc->wi_tx_key + 1; diff --git a/sys/dev/ic/if_wivar.h b/sys/dev/ic/if_wivar.h index ee065adb670..d56f0cdb29a 100644 --- a/sys/dev/ic/if_wivar.h +++ b/sys/dev/ic/if_wivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wivar.h,v 1.9 2002/04/07 23:23:49 millert Exp $ */ +/* $OpenBSD: if_wivar.h,v 1.10 2002/04/11 00:08:25 millert Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -72,7 +72,6 @@ struct wi_softc { struct ieee80211_nwid wi_ibss_name; u_int8_t wi_txbuf[1596]; - int wi_has_wep; int wi_use_wep; int wi_authmode; int wi_tx_key; @@ -80,18 +79,24 @@ struct wi_softc { struct wi_counters wi_stats; void *sc_ih; struct timeout sc_timo; - int sc_enabled; int sc_firmware_type; int sc_sta_firmware_ver; int sc_pci; struct wihap_info wi_hostap_info; u_int32_t wi_icv; int wi_icv_flag; + int wi_ibss_port; }; /* Values for wi_flags. */ -#define WI_FLAGS_ATTACHED 0x01 -#define WI_FLAGS_INITIALIZED 0x02 +#define WI_FLAGS_ATTACHED 0x01 +#define WI_FLAGS_INITIALIZED 0x02 +#define WI_FLAGS_HAS_WEP 0x04 +#define WI_FLAGS_HAS_IBSS 0x08 +#define WI_FLAGS_HAS_CREATE_IBSS 0x10 +#define WI_FLAGS_HAS_MOR 0x20 +#define WI_FLAGS_HAS_ROAMING 0x30 +#define WI_FLAGS_HAS_DIVERSITY 0x40 /* Firmware types */ #define WI_LUCENT 0 |