Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/net80211 Pull in net80211/ from FreeBSD. This contains S...



details:   https://anonhg.NetBSD.org/src/rev/4cb138050e3e
branches:  trunk
changeset: 551159:4cb138050e3e
user:      dyoung <dyoung%NetBSD.org@localhost>
date:      Sat Aug 30 21:26:03 2003 +0000

description:
Pull in net80211/ from FreeBSD. This contains Sam Leffler's
enhancements to the 802.11 layer, which are necessary for ath(4),
the Atheros-chipset driver.

diffstat:

 sys/net80211/ieee80211.c        |   875 +++++++++++++++++++++++++++++++
 sys/net80211/ieee80211.h        |   332 ++++++++++++
 sys/net80211/ieee80211_crypto.c |   307 +++++++++++
 sys/net80211/ieee80211_crypto.h |    50 +
 sys/net80211/ieee80211_input.c  |  1078 +++++++++++++++++++++++++++++++++++++++
 sys/net80211/ieee80211_ioctl.c  |   988 +++++++++++++++++++++++++++++++++++
 sys/net80211/ieee80211_ioctl.h  |    84 +++
 sys/net80211/ieee80211_node.c   |   570 ++++++++++++++++++++
 sys/net80211/ieee80211_node.h   |   147 +++++
 sys/net80211/ieee80211_output.c |   551 +++++++++++++++++++
 sys/net80211/ieee80211_proto.c  |   503 ++++++++++++++++++
 sys/net80211/ieee80211_proto.h  |    78 ++
 sys/net80211/ieee80211_var.h    |   265 +++++++++
 13 files changed, 5828 insertions(+), 0 deletions(-)

diffs (truncated from 5880 to 300 lines):

diff -r b0e3a780fba9 -r 4cb138050e3e sys/net80211/ieee80211.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/net80211/ieee80211.c  Sat Aug 30 21:26:03 2003 +0000
@@ -0,0 +1,875 @@
+/*-
+ * Copyright (c) 2001 Atsushi Onoe
+ * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/net80211/ieee80211.c,v 1.7 2003/08/13 22:09:44 sam Exp $");
+
+/*
+ * IEEE 802.11 generic handler
+ */
+
+#include "opt_inet.h"
+
+#include <sys/param.h>
+#include <sys/systm.h> 
+#include <sys/mbuf.h>   
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/endian.h>
+#include <sys/errno.h>
+#include <sys/bus.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+
+#include <machine/atomic.h>
+ 
+#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 <net80211/ieee80211_var.h>
+
+#include <net/bpf.h>
+
+#ifdef INET
+#include <netinet/in.h> 
+#include <netinet/if_ether.h>
+#endif
+
+#ifdef IEEE80211_DEBUG
+int    ieee80211_debug = 0;
+SYSCTL_INT(_debug, OID_AUTO, ieee80211, CTLFLAG_RW, &ieee80211_debug,
+           0, "IEEE 802.11 media debugging printfs");
+#endif
+
+static void ieee80211_set11gbasicrates(struct ieee80211_rateset *,
+               enum ieee80211_phymode);
+
+static const char *ieee80211_phymode_name[] = {
+       "auto",         /* IEEE80211_MODE_AUTO */
+       "11a",          /* IEEE80211_MODE_11A */
+       "11b",          /* IEEE80211_MODE_11B */
+       "11g",          /* IEEE80211_MODE_11G */
+       "turbo",        /* IEEE80211_MODE_TURBO */
+};
+
+void
+ieee80211_ifattach(struct ifnet *ifp)
+{
+       struct ieee80211com *ic = (void *)ifp;
+       struct ieee80211_channel *c;
+       int i;
+
+       ether_ifattach(ifp, ic->ic_myaddr);
+       bpfattach2(ifp, DLT_IEEE802_11,
+           sizeof(struct ieee80211_frame_addr4), &ic->ic_rawbpf);
+       ieee80211_crypto_attach(ifp);
+
+       /*
+        * 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));
+       ic->ic_modecaps |= 1<<IEEE80211_MODE_AUTO;
+       for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
+               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);
+                               c->ic_flags = 0;        /* NB: remove */
+                               continue;
+                       }
+                       setbit(ic->ic_chan_avail, i);
+                       /*
+                        * Identify mode capabilities.
+                        */
+                       if (IEEE80211_IS_CHAN_A(c))
+                               ic->ic_modecaps |= 1<<IEEE80211_MODE_11A;
+                       if (IEEE80211_IS_CHAN_B(c))
+                               ic->ic_modecaps |= 1<<IEEE80211_MODE_11B;
+                       if (IEEE80211_IS_CHAN_PUREG(c))
+                               ic->ic_modecaps |= 1<<IEEE80211_MODE_11G;
+                       if (IEEE80211_IS_CHAN_T(c))
+                               ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO;
+               }
+       }
+       /* validate ic->ic_curmode */
+       if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0)
+               ic->ic_curmode = IEEE80211_MODE_AUTO;
+
+       (void) ieee80211_setmode(ic, ic->ic_curmode);
+
+       ic->ic_des_chan = IEEE80211_CHAN_ANYC;  /* any channel is ok */
+       if (ic->ic_lintval == 0)
+               ic->ic_lintval = 100;           /* default sleep */
+       ic->ic_bmisstimeout = 7*ic->ic_lintval; /* default 7 beacons */
+
+       ieee80211_node_attach(ifp);
+       ieee80211_proto_attach(ifp);
+}
+
+void
+ieee80211_ifdetach(struct ifnet *ifp)
+{
+       struct ieee80211com *ic = (void *)ifp;
+
+       ieee80211_proto_detach(ifp);
+       ieee80211_crypto_detach(ifp);
+       ieee80211_node_detach(ifp);
+       ifmedia_removeall(&ic->ic_media);
+       bpfdetach(ifp);
+       ether_ifdetach(ifp);
+}
+
+/*
+ * Convert MHz frequency to IEEE channel number.
+ */
+u_int
+ieee80211_mhz2ieee(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 (flags & 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 ieee80211_channel *c)
+{
+       if (ic->ic_channels <= c && c <= &ic->ic_channels[IEEE80211_CHAN_MAX])
+               return c - ic->ic_channels;
+       else if (c == IEEE80211_CHAN_ANYC)
+               return IEEE80211_CHAN_ANY;
+       else if (c != NULL) {
+               if_printf(&ic->ic_if, "invalid channel freq %u flags %x\n",
+                       c->ic_freq, c->ic_flags);
+               return 0;               /* XXX */
+       } else {
+               if_printf(&ic->ic_if, "invalid channel (NULL)\n");
+               return 0;               /* XXX */
+       }
+}
+
+/*
+ * Convert IEEE channel number to MHz frequency.
+ */
+u_int
+ieee80211_ieee2mhz(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);
+       }
+}
+
+/*
+ * Setup the media data structures according to the channel and
+ * rate tables.  This must be called by the driver after
+ * ieee80211_attach and before most anything else.
+ */
+void
+ieee80211_media_init(struct ifnet *ifp,
+       ifm_change_cb_t media_change, ifm_stat_cb_t media_stat)
+{
+#define        ADD(_ic, _s, _o) \
+       ifmedia_add(&(_ic)->ic_media, \
+               IFM_MAKEWORD(IFM_IEEE80211, (_s), (_o), 0), 0, NULL)
+       struct ieee80211com *ic = (void *)ifp;
+       struct ifmediareq imr;
+       int i, j, mode, rate, maxrate, mword, mopt, r;
+       struct ieee80211_rateset *rs;
+       struct ieee80211_rateset allrates;
+
+       /*
+        * Do late attach work that must wait for any subclass
+        * (i.e. driver) work such as overriding methods.
+        */
+       ieee80211_node_lateattach(ifp);
+
+       /*
+        * Fill in media characteristics.
+        */
+       ifmedia_init(&ic->ic_media, 0, media_change, media_stat);
+       maxrate = 0;
+       memset(&allrates, 0, sizeof(allrates));
+       for (mode = IEEE80211_MODE_AUTO; mode < IEEE80211_MODE_MAX; mode++) {
+               static const u_int mopts[] = { 
+                       IFM_AUTO,
+                       IFM_MAKEMODE(IFM_IEEE80211_11A),
+                       IFM_MAKEMODE(IFM_IEEE80211_11B),
+                       IFM_MAKEMODE(IFM_IEEE80211_11G),
+                       IFM_MAKEMODE(IFM_IEEE80211_11A) | IFM_IEEE80211_TURBO,
+               };
+               if ((ic->ic_modecaps & (1<<mode)) == 0)
+                       continue;
+               mopt = mopts[mode];
+               ADD(ic, IFM_AUTO, mopt);        /* e.g. 11a auto */
+               if (ic->ic_caps & IEEE80211_C_IBSS)
+                       ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_ADHOC);
+               if (ic->ic_caps & IEEE80211_C_HOSTAP)
+                       ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_HOSTAP);
+               if (ic->ic_caps & IEEE80211_C_AHDEMO)
+                       ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_ADHOC | IFM_FLAG0);
+               if (ic->ic_caps & IEEE80211_C_MONITOR)
+                       ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_MONITOR);
+               if (mode == IEEE80211_MODE_AUTO)
+                       continue;
+               if_printf(ifp, "%s rates: ", ieee80211_phymode_name[mode]);
+               rs = &ic->ic_sup_rates[mode];
+               for (i = 0; i < rs->rs_nrates; i++) {
+                       rate = rs->rs_rates[i];
+                       mword = ieee80211_rate2media(ic, rate, mode);
+                       if (mword == 0)
+                               continue;
+                       printf("%s%d%sMbps", (i != 0 ? " " : ""),
+                           (rate & IEEE80211_RATE_VAL) / 2,



Home | Main Index | Thread Index | Old Index