Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic * Add "wi_flags" to the softc to indicate capabil...
details: https://anonhg.NetBSD.org/src/rev/9642c5f8a384
branches: trunk
changeset: 535131:9642c5f8a384
user: thorpej <thorpej%NetBSD.org@localhost>
date: Sun Aug 11 01:30:28 2002 +0000
description:
* Add "wi_flags" to the softc to indicate capabilities of the card. Fill
in this info based on firmware type and version. Replace "wi_has_wep"
with a flag.
* For cards which support IBSS, add "ibss" has a media option.
* For cards which support CREATE_IBSS, add "ibss-master" as a media
option.
* Use the "ibss" and "ibss-master" media options to determine if
we should go into IBSS mode and/or create the IBSS.
* Internally convert between the generic WI_PORTTYPE_IBSS and the
value the firmware wants to use for IBSS.
* When setting the IBSS name, if a desired-SSID is set, and we're
an ibss-master, write the desired-SSID into the own-SSID slot.
This ensures that "ifconfig wi0 nwid FOO" will do the expected
thing.
* Only set the roaming mode if the card supports roaming.
>From OpenBSD.
diffstat:
sys/dev/ic/wi.c | 189 ++++++++++++++++++++++++++++++++++++++++++++--------
sys/dev/ic/wivar.h | 16 +++-
2 files changed, 173 insertions(+), 32 deletions(-)
diffs (truncated from 410 to 300 lines):
diff -r 8ead85c0bc79 -r 9642c5f8a384 sys/dev/ic/wi.c
--- a/sys/dev/ic/wi.c Sun Aug 11 00:11:52 2002 +0000
+++ b/sys/dev/ic/wi.c Sun Aug 11 01:30:28 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wi.c,v 1.76 2002/08/11 00:11:52 thorpej Exp $ */
+/* $NetBSD: wi.c,v 1.77 2002/08/11 01:30:28 thorpej Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.76 2002/08/11 00:11:52 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.77 2002/08/11 01:30:28 thorpej Exp $");
#define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */
#define WI_HERMES_STATS_WAR /* Work around stats counter bug. */
@@ -272,16 +272,52 @@
/* AP info was filled with 0 */
memset((char *)&sc->wi_aps, 0, sizeof(sc->wi_aps));
- sc->wi_scanning=0;
- sc->wi_naps=0;
+ sc->wi_scanning = 0;
+ sc->wi_naps = 0;
+
+ /*
+ * 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_HOSTAP;
+ 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;
+ if (sc->sc_sta_firmware_ver >= 20000)
+ sc->wi_flags |= WI_FLAGS_HAS_IBSS;
+ if (sc->sc_sta_firmware_ver >= 25000)
+ sc->wi_flags |= WI_FLAGS_HAS_CREATE_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;
- wi_read_record(sc, &gen);
- sc->wi_has_wep = le16toh(gen.wi_val);
+ if (wi_read_record(sc, &gen) == 0 &&
+ gen.wi_val != le16toh(0))
+ sc->wi_flags |= WI_FLAGS_HAS_WEP;
/* Find supported rates (Prism2 only). */
gen.wi_type = WI_RID_SUPPORT_RATE;
@@ -299,29 +335,59 @@
#define PRINT(n) printf("%s%s", sep, (n)); sep = ", "
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0);
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_ADHOC, 0), 0);
+ 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->wi_supprates & WI_SUPPRATES_1M) {
PRINT("1Mbps");
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0);
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
IFM_IEEE80211_ADHOC, 0), 0);
+ 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->wi_supprates & WI_SUPPRATES_2M) {
PRINT("2Mbps");
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0);
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
IFM_IEEE80211_ADHOC, 0), 0);
+ 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->wi_supprates & WI_SUPPRATES_5M) {
PRINT("5.5Mbps");
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0);
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
IFM_IEEE80211_ADHOC, 0), 0);
+ 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->wi_supprates & WI_SUPPRATES_11M) {
PRINT("11Mbps");
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0);
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
IFM_IEEE80211_ADHOC, 0), 0);
+ 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);
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_MANUAL, 0, 0), 0);
}
if (sc->wi_supprates != 0)
@@ -956,7 +1022,16 @@
if (ltv->wi_len > 1)
CSR_READ_MULTI_STREAM_2(sc, WI_DATA1, ptr, ltv->wi_len - 1);
- if (sc->sc_firmware_type != WI_LUCENT) {
+ if (ltv->wi_type == WI_RID_PORTTYPE &&
+ sc->wi_ptype == WI_PORTTYPE_IBSS &&
+ 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
+ * have to rely on wi_ptype to distinguish this for us.
+ */
+ ltv->wi_val = htole16(WI_PORTTYPE_IBSS);
+ } else if (sc->sc_firmware_type != WI_LUCENT) {
int v;
switch (oltv->wi_type) {
@@ -1009,7 +1084,14 @@
int i;
struct wi_ltv_gen p2ltv;
- if (sc->sc_firmware_type != WI_LUCENT) {
+ if (ltv->wi_type == WI_RID_PORTTYPE &&
+ ltv->wi_val == le16toh(WI_PORTTYPE_IBSS)) {
+ /* Convert WI_PORTTYPE_IBSS to vendor IBSS port type. */
+ p2ltv.wi_type = WI_RID_PORTTYPE;
+ p2ltv.wi_len = 2;
+ p2ltv.wi_val = sc->wi_ibss_port;
+ ltv = &p2ltv;
+ } else if (sc->sc_firmware_type != WI_LUCENT) {
int v;
switch (ltv->wi_type) {
@@ -1313,10 +1395,12 @@
memcpy(LLADDR(sdl), (char *)&wreq->wi_val, ETHER_ADDR_LEN);
break;
case WI_RID_PORTTYPE:
- error = wi_sync_media(sc, le16toh(wreq->wi_val[0]), sc->wi_tx_rate);
+ error = wi_sync_media(sc, le16toh(wreq->wi_val[0]),
+ sc->wi_tx_rate);
break;
case WI_RID_TX_RATE:
- error = wi_sync_media(sc, sc->wi_ptype, le16toh(wreq->wi_val[0]));
+ error = wi_sync_media(sc, sc->wi_ptype,
+ le16toh(wreq->wi_val[0]));
break;
case WI_RID_MAX_DATALEN:
sc->wi_max_data_len = le16toh(wreq->wi_val[0]);
@@ -1328,8 +1412,8 @@
sc->wi_ap_density = le16toh(wreq->wi_val[0]);
break;
case WI_RID_CREATE_IBSS:
- if (sc->sc_firmware_type != WI_INTERSIL)
- sc->wi_create_ibss = le16toh(wreq->wi_val[0]);
+ sc->wi_create_ibss = le16toh(wreq->wi_val[0]);
+ error = wi_sync_media(sc, sc->wi_ptype, sc->wi_tx_rate);
break;
case WI_RID_OWN_CHNL:
sc->wi_channel = le16toh(wreq->wi_val[0]);
@@ -1414,8 +1498,7 @@
wreq->wi_val[0] = htole16(sc->wi_ap_density);
break;
case WI_RID_CREATE_IBSS:
- if (sc->sc_firmware_type != WI_INTERSIL)
- wreq->wi_val[0] = htole16(sc->wi_create_ibss);
+ wreq->wi_val[0] = htole16(sc->wi_create_ibss);
break;
case WI_RID_OWN_CHNL:
wreq->wi_val[0] = htole16(sc->wi_channel);
@@ -1445,7 +1528,8 @@
wreq->wi_val[0] = htole16(sc->wi_roaming);
break;
case WI_RID_WEP_AVAIL:
- wreq->wi_val[0] = htole16(sc->wi_has_wep);
+ wreq->wi_val[0] = (sc->wi_flags & WI_FLAGS_HAS_WEP) ?
+ htole16(1) : htole16(0);
break;
case WI_RID_ENCRYPTION:
wreq->wi_val[0] = htole16(sc->wi_use_wep);
@@ -1634,6 +1718,18 @@
}
}
} else {
+ /*
+ * Filter stuff out based on what the
+ * card can do.
+ */
+ if ((wreq.wi_type == WI_RID_ROAMING_MODE &&
+ (sc->wi_flags & WI_FLAGS_HAS_ROAMING) == 0) ||
+ (wreq.wi_type == WI_RID_CREATE_IBSS &&
+ (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS) == 0) ||
+ (wreq.wi_type == WI_RID_MICROWAVE_OVEN &&
+ (sc->wi_flags & WI_FLAGS_HAS_MOR) == 0))
+ break;
+
if (wreq.wi_len > WI_MAX_DATALEN)
error = EINVAL;
else if (sc->sc_enabled != 0)
@@ -1728,8 +1824,7 @@
WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len);
/* Enable/disable IBSS creation. */
- if (sc->sc_firmware_type != WI_INTERSIL)
- WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
+ WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
/* Set the port type. */
WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype);
@@ -1750,14 +1845,19 @@
WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep);
/* Roaming type */
- WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming);
-
- /* Specify the IBSS name */
- wi_write_ssid(sc, WI_RID_OWN_SSID, &wreq, &sc->wi_ibssid);
+ if (sc->wi_flags & WI_FLAGS_HAS_ROAMING)
+ WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming);
/* Specify the network name */
wi_write_ssid(sc, WI_RID_DESIRED_SSID, &wreq, &sc->wi_netid);
+ /* Specify the IBSS name */
+ if (sc->wi_netid.i_len != 0 &&
+ (sc->wi_create_ibss && sc->wi_ptype == WI_PORTTYPE_IBSS))
+ wi_write_ssid(sc, WI_RID_OWN_SSID, &wreq, &sc->wi_netid);
+ else
+ wi_write_ssid(sc, WI_RID_OWN_SSID, &wreq, &sc->wi_ibssid);
+
/* Specify the frequency to use */
WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel);
@@ -1778,7 +1878,7 @@
}
/* 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;
@@ -2267,12 +2367,20 @@
subtype = IFM_MANUAL; /* Unable to represent */
break;
}
+
+ options &= ~IFM_OMASK;
switch (ptype) {
+ case WI_PORTTYPE_BSS:
+ /* default port type */
+ break;
case WI_PORTTYPE_ADHOC:
options |= IFM_IEEE80211_ADHOC;
break;
- case WI_PORTTYPE_BSS:
- options &= ~IFM_IEEE80211_ADHOC;
+ case WI_PORTTYPE_IBSS:
+ if (sc->wi_create_ibss)
+ options |= IFM_IEEE80211_IBSSMASTER;
+ else
+ options |= IFM_IEEE80211_IBSS;
break;
default:
subtype = IFM_MANUAL; /* Unable to represent */
Home |
Main Index |
Thread Index |
Old Index