summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/ic/if_wi.c119
-rw-r--r--sys/net/if_media.h6
2 files changed, 101 insertions, 24 deletions
diff --git a/sys/dev/ic/if_wi.c b/sys/dev/ic/if_wi.c
index 1e41606be22..04dea2b55d2 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.50 2002/04/08 18:31:27 mickey Exp $ */
+/* $OpenBSD: if_wi.c,v 1.51 2002/04/10 19:25:07 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.50 2002/04/08 18:31:27 mickey Exp $";
+ "$OpenBSD: if_wi.c,v 1.51 2002/04/10 19:25:07 millert Exp $";
#endif /* lint */
#ifdef foo
@@ -175,6 +175,13 @@ 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;
@@ -269,8 +276,11 @@ wi_attach(sc)
ifmedia_init(&sc->sc_media, 0, wi_media_change, wi_media_status);
#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_ADHOC, 0), 0);
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_IBSS, 0), 0);
+ if (sc->sc_firmware_type != WI_SYMBOL)
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
+ IFM_IEEE80211_IBSSMASTER, 0), 0);
if (sc->sc_firmware_type == WI_INTERSIL)
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
IFM_IEEE80211_HOSTAP, 0), 0);
@@ -278,6 +288,11 @@ 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)
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
+ IFM_IEEE80211_IBSSMASTER, 0), 0);
if (sc->sc_firmware_type == WI_INTERSIL)
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
IFM_IEEE80211_HOSTAP, 0), 0);
@@ -286,6 +301,11 @@ 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)
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
+ IFM_IEEE80211_IBSSMASTER, 0), 0);
if (sc->sc_firmware_type == WI_INTERSIL)
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
IFM_IEEE80211_HOSTAP, 0), 0);
@@ -294,6 +314,11 @@ 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)
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
+ IFM_IEEE80211_IBSSMASTER, 0), 0);
if (sc->sc_firmware_type == WI_INTERSIL)
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
IFM_IEEE80211_HOSTAP, 0), 0);
@@ -302,6 +327,11 @@ 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)
+ ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
+ IFM_IEEE80211_IBSSMASTER, 0), 0);
if (sc->sc_firmware_type == WI_INTERSIL)
ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
IFM_IEEE80211_HOSTAP, 0), 0);
@@ -788,7 +818,15 @@ wi_read_record(sc, ltv)
if (ltv->wi_len > 1)
CSR_READ_RAW_2(sc, WI_DATA1, ptr, (ltv->wi_len-1)*2);
- if (sc->sc_firmware_type != WI_LUCENT) {
+ if (ltv->wi_type == WI_RID_PORTTYPE && sc->wi_ptype == WI_PORTTYPE_IBSS
+ && letoh16(ltv->wi_val) == ibss_portmap[sc->sc_firmware_type]) {
+ /*
+ * 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) {
@@ -836,7 +874,14 @@ wi_write_record(sc, ltv)
int i;
struct wi_ltv_gen p2ltv;
- if (sc->sc_firmware_type != WI_LUCENT) {
+ if (ltv->wi_type == WI_RID_PORTTYPE &&
+ letoh16(ltv->wi_val) == 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 = htole16(ibss_portmap[sc->sc_firmware_type]);
+ ltv = &p2ltv;
+ } else if (sc->sc_firmware_type != WI_LUCENT) {
int v;
switch (ltv->wi_type) {
@@ -1142,6 +1187,7 @@ wi_setdef(sc, wreq)
break;
case WI_RID_CREATE_IBSS:
sc->wi_create_ibss = letoh16(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 = letoh16(wreq->wi_val[0]);
@@ -1450,12 +1496,12 @@ wi_init(sc)
/* Program max data length. */
WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len);
- /* Enable/disable IBSS creation. */
- WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
-
/* Set the port type. */
WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype);
+ /* Enable/disable IBSS creation. */
+ WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
+
/* Program the RTS/CTS threshold. */
WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh);
@@ -1483,7 +1529,8 @@ wi_init(sc)
WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name);
/* Specify the IBSS name */
- if (sc->wi_ptype == WI_PORTTYPE_AP)
+ if ((sc->wi_create_ibss && sc->wi_ptype == WI_PORTTYPE_IBSS) ||
+ sc->wi_ptype == WI_PORTTYPE_AP)
WI_SETSTR(WI_RID_OWN_SSID, sc->wi_net_name);
else
WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name);
@@ -2107,12 +2154,22 @@ wi_sync_media(sc, ptype, txrate)
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_AP:
+ options |= IFM_IEEE80211_HOSTAP;
+ break;
+ 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 */
@@ -2135,21 +2192,37 @@ wi_media_change(ifp)
struct wi_softc *sc = ifp->if_softc;
int otype = sc->wi_ptype;
int orate = sc->wi_tx_rate;
+ int ocreate_ibss = sc->wi_create_ibss;
- if ((sc->sc_media.ifm_cur->ifm_media &
- (IFM_IEEE80211_ADHOC|IFM_IEEE80211_HOSTAP)) ==
- (IFM_IEEE80211_ADHOC|IFM_IEEE80211_HOSTAP))
- return (EINVAL);
if ((sc->sc_media.ifm_cur->ifm_media & IFM_IEEE80211_HOSTAP) &&
- sc->sc_firmware_type == WI_LUCENT)
+ sc->sc_firmware_type != WI_INTERSIL)
return (EINVAL);
- if ((sc->sc_media.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC))
+ sc->wi_create_ibss = 0;
+
+ switch (sc->sc_media.ifm_cur->ifm_media & IFM_OMASK) {
+ case 0:
+ sc->wi_ptype = WI_PORTTYPE_BSS;
+ break;
+ case IFM_IEEE80211_ADHOC:
sc->wi_ptype = WI_PORTTYPE_ADHOC;
- else if ((sc->sc_media.ifm_cur->ifm_media & IFM_IEEE80211_HOSTAP))
+ break;
+ case IFM_IEEE80211_HOSTAP:
sc->wi_ptype = WI_PORTTYPE_AP;
- else
- sc->wi_ptype = WI_PORTTYPE_BSS;
+ 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 */
+ sc->wi_create_ibss = 1;
+ /* FALLTHROUGH */
+ case IFM_IEEE80211_IBSS:
+ sc->wi_ptype = WI_PORTTYPE_IBSS;
+ break;
+ default:
+ /* Invalid combination. */
+ return (EINVAL);
+ }
switch (IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media)) {
case IFM_IEEE80211_DS1:
@@ -2170,8 +2243,8 @@ wi_media_change(ifp)
}
if (sc->arpcom.ac_if.if_flags & IFF_UP) {
- if (otype != sc->wi_ptype ||
- orate != sc->wi_tx_rate)
+ if (otype != sc->wi_ptype || orate != sc->wi_tx_rate ||
+ ocreate_ibss != sc->wi_create_ibss)
wi_init(sc);
}
diff --git a/sys/net/if_media.h b/sys/net/if_media.h
index 8726a19fb66..3d766e1df76 100644
--- a/sys/net/if_media.h
+++ b/sys/net/if_media.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_media.h,v 1.9 2002/03/28 18:23:07 mickey Exp $ */
+/* $OpenBSD: if_media.h,v 1.10 2002/04/10 19:25:07 millert Exp $ */
/* $NetBSD: if_media.h,v 1.22 2000/02/17 21:53:16 sommerfeld Exp $ */
/*-
@@ -214,6 +214,8 @@ int ifmedia_baudrate(int);
#define IFM_IEEE80211_DS1 8 /* Direct Sequence 1Mbps*/
#define IFM_IEEE80211_ADHOC 0x100 /* Operate in Adhoc mode */
#define IFM_IEEE80211_HOSTAP 0x200 /* Operate in Host AP mode */
+#define IFM_IEEE80211_IBSS 0x400 /* Operate in IBSS mode */
+#define IFM_IEEE80211_IBSSMASTER 0x800 /* Operate as an IBSS master */
/*
* Shared media sub-types
@@ -404,6 +406,8 @@ struct ifmedia_description {
\
{ IFM_IEEE80211|IFM_IEEE80211_ADHOC, "adhoc" }, \
{ IFM_IEEE80211|IFM_IEEE80211_HOSTAP, "hostap" }, \
+ { IFM_IEEE80211|IFM_IEEE80211_IBSS, "ibss" }, \
+ { IFM_IEEE80211|IFM_IEEE80211_IBSSMASTER, "ibss-master" }, \
\
{ 0, NULL }, \
}