Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 6 Mar 2003 17:40:21 -0800 (PST)
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 26457 for review
Message-ID:  <200303070140.h271eL89086523@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=26457

Change 26457 by sam@sam_ebb on 2003/03/06 17:39:39

	first steps toward integrating a/b/g support:
	o introduce ieee80211channel instead of using IEEE channel #'s
	o redo scanning so active scan is done to completion instead of
	  based on a timer (with a/b/g there can be too many channels
	  to scan in 2 seconds)
	o move capability bits in ic_flags to a new if_caps field
	  and rename values to separate them from flags
	o add new capabilities for txpower management and software tx
	  retry (more to come)
	o add rts threshold, tx power controls, fragmentation threshold,
	  and other stuff; mostly for use by drivers
	o fix contruction of ssid and rate elements in outbound frames
	o move most media handling to 802.11 code
	o add new routines for converting between IEEE channel numbers
	  and frequency/flag settings (or ieee80211channel structures)
	o split ioctl support into separate files to ease portability

Affected files ...

.. //depot/projects/wlan/sys/dev/wi/if_wi.c#5 edit
.. //depot/projects/wlan/sys/dev/wi/if_wivar.h#2 edit
.. //depot/projects/wlan/sys/net/if_ieee80211.h#2 edit
.. //depot/projects/wlan/sys/net/if_ieee80211ioctl.c#1 add
.. //depot/projects/wlan/sys/net/if_ieee80211ioctl.h#1 add
.. //depot/projects/wlan/sys/net/if_ieee80211subr.c#3 edit

Differences ...

==== //depot/projects/wlan/sys/dev/wi/if_wi.c#5 (text+ko) ====

@@ -120,7 +120,6 @@
 static int  wi_reset(struct wi_softc *);
 static void wi_watchdog(struct ifnet *);
 static int  wi_ioctl(struct ifnet *, u_long, caddr_t);
-static int  wi_media_change(struct ifnet *);
 static void wi_media_status(struct ifnet *, struct ifmediareq *);
 
 static void wi_rx_intr(struct wi_softc *);
@@ -241,8 +240,7 @@
 	struct wi_softc	*sc = device_get_softc(dev);
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ifnet *ifp = &ic->ic_if;
-	int i, nrate, mword, buflen;
-	u_int8_t r;
+	int i, nrate, buflen;
 	u_int16_t val;
 	u_int8_t ratebuf[2 + IEEE80211_RATE_SIZE];
 	static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
@@ -311,35 +309,43 @@
 
 	ic->ic_phytype = IEEE80211_T_DS;
 	ic->ic_opmode = IEEE80211_M_STA;
-	ic->ic_flags = IEEE80211_F_HASPMGT | IEEE80211_F_HASAHDEMO;
+	ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_AHDEMO;
 	ic->ic_state = IEEE80211_S_INIT;
 	ic->ic_newstate = wi_newstate;
 
-	/* Find available channels */
+	/*
+	 * Query the card for available channels and setup the
+	 * channel table.  We assume these are all 11b channels.
+	 */
 	buflen = sizeof(val);
 	if (wi_read_rid(sc, WI_RID_CHANNEL_LIST, &val, &buflen) != 0)
 		val = htole16(0x1fff);	/* assume 1-11 */
-	for (i = 0; i < 16; i++) {
-		if (isset((u_int8_t*)&val, i))
-			setbit(ic->ic_chan_avail, i + 1);
+	KASSERT(val != 0, ("wi_attach: no available channels listed!"));
+
+	val <<= 1;			/* shift for base 1 indices */
+	for (i = 1; i < 16; i++) {
+		if (isset((u_int8_t*)&val, i)) {
+			ic->ic_channels[i].ic_freq =
+				ieee80211_ieee2ghz(i, IEEE80211_CHAN_B);
+			ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B;
+		}
 	}
-	KASSERT(ic->ic_chan_avail != 0,
-		("wi_attach: no available channels listed!"));
 
 	/*
 	 * Read the default channel from the NIC. This may vary
 	 * depending on the country where the NIC was purchased, so
 	 * we can't hard-code a default and expect it to work for
 	 * everyone.
+	 *
+	 * If no channel is specified, let the 802.11 code select.
 	 */
 	buflen = sizeof(val);
-	if (wi_read_rid(sc, WI_RID_OWN_CHNL, &val, &buflen) == 0)
-		ic->ic_ibss_chan = le16toh(val);
-	else {
-		/* use lowest available channel */
-		for (i = 0; i < 16 && !isset(ic->ic_chan_avail, i); i++)
-			;
-		ic->ic_ibss_chan = i;
+	if (wi_read_rid(sc, WI_RID_OWN_CHNL, &val, &buflen) == 0) {
+		val = le16toh(val);
+		KASSERT(val < IEEE80211_CHAN_MAX &&
+			ic->ic_channels[val].ic_flags != 0,
+			("wi_attach: invalid own channel %u!", val));
+		ic->ic_ibss_chan = &ic->ic_channels[val];
 	}
 
 	/*
@@ -357,7 +363,7 @@
 		if (sc->sc_sta_firmware_ver >= 60000)
 			sc->sc_flags |= WI_FLAGS_HAS_MOR;
 		if (sc->sc_sta_firmware_ver >= 60006)
-			ic->ic_flags |= IEEE80211_F_HASIBSS;
+			ic->ic_caps |= IEEE80211_C_IBSS;
 		sc->sc_ibss_port = htole16(1);
 		break;
 
@@ -368,21 +374,21 @@
 		if (sc->sc_sta_firmware_ver > 10101)
 			sc->sc_flags |= WI_FLAGS_HAS_DBMADJUST;
 		if (sc->sc_sta_firmware_ver >= 800)
-			ic->ic_flags |= IEEE80211_F_HASIBSS;
+			ic->ic_caps |= IEEE80211_C_IBSS;
 		/*
 		 * version 0.8.3 and newer are the only ones that are known
 		 * to currently work.  Earlier versions can be made to work,
 		 * at least according to the Linux driver.
 		 */
 		if (sc->sc_sta_firmware_ver >= 803)
-			ic->ic_flags |= IEEE80211_F_HASHOSTAP;
+			ic->ic_caps |= IEEE80211_C_HOSTAP;
 		sc->sc_ibss_port = htole16(0);
 		break;
 
 	case WI_SYMBOL:
 		sc->sc_flags |= WI_FLAGS_HAS_DIVERSITY;
 		if (sc->sc_sta_firmware_ver >= 25000)
-			ic->ic_flags |= IEEE80211_F_HASIBSS;
+			ic->ic_caps |= IEEE80211_C_IBSS;
 		sc->sc_ibss_port = htole16(4);
 		break;
 	}
@@ -393,7 +399,7 @@
 	buflen = sizeof(val);
 	if (wi_read_rid(sc, WI_RID_WEP_AVAIL, &val, &buflen) == 0 &&
 	    val != htole16(0))
-		ic->ic_flags |= IEEE80211_F_HASWEP;
+		ic->ic_caps |= IEEE80211_C_WEP;
 
 	/* Find supported rates. */
 	buflen = sizeof(ratebuf);
@@ -415,8 +421,6 @@
 		sc->sc_dbm_adjust = 100;	/* default */
 
 	sc->sc_max_datalen = 2304;
-	sc->sc_rts_thresh = 2347;
-	sc->sc_frag_thresh = 2346;
 	sc->sc_system_scale = 1;
 	sc->sc_cnfauthmode = IEEE80211_AUTH_OPEN;
 	sc->sc_roaming_mode = 1;
@@ -432,39 +436,14 @@
 	bcopy(WI_DEFAULT_NETNAME, sc->sc_net_name,
 	    sizeof(WI_DEFAULT_NETNAME) - 1);
 
-	ifmedia_init(&sc->sc_media, 0, wi_media_change, wi_media_status);
-	if_printf(ifp, "supported rates: ");
-#define	ADD(s, o)	ifmedia_add(&sc->sc_media, \
-	IFM_MAKEWORD(IFM_IEEE80211, (s), (o), 0), 0, NULL)
-	ADD(IFM_AUTO, 0);
-	if (ic->ic_flags & IEEE80211_F_HASHOSTAP)
-		ADD(IFM_AUTO, IFM_IEEE80211_HOSTAP);
-	if (ic->ic_flags & IEEE80211_F_HASIBSS)
-		ADD(IFM_AUTO, IFM_IEEE80211_ADHOC);
-	ADD(IFM_AUTO, IFM_IEEE80211_ADHOC | IFM_FLAG0);
-	for (i = 0; i < nrate; i++) {
-		r = ic->ic_sup_rates[i];
-		mword = ieee80211_rate2media(r, IEEE80211_T_DS);
-		if (mword == 0)
-			continue;
-		printf("%s%d%sMbps", (i != 0 ? " " : ""),
-		    (r & IEEE80211_RATE_VAL) / 2, ((r & 0x1) != 0 ? ".5" : ""));
-		ADD(mword, 0);
-		if (ic->ic_flags & IEEE80211_F_HASHOSTAP)
-			ADD(mword, IFM_IEEE80211_HOSTAP);
-		if (ic->ic_flags & IEEE80211_F_HASIBSS)
-			ADD(mword, IFM_IEEE80211_ADHOC);
-		ADD(mword, IFM_IEEE80211_ADHOC | IFM_FLAG0);
-	}
-	printf("\n");
-	ifmedia_set(&sc->sc_media, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0));
-#undef ADD
-
 	/*
 	 * Call MI attach routine.
 	 */
 	ieee80211_ifattach(ifp);
 
+	/* NB: override default setting */
+	ic->ic_media.ifm_status = wi_media_status;
+
 	return (0);
 }
 
@@ -482,9 +461,6 @@
 
 	wi_stop(ifp, 0);
 
-	/* Delete all remaining media. */
-	ifmedia_removeall(&sc->sc_media);
-
 	ieee80211_ifdetach(ifp);
 	bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
 	wi_free(dev);
@@ -667,7 +643,8 @@
 	wi_write_val(sc, WI_RID_MAX_SLEEP, ic->ic_lintval);
 	wi_write_ssid(sc, WI_RID_DESIRED_SSID, ic->ic_des_essid,
 	    ic->ic_des_esslen);
-	wi_write_val(sc, WI_RID_OWN_CHNL, ic->ic_ibss_chan);
+	wi_write_val(sc, WI_RID_OWN_CHNL,
+		ieee80211_chan2ieee(ic, ic->ic_ibss_chan));
 	wi_write_ssid(sc, WI_RID_OWN_SSID, ic->ic_des_essid, ic->ic_des_esslen);
 
 	ifa = ifaddr_byindex(ifp->if_index);
@@ -680,9 +657,9 @@
 
 	/* not yet common 802.11 configuration */
 	wi_write_val(sc, WI_RID_MAX_DATALEN, sc->sc_max_datalen);
-	wi_write_val(sc, WI_RID_RTS_THRESH, sc->sc_rts_thresh);
+	wi_write_val(sc, WI_RID_RTS_THRESH, ic->ic_rtsthreshold);
 	if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)
-		wi_write_val(sc, WI_RID_FRAG_THRESH, sc->sc_frag_thresh);
+		wi_write_val(sc, WI_RID_FRAG_THRESH, ic->ic_fragthreshold);
 
 	/* driver specific 802.11 configuration */
 	if (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE)
@@ -718,7 +695,7 @@
 	}
 
 	/* Configure WEP. */
-	if (ic->ic_flags & IEEE80211_F_HASWEP)
+	if (ic->ic_caps & IEEE80211_C_WEP)
 		wi_write_wep(sc);
 
 	/* Set multicast filter. */
@@ -764,12 +741,13 @@
 
 	if (ic->ic_opmode == IEEE80211_M_STA &&
 	    ((ic->ic_flags & IEEE80211_F_DESBSSID) ||
-	    ic->ic_des_chan != IEEE80211_CHAN_ANY)) {
+	    ic->ic_des_chan != (struct ieee80211channel *)IEEE80211_CHAN_ANY)) {
 		memset(&join, 0, sizeof(join));
 		if (ic->ic_flags & IEEE80211_F_DESBSSID)
 			IEEE80211_ADDR_COPY(&join.wi_bssid, ic->ic_des_bssid);
-		if (ic->ic_des_chan != IEEE80211_CHAN_ANY)
-			join.wi_chan = htole16(ic->ic_des_chan);
+		if (ic->ic_des_chan != (struct ieee80211channel *)IEEE80211_CHAN_ANY)
+			join.wi_chan = htole16(
+				ieee80211_chan2ieee(ic, ic->ic_des_chan));
 		/* Lucent firmware does not support the JOIN RID. */
 		if (sc->sc_firmware_type != WI_LUCENT)
 			wi_write_rid(sc, WI_RID_JOIN_REQ, &join, sizeof(join));
@@ -841,8 +819,6 @@
 		WI_UNLOCK(sc);
 		return;
 	}
-	KASSERT((ifp->if_flags & IFF_OACTIVE) == 0,
-		("wi_start: if_flags %x\n", ifp->if_flags));
 
 	memset(&frmhdr, 0, sizeof(frmhdr));
 	cur = sc->sc_txnext;
@@ -1079,10 +1055,6 @@
 		sc->sc_if_flags = ifp->if_flags;
 		error = 0;
 		break;
-	case SIOCSIFMEDIA:
-	case SIOCGIFMEDIA:
-		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
-		break;
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
 		error = wi_write_multi(sc);
@@ -1175,58 +1147,6 @@
 	return (error);
 }
 
-static int
-wi_media_change(struct ifnet *ifp)
-{
-	struct wi_softc *sc = ifp->if_softc;
-	struct ieee80211com *ic = &sc->sc_ic;
-	struct ifmedia_entry *ime;
-	enum ieee80211_opmode newmode;
-	int i, rate, error = 0;
-
-	ime = sc->sc_media.ifm_cur;
-	if (IFM_SUBTYPE(ime->ifm_media) == IFM_AUTO) {
-		i = -1;
-	} else {
-		rate = ieee80211_media2rate(ime->ifm_media, IEEE80211_T_DS);
-		if (rate == 0)
-			return EINVAL;
-		for (i = 0; i < IEEE80211_RATE_SIZE; i++) {
-			if ((ic->ic_sup_rates[i] & IEEE80211_RATE_VAL) == rate)
-				break;
-		}
-		if (i == IEEE80211_RATE_SIZE)
-			return EINVAL;
-	}
-	if (ic->ic_fixed_rate != i) {
-		ic->ic_fixed_rate = i;
-		error = ENETRESET;
-	}
-
-	if ((ime->ifm_media & IFM_IEEE80211_ADHOC) &&
-	    (ime->ifm_media & IFM_FLAG0))
-		newmode = IEEE80211_M_AHDEMO;
-	else if (ime->ifm_media & IFM_IEEE80211_ADHOC)
-		newmode = IEEE80211_M_IBSS;
-	else if (ime->ifm_media & IFM_IEEE80211_HOSTAP)
-		newmode = IEEE80211_M_HOSTAP;
-	else
-		newmode = IEEE80211_M_STA;
-	if (ic->ic_opmode != newmode) {
-		ic->ic_opmode = newmode;
-		error = ENETRESET;
-	}
-	if (error == ENETRESET) {
-		if (sc->sc_enabled)
-			wi_init(ifp->if_softc); /* XXX error code lost */
-		error = 0;
-	}
-#if 0
-	ifp->if_baudrate = ifmedia_baudrate(sc->sc_media.ifm_cur->ifm_media);
-#endif
-	return error;
-}
-
 static void
 wi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
 {
@@ -1262,7 +1182,7 @@
 				rate = 22;	/* 11Mbps */
 		}
 	}
-	imr->ifm_active |= ieee80211_rate2media(rate, IEEE80211_T_DS);
+	imr->ifm_active |= ieee80211_rate2media(rate, ic->ic_phytype);
 	switch (ic->ic_opmode) {
 	case IEEE80211_M_STA:
 		break;
@@ -1769,7 +1689,7 @@
 			    &len);
 			break;
 		}
-		wreq.wi_val[0] = htole16(sc->sc_frag_thresh);
+		wreq.wi_val[0] = htole16(ic->ic_fragthreshold);
 		len = sizeof(u_int16_t);
 		break;
 
@@ -1877,7 +1797,7 @@
 			len = sizeof(u_int16_t);
 			break;
 		case WI_RID_RTS_THRESH:
-			wreq.wi_val[0] = htole16(sc->sc_rts_thresh);
+			wreq.wi_val[0] = htole16(ic->ic_rtsthreshold);
 			len = sizeof(u_int16_t);
 			break;
 		case WI_RID_CNFAUTHMODE:
@@ -1967,10 +1887,10 @@
 		}
 		switch (wreq.wi_type) {
 		case WI_RID_FRAG_THRESH:
-			sc->sc_frag_thresh = le16toh(wreq.wi_val[0]);
+			ic->ic_fragthreshold = le16toh(wreq.wi_val[0]);
 			break;
 		case WI_RID_RTS_THRESH:
-			sc->sc_rts_thresh = le16toh(wreq.wi_val[0]);
+			ic->ic_rtsthreshold = le16toh(wreq.wi_val[0]);
 			break;
 		case WI_RID_MICROWAVE_OVEN:
 			sc->sc_microwave_oven = le16toh(wreq.wi_val[0]);
@@ -2504,7 +2424,8 @@
 		IEEE80211_ADDR_COPY(ni->ni_macaddr, ni->ni_bssid);
 		buflen = sizeof(val);
 		wi_read_rid(sc, WI_RID_CURRENT_CHAN, &val, &buflen);
-		ni->ni_chan = le16toh(val);
+		/* XXX validate channel */
+		ni->ni_chan = &ic->ic_channels[le16toh(val)];
 
 		if (IEEE80211_ADDR_EQ(old_bssid, ni->ni_bssid))
 			sc->sc_false_syns++;

==== //depot/projects/wlan/sys/dev/wi/if_wivar.h#2 (text+ko) ====

@@ -94,7 +94,6 @@
 	void *			wi_intrhand;
 	int			wi_io_addr;
 
-	struct ifmedia		sc_media;
 	struct bpf_if		*sc_drvbpf;
 	int			sc_flags;
 	int			sc_if_flags;
@@ -106,8 +105,6 @@
 
 	u_int16_t		sc_dbm_adjust;
 	u_int16_t		sc_max_datalen;
-	u_int16_t		sc_frag_thresh;
-	u_int16_t		sc_rts_thresh;
 	u_int16_t		sc_system_scale;
 	u_int16_t		sc_cnfauthmode;
 	u_int16_t		sc_roaming_mode;

==== //depot/projects/wlan/sys/net/if_ieee80211.h#2 (text+ko) ====

@@ -37,11 +37,8 @@
 #ifndef _NET_IF_IEEE80211_H_
 #define _NET_IF_IEEE80211_H_
 
-#include <net/ethernet.h>
-#include <net/if_arp.h>
+#define	IEEE80211_ADDR_LEN	6		/* size of 802.11 address */
 
-#define	IEEE80211_ADDR_LEN			ETHER_ADDR_LEN
-
 /*
  * generic definitions for IEEE 802.11 frames
  */
@@ -281,125 +278,16 @@
 #define	IEEE80211_MAX_LEN			(2300 + IEEE80211_CRC_LEN + \
     (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN))
 
-/*
- * ioctls
- */
-
-/* nwid is pointed at by ifr.ifr_data */
-struct ieee80211_nwid {
-	u_int8_t	i_len;
-	u_int8_t	i_nwid[IEEE80211_NWID_LEN];
-};
-
-#define	SIOCS80211NWID		_IOWR('i', 230, struct ifreq)
-#define	SIOCG80211NWID		_IOWR('i', 231, struct ifreq)
-
-/* the first member must be matched with struct ifreq */
-struct ieee80211_nwkey {
-	char		i_name[IFNAMSIZ];	/* if_name, e.g. "wi0" */
-	int		i_wepon;		/* wep enabled flag */
-	int		i_defkid;		/* default encrypt key id */
-	struct {
-		int		i_keylen;
-		u_int8_t	*i_keydat;
-	}		i_key[IEEE80211_WEP_NKID];
-};
-#define	SIOCS80211NWKEY		 _IOW('i', 232, struct ieee80211_nwkey)
-#define	SIOCG80211NWKEY		_IOWR('i', 233, struct ieee80211_nwkey)
-/* i_wepon */
-#define	IEEE80211_NWKEY_OPEN	0		/* No privacy */
-#define	IEEE80211_NWKEY_WEP	1		/* WEP enabled */
-#define	IEEE80211_NWKEY_EAP	2		/* EAP enabled */
-#define	IEEE80211_NWKEY_PERSIST	0x100		/* designate persist keyset */
-
-/* power management parameters */
-struct ieee80211_power {
-	char		i_name[IFNAMSIZ];	/* if_name, e.g. "wi0" */
-	int		i_enabled;		/* 1 == on, 0 == off */
-	int		i_maxsleep;		/* max sleep in ms */
-};
-#ifdef __NetBSD__
-#define	SIOCS80211POWER		 _IOW('i', 234, struct ieee80211_power)
-#define	SIOCG80211POWER		_IOWR('i', 235, struct ieee80211_power)
-#else
-#define	SIOCS80211POWER		 _IOW('i', 242, struct ieee80211_power)
-#define	SIOCG80211POWER		_IOWR('i', 243, struct ieee80211_power)
-#endif
-
-struct ieee80211_auth {
-	char		i_name[IFNAMSIZ];	/* if_name, e.g. "wi0" */
-	int		i_authtype;
-};
+#define	IEEE80211_CHAN_ANY	0xffff		/* token for ``any channel'' */
 
 #define	IEEE80211_AUTH_NONE	0
 #define	IEEE80211_AUTH_OPEN	1
 #define	IEEE80211_AUTH_SHARED	2
 
-#define	SIOCS80211AUTH		 _IOW('i', 236, struct ieee80211_auth)
-#define	SIOCG80211AUTH		_IOWR('i', 237, struct ieee80211_auth)
-
-struct ieee80211_channel {
-	char		i_name[IFNAMSIZ];	/* if_name, e.g. "wi0" */
-	u_int16_t	i_channel;
-};
+#include <net/if_ieee80211ioctl.h>
 
-#define	IEEE80211_CHAN_ANY	0xffff
-
-#define	SIOCS80211CHANNEL	 _IOW('i', 238, struct ieee80211_channel)
-#define	SIOCG80211CHANNEL	_IOWR('i', 239, struct ieee80211_channel)
-
-struct ieee80211_bssid {
-	char		i_name[IFNAMSIZ];	/* if_name, e.g. "wi0" */
-	u_int8_t	i_bssid[IEEE80211_ADDR_LEN];
-};
-
-#define	SIOCS80211BSSID		 _IOW('i', 240, struct ieee80211_bssid)
-#define	SIOCG80211BSSID		_IOWR('i', 241, struct ieee80211_bssid)
-
-/*
- * FreeBSD-style ioctls.
- */
-/* the first member must be matched with struct ifreq */
-struct ieee80211req {
-	char		i_name[IFNAMSIZ];	/* if_name, e.g. "wi0" */
-	u_int16_t	i_type;			/* req type */
-	int16_t		i_val;			/* Index or simple value */
-	int16_t		i_len;			/* Index or simple value */
-	void		*i_data;		/* Extra data */
-};
-#ifdef __FreeBSD__
-#define	SIOCS80211		 _IOW('i', 234, struct ieee80211req)
-#define	SIOCG80211		_IOWR('i', 235, struct ieee80211req)
-#else
-#define	SIOCS80211		 _IOW('i', 242, struct ieee80211req)
-#define	SIOCG80211		_IOWR('i', 243, struct ieee80211req)
-#endif
-
-#define IEEE80211_IOC_SSID		1
-#define IEEE80211_IOC_NUMSSIDS		2
-#define IEEE80211_IOC_WEP		3
-#define 	IEEE80211_WEP_NOSUP	-1
-#define 	IEEE80211_WEP_OFF	0
-#define 	IEEE80211_WEP_ON	1
-#define 	IEEE80211_WEP_MIXED	2
-#define IEEE80211_IOC_WEPKEY		4
-#define IEEE80211_IOC_NUMWEPKEYS	5
-#define IEEE80211_IOC_WEPTXKEY		6
-#define IEEE80211_IOC_AUTHMODE		7
-#define IEEE80211_IOC_STATIONNAME	8
-#define IEEE80211_IOC_CHANNEL		9
-#define IEEE80211_IOC_POWERSAVE		10
-#define 	IEEE80211_POWERSAVE_NOSUP	-1
-#define 	IEEE80211_POWERSAVE_OFF		0
-#define 	IEEE80211_POWERSAVE_CAM		1
-#define 	IEEE80211_POWERSAVE_PSP		2
-#define 	IEEE80211_POWERSAVE_PSP_CAM	3
-#define 	IEEE80211_POWERSAVE_ON		IEEE80211_POWERSAVE_CAM
-#define IEEE80211_IOC_POWERSAVESLEEP	11
-
 #ifdef _KERNEL
 
-#define	IEEE80211_ASCAN_WAIT	2		/* active scan wait */
 #define	IEEE80211_PSCAN_WAIT 	5		/* passive scan wait */
 #define	IEEE80211_TRANS_WAIT 	5		/* transition wait */
 #define	IEEE80211_INACT_WAIT	5		/* inactivity timer interval */
@@ -409,7 +297,7 @@
  * Structure for IEEE 802.11 drivers.
  */
 
-#define	IEEE80211_CHAN_MAX	255
+#define	IEEE80211_CHAN_MAX	64
 #define	IEEE80211_RATE_SIZE	12
 #define	IEEE80211_KEYBUF_SIZE	16
 #define	IEEE80211_NODE_HASHSIZE	32
@@ -440,6 +328,41 @@
 };
 
 /*
+ * Channels are specified by frequency and attributes.
+ */
+/* XXX should be ieee80211_channel but NetBSD took that for an ioctl param */
+struct ieee80211channel {
+	u_int16_t	ic_freq;	/* setting in Mhz */
+	u_int16_t	ic_flags;	/* see below */
+};
+
+#define	IEEE80211_CHAN_PASSIVE	0x0001	/* Only passive scan allowed on channel */
+/* bits 4-7 are for private use by drivers */
+#define	IEEE80211_CHAN_PRIV3	0x0010
+#define	IEEE80211_CHAN_PRIV2	0x0020
+#define	IEEE80211_CHAN_PRIV1	0x0040
+#define	IEEE80211_CHAN_PRIV0	0x0080
+/* channel attributes */
+#define	IEEE80211_CHAN_TURBO	0x0100	/* Turbo channel */
+#define	IEEE80211_CHAN_CCK	0x0200	/* CCK channel */
+#define	IEEE80211_CHAN_OFDM	0x0400	/* OFDM channel */
+#define	IEEE80211_CHAN_2GHZ	0x0800	/* 2 GHz spectrum channel. */
+#define	IEEE80211_CHAN_5GHZ	0x1000	/* 5 GHz spectrum channel */
+/* bits 13-15 are reserved for future use and should not be used */
+
+/*
+ * Useful combinations of channel characteristics.
+ */
+#define	IEEE80211_CHAN_A \
+	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
+#define	IEEE80211_CHAN_B \
+	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
+#define	IEEE80211_CHAN_PUREG \
+	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
+#define	IEEE80211_CHAN_T \
+	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
+
+/*
  * Node specific information.
  */
 struct ieee80211_node {
@@ -462,7 +385,7 @@
 	u_int8_t		ni_essid[IEEE80211_NWID_LEN];
 	int			ni_nrate;
 	u_int8_t		ni_rates[IEEE80211_RATE_SIZE];
-	u_int8_t		ni_chan;
+	struct ieee80211channel	*ni_chan;
 	u_int16_t		ni_fhdwell;	/* FH only */
 	u_int8_t		ni_fhindex;	/* FH only */
 
@@ -510,29 +433,39 @@
 	int			(*ic_chancheck)(void *, u_char *);
 	u_int8_t		ic_myaddr[IEEE80211_ADDR_LEN];
 	u_int8_t		ic_sup_rates[IEEE80211_RATE_SIZE];
+	struct ieee80211channel ic_channels[IEEE80211_CHAN_MAX+1];
 	u_char			ic_chan_avail[roundup(IEEE80211_CHAN_MAX,NBBY)];
 	u_char			ic_chan_active[roundup(IEEE80211_CHAN_MAX, NBBY)];
+	u_char			ic_chan_scan[roundup(IEEE80211_CHAN_MAX,NBBY)];
 	struct ifqueue		ic_mgtq;
-	int			ic_flags;
+	u_int32_t		ic_flags;	/* state flags */
+	u_int32_t		ic_caps;	/* capabilities */
 	enum ieee80211_phytype	ic_phytype;
-	enum ieee80211_opmode	ic_opmode;
-	enum ieee80211_state	ic_state;
+	enum ieee80211_opmode	ic_opmode;	/* operation mode */
+	enum ieee80211_state	ic_state;	/* 802.11 state */
+	struct ifmedia		ic_media;	/* interface media config */
 	struct bpf_if		*ic_rawbpf;	/* packet filter structure */
 	struct ieee80211_node	ic_bss;		/* information for this node */
 	int			ic_node_privlen;/* size for ni_private */
 	void			(*ic_node_free)(struct ieee80211com *,
 				    struct ieee80211_node *);	/* callback */
-	u_int8_t		ic_ibss_chan;
+	struct ieee80211channel	*ic_ibss_chan;
 	int			ic_fixed_rate;	/* index to ic_sup_rates[] */
+	u_int16_t		ic_rtsthreshold;
+	u_int16_t		ic_fragthreshold;
 	TAILQ_HEAD(, ieee80211_node) ic_node;	/* information of all nodes */
 	LIST_HEAD(, ieee80211_node) ic_hash[IEEE80211_NODE_HASHSIZE];
 	u_int16_t		ic_lintval;	/* listen interval */
+	u_int16_t		ic_holdover;	/* PM hold over duration */
+	u_int16_t		ic_txmin;	/* min tx retry count */
+	u_int16_t		ic_txmax;	/* max tx retry count */
+	u_int16_t		ic_txlifetime;	/* tx lifetime */
+	u_int16_t		ic_txpower;	/* tx power setting (dbM) */
 	int			ic_mgt_timer;	/* mgmt timeout */
-	int			ic_scan_timer;	/* scant wait */
 	int			ic_inact_timer;	/* inactivity timer wait */
 	int			ic_des_esslen;
 	u_int8_t		ic_des_essid[IEEE80211_NWID_LEN];
-	int			ic_des_chan;	/* desired channel */
+	struct ieee80211channel	*ic_des_chan;	/* desired channel */
 	u_int8_t		ic_des_bssid[IEEE80211_ADDR_LEN];
 	struct ieee80211_wepkey	ic_nw_keys[IEEE80211_WEP_NKID];
 	int			ic_wep_txkey;	/* default tx key index */
@@ -560,7 +493,8 @@
 #define	IEEE80211_ADDR_EQ(a1,a2)	(memcmp(a1,a2,IEEE80211_ADDR_LEN) == 0)
 #define	IEEE80211_ADDR_COPY(dst,src)	memcpy(dst,src,IEEE80211_ADDR_LEN)
 
-#define	IEEE80211_IS_MULTICAST(a)	ETHER_IS_MULTICAST(a)
+/* is 802.11 address multicast/broadcast? */
+#define	IEEE80211_IS_MULTICAST(_a)	(*(_a) & 0x01)
 
 /* ic_flags */
 #define	IEEE80211_F_ASCAN	0x00000001	/* STATUS: active scan */
@@ -570,11 +504,21 @@
 #define	IEEE80211_F_PMGTON	0x00000400	/* CONF: Power mgmt enable */
 #define	IEEE80211_F_DESBSSID	0x00000800	/* CONF: des_bssid is set */
 #define	IEEE80211_F_SCANAP	0x00001000	/* CONF: Scanning AP */
-#define	IEEE80211_F_HASWEP	0x00010000	/* CAPABILITY: WEP available */
-#define	IEEE80211_F_HASIBSS	0x00020000	/* CAPABILITY: IBSS available */
-#define	IEEE80211_F_HASPMGT	0x00040000	/* CAPABILITY: Power mgmt */
-#define	IEEE80211_F_HASHOSTAP	0x00080000	/* CAPABILITY: HOSTAP avail */
-#define	IEEE80211_F_HASAHDEMO	0x00100000	/* CAPABILITY: Old Adhoc Demo */
+#define	IEEE80211_F_ROAMING	0x00002000	/* CONF: roaming enabled */
+#define	IEEE80211_F_SWRETRY	0x00004000	/* CONF: sw tx retry enabled */
+#define	IEEE80211_F_TXPMGT	0x00018000	/* STATUS: tx power */
+#define IEEE80211_F_TXPOW_OFF	0x00000000	/* TX Power: radio disabled */
+#define IEEE80211_F_TXPOW_FIXED	0x00008000	/* TX Power: fixed rate */
+#define IEEE80211_F_TXPOW_AUTO	0x00010000	/* TX Power: undefined */
+
+/* ic_capabilities */
+#define	IEEE80211_C_WEP		0x00000001	/* CAPABILITY: WEP available */
+#define	IEEE80211_C_IBSS	0x00000002	/* CAPABILITY: IBSS available */
+#define	IEEE80211_C_PMGT	0x00000004	/* CAPABILITY: Power mgmt */
+#define	IEEE80211_C_HOSTAP	0x00000008	/* CAPABILITY: HOSTAP avail */
+#define	IEEE80211_C_AHDEMO	0x00000010	/* CAPABILITY: Old Adhoc Demo */
+#define	IEEE80211_C_SWRETRY	0x00000020	/* CAPABILITY: sw tx retry */
+#define	IEEE80211_C_TXPMGT	0x00000040	/* CAPABILITY: tx power mgmt */
 
 /* flags for ieee80211_fix_rate() */
 #define	IEEE80211_F_DOSORT	0x00000001	/* sort rate list */
@@ -589,7 +533,10 @@
     struct mbuf *, int);
 struct mbuf *ieee80211_encap(struct ifnet *, struct mbuf *);
 struct mbuf *ieee80211_decap(struct ifnet *, struct mbuf *);
+void	ieee80211_media_status(struct ifnet *, struct ifmediareq *);
 int	ieee80211_ioctl(struct ifnet *, u_long, caddr_t);
+int	ieee80211_cfgget(struct ifnet *, u_long, caddr_t);
+int	ieee80211_cfgset(struct ifnet *, u_long, caddr_t);
 void	ieee80211_print_essid(u_int8_t *, int);
 void	ieee80211_dump_pkt(u_int8_t *, int, int, int);
 void	ieee80211_watchdog(struct ifnet *);
@@ -605,9 +552,9 @@
 struct mbuf *ieee80211_wep_crypt(struct ifnet *, struct mbuf *, int);
 int	ieee80211_rate2media(int, enum ieee80211_phytype);
 int	ieee80211_media2rate(int, enum ieee80211_phytype);
-
-int	ieee80211_cfgget(struct ifnet *, u_long, caddr_t);
-int	ieee80211_cfgset(struct ifnet *, u_long, caddr_t);
+u_int	ieee80211_ghz2ieee(u_int, u_int);
+u_int	ieee80211_chan2ieee(struct ieee80211com *, struct ieee80211channel *);
+u_int	ieee80211_ieee2ghz(u_int, u_int);
 
 #endif /* _KERNEL */
 

==== //depot/projects/wlan/sys/net/if_ieee80211subr.c#3 (text+ko) ====

@@ -67,6 +67,7 @@
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
+#include <net/if_arp.h>
 #include <net/ethernet.h>
 #include <net/if_llc.h>
 #include <net/if_ieee80211.h>
@@ -80,8 +81,6 @@
 #include <netinet/if_ether.h>
 #endif
 
-#include <dev/wi/if_wavelan_ieee.h>
-
 #define	IEEE80211_DEBUG
 #ifdef IEEE80211_DEBUG
 int ieee80211_debug = 0;
@@ -137,6 +136,8 @@
 static void ieee80211_recv_deauth(struct ieee80211com *,
     struct mbuf *, int, u_int32_t);
 
+static int ieee80211_media_change(struct ifnet *);
+
 static void ieee80211_crc_init(void);
 static u_int32_t ieee80211_crc_update(u_int32_t, u_int8_t *, int);
 
@@ -151,7 +152,8 @@
 ieee80211_ifattach(struct ifnet *ifp)
 {
 	struct ieee80211com *ic = (void *)ifp;
-	int i, rate;
+	struct ifmediareq imr;
+	int i, rate, mword;
 
 	/* XXX need unit */
 	mtx_init(&ic->ic_mtx, ifp->if_name, "802.11 link layer", MTX_DEF);
@@ -161,22 +163,93 @@
 	bpfattach2(ifp, DLT_IEEE802_11,
 	    sizeof(struct ieee80211_frame_addr4), &ic->ic_rawbpf);
 #endif
+
+	/*
+	 * Setup crypto support.
+	 */
 	ieee80211_crc_init();
 	ic->ic_iv = arc4random();
+
+	/*
+	 * Fill in 802.11 available channel set, mark
+	 * all available channels as active, and pick
+	 * a default channel if not already specified.
+	 */
+	memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail));
+	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
+		struct ieee80211channel *c = &ic->ic_channels[i];
+		if (c->ic_flags) {
+			/*
+			 * Verify driver passed us valid data.
+			 */
+			if (i != ieee80211_chan2ieee(ic, c)) {
+				if_printf(ifp, "bad channel ignored; "
+					"freq %u flags %x number %u\n",
+					c->ic_freq, c->ic_flags, i);
+				continue;
+			}
+			setbit(ic->ic_chan_avail, i);
+		}
+	}
 	memcpy(ic->ic_chan_active, ic->ic_chan_avail,
 	    sizeof(ic->ic_chan_active));
-	if (isclr(ic->ic_chan_active, ic->ic_ibss_chan)) {
+	if (ic->ic_ibss_chan == NULL) {
+		/*
+		 * Pick the first active channel for default.
+		 * XXX probably not right.
+		 */
 		for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
 			if (isset(ic->ic_chan_active, i)) {
-				ic->ic_ibss_chan = i;
+				ic->ic_ibss_chan = &ic->ic_channels[i];
 				break;
 			}
 		}
 	}
-	ic->ic_des_chan = IEEE80211_CHAN_ANY;
-	ic->ic_fixed_rate = -1;
+
+	/*
+	 * Fill in media characteristics.
+	 */
+#define	ADD(_ic, _s, _o) \
+	ifmedia_add(&(_ic)->ic_media, \
+		IFM_MAKEWORD(IFM_IEEE80211, (_s), (_o), 0), 0, NULL)
+	ifmedia_init(&ic->ic_media, 0,
+		ieee80211_media_change, ieee80211_media_status);
+	ADD(ic, IFM_AUTO, 0);
+	if (ic->ic_caps & IEEE80211_C_IBSS)
+		ADD(ic, IFM_AUTO, IFM_IEEE80211_ADHOC);
+	if (ic->ic_caps & IEEE80211_C_HOSTAP)
+		ADD(ic, IFM_AUTO, IFM_IEEE80211_HOSTAP);
+	if (ic->ic_caps & IEEE80211_C_AHDEMO)
+		ADD(ic, IFM_AUTO, IFM_IEEE80211_ADHOC | IFM_FLAG0);
+	if_printf(ifp, "supported rates: ");
+	for (i = 0; i < IEEE80211_RATE_SIZE; i++) {
+		rate = ic->ic_sup_rates[i];
+		mword = ieee80211_rate2media(rate, ic->ic_phytype);
+		if (mword == 0)
+			continue;
+		printf("%s%d%sMbps", (i != 0 ? " " : ""),
+		    (rate & IEEE80211_RATE_VAL) / 2,
+		    ((rate & 0x1) != 0 ? ".5" : ""));
+		ADD(ic, mword, 0);
+		if (ic->ic_caps & IEEE80211_C_IBSS)
+			ADD(ic, mword, IFM_IEEE80211_ADHOC);
+		if (ic->ic_caps & IEEE80211_C_HOSTAP)
+			ADD(ic, mword, IFM_IEEE80211_HOSTAP);
+		if (ic->ic_caps & IEEE80211_C_AHDEMO)
+			ADD(ic, mword, IFM_IEEE80211_ADHOC | IFM_FLAG0);
+	}
+	printf("\n");
+	ieee80211_media_status(ifp, &imr);
+	ifmedia_set(&ic->ic_media, imr.ifm_active);
+#undef ADD
+
+	ic->ic_rtsthreshold = 2347;		/* XXX not used yet */
+	ic->ic_fragthreshold = 2346;		/* XXX not used yet */
+	ic->ic_des_chan =			/* any channel is ok */
+		(struct ieee80211channel *) IEEE80211_CHAN_ANY;
+	ic->ic_fixed_rate = -1;			/* no fixed rate */
 	if (ic->ic_lintval == 0)
-		ic->ic_lintval = 100;	/* default sleep */
+		ic->ic_lintval = 100;		/* default sleep */
 	TAILQ_INIT(&ic->ic_node);
 	mtx_init(&ic->ic_mgtq.ifq_mtx, ifp->if_name, "mgmt send q", MTX_DEF);
 
@@ -189,7 +262,7 @@
 		ifp->if_baudrate = IF_Mbps(rate);
 	ifp->if_hdrlen = sizeof(struct ieee80211_frame);
 
-	/* initialize management frame handler */
+	/* initialize management frame handlers */
 	ic->ic_recv_mgmt[IEEE80211_FC0_SUBTYPE_PROBE_RESP
 	    >> IEEE80211_FC0_SUBTYPE_SHIFT] = ieee80211_recv_beacon;
 	ic->ic_recv_mgmt[IEEE80211_FC0_SUBTYPE_BEACON
@@ -244,6 +317,7 @@
 		ic->ic_wep_ctx = NULL;
 	}
 	ieee80211_free_allnodes(ic);
+	ifmedia_removeall(&ic->ic_media);
 #if NBPFILTER > 0
 	bpfdetach(ifp);
 #endif
@@ -252,6 +326,208 @@
 	mtx_destroy(&ic->ic_mtx);
 }
 
+/*
+ * Convert GHz frequency to IEEE channel number.
+ */
+u_int
+ieee80211_ghz2ieee(u_int freq, u_int flags)
+{
+	if (flags & IEEE80211_CHAN_2GHZ) {	/* 2GHz band */
+		if (freq == 2484)
+			return 14;
+		if (freq < 2484)
+			return (freq - 2407) / 5;
+		else
+			return 15 + ((freq - 2512) / 20);
+	} else if (IEEE80211_CHAN_5GHZ) {/* 5Ghz band */
+		return (freq - 5000) / 5;
+	} else {			/* either, guess */
+		if (freq == 2484)
+			return 14;
+		if (freq < 2484)
+			return (freq - 2407) / 5;
+		if (freq < 5000)
+			return 15 + ((freq - 2512) / 20);
+		return (freq - 5000) / 5;
+	}
+}
+
+/*
+ * Convert channel to IEEE channel number.
+ */
+u_int
+ieee80211_chan2ieee(struct ieee80211com *ic, struct ieee80211channel *c)
+{
+	if (ic->ic_channels <= c && c <= &ic->ic_channels[IEEE80211_CHAN_MAX])
+		return c - ic->ic_channels;
+	else if (c == (struct ieee80211channel *)IEEE80211_CHAN_ANY)
+		return IEEE80211_CHAN_ANY;
+	else {
+		if_printf(&ic->ic_if, "invalid channel %p\n", c);
+		return 0;		/* XXX */
+	}
+}
+
+/*
+ * Convert IEEE channel number to GHz frequency.
+ */
+u_int
+ieee80211_ieee2ghz(u_int chan, u_int flags)
+{
+	if (flags & IEEE80211_CHAN_2GHZ) {	/* 2GHz band */
+		if (chan == 14)
+			return 2484;
+		if (chan < 14)
+			return 2407 + chan*5;
+		else
+			return 2512 + ((chan-15)*20);
+	} else if (flags & IEEE80211_CHAN_5GHZ) {/* 5Ghz band */
+		return 5000 + (chan*5);
+	} else {			/* either, guess */
+		if (chan == 14)
+			return 2484;
+		if (chan < 14)		/* 0-13 */
+			return 2407 + chan*5;
+		if (chan < 27)		/* 15-26 */
+			return 2512 + ((chan-15)*20);
+		return 5000 + (chan*5);
+	}
+}
+
+static int
+ieee80211_media_change(struct ifnet *ifp)
+{
+	struct ieee80211com *ic = (void *)ifp;
+	struct ifmedia_entry *ime;
+	enum ieee80211_opmode newmode;
+	int i, rate, error = 0;
+
+	ime = ic->ic_media.ifm_cur;
+	if (IFM_SUBTYPE(ime->ifm_media) != IFM_AUTO) {
+		/* phytype is not right */
+		rate = ieee80211_media2rate(ime->ifm_media, ic->ic_phytype);
+		if (rate == 0)
+			return EINVAL;
+		for (i = 0; i < IEEE80211_RATE_SIZE; i++)
+			if ((ic->ic_sup_rates[i] & IEEE80211_RATE_VAL) == rate)
+				break;
+		if (i == IEEE80211_RATE_SIZE)
+			return EINVAL;
+	} else {
+		i = -1;
+	}
+	if (ic->ic_fixed_rate != i) {
+		ic->ic_fixed_rate = i;
+		error = ENETRESET;
+	}
+	if ((ime->ifm_media & (IFM_IEEE80211_ADHOC|IFM_FLAG0)) ==
+	    (IFM_IEEE80211_ADHOC|IFM_FLAG0))
+		newmode = IEEE80211_M_AHDEMO;
+	else if (ime->ifm_media & IFM_IEEE80211_HOSTAP)
+		newmode = IEEE80211_M_HOSTAP;
+	else if (ime->ifm_media & IFM_IEEE80211_ADHOC)
+		newmode = IEEE80211_M_IBSS;
+	else
+		newmode = IEEE80211_M_STA;
+	if (ic->ic_opmode != newmode) {
+		ic->ic_opmode = newmode;
+		switch (newmode) {
+		case IEEE80211_M_AHDEMO:
+		case IEEE80211_M_HOSTAP:
+		case IEEE80211_M_STA:
+			ic->ic_flags &= ~IEEE80211_F_IBSSON;
+			break;
+		case IEEE80211_M_IBSS:
+			ic->ic_flags |= IEEE80211_F_IBSSON;
+			break;
+		}
+		error = ENETRESET;
+	}
+	if (error == ENETRESET) {
+		(*ifp->if_init)(ifp);		/* lose error */
+		error = 0;

>>> TRUNCATED FOR MAIL (1000 lines) <<<

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200303070140.h271eL89086523>