wlan - Update wlan from Adrian / FreeBSD
authorMatthew Dillon <dillon@apollo.backplane.com>
Sun, 11 Jan 2015 17:50:12 +0000 (09:50 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 3 Feb 2015 20:10:54 +0000 (12:10 -0800)
* Update the wlan infrastructure, initially working with ath.

97 files changed:
contrib/hostapd/src/drivers/driver_bsd.c
sys/bus/u4b/wlan/if_rum.c
sys/bus/u4b/wlan/if_run.c
sys/bus/u4b/wlan/if_uath.c
sys/bus/u4b/wlan/if_upgt.c
sys/bus/u4b/wlan/if_ural.c
sys/bus/u4b/wlan/if_urtw.c
sys/bus/u4b/wlan/if_urtwn.c
sys/bus/u4b/wlan/if_zyd.c
sys/ddb/ddb.h
sys/dev/netif/acx/if_acx.c
sys/dev/netif/ath/ath/if_ath.c
sys/dev/netif/ath/ath/if_ath_tx.c
sys/dev/netif/ath/ath/if_athvar.h
sys/dev/netif/bwi/if_bwi.c
sys/dev/netif/bwn/bwn/if_bwn.c
sys/dev/netif/iwi/if_iwi.c
sys/dev/netif/iwl/iwl2100.c
sys/dev/netif/iwn/if_iwn.c
sys/dev/netif/ral/rt2560.c
sys/dev/netif/ral/rt2661.c
sys/dev/netif/ral/rt2860.c
sys/dev/netif/rtw/rtw.c
sys/dev/netif/wi/if_wi.c
sys/dev/netif/wpi/if_wpi.c
sys/net/ethernet.h
sys/netproto/802_11/README.DRAGONFLY
sys/netproto/802_11/_ieee80211.h
sys/netproto/802_11/ieee80211.h
sys/netproto/802_11/ieee80211_action.h
sys/netproto/802_11/ieee80211_adhoc.h
sys/netproto/802_11/ieee80211_ageq.h
sys/netproto/802_11/ieee80211_alq.h [copied from sys/netproto/802_11/ieee80211_wds.h with 63% similarity]
sys/netproto/802_11/ieee80211_amrr.h
sys/netproto/802_11/ieee80211_crypto.h
sys/netproto/802_11/ieee80211_dfs.h
sys/netproto/802_11/ieee80211_dragonfly.h
sys/netproto/802_11/ieee80211_hostap.h
sys/netproto/802_11/ieee80211_ht.h
sys/netproto/802_11/ieee80211_input.h
sys/netproto/802_11/ieee80211_ioctl.h
sys/netproto/802_11/ieee80211_mesh.h
sys/netproto/802_11/ieee80211_monitor.h
sys/netproto/802_11/ieee80211_node.h
sys/netproto/802_11/ieee80211_phy.h
sys/netproto/802_11/ieee80211_power.h
sys/netproto/802_11/ieee80211_proto.h
sys/netproto/802_11/ieee80211_radiotap.h
sys/netproto/802_11/ieee80211_ratectl.h
sys/netproto/802_11/ieee80211_regdomain.h
sys/netproto/802_11/ieee80211_rssadapt.h
sys/netproto/802_11/ieee80211_scan.h
sys/netproto/802_11/ieee80211_sta.h
sys/netproto/802_11/ieee80211_superg.h
sys/netproto/802_11/ieee80211_tdma.h
sys/netproto/802_11/ieee80211_var.h
sys/netproto/802_11/ieee80211_wds.h
sys/netproto/802_11/wlan/Makefile
sys/netproto/802_11/wlan/ieee80211.c
sys/netproto/802_11/wlan/ieee80211_action.c
sys/netproto/802_11/wlan/ieee80211_adhoc.c
sys/netproto/802_11/wlan/ieee80211_ageq.c
sys/netproto/802_11/wlan/ieee80211_alq.c [new file with mode: 0644]
sys/netproto/802_11/wlan/ieee80211_amrr.c
sys/netproto/802_11/wlan/ieee80211_crypto.c
sys/netproto/802_11/wlan/ieee80211_crypto_none.c
sys/netproto/802_11/wlan/ieee80211_ddb.c
sys/netproto/802_11/wlan/ieee80211_dfs.c
sys/netproto/802_11/wlan/ieee80211_dragonfly.c
sys/netproto/802_11/wlan/ieee80211_hostap.c
sys/netproto/802_11/wlan/ieee80211_ht.c
sys/netproto/802_11/wlan/ieee80211_hwmp.c
sys/netproto/802_11/wlan/ieee80211_input.c
sys/netproto/802_11/wlan/ieee80211_ioctl.c
sys/netproto/802_11/wlan/ieee80211_mesh.c
sys/netproto/802_11/wlan/ieee80211_monitor.c
sys/netproto/802_11/wlan/ieee80211_node.c
sys/netproto/802_11/wlan/ieee80211_output.c
sys/netproto/802_11/wlan/ieee80211_phy.c
sys/netproto/802_11/wlan/ieee80211_power.c
sys/netproto/802_11/wlan/ieee80211_proto.c
sys/netproto/802_11/wlan/ieee80211_radiotap.c
sys/netproto/802_11/wlan/ieee80211_ratectl.c
sys/netproto/802_11/wlan/ieee80211_ratectl_none.c
sys/netproto/802_11/wlan/ieee80211_regdomain.c
sys/netproto/802_11/wlan/ieee80211_rssadapt.c
sys/netproto/802_11/wlan/ieee80211_scan.c
sys/netproto/802_11/wlan/ieee80211_scan_sta.c
sys/netproto/802_11/wlan/ieee80211_sta.c
sys/netproto/802_11/wlan/ieee80211_superg.c
sys/netproto/802_11/wlan/ieee80211_tdma.c
sys/netproto/802_11/wlan/ieee80211_wds.c
sys/netproto/802_11/wlan_acl/ieee80211_acl.c
sys/netproto/802_11/wlan_ccmp/ieee80211_crypto_ccmp.c
sys/netproto/802_11/wlan_tkip/ieee80211_crypto_tkip.c
sys/netproto/802_11/wlan_wep/ieee80211_crypto_wep.c
sys/netproto/802_11/wlan_xauth/ieee80211_xauth.c

index ca64d5c..4b3b11a 100644 (file)
@@ -615,7 +615,7 @@ rtbuf_len(void)
 static int bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
                          int reason_code);
 
-static const char *
+const char *
 ether_sprintf(const u8 *addr)
 {
        static char buf[sizeof(MACSTR)];
index e5cae49..cf6f715 100644 (file)
@@ -1122,7 +1122,7 @@ rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
        sc->tx_nfree--;
 
        wh = mtod(m0, struct ieee80211_frame *);
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
                        m_freem(m0);
@@ -1240,7 +1240,7 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
        else
                rate = ni->ni_txrate;
 
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
                        m_freem(m0);
index cb48f62..5b95109 100644 (file)
@@ -2812,8 +2812,8 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
 
        wh = mtod(m, struct ieee80211_frame *);
 
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
-               wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
+               wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
                m->m_flags |= M_WEP;
        }
 
index b7aa61d..f73b41b 100644 (file)
@@ -1621,7 +1621,7 @@ uath_tx_start(struct uath_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
        }
 
        wh = mtod(m0, struct ieee80211_frame *);
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
                        m_freem(m0);
index 37c7310..07dc527 100644 (file)
@@ -2165,7 +2165,7 @@ upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
         * Software crypto.
         */
        wh = mtod(m, struct ieee80211_frame *);
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m);
                if (k == NULL) {
                        device_printf(sc->sc_dev,
index e6ad0cf..c88ce92 100644 (file)
@@ -1096,7 +1096,7 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
        tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
 
        wh = mtod(m0, struct ieee80211_frame *);
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
                        m_freem(m0);
@@ -1265,7 +1265,7 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
        else
                rate = ni->ni_txrate;
 
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
                        m_freem(m0);
index acef1c0..48d85b5 100644 (file)
@@ -1666,7 +1666,7 @@ urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
        /*
         * Software crypto.
         */
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
                        device_printf(sc->sc_dev,
index 36985c8..4045357 100644 (file)
@@ -1812,7 +1812,7 @@ urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni,
        wh = mtod(m0, struct ieee80211_frame *);
        type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
                        device_printf(sc->sc_dev,
index cb57b13..302a6f9 100644 (file)
@@ -2487,7 +2487,7 @@ zyd_tx_start(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
                }
        }
 
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
                        m_freem(m0);
index 4a725f9..5975cdb 100644 (file)
@@ -97,7 +97,11 @@ struct vm_map        *db_map_addr (vm_offset_t);
 boolean_t      db_map_current (struct vm_map *);
 boolean_t      db_map_equal (struct vm_map *, struct vm_map *);
 void           db_print_loc_and_inst (db_addr_t loc, db_regs_t *regs);
-void           db_printf (const char *fmt, ...) __printflike(1, 2);
+
+/*void         db_printf (const char *fmt, ...) __printflike(1, 2);*/
+/* can't use __printflike due to use of %nD */
+void           db_printf (const char *fmt, ...);
+
 void           db_vprintf (const char *fmt, __va_list va) __printflike(1, 0);
 void           db_read_bytes (vm_offset_t addr, size_t size, char *data);
                                /* machine-dependent */
index a28db9c..ffe5e87 100644 (file)
@@ -1172,7 +1172,7 @@ acx_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
                        bpf_mtap(ic->ic_rawbpf, m);
 
                f = mtod(m, struct ieee80211_frame *);
-               if ((f->i_fc[1] & IEEE80211_FC1_WEP) && !sc->chip_hw_crypt) {
+               if ((f->i_fc[1] & IEEE80211_FC1_PROTECTED) && !sc->chip_hw_crypt) {
                        KASSERT(ni != NULL, ("TX node is NULL (WEP)"));
                        if (ieee80211_crypto_encap(ic, ni, m) == NULL) {
                                ieee80211_free_node(ni);
@@ -1495,7 +1495,7 @@ acx_rxeof(struct acx_softc *sc)
                m->m_pkthdr.rcvif = &ic->ic_if;
 
                wh = mtod(m, struct ieee80211_frame_min *);
-               is_priv = (wh->i_fc[1] & IEEE80211_FC1_WEP);
+               is_priv = (wh->i_fc[1] & IEEE80211_FC1_PROTECTED);
 
                if (sc->sc_drvbpf != NULL) {
                        sc->sc_rx_th.wr_tsf = htole32(head->rbh_time);
@@ -1536,7 +1536,7 @@ acx_rxeof(struct acx_softc *sc)
 
                        if (is_priv && sc->chip_hw_crypt) {
                                /* Short circuit software WEP */
-                               wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
+                               wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
 
                                /* Do chip specific RX buffer processing */
                                if (sc->chip_proc_wep_rxbuf != NULL) {
@@ -2479,7 +2479,7 @@ acx_encap(struct acx_softc *sc, struct acx_txbuf *txbuf, struct mbuf *m,
 
                wh = mtod(m, struct ieee80211_frame_min *);
                sc->sc_tx_th.wt_flags = 0;
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP)
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
                        sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
                sc->sc_tx_th.wt_rate = rate;
 
index c80e416..7b8884c 100644 (file)
  */
 #define        ATH_SW_PSQ
 
-#ifdef __DragonFly__
-#define CURVNET_SET(name)
-#define CURVNET_RESTORE()
-#endif
-
 /*
  * ATH_BCBUF determines the number of vap's that can transmit
  * beacons and also (currently) the number of vap's that can
@@ -2529,7 +2524,13 @@ ath_txrx_stop_locked(struct ath_softc *sc)
            sc->sc_txstart_cnt || sc->sc_intr_cnt) {
                if (i <= 0)
                        break;
-               wlan_serialize_sleep(sc, 0, "ath_txrx_stop", (hz + 99) / 100);
+               if (wlan_is_serialized()) {
+                       wlan_serialize_exit();
+                       tsleep(sc, 0, "ath_txrx_stop", (hz + 99) / 100);
+                       wlan_serialize_enter();
+               } else {
+                       tsleep(sc, 0, "ath_txrx_stop", (hz + 99) / 100);
+               }
                i--;
        }
 
@@ -2594,8 +2595,13 @@ ath_reset_grablock(struct ath_softc *sc, int dowait)
                        break;
                }
                ATH_PCU_UNLOCK(sc);
-               wlan_serialize_sleep(sc, 0, "ath_reset_grablock",
-                                    (hz + 9) / 10);
+               if (wlan_is_serialized()) {
+                       wlan_serialize_exit();
+                       tsleep(sc, 0, "ath_reset_grablock", (hz + 9) / 10);
+                       wlan_serialize_enter();
+               } else {
+                       tsleep(sc, 0, "ath_reset_grablock", (hz + 9) / 10);
+               }
                i--;
                ATH_PCU_LOCK(sc);
        } while (i > 0);
@@ -5762,9 +5768,13 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
        if (ostate == IEEE80211_S_CSA && nstate == IEEE80211_S_RUN)
                csa_run_transition = 1;
 
-       wlan_serialize_exit();
-       callout_stop_sync(&sc->sc_cal_ch);
-       wlan_serialize_enter();
+       if (wlan_is_serialized()) {
+               wlan_serialize_exit();
+               callout_stop_sync(&sc->sc_cal_ch);
+               wlan_serialize_enter();
+       } else {
+               callout_stop_sync(&sc->sc_cal_ch);
+       }
        ath_hal_setledstate(ah, leds[nstate]);  /* set LED */
 
        if (nstate == IEEE80211_S_SCAN) {
@@ -6366,12 +6376,14 @@ ath_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
 {
        struct ath_softc *sc = ifp->if_softc;
        struct mbuf *m;
+       int wst;
 
-       wlan_assert_serialized();
        ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq);
+       wst = wlan_serialize_push();
 
        if ((ifp->if_flags & IFF_RUNNING) == 0 || sc->sc_invalid) {
                ifq_purge(&ifp->if_snd);
+               wlan_serialize_pop(wst);
                return;
        }
        ifq_set_oactive(&ifp->if_snd);
@@ -6382,6 +6394,7 @@ ath_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
                ath_transmit(ifp, m);
        }
        ifq_clr_oactive(&ifp->if_snd);
+       wlan_serialize_pop(wst);
 }
 
 /*
@@ -6550,11 +6563,13 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data,
                    rt->info[sc->sc_txrix].dot11Rate &~ IEEE80211_RATE_BASIC;
                if (rt->info[sc->sc_txrix].phy & IEEE80211_T_HT)
                        sc->sc_stats.ast_tx_rate |= IEEE80211_RATE_MCS;
-               return copyout(&sc->sc_stats,
-                   ifr->ifr_data, sizeof (sc->sc_stats));
+               error = copyout(&sc->sc_stats, ifr->ifr_data,
+                               sizeof (sc->sc_stats));
+               break;
        case SIOCGATHAGSTATS:
-               return copyout(&sc->sc_aggr_stats,
-                   ifr->ifr_data, sizeof (sc->sc_aggr_stats));
+               error = copyout(&sc->sc_aggr_stats, ifr->ifr_data,
+                               sizeof (sc->sc_aggr_stats));
+               break;
        case SIOCZATHSTATS:
                error = priv_check(curthread, PRIV_DRIVER);
                if (error == 0) {
index bc225f1..301827b 100644 (file)
@@ -1549,7 +1549,7 @@ ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni,
        ATH_TX_LOCK_ASSERT(sc);
 
        wh = mtod(m0, struct ieee80211_frame *);
-       iswep = wh->i_fc[1] & IEEE80211_FC1_WEP;
+       iswep = wh->i_fc[1] & IEEE80211_FC1_PROTECTED;
        ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
        isfrag = m0->m_flags & M_FRAG;
        hdrlen = ieee80211_anyhdrsize(wh);
@@ -2194,7 +2194,7 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
 
                sc->sc_tx_th.wt_tsf = htole64(tsf);
                sc->sc_tx_th.wt_flags = sc->sc_hwmap[rix].txflags;
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP)
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
                        sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
                if (m0->m_flags & M_FRAG)
                        sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_FRAG;
@@ -5698,7 +5698,7 @@ ath_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
     int dialogtoken, int baparamset, int batimeout)
 {
        struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
-       int tid = tap->txa_ac;
+       int tid = tap->txa_tid;
        struct ath_node *an = ATH_NODE(ni);
        struct ath_tid *atid = &an->an_tid[tid];
 
@@ -5775,7 +5775,7 @@ ath_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
     int status, int code, int batimeout)
 {
        struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
-       int tid = tap->txa_ac;
+       int tid = tap->txa_tid;
        struct ath_node *an = ATH_NODE(ni);
        struct ath_tid *atid = &an->an_tid[tid];
        int r;
@@ -5821,7 +5821,7 @@ void
 ath_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
 {
        struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
-       int tid = tap->txa_ac;
+       int tid = tap->txa_tid;
        struct ath_node *an = ATH_NODE(ni);
        struct ath_tid *atid = &an->an_tid[tid];
        ath_bufhead bf_cq;
@@ -5954,7 +5954,7 @@ ath_bar_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
     int status)
 {
        struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
-       int tid = tap->txa_ac;
+       int tid = tap->txa_tid;
        struct ath_node *an = ATH_NODE(ni);
        struct ath_tid *atid = &an->an_tid[tid];
        int attempts = tap->txa_attempts;
@@ -5965,7 +5965,7 @@ ath_bar_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
            ",  txa_start=%d, txa_seqpending=%d\n",
            __func__,
            ath_hal_ether_sprintf(ni->ni_macaddr),
-           tap->txa_ac,
+           tap->txa_tid,
            atid->tid,
            status,
            attempts,
@@ -6026,7 +6026,7 @@ ath_addba_response_timeout(struct ieee80211_node *ni,
     struct ieee80211_tx_ampdu *tap)
 {
        struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
-       int tid = tap->txa_ac;
+       int tid = tap->txa_tid;
        struct ath_node *an = ATH_NODE(ni);
        struct ath_tid *atid = &an->an_tid[tid];
 
index aaa148f..83b48b1 100644 (file)
@@ -385,9 +385,6 @@ struct ath_txq {
 /* already serialized by wlan_serializer */
 #define IF_LOCK(ifp)
 #define IF_UNLOCK(ifp)
-#define IEEE80211_LOCK_ASSERT(ic)
-#define IEEE80211_LOCK(ic)
-#define IEEE80211_UNLOCK(ic)
 #endif
 
 #define        ATH_TXQ_LOCK_INIT(_sc, _tq)
index f3e81a2..bff5797 100644 (file)
@@ -1630,7 +1630,7 @@ bwi_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
                        bpf_mtap(ic->ic_rawbpf, m);
 
                wh = mtod(m, struct ieee80211_frame *);
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                        if (ieee80211_crypto_encap(ic, ni, m) == NULL) {
                                ieee80211_free_node(ni);
                                m_freem(m);
@@ -3072,7 +3072,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
         */
        if (sc->sc_drvbpf != NULL) {
                sc->sc_tx_th.wt_flags = 0;
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP)
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
                        sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
                if (ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_DS &&
                    (ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
@@ -3721,7 +3721,7 @@ bwi_rx_radiotap(struct bwi_softc *sc, struct mbuf *m,
                sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
 
        wh = mtod(m, const struct ieee80211_frame_min *);
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP)
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
                sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
 
        sc->sc_rx_th.wr_tsf = hdr->rxh_tsf; /* No endian convertion */
index 8deeeff..54da33a 100644 (file)
@@ -1284,7 +1284,7 @@ bwn_start_locked(struct ifnet *ifp)
                }
                KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
                wh = mtod(m, struct ieee80211_frame *);
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                        k = ieee80211_crypto_encap(ni, m);
                        if (k == NULL) {
                                ieee80211_free_node(ni);
@@ -9668,7 +9668,7 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
         */
        if (ieee80211_radiotap_active_vap(vap)) {
                sc->sc_tx_th.wt_flags = 0;
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP)
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
                        sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
                if (isshort &&
                    (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
@@ -10215,7 +10215,7 @@ bwn_rx_radiotap(struct bwn_mac *mac, struct mbuf *m,
                sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
 
        wh = mtod(m, const struct ieee80211_frame_min *);
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP)
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
                sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
 
        bwn_tsf_read(mac, &tsf);
index 02f0512..5a3bc9c 100644 (file)
@@ -1824,7 +1824,7 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni,
        } else
                staid = 0;
 
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
                        m_freem(m0);
index 539601f..e0e4e4e 100644 (file)
@@ -906,7 +906,7 @@ iwl2100_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
                        bpf_mtap(ic->ic_rawbpf, m);
 
                wh = mtod(m, struct ieee80211_frame *);
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                        if (ieee80211_crypto_encap(ic, ni, m) == NULL) {
                                ieee80211_free_node(ni);
                                m_freem(m);
@@ -919,7 +919,7 @@ iwl2100_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
                 * TX radio tap
                 */
                if (sc->sc_drvbpf != NULL) {
-                       if (wh->i_fc[1] & IEEE80211_FC1_WEP)
+                       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
                                sc->sc_tx_th.wt_flags = IEEE80211_RADIOTAP_F_WEP;
                        else
                                sc->sc_tx_th.wt_flags = 0;
@@ -3063,7 +3063,7 @@ iwl2100_rxeof_data(struct iwl2100_softc *sc, int i)
         * RX radio tap
         */
        if (sc->sc_drvbpf != NULL) {
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP)
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
                        sc->sc_rx_th.wr_flags = IEEE80211_RADIOTAP_F_WEP;
                else
                        sc->sc_rx_th.wr_flags = 0;
@@ -3323,7 +3323,7 @@ iwl2100_encap(struct iwl2100_softc *sc, struct mbuf *m)
                IEEE80211_ADDR_COPY(dst, wh->i_addr3);
        else
                IEEE80211_ADDR_COPY(dst, wh->i_addr1);
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP)
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
                host_enc = 1;
        else
                host_enc = 0;
index 18c15d7..7fbd03b 100644 (file)
@@ -3105,7 +3105,7 @@ iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc,
        qid = le16toh(ba->qid);
        txq = &sc->txq[ba->qid];
        tap = sc->qid2tap[ba->qid];
-       tid = tap->txa_ac;
+       tid = tap->txa_tid;
        wn = (void *)tap->txa_ni;
 
        res = NULL;
@@ -3597,7 +3597,7 @@ iwn_ampdu_tx_done(struct iwn_softc *sc, int qid, int idx, int nframes,
                         * layer.
                         */
                        tap = sc->qid2tap[qid];
-                       tid = tap->txa_ac;
+                       tid = tap->txa_tid;
                        wn = (void *)tap->txa_ni;
                        ni = tap->txa_ni;
                        ieee80211_ratectl_tx_complete(ni->ni_vap, ni,
@@ -3629,7 +3629,7 @@ iwn_ampdu_tx_done(struct iwn_softc *sc, int qid, int idx, int nframes,
                bitmap |= 1ULL << bit;
        }
        tap = sc->qid2tap[qid];
-       tid = tap->txa_ac;
+       tid = tap->txa_tid;
        wn = (void *)tap->txa_ni;
        wn->agg[tid].bitmap = bitmap;
        wn->agg[tid].startidx = start;
@@ -4310,7 +4310,7 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
        }
 
        /* Encrypt the frame if need be. */
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                /* Retrieve key for TX. */
                k = ieee80211_crypto_encap(ni, m);
                if (k == NULL) {
@@ -7089,7 +7089,7 @@ iwn_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
 {
        struct iwn_softc *sc = ni->ni_ic->ic_ifp->if_softc;
        int qid = *(int *)tap->txa_private;
-       uint8_t tid = tap->txa_ac;
+       uint8_t tid = tap->txa_tid;
        int ret;
 
        DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
@@ -7152,7 +7152,7 @@ iwn_ampdu_tx_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
 {
        struct iwn_softc *sc = ni->ni_ic->ic_ifp->if_softc;
        struct iwn_ops *ops = &sc->ops;
-       uint8_t tid = tap->txa_ac;
+       uint8_t tid = tap->txa_tid;
        int qid;
 
        DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
index 3c4da86..65eeee5 100644 (file)
@@ -1547,7 +1547,7 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0,
 
        wh = mtod(m0, struct ieee80211_frame *);
 
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
                        m_freem(m0);
@@ -1793,7 +1793,7 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
                rate = ni->ni_txrate;
        }
 
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
                        m_freem(m0);
index 1b5fdf4..556ae57 100644 (file)
@@ -1310,7 +1310,7 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0,
 
        wh = mtod(m0, struct ieee80211_frame *);
 
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
                        m_freem(m0);
@@ -1485,7 +1485,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
                noack = cap->cap_wmeParams[ac].wmep_noackPolicy;
        }
 
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
                        m_freem(m0);
index ddf97e6..147e4db 100644 (file)
@@ -1283,9 +1283,9 @@ rt2860_rx_intr(struct rt2860_softc *sc)
 
                wh = mtod(m, struct ieee80211_frame *);
 #ifdef HW_CRYPTO
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                        /* frame is decrypted by hardware */
-                       wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
+                       wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
                }
 #endif
 
@@ -1482,7 +1482,7 @@ rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
 
        wh = mtod(m, struct ieee80211_frame *);
 
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m);
                if (k == NULL) {
                        m_freem(m);
index 6e12f55..0be2a05 100644 (file)
@@ -3174,7 +3174,7 @@ rtw_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
 
                wh = mtod(m0, struct ieee80211_frame_min *);
 
-               if ((wh->i_fc[1] & IEEE80211_FC1_WEP) != 0 &&
+               if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) != 0 &&
                    (k = ieee80211_crypto_encap(ic, ni, m0)) == NULL) {
                        ieee80211_free_node(ni);
                        m_freem(m0);
index 8ce6b3f..b8ace23 100644 (file)
@@ -971,7 +971,7 @@ wi_start_locked(struct ifnet *ifp)
                    mtod(m0, const uint8_t *) + ieee80211_hdrsize(wh));
                frmhdr.wi_ehdr.ether_type = llc->llc_snap.ether_type;
                frmhdr.wi_tx_ctl = htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX);
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                        k = ieee80211_crypto_encap(ni, m0);
                        if (k == NULL) {
                                ieee80211_free_node(ni);
@@ -1069,7 +1069,7 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0,
        frmhdr.wi_tx_ctl = htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX);
        if (params && (params->ibp_flags & IEEE80211_BPF_NOACK))
                frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_ALTRTRY);
-       if ((wh->i_fc[1] & IEEE80211_FC1_WEP) &&
+       if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
            (!params || (params && (params->ibp_flags & IEEE80211_BPF_CRYPTO)))) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
index 67cb525..538153f 100644 (file)
@@ -1871,7 +1871,7 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
        hdrlen = ieee80211_hdrsize(wh);
        ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
 
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                k = ieee80211_crypto_encap(ni, m0);
                if (k == NULL) {
                        m_freem(m0);
@@ -1940,7 +1940,7 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
                tap->wt_flags = 0;
                tap->wt_rate = rate;
                tap->wt_hwqueue = ac;
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP)
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
                        tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
 
                ieee80211_radiotap_tx(vap, m0);
index dfdfa6e..749aa50 100644 (file)
@@ -257,7 +257,7 @@ extern const uint8_t        etherbroadcastaddr[ETHER_ADDR_LEN];
                    /* 0x80E0 - 0x80E3     Allen-Bradley */
                    /* 0x80E4 - 0x80F0     Datability */
 #define        ETHERTYPE_RETIX         0x80F2  /* Retix */
-                            /* 0x80F3     AppleTalk AARP */
+#define ETHERTYPE_AARP         0x80F3  /* AppleTalk AARP */
                    /* 0x80F4 - 0x80F5     Kinetics */
 #define        ETHERTYPE_APOLLO        0x80F7  /* Apollo Computer */
 #define ETHERTYPE_VLAN         0x8100  /* IEEE 802.1Q VLAN tagging (XXX conflicts) */
index e13680e..b0575ea 100644 (file)
@@ -1,92 +1,24 @@
 
                            README.DRAGONFLY
 
-    All ABI entry points into the wlan infrastructure must acquire the
-    wlan_global_serializer.  Normally all wireless base drivers also
-    use this serializer to avoid deadlocks.
+    If a major re-port of the 802_11 infrastructure is required, the
+    easiest way to do it is to copy the FreeBSD files into the appropriate
+    places in the DragonFly archive and then do a 'git diff .' in 802_11
+    and restore the pieces that required DragonFly adjustments.
 
-STEP 1:
+    * Change all #include <net80211/...> to <netproto/802_11/...>
 
-    When porting a new wireless low level device be sure to remove all
-    *LOCK* (upper case) macro calls because the whole point of this is
-    to redo the locking with our own.
+    * Change all M_NOWAIT to either M_INTWAIT for mallocs or MB_DONTWAIT
+      for mbuf function calls.
 
-STEP 2:
+    * malloc -> kmalloc
 
-    All border crossings (module loader, sysctl, eventhandlers, tasks,
-    callouts, ifnet, devmethod, and interrupt handlers) must be properly
-    wrapped with wlan_serialize_enter() and wlan_serialize_exit().  Pay
-    careful attention to any early return()s that might break your locks.
+    * free -> kfree
 
+    * *printf -> k*printf (printf, vprintf, vsnprintf, etc)
 
-modevent       search for DECLARE_MODULE and MOD_LOAD and friends.
+    * if_inc_counter(ifp, BLAH, 1) -> IFNET_STAT_INC(ifp, blah, 1)
+       (lower case blah)
 
-sysctl         search for SYSCTL_HANDLER_ARGS.
+    * Trailing white-space pass
 
-               Generally speaking sysctls should be rewritten to use
-               a flow-through model (see ath for an example) as most
-               of them currently use a badly designed early-termination
-               model.
-
-eventhandler   search for EVENTHANDLER_REGISTER.
-
-taskq          search for TASK_INIT.
-
-               All taskq callback procedures should be renamed to
-               "<blah>_task".
-
-callout                search for callout_reset.
-
-               search for callout_stop to deal with potential deadlock
-               issues.
-
-               All callout callback procedures should be renamed to
-               "<blah>_callout"
-
-ifnet          wlan/ieee80211.c
-
-               This is handled by ieee80211_ifattach() where we set
-               the serializer to &wlan_global_serializer when we
-               call ether_ifattach().  The low level drivers should
-               just be calling ieee80211_ifattach() so no additional
-               work should be needed here.
-
-devmethod      Search for DEVMETHOD (low level drivers).  Typically
-               this is in the *_pci.c file.  The attach function might
-               present an issue where you may wish to release the
-               serializer across the main DMA area allocations.
-               see ath.
-
-interrupt      Search for bus_setup_intr().
-
-               Typically we pass the &wlan_global_serializer to
-               bus_setup_intr().  The interrupt callback is thus
-               serialized automatically.
-
-ieee80211_ioctl()
-               This is called directly from the wlan's ifp->if_ioctl and
-               also from various wireless drivers.  This function expects
-               the serializer to already be acquired.
-
-               The kernel will acquire if_serializer when making
-               ifp->if_ioctl() calls.
-
-{t,lk}sleep            Low level drivers sometimes call {t,lk}sleep() to
-               wait for an interrupt driven event to wake them up.  In
-               these cases the interrupt will be blocked on the wlan
-               serializer and the tsleep will timeout.  To fix the
-               problem use zsleep() to release the &wlan_global_serializer
-               across the sleep operation.
-
-firmware       The firmware loader uses a taskq to defer certain
-               operations which can then deadlock against the wlan
-               serializer.  Thus it is usually a good idea to
-               release the serializer (wlan_serialize_exit/enter)
-               around the call to firmware_get().
-
-Low level device drivers
-               Don't forget that low level device drivers such as ath
-               have callouts, taskq, sysctl, and other elements also!
-
-               Look for old calls to ifnet_serialize*() and remove,
-               in addition to the various LOCK macros.
index c1aa4ff..5120d41 100644 (file)
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/_ieee80211.h 195618 2009-07-11 15:02:45Z rpaulo $
+ * $FreeBSD$
  */
 #ifndef _NET80211__IEEE80211_H_
 #define _NET80211__IEEE80211_H_
@@ -133,7 +133,7 @@ enum ieee80211_roamingmode {
  */
 struct ieee80211_channel {
        uint32_t        ic_flags;       /* see below */
-       uint16_t        ic_freq;        /* setting in Mhz */
+       uint16_t        ic_freq;        /* setting in MHz */
        uint8_t         ic_ieee;        /* IEEE channel number */
        int8_t          ic_maxregpower; /* maximum regulatory tx power in dBm */
        int8_t          ic_maxpower;    /* maximum tx power in .5 dBm */
@@ -242,6 +242,8 @@ struct ieee80211_channel {
        (((_c)->ic_flags & (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN)) != 0)
 #define        IEEE80211_IS_CHAN_CCK(_c) \
        (((_c)->ic_flags & (IEEE80211_CHAN_CCK | IEEE80211_CHAN_DYN)) != 0)
+#define        IEEE80211_IS_CHAN_DYN(_c) \
+       (((_c)->ic_flags & IEEE80211_CHAN_DYN) == IEEE80211_CHAN_DYN)
 #define        IEEE80211_IS_CHAN_GFSK(_c) \
        (((_c)->ic_flags & IEEE80211_CHAN_GFSK) != 0)
 #define        IEEE80211_IS_CHAN_TURBO(_c) \
@@ -335,7 +337,7 @@ struct ieee80211_rateset {
  * the structure such that it can be used interchangeably
  * with an ieee80211_rateset (modulo structure size).
  */
-#define        IEEE80211_HTRATE_MAXSIZE 127
+#define        IEEE80211_HTRATE_MAXSIZE        77
 
 struct ieee80211_htrateset {
        uint8_t         rs_nrates;
@@ -387,9 +389,16 @@ struct ieee80211_regdomain {
 /*
  * MIMO antenna/radio state.
  */
+
+#define        IEEE80211_MAX_CHAINS            3
+#define        IEEE80211_MAX_EVM_PILOTS        6
+
+/*
+ * XXX This doesn't yet export both ctl/ext chain details
+ */
 struct ieee80211_mimo_info {
-       int8_t          rssi[3];        /* per-antenna rssi */
-       int8_t          noise[3];       /* per-antenna noise floor */
+       int8_t          rssi[IEEE80211_MAX_CHAINS];     /* per-antenna rssi */
+       int8_t          noise[IEEE80211_MAX_CHAINS];    /* per-antenna noise floor */
        uint8_t         pad[2];
        uint32_t        evm[3];         /* EVM data */
 };
index 8a88091..9b005f3 100644 (file)
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211.h 197413 2009-09-22 18:18:14Z rpaulo $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_H_
 #define _NET80211_IEEE80211_H_
@@ -131,6 +131,7 @@ struct ieee80211_qosframe_addr4 {
 #define        IEEE80211_FC0_SUBTYPE_AUTH              0xb0
 #define        IEEE80211_FC0_SUBTYPE_DEAUTH            0xc0
 #define        IEEE80211_FC0_SUBTYPE_ACTION            0xd0
+#define        IEEE80211_FC0_SUBTYPE_ACTION_NOACK      0xe0
 /* for TYPE_CTL */
 #define        IEEE80211_FC0_SUBTYPE_BAR               0x80
 #define        IEEE80211_FC0_SUBTYPE_BA                0x90
@@ -165,7 +166,7 @@ struct ieee80211_qosframe_addr4 {
 #define        IEEE80211_FC1_RETRY                     0x08
 #define        IEEE80211_FC1_PWR_MGT                   0x10
 #define        IEEE80211_FC1_MORE_DATA                 0x20
-#define        IEEE80211_FC1_WEP                       0x40
+#define        IEEE80211_FC1_PROTECTED                 0x40
 #define        IEEE80211_FC1_ORDER                     0x80
 
 #define        IEEE80211_SEQ_FRAG_MASK                 0x000f
@@ -198,6 +199,13 @@ struct ieee80211_qosframe_addr4 {
 #define        IEEE80211_QOS_EOSP                      0x10    /* EndOfService Period*/
 #define        IEEE80211_QOS_EOSP_S                    4
 #define        IEEE80211_QOS_TID                       0x0f
+/* qos[1] byte used for all frames sent by mesh STAs in a mesh BSS */
+#define IEEE80211_QOS_MC                       0x01    /* Mesh control */
+/* Mesh power save level*/
+#define IEEE80211_QOS_MESH_PSL                 0x02
+/* Mesh Receiver Service Period Initiated */
+#define IEEE80211_QOS_RSPI                     0x04
+/* bits 11 to 15 reserved */
 
 /* does frame have QoS sequence control data */
 #define        IEEE80211_QOS_HAS_SEQ(wh) \
@@ -324,6 +332,9 @@ struct ieee80211_action {
 #define        IEEE80211_ACTION_CAT_DLS        2       /* DLS */
 #define        IEEE80211_ACTION_CAT_BA         3       /* BA */
 #define        IEEE80211_ACTION_CAT_HT         7       /* HT */
+#define        IEEE80211_ACTION_CAT_MESH       13      /* Mesh */
+#define        IEEE80211_ACTION_CAT_SELF_PROT  15      /* Self-protected */
+/* 16 - 125 reserved */
 #define        IEEE80211_ACTION_CAT_VENDOR     127     /* Vendor Specific */
 
 #define        IEEE80211_ACTION_HT_TXCHWIDTH   0       /* recommended xmit chan width*/
@@ -700,6 +711,7 @@ enum {
        IEEE80211_ELEMID_IBSSDFS        = 41,
        IEEE80211_ELEMID_ERP            = 42,
        IEEE80211_ELEMID_HTCAP          = 45,
+       IEEE80211_ELEMID_QOS            = 46,
        IEEE80211_ELEMID_RSN            = 48,
        IEEE80211_ELEMID_XRATES         = 50,
        IEEE80211_ELEMID_HTINFO         = 61,
@@ -708,27 +720,32 @@ enum {
        IEEE80211_ELEMID_VENDOR         = 221,  /* vendor private */
 
        /*
-        * 802.11s IEs based on D3.03 spec and were not assigned by
-        * ANA. Beware changing them because some of them are being
-        * kept compatible with Linux.
+        * 802.11s IEs
+        * NB: On vanilla Linux still IEEE80211_ELEMID_MESHPEER = 55,
+        * but they defined a new with id 117 called PEER_MGMT.
+        * NB: complies with open80211
         */
-       IEEE80211_ELEMID_MESHCONF       = 51,
-       IEEE80211_ELEMID_MESHID         = 52,
-       IEEE80211_ELEMID_MESHLINK       = 35,
-       IEEE80211_ELEMID_MESHCNGST      = 36,
-       IEEE80211_ELEMID_MESHPEER       = 55,
-       IEEE80211_ELEMID_MESHCSA        = 38,
-       IEEE80211_ELEMID_MESHTIM        = 39,
-       IEEE80211_ELEMID_MESHAWAKEW     = 40,
-       IEEE80211_ELEMID_MESHBEACONT    = 41,
-       IEEE80211_ELEMID_MESHPANN       = 48,
-       IEEE80211_ELEMID_MESHRANN       = 49,
-       IEEE80211_ELEMID_MESHPREQ       = 68,
-       IEEE80211_ELEMID_MESHPREP       = 69,
-       IEEE80211_ELEMID_MESHPERR       = 70,
-       IEEE80211_ELEMID_MESHPXU        = 53,
-       IEEE80211_ELEMID_MESHPXUC       = 54,
-       IEEE80211_ELEMID_MESHAH         = 60, /* Abbreviated Handshake */
+       IEEE80211_ELEMID_MESHCONF       = 113,
+       IEEE80211_ELEMID_MESHID         = 114,
+       IEEE80211_ELEMID_MESHLINK       = 115,
+       IEEE80211_ELEMID_MESHCNGST      = 116,
+       IEEE80211_ELEMID_MESHPEER       = 117,
+       IEEE80211_ELEMID_MESHCSA        = 118,
+       IEEE80211_ELEMID_MESHTIM        = 39, /* XXX: remove */
+       IEEE80211_ELEMID_MESHAWAKEW     = 119,
+       IEEE80211_ELEMID_MESHBEACONT    = 120,
+       /* 121-124 MMCAOP not implemented yet */
+       IEEE80211_ELEMID_MESHGANN       = 125,
+       IEEE80211_ELEMID_MESHRANN       = 126,
+       /* 127 Extended Capabilities */
+       /* 128-129 reserved */
+       IEEE80211_ELEMID_MESHPREQ       = 130,
+       IEEE80211_ELEMID_MESHPREP       = 131,
+       IEEE80211_ELEMID_MESHPERR       = 132,
+       /* 133-136 reserved */
+       IEEE80211_ELEMID_MESHPXU        = 137,
+       IEEE80211_ELEMID_MESHPXUC       = 138,
+       IEEE80211_ELEMID_MESHAH         = 60, /* XXX: remove */
 };
 
 struct ieee80211_tim_ie {
@@ -755,6 +772,18 @@ struct ieee80211_country_ie {
 #define        IEEE80211_COUNTRY_MAX_SIZE \
        (sizeof(struct ieee80211_country_ie) + 3*(IEEE80211_COUNTRY_MAX_BANDS-1))
 
+/*
+ * 802.11h Quiet Time Element.
+ */
+struct ieee80211_quiet_ie {
+       uint8_t         quiet_ie;               /* IEEE80211_ELEMID_QUIET */
+       uint8_t         len;
+       uint8_t         tbttcount;              /* quiet start */
+       uint8_t         period;                 /* beacon intervals between quiets */
+       uint16_t        duration;               /* TUs of each quiet*/
+       uint16_t        offset;                 /* TUs of from TBTT of quiet start */
+} __packed;
+
 /*
  * 802.11h Channel Switch Announcement (CSA).
  */
@@ -914,19 +943,21 @@ enum {
        IEEE80211_REASON_SETUP_NEEDED           = 38,   /* 11e */
        IEEE80211_REASON_TIMEOUT                = 39,   /* 11e */
 
-       /* values not yet allocated by ANA */
-       IEEE80211_REASON_PEER_LINK_CANCELED     = 2,    /* 11s */
-       IEEE80211_REASON_MESH_MAX_PEERS         = 3,    /* 11s */
-       IEEE80211_REASON_MESH_CPVIOLATION       = 4,    /* 11s */
-       IEEE80211_REASON_MESH_CLOSE_RCVD        = 5,    /* 11s */
-       IEEE80211_REASON_MESH_MAX_RETRIES       = 6,    /* 11s */
-       IEEE80211_REASON_MESH_CONFIRM_TIMEOUT   = 7,    /* 11s */
-       IEEE80211_REASON_MESH_INVALID_GTK       = 8,    /* 11s */
-       IEEE80211_REASON_MESH_INCONS_PARAMS     = 9,    /* 11s */
-       IEEE80211_REASON_MESH_INVALID_SECURITY  = 10,   /* 11s */
-       IEEE80211_REASON_MESH_PERR_UNSPEC       = 11,   /* 11s */
-       IEEE80211_REASON_MESH_PERR_NO_FI        = 12,   /* 11s */
-       IEEE80211_REASON_MESH_PERR_DEST_UNREACH = 13,   /* 11s */
+       IEEE80211_REASON_PEER_LINK_CANCELED     = 52,   /* 11s */
+       IEEE80211_REASON_MESH_MAX_PEERS         = 53,   /* 11s */
+       IEEE80211_REASON_MESH_CPVIOLATION       = 54,   /* 11s */
+       IEEE80211_REASON_MESH_CLOSE_RCVD        = 55,   /* 11s */
+       IEEE80211_REASON_MESH_MAX_RETRIES       = 56,   /* 11s */
+       IEEE80211_REASON_MESH_CONFIRM_TIMEOUT   = 57,   /* 11s */
+       IEEE80211_REASON_MESH_INVALID_GTK       = 58,   /* 11s */
+       IEEE80211_REASON_MESH_INCONS_PARAMS     = 59,   /* 11s */
+       IEEE80211_REASON_MESH_INVALID_SECURITY  = 60,   /* 11s */
+       IEEE80211_REASON_MESH_PERR_NO_PROXY     = 61,   /* 11s */
+       IEEE80211_REASON_MESH_PERR_NO_FI        = 62,   /* 11s */
+       IEEE80211_REASON_MESH_PERR_DEST_UNREACH = 63,   /* 11s */
+       IEEE80211_REASON_MESH_MAC_ALRDY_EXISTS_MBSS = 64, /* 11s */
+       IEEE80211_REASON_MESH_CHAN_SWITCH_REG   = 65,   /* 11s */
+       IEEE80211_REASON_MESH_CHAN_SWITCH_UNSPEC = 66,  /* 11s */
 
        IEEE80211_STATUS_SUCCESS                = 0,
        IEEE80211_STATUS_UNSPECIFIED            = 1,
@@ -1084,8 +1115,4 @@ struct ieee80211_duration {
                                 IEEE80211_DUR_DS_SLOW_PLCPHDR + \
                                 IEEE80211_DUR_DIFS)
 
-#ifdef _KERNEL
-extern lwkt_token wlan_token;
-#endif
-
 #endif /* _NET80211_IEEE80211_H_ */
index c1ee3f4..4ee2aff 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_action.h 195377 2009-07-05 17:59:19Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_ACTION_H_
 #define _NET80211_IEEE80211_ACTION_H_
index 516c00f..d8e19e5 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_adhoc.h 178354 2008-04-20 20:35:46Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_ADHOC_H_
 #define _NET80211_IEEE80211_ADHOC_H_
index 3e883c2..fdcf071 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_ageq.h 195379 2009-07-05 18:17:37Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_STAGEQ_H_
 #define _NET80211_IEEE80211_STAGEQ_H_
@@ -31,6 +31,7 @@ struct ieee80211_node;
 struct mbuf;
 
 struct ieee80211_ageq {
+       ieee80211_ageq_lock_t   aq_lock;
        int                     aq_len;         /* # items on queue */
        int                     aq_maxlen;      /* max queue length */
        int                     aq_drops;       /* frames dropped */
similarity index 63%
copy from sys/netproto/802_11/ieee80211_wds.h
copy to sys/netproto/802_11/ieee80211_alq.h
index dd1a0d0..112c6b1 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2011 Adrian Chadd, Xenion Lty Ltd
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_wds.h 178354 2008-04-20 20:35:46Z sam $
+ * $FreeBSD$
  */
-#ifndef _NET80211_IEEE80211_WDS_H_
-#define _NET80211_IEEE80211_WDS_H_
+#ifndef        __IEEE80211_ALQ_H__
+#define        __IEEE80211_ALQ_H__
+
+#define        IEEE80211_ALQ_PAYLOAD_SIZE      24
 
 /*
- * WDS implementation definitions.
+ * timestamp
+ * wlan interface
+ * operation
+ * sub-operation
+ * rest of structure - operation specific
  */
-void   ieee80211_wds_attach(struct ieee80211com *);
-void   ieee80211_wds_detach(struct ieee80211com *);
+struct ieee80211_alq_rec {
+       uint32_t        r_timestamp;    /* XXX may wrap! */
+       uint32_t        r_threadid;     /* current thread id */
+       uint16_t        r_wlan;         /* wlan interface number */
+       uint8_t         r_version;      /* version */
+       uint8_t         r_op;           /* top-level operation id */
+       u_char          r_payload[IEEE80211_ALQ_PAYLOAD_SIZE];
+                                       /* operation-specific payload */
+};
+
+/* General logging function */
+extern void ieee80211_alq_log(struct ieee80211vap *vap, uint8_t op,
+           u_char *p, int l);
 
-void   ieee80211_dwds_mcast(struct ieee80211vap *, struct mbuf *);
-void   ieee80211_dwds_discover(struct ieee80211_node *, struct mbuf *);
-int    ieee80211_node_wdsq_age(struct ieee80211_node *);
-#endif /* !_NET80211_IEEE80211_WDS_H_ */
+#endif /* __IEEE80211_ALQ_H__ */
index 61e9997..ec67bdf 100644 (file)
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/net80211/ieee80211_amrr.h 206358 2010-04-07 15:29:13Z rpaulo $ */
+/* $FreeBSD$ */
 /*     $OpenBSD: ieee80211_amrr.h,v 1.3 2006/06/17 19:34:31 damien Exp $       */
 
 /*-
index ea2c9e8..d7ac436 100644 (file)
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_crypto.h 195812 2009-07-21 19:36:32Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_CRYPTO_H_
 #define _NET80211_IEEE80211_CRYPTO_H_
@@ -78,6 +78,7 @@ struct ieee80211_key {
 #define        IEEE80211_KEY_XMIT      0x0001  /* key used for xmit */
 #define        IEEE80211_KEY_RECV      0x0002  /* key used for recv */
 #define        IEEE80211_KEY_GROUP     0x0004  /* key used for WPA group operation */
+#define        IEEE80211_KEY_NOREPLAY  0x0008  /* ignore replay failures */
 #define        IEEE80211_KEY_SWENCRYPT 0x0010  /* host-based encrypt */
 #define        IEEE80211_KEY_SWDECRYPT 0x0020  /* host-based decrypt */
 #define        IEEE80211_KEY_SWENMIC   0x0040  /* host-based enmic */
@@ -98,7 +99,8 @@ struct ieee80211_key {
        uint8_t         wk_macaddr[IEEE80211_ADDR_LEN];
 };
 #define        IEEE80211_KEY_COMMON            /* common flags passed in by apps */\
-       (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP)
+       (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP | \
+        IEEE80211_KEY_NOREPLAY)
 #define        IEEE80211_KEY_DEVICE            /* flags owned by device driver */\
        (IEEE80211_KEY_DEVKEY|IEEE80211_KEY_CIPHER0|IEEE80211_KEY_CIPHER1)
 
index 0efe3eb..a5688e3 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_dfs.h 186107 2008-12-15 01:26:33Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_DFS_H_
 #define _NET80211_IEEE80211_DFS_H_
  * 802.11h/DFS definitions.
  */
 
+typedef enum {
+       DFS_DBG_NONE            = 0,
+       DFS_DBG_NONOL           = 1,
+       DFS_DBG_NOCSANOL        = 2
+} dfs_debug_t;
+
 struct ieee80211_dfs_state {
        int             nol_event[IEEE80211_CHAN_MAX];
        struct callout  nol_timer;              /* NOL list processing */
index 5a53105..33099e3 100644 (file)
@@ -34,6 +34,7 @@
 #include <sys/serialize.h>
 #include <sys/sysctl.h>
 #include <sys/condvar.h>
+#include <sys/lock.h>
 #include <sys/taskqueue.h>
 
 #include <sys/mutex2.h>
@@ -66,8 +67,14 @@ extern int ieee80211_force_swcrypto;
 
 #define wlan_serialize_enter() _wlan_serialize_enter(__func__)
 #define wlan_serialize_exit()  _wlan_serialize_exit(__func__)
+#define wlan_serialize_push()  _wlan_serialize_push(__func__)
+#define wlan_serialize_pop(wst)        _wlan_serialize_pop(__func__, wst)
+#define wlan_is_serialized()   _wlan_is_serialized()
 void _wlan_serialize_enter(const char *funcname);
 void _wlan_serialize_exit(const char *funcname);
+int  _wlan_serialize_push(const char *funcname);
+void _wlan_serialize_pop(const char *funcname, int wst);
+int  _wlan_is_serialized(void);
 int wlan_serialize_sleep(void *ident, int flags, const char *wmesg, int timo);
 
 static __inline void
@@ -76,14 +83,6 @@ wlan_assert_serialized(void)
        ASSERT_SERIALIZED(&wlan_global_serializer);
 }
 
-/*
- * wlan condition variables.  Assume the global serializer is held.
- */
-void wlan_cv_init(struct cv *cv, const char *desc);
-int wlan_cv_timedwait(struct cv *cv, int ticks);
-void wlan_cv_wait(struct cv *cv);
-void wlan_cv_signal(struct cv *cv, int broadcast);
-
 /*
  * Node reference counting definitions.
  *
@@ -108,9 +107,12 @@ int        ieee80211_node_dectestref(struct ieee80211_node *ni);
 
 struct ifqueue;
 struct ieee80211vap;
+struct ieee80211com;
 void   ieee80211_flush_ifq(struct ifaltq *, struct ieee80211vap *);
 
 void   ieee80211_vap_destroy(struct ieee80211vap *);
+int    ieee80211_vap_xmitpkt(struct ieee80211vap *vap, struct mbuf *m);
+int    ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m);
 int    ieee80211_handoff(struct ifnet *, struct mbuf *);
 uint16_t ieee80211_txtime(struct ieee80211_node *, u_int, uint8_t, uint32_t);
 
@@ -226,8 +228,6 @@ wlan_##name##_modevent(module_t mod, int type, void *unused)                \
        policy##_setup * const *iter, f;                                \
        int error;                                                      \
                                                                        \
-       wlan_serialize_enter();                                         \
-                                                                       \
        switch (type) {                                                 \
        case MOD_LOAD:                                                  \
                SET_FOREACH(iter, policy##_set) {                       \
@@ -255,8 +255,6 @@ wlan_##name##_modevent(module_t mod, int type, void *unused)                \
                break;                                                  \
        }                                                               \
                                                                        \
-       wlan_serialize_exit();                                          \
-                                                                       \
        return error;                                                   \
 }                                                                      \
 static moduledata_t name##_mod = {                                     \
@@ -491,4 +489,107 @@ struct ieee80211_bpf_params {
        uint8_t         ibp_try3;       /* series 4 try count */
        uint8_t         ibp_rate3;      /* series 4 IEEE tx rate */
 };
+
+/*
+ * FreeBSD overrides
+ */
+const char *ether_sprintf(const u_char *buf);
+
+#define V_ifnet        ifnet
+#define IFF_DRV_RUNNING        IFF_RUNNING
+#define if_drv_flags   if_flags
+
+typedef struct lock    ieee80211_psq_lock_t;
+typedef struct lock    ieee80211_ageq_lock_t;
+typedef struct lock    ieee80211_node_lock_t;
+typedef struct lock    ieee80211_scan_lock_t;
+typedef struct lock    ieee80211_com_lock_t;
+typedef struct lock    ieee80211_tx_lock_t;
+typedef struct lock    ieee80211_ageq_lock_t;
+typedef struct lock    ieee80211_scan_table_lock_t;
+typedef struct lock    acl_lock_t;
+
+#define IEEE80211_LOCK_OBJ(ic)                 (&(ic)->ic_comlock)
+
+#define IEEE80211_LOCK_INIT(ic, name)          lockinit(&(ic)->ic_comlock, name, 0, LK_CANRECURSE)
+#define IEEE80211_NODE_LOCK_INIT(ic, name)     lockinit(&(nt)->nt_nodelock, name, 0, LK_CANRECURSE)
+#define IEEE80211_NODE_ITERATE_LOCK_INIT(ic, name)     lockinit(&(nt)->nt_scanlock, name, 0, LK_CANRECURSE)
+#define IEEE80211_SCAN_TABLE_LOCK_INIT(st, name)       lockinit(&(st)->st_lock, name, 0, LK_CANRECURSE)
+#define IEEE80211_TX_LOCK_INIT(ic, name)       lockinit(&(ic)->ic_txlock, name, 0, LK_CANRECURSE)
+#define IEEE80211_AGEQ_LOCK_INIT(aq, name)     lockinit(&(aq)->aq_lock, name, 0, LK_CANRECURSE)
+#define IEEE80211_PSQ_INIT(psq, name)          lockinit(&(psq)->psq_lock, name, 0, LK_CANRECURSE)
+#define ACL_LOCK_INIT(as, name)                lockinit(&(as)->as_lock, name, 0, LK_CANRECURSE)
+
+#define IEEE80211_LOCK_DESTROY(ic)             lockuninit(&(ic)->ic_comlock)
+#define IEEE80211_NODE_LOCK_DESTROY(nt)                lockuninit(&(nt)->nt_nodelock)
+#define IEEE80211_NODE_ITERATE_LOCK_DESTROY(nt)        lockuninit(&(nt)->nt_scanlock)
+#define IEEE80211_SCAN_TABLE_LOCK_DESTROY(st)  lockuninit(&(st)->st_lock)
+#define IEEE80211_TX_LOCK_DESTROY(ic)          lockuninit(&(ic)->ic_txlock)
+#define IEEE80211_AGEQ_LOCK_DESTROY(aq)                lockuninit(&(aq)->aq_lock)
+#define IEEE80211_PSQ_DESTROY(psq)             lockuninit(&(psq)->psq_lock)
+#define ACL_LOCK_DESTROY(as)                   lockuninit(&(as)->as_lock)
+
+#define IEEE80211_LOCK(ic)                     lockmgr(&(ic)->ic_comlock, LK_EXCLUSIVE)
+#define IEEE80211_NODE_LOCK(nt)                        lockmgr(&(nt)->nt_nodelock, LK_EXCLUSIVE)
+#define IEEE80211_NODE_ITERATE_LOCK(nt)                lockmgr(&(nt)->nt_scanlock, LK_EXCLUSIVE)
+#define IEEE80211_SCAN_TABLE_LOCK(st)          lockmgr(&(st)->st_lock, LK_EXCLUSIVE)
+#define IEEE80211_TX_LOCK(ic)                  lockmgr(&(ic)->ic_txlock, LK_EXCLUSIVE)
+#define IEEE80211_AGEQ_LOCK(aq)                        lockmgr(&(aq)->aq_lock, LK_EXCLUSIVE)
+#define IEEE80211_PSQ_LOCK(psq)                        lockmgr(&(psq)->psq_lock, LK_EXCLUSIVE)
+#define ACL_LOCK(as)                           lockmgr(&(as)->as_lock, LK_EXCLUSIVE)
+
+#define IEEE80211_UNLOCK(ic)                   lockmgr(&(ic)->ic_comlock, LK_RELEASE)
+#define IEEE80211_NODE_UNLOCK(nt)              lockmgr(&(nt)->nt_nodelock, LK_RELEASE)
+#define IEEE80211_NODE_ITERATE_UNLOCK(nt)      lockmgr(&(nt)->nt_scanlock, LK_RELEASE)
+#define IEEE80211_SCAN_TABLE_UNLOCK(nt)                lockmgr(&(st)->st_lock, LK_RELEASE)
+#define IEEE80211_TX_UNLOCK(ic)                        lockmgr(&(ic)->ic_txlock, LK_RELEASE)
+#define IEEE80211_AGEQ_UNLOCK(aq)              lockmgr(&(aq)->aq_lock, LK_RELEASE)
+#define IEEE80211_PSQ_UNLOCK(psq)              lockmgr(&(psq)->psq_lock, LK_RELEASE)
+#define ACL_UNLOCK(as)                         lockmgr(&(as)->as_lock, LK_RELEASE)
+
+#define IEEE80211_LOCK_ASSERT(ic)              \
+                               KKASSERT(lockstatus(&(ic)->ic_comlock, curthread) == LK_EXCLUSIVE)
+#define IEEE80211_NODE_LOCK_ASSERT(nt)         \
+                               KKASSERT(lockstatus(&(nt)->nt_nodelock, curthread) == LK_EXCLUSIVE)
+#define IEEE80211_NODE_ITERATE_LOCK_ASSERT(nt)         \
+                               KKASSERT(lockstatus(&(nt)->nt_scanlock, curthread) == LK_EXCLUSIVE)
+#define IEEE80211_TX_LOCK_ASSERT(ic)           \
+                               KKASSERT(lockstatus(&(ic)->ic_txlock, curthread) == LK_EXCLUSIVE)
+#define IEEE80211_TX_UNLOCK_ASSERT(ic)         \
+                               KKASSERT(lockstatus(&(ic)->ic_txlock, curthread) != LK_EXCLUSIVE)
+#define IEEE80211_AGEQ_LOCK_ASSERT(aq)         \
+                               KKASSERT(lockstatus(&(aq)->aq_lock, curthread) == LK_EXCLUSIVE)
+#define ACL_LOCK_ASSERT(as)            \
+                               KKASSERT(lockstatus(&(as)->as_lock, curthread) == LK_EXCLUSIVE)
+
+#define IEEE80211_NODE_IS_LOCKED(nt)           \
+                               (lockstatus(&(nt)->nt_nodelock, curthread) == LK_EXCLUSIVE)
+
+#define arc4random     karc4random
+
+#define IEEE80211_AGEQ_INIT(aq, name)
+#define IEEE80211_AGEQ_DESTROY(aq)
+#define CURVNET_SET(x)
+#define CURVNET_RESTORE()
+#define ifa_free(ifa)
+
+#define ALIGNED_POINTER(p, t)  (((uintptr_t)(p) & (sizeof(t) - 1)) == 0)
+
+#define osdep_va_list          __va_list
+#define osdep_va_start         __va_start
+#define osdep_va_end           __va_end
+
+/*
+ * DragonFly does not implement _SAFE macros because they are generally not
+ * actually safe in a MP environment, and so it is bad programming practice
+ * to use them.
+ */
+#define TAILQ_FOREACH_SAFE(scan, list, next, save)     \
+       for (scan = TAILQ_FIRST(list); (save = scan ? TAILQ_NEXT(scan, next) : NULL), scan; scan = save)        \
+
+#define callout_init_mtx(callo, lk, flags)             \
+                               callout_init_lk(callo, lk)
+#define callout_schedule_dfly(callo, timo, func, args) \
+                               callout_reset(callo, timo, func, args)
+
 #endif /* _NET80211_IEEE80211_DRAGONFLY_H_ */
index 3d8c66f..e08c4a0 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_hostap.h 178354 2008-04-20 20:35:46Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_HOSTAP_H_
 #define _NET80211_IEEE80211_HOSTAP_H_
  */
 void   ieee80211_hostap_attach(struct ieee80211com *);
 void   ieee80211_hostap_detach(struct ieee80211com *);
+
+/*
+ * This method can be overridden
+ */
+void ieee80211_recv_pspoll(struct ieee80211_node *, struct mbuf *);
+
 #endif /* !_NET80211_IEEE80211_HOSTAP_H_ */
index feb0170..3bda5fe 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_ht.h 195377 2009-07-05 17:59:19Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_HT_H_
 #define _NET80211_IEEE80211_HT_H_
@@ -44,7 +44,7 @@ struct ieee80211_tx_ampdu {
 #define        IEEE80211_AGGR_SETUP            0x0008  /* deferred state setup */
 #define        IEEE80211_AGGR_NAK              0x0010  /* peer NAK'd ADDBA request */
 #define        IEEE80211_AGGR_BARPEND          0x0020  /* BAR response pending */
-       uint8_t         txa_ac;
+       uint8_t         txa_tid;
        uint8_t         txa_token;      /* dialog token */
        int             txa_lastsample; /* ticks @ last traffic sample */
        int             txa_pkts;       /* packets over last sample interval */
@@ -142,7 +142,8 @@ struct ieee80211_rx_ampdu {
        int             rxa_age;        /* age of oldest frame in window */
        int             rxa_nframes;    /* frames since ADDBA */
        struct mbuf *rxa_m[IEEE80211_AGGR_BAWMAX];
-       uint64_t        rxa_pad[4];
+       void            *rxa_private;
+       uint64_t        rxa_pad[3];
 };
 
 void   ieee80211_ht_attach(struct ieee80211com *);
@@ -158,7 +159,7 @@ struct ieee80211_mcs_rates {
        uint16_t        ht40_rate_800ns;
        uint16_t        ht40_rate_400ns;
 };
-extern const struct ieee80211_mcs_rates ieee80211_htrates[16];
+extern const struct ieee80211_mcs_rates ieee80211_htrates[];
 const struct ieee80211_htrateset *ieee80211_get_suphtrates(
                struct ieee80211com *, const struct ieee80211_channel *);
 
@@ -183,7 +184,7 @@ void        ieee80211_htprot_update(struct ieee80211com *, int protmode);
 void   ieee80211_ht_timeout(struct ieee80211com *);
 void   ieee80211_parse_htcap(struct ieee80211_node *, const uint8_t *);
 void   ieee80211_parse_htinfo(struct ieee80211_node *, const uint8_t *);
-void   ieee80211_ht_updateparams(struct ieee80211_node *, const uint8_t *,
+int    ieee80211_ht_updateparams(struct ieee80211_node *, const uint8_t *,
                const uint8_t *);
 void   ieee80211_ht_updatehtcap(struct ieee80211_node *, const uint8_t *);
 int    ieee80211_ampdu_request(struct ieee80211_node *,
index 3a5291b..1e7aab9 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_input.h 195757 2009-07-18 20:19:53Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_INPUT_H_
 #define _NET80211_IEEE80211_INPUT_H_
 #define        IEEE80211_VERIFY_LENGTH(_len, _minlen, _action) do {            \
        if ((_len) < (_minlen)) {                                       \
                IEEE80211_DISCARD(vap, IEEE80211_MSG_ELEMID,            \
-                   wh, NULL, "ie too short, got %jd, expected %jd",    \
-                   (intmax_t)(_len), (intmax_t)(_minlen));             \
+                   wh, NULL, "ie too short, got %d, expected %d",      \
+                   (_len), (_minlen));                                 \
                vap->iv_stats.is_rx_elem_toosmall++;                    \
                _action;                                                \
        }                                                               \
 } while (0)
 
+#ifdef IEEE80211_DEBUG
 void   ieee80211_ssid_mismatch(struct ieee80211vap *, const char *tag,
        uint8_t mac[IEEE80211_ADDR_LEN], uint8_t *ssid);
 
-#ifdef IEEE80211_DEBUG
-
 #define        IEEE80211_VERIFY_SSID(_ni, _ssid, _action) do {                 \
        if ((_ssid)[1] != 0 &&                                          \
            ((_ssid)[1] != (_ni)->ni_esslen ||                          \
@@ -143,6 +142,104 @@ ishtinfooui(const uint8_t *frm)
        return frm[1] > 3 && LE_READ_4(frm+2) == ((BCM_OUI_HTINFO<<24)|BCM_OUI);
 }
 
+#include <sys/endian.h>                /* For le16toh() */
+
+/*
+ * Check the current frame sequence number against the current TID
+ * state and return whether it's in sequence or should be dropped.
+ *
+ * Since out of order packet and duplicate packet eliminations should
+ * be done by the AMPDU RX code, this routine blindly accepts all
+ * frames from a HT station w/ a TID that is currently doing AMPDU-RX.
+ * HT stations without WME or where the TID is not doing AMPDU-RX
+ * are checked like non-HT stations.
+ *
+ * The routine only eliminates packets whose sequence/fragment
+ * match or are less than the last seen sequence/fragment number
+ * AND are retransmits It doesn't try to eliminate out of order packets.
+ *
+ * Since all frames after sequence number 4095 will be less than 4095
+ * (as the seqnum wraps), handle that special case so packets aren't
+ * incorrectly dropped - ie, if the next packet is sequence number 0
+ * but a retransmit since the initial packet didn't make it.
+ */
+static __inline int
+ieee80211_check_rxseq(struct ieee80211_node *ni, struct ieee80211_frame *wh)
+{
+#define        SEQ_LEQ(a,b)    ((int)((a)-(b)) <= 0)
+#define        SEQ_EQ(a,b)     ((int)((a)-(b)) == 0)
+#define        HAS_SEQ(type)   ((type & 0x4) == 0)
+#define        SEQNO(a)        ((a) >> IEEE80211_SEQ_SEQ_SHIFT)
+#define        FRAGNO(a)       ((a) & IEEE80211_SEQ_FRAG_MASK)
+       uint16_t rxseq;
+       uint8_t type;
+       uint8_t tid;
+       struct ieee80211_rx_ampdu *rap;
+
+       rxseq = le16toh(*(uint16_t *)wh->i_seq);
+       type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+
+       /* Types with no sequence number are always treated valid */
+       if (! HAS_SEQ(type))
+               return 1;
+
+       tid = ieee80211_gettid(wh);
+
+       /*
+        * Only do the HT AMPDU check for WME stations; non-WME HT stations
+        * shouldn't exist outside of debugging. We should at least
+        * handle that.
+        */
+       if (tid < WME_NUM_TID) {
+               rap = &ni->ni_rx_ampdu[tid];
+               /* HT nodes currently doing RX AMPDU are always valid */
+               if ((ni->ni_flags & IEEE80211_NODE_HT) &&
+                   (rap->rxa_flags & IEEE80211_AGGR_RUNNING))
+                       return 1;
+       }
+
+       /*
+        * Otherwise, retries for packets below or equal to the last
+        * seen sequence number should be dropped.
+        */
+
+       /*
+        * Treat frame seqnum 4095 as special due to boundary
+        * wrapping conditions.
+        */
+       if (SEQNO(ni->ni_rxseqs[tid]) == 4095) {
+               /*
+                * Drop retransmits on seqnum 4095/current fragment for itself.
+                */
+               if (SEQ_EQ(rxseq, ni->ni_rxseqs[tid]) &&
+                   (wh->i_fc[1] & IEEE80211_FC1_RETRY))
+                       return 0;
+               /*
+                * Treat any subsequent frame as fine if the last seen frame
+                * is 4095 and it's not a retransmit for the same sequence
+                * number. However, this doesn't capture incorrectly ordered
+                * fragments w/ sequence number 4095. It shouldn't be seen
+                * in practice, but see the comment above for further info.
+                */
+               return 1;
+       }
+
+       /*
+        * At this point we assume that retransmitted seq/frag numbers below
+        * the current can simply be eliminated.
+        */
+       if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
+           SEQ_LEQ(rxseq, ni->ni_rxseqs[tid]))
+               return 0;
+
+       return 1;
+#undef SEQ_LEQ
+#undef SEQ_EQ
+#undef HAS_SEQ
+#undef SEQNO
+#undef FRAGNO
+}
+
 void   ieee80211_deliver_data(struct ieee80211vap *,
                struct ieee80211_node *, struct mbuf *);
 struct mbuf *ieee80211_defrag(struct ieee80211_node *,
index f2a9d86..fd645d4 100644 (file)
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_ioctl.h 203556 2010-02-06 19:24:16Z rpaulo $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_IOCTL_H_
 #define _NET80211_IEEE80211_IOCTL_H_
@@ -241,8 +241,12 @@ struct ieee80211_stats {
        uint32_t        is_mesh_notproxy;       /* dropped 'cuz not proxying */
        uint32_t        is_rx_badalign;         /* dropped 'cuz misaligned */
        uint32_t        is_hwmp_proxy;          /* PREP for proxy route */
-       
-       uint32_t        is_spare[11];
+       uint32_t        is_beacon_bad;          /* Number of bad beacons */
+       uint32_t        is_ampdu_bar_tx;        /* A-MPDU BAR frames TXed */
+       uint32_t        is_ampdu_bar_tx_retry;  /* A-MPDU BAR frames TX rtry */
+       uint32_t        is_ampdu_bar_tx_fail;   /* A-MPDU BAR frames TX fail */
+
+       uint32_t        is_spare[7];
 };
 
 /*
@@ -335,8 +339,10 @@ enum {
 
 struct ieee80211req_mesh_route {
        uint8_t         imr_flags;
-#define        IEEE80211_MESHRT_FLAGS_VALID    0x01
-#define        IEEE80211_MESHRT_FLAGS_PROXY    0x02
+#define        IEEE80211_MESHRT_FLAGS_DISCOVER 0x01
+#define        IEEE80211_MESHRT_FLAGS_VALID    0x02
+#define        IEEE80211_MESHRT_FLAGS_PROXY    0x04
+#define        IEEE80211_MESHRT_FLAGS_GATE     0x08
        uint8_t         imr_dest[IEEE80211_ADDR_LEN];
        uint8_t         imr_nexthop[IEEE80211_ADDR_LEN];
        uint16_t        imr_nhops;
@@ -569,16 +575,16 @@ struct ieee80211req_sta_vlan {
        uint16_t        sv_vlan;
 };
 
-#ifdef __DragonFly__
+#if defined(__FreeBSD__) || defined(__DragonFly__)
 /*
- * DragonFlyBSD-style ioctls.
+ * FreeBSD-style ioctls.
  */
 /* the first member must be matched with struct ifreq */
 struct ieee80211req {
        char            i_name[IFNAMSIZ];       /* if_name, e.g. "wi0" */
        uint16_t        i_type;                 /* req type */
        int16_t         i_val;                  /* Index or simple value */
-       int16_t         i_len;                  /* Index or simple value */
+       uint16_t        i_len;                  /* Index or simple value */
        void            *i_data;                /* Extra data */
 };
 #define        SIOCS80211               _IOW('i', 234, struct ieee80211req)
@@ -705,6 +711,7 @@ struct ieee80211req {
 #define        IEEE80211_IOC_MESH_PR_SIG       178     /* mesh sig protocol */
 #define        IEEE80211_IOC_MESH_PR_CC        179     /* mesh congestion protocol */
 #define        IEEE80211_IOC_MESH_PR_AUTH      180     /* mesh auth protocol */
+#define        IEEE80211_IOC_MESH_GATE         181     /* mesh gate XXX: 173? */
 
 #define        IEEE80211_IOC_HWMP_ROOTMODE     190     /* HWMP root mode */
 #define        IEEE80211_IOC_HWMP_MAXHOPS      191     /* number of hops before drop */
@@ -715,6 +722,11 @@ struct ieee80211req {
 #define        IEEE80211_IOC_TDMA_SLOTLEN      203     /* TDMA: slot length (usecs) */
 #define        IEEE80211_IOC_TDMA_BINTERVAL    204     /* TDMA: beacon intvl (slots) */
 
+#define        IEEE80211_IOC_QUIET             205     /* Quiet Enable/Disable */
+#define        IEEE80211_IOC_QUIET_PERIOD      206     /* Quiet Period */
+#define        IEEE80211_IOC_QUIET_OFFSET      207     /* Quiet Offset */
+#define        IEEE80211_IOC_QUIET_DUR         208     /* Quiet Duration */
+#define        IEEE80211_IOC_QUIET_COUNT       209     /* Quiet Count */
 /*
  * Parameters for controlling a scan requested with
  * IEEE80211_IOC_SCAN_REQ.
@@ -844,6 +856,6 @@ struct ieee80211_clone_params {
 #define        IEEE80211_CLONE_WDSLEGACY       0x0004  /* legacy WDS processing */
 #define        IEEE80211_CLONE_MACADDR         0x0008  /* use specified mac addr */
 #define        IEEE80211_CLONE_TDMA            0x0010  /* operate in TDMA mode */
-#endif /* __DragonFly__ */
+#endif /* __FreeBSD__ */
 
 #endif /* _NET80211_IEEE80211_IOCTL_H_ */
index 3ef29bb..992993a 100644 (file)
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  * SUCH DAMAGE. 
  * 
- * $FreeBSD: head/sys/net80211/ieee80211_mesh.h 202178 2010-01-12 22:22:27Z rpaulo $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_MESH_H_
 #define _NET80211_IEEE80211_MESH_H_
 
 #define        IEEE80211_MESH_DEFAULT_TTL      31
+#define        IEEE80211_MESH_MAX_NEIGHBORS    15
 
 /*
  * NB: all structures are __packed  so sizeof works on arm, et. al.
@@ -40,6 +41,7 @@
  * 802.11s Information Elements.
 */
 /* Mesh Configuration */
+#define IEEE80211_MESH_CONF_SZ         (7)
 struct ieee80211_meshconf_ie {
        uint8_t         conf_ie;        /* IEEE80211_ELEMID_MESHCONF */
        uint8_t         conf_len;
@@ -49,31 +51,66 @@ struct ieee80211_meshconf_ie {
        uint8_t         conf_syncid;    /* Sync. Protocol ID */
        uint8_t         conf_authid;    /* Auth. Protocol ID */
        uint8_t         conf_form;      /* Formation Information */
-       uint16_t        conf_cap;
+       uint8_t         conf_cap;
 } __packed;
 
 /* Hybrid Wireless Mesh Protocol */
-#define        IEEE80211_MESHCONF_PATH_HWMP            0x00
+enum {
+       /* 0 reserved */
+       IEEE80211_MESHCONF_PATH_HWMP            = 1,
+       /* 2-254 reserved */
+       IEEE80211_MESHCONF_PATH_VENDOR          = 255,
+};
+
 /* Airtime Link Metric */
-#define        IEEE80211_MESHCONF_METRIC_AIRTIME       0x00
+enum {
+       /* 0 reserved */
+       IEEE80211_MESHCONF_METRIC_AIRTIME       = 1,
+       /* 2-254 reserved */
+       IEEE80211_MESHCONF_METRIC_VENDOR        = 255,
+};
+
 /* Congestion Control */
-#define        IEEE80211_MESHCONF_CC_DISABLED          0x00
-#define        IEEE80211_MESHCONF_CC_SIG               0x01
+enum {
+       IEEE80211_MESHCONF_CC_DISABLED          = 0,
+       IEEE80211_MESHCONF_CC_SIG               = 1,
+       /* 2-254 reserved */
+       IEEE80211_MESHCONF_CC_VENDOR            = 255,
+};
+
 /* Neighbour Offset */
-#define        IEEE80211_MESHCONF_SYNC_NEIGHOFF        0x00
-#define        IEEE80211_MESHCONF_AUTH_DISABLED        0x00
-/* Simultaneous Authenticaction of Equals */
-#define        IEEE80211_MESHCONF_AUTH_SAE             0x01
-#define        IEEE80211_MESHCONF_FORM_MP              0x01 /* Connected to Portal */
-#define        IEEE80211_MESHCONF_FORM_NNEIGH_MASK     0x04 /* Number of Neighbours */
+enum {
+       /* 0 reserved */
+       IEEE80211_MESHCONF_SYNC_NEIGHOFF        = 1,
+       /* 2-254 rserved */
+       IEEE80211_MESHCONF_SYNC_VENDOR          = 255,
+};
+
+/* Authentication Protocol Identifier */
+enum {
+
+       IEEE80211_MESHCONF_AUTH_DISABLED        = 0,
+       /* Simultaneous Authenticaction of Equals */
+       IEEE80211_MESHCONF_AUTH_SEA             = 1,
+       IEEE80211_MESHCONF_AUTH_8021X           = 2, /* IEEE 802.1X */
+       /* 3-254 reserved */
+       IEEE80211_MESHCONF_AUTH_VENDOR          = 255,
+};
+
+/* Mesh Formation Info */
+#define        IEEE80211_MESHCONF_FORM_GATE    0x01    /* Connected to Gate */
+#define        IEEE80211_MESHCONF_FORM_NNEIGH_MASK 0x7E /* Number of Neighbours */
+#define        IEEE80211_MESHCONF_FORM_SA      0xF0    /* indicating 802.1X auth */
+
+/* Mesh Capability */
 #define        IEEE80211_MESHCONF_CAP_AP       0x01    /* Accepting Peers */
 #define        IEEE80211_MESHCONF_CAP_MCCAS    0x02    /* MCCA supported */
 #define        IEEE80211_MESHCONF_CAP_MCCAE    0x04    /* MCCA enabled */
 #define        IEEE80211_MESHCONF_CAP_FWRD     0x08    /* forwarding enabled */
 #define        IEEE80211_MESHCONF_CAP_BTR      0x10    /* Beacon Timing Report Enab */
-#define        IEEE80211_MESHCONF_CAP_TBTTA    0x20    /* TBTT Adj. Enabled */
-#define        IEEE80211_MESHCONF_CAP_TBTT     0x40    /* TBTT Adjusting  */
-#define        IEEE80211_MESHCONF_CAP_PSL      0x80    /* Power Save Level */
+#define        IEEE80211_MESHCONF_CAP_TBTT     0x20    /* TBTT Adjusting  */
+#define        IEEE80211_MESHCONF_CAP_PSL      0x40    /* Power Save Level */
+/* 0x80 reserved */
 
 /* Mesh Identifier */
 struct ieee80211_meshid_ie {
@@ -83,8 +120,14 @@ struct ieee80211_meshid_ie {
 
 /* Link Metric Report */
 struct ieee80211_meshlmetric_ie {
-       uint8_t         lm_ie;  /* IEEE80211_ELEMID_MESHLINK */
+       uint8_t         lm_ie;  /* IEEE80211_ACTION_MESH_LMETRIC */
        uint8_t         lm_len;
+       uint8_t         lm_flags;
+#define        IEEE80211_MESH_LMETRIC_FLAGS_REQ        0x01    /* Request */
+       /*
+        * XXX: this field should be variable in size and depend on
+        * the active active path selection metric identifier
+        */
        uint32_t        lm_metric;
 #define        IEEE80211_MESHLMETRIC_INITIALVAL        0
 } __packed;
@@ -98,32 +141,24 @@ struct ieee80211_meshcngst_ie {
 } __packed;
 
 /* Peer Link Management */
+#define IEEE80211_MPM_BASE_SZ  (4)
+#define IEEE80211_MPM_MAX_SZ   (8)
 struct ieee80211_meshpeer_ie {
        uint8_t         peer_ie;        /* IEEE80211_ELEMID_MESHPEER */
        uint8_t         peer_len;
-       uint8_t         peer_proto[4];  /* Peer Management Protocol */
+       uint16_t        peer_proto;     /* Peer Management Protocol */
        uint16_t        peer_llinkid;   /* Local Link ID */
        uint16_t        peer_linkid;    /* Peer Link ID */
        uint16_t        peer_rcode;
 } __packed;
 
+/* Mesh Peering Protocol Identifier field value */
 enum {
-       IEEE80211_MESH_PEER_LINK_OPEN           = 0,
-       IEEE80211_MESH_PEER_LINK_CONFIRM        = 1,
-       IEEE80211_MESH_PEER_LINK_CLOSE          = 2,
-       /* values 3-255 are reserved */
+       IEEE80211_MPPID_MPM             = 0,    /* Mesh peering management */
+       IEEE80211_MPPID_AUTH_MPM        = 1,    /* Auth. mesh peering exchange */
+       /* 2-65535 reserved */
 };
 
-/* Mesh Peering Management Protocol */
-#define        IEEE80211_MESH_PEER_PROTO_OUI           0x00, 0x0f, 0xac
-#define        IEEE80211_MESH_PEER_PROTO_VALUE         0x2a
-#define        IEEE80211_MESH_PEER_PROTO       { IEEE80211_MESH_PEER_PROTO_OUI, \
-                                         IEEE80211_MESH_PEER_PROTO_VALUE }
-/* Abbreviated Handshake Protocol */
-#define        IEEE80211_MESH_PEER_PROTO_AH_OUI        0x00, 0x0f, 0xac
-#define        IEEE80211_MESH_PEER_PROTO_AH_VALUE      0x2b
-#define        IEEE80211_MESH_PEER_PROTO_AH    { IEEE80211_MESH_PEER_PROTO_AH_OUI, \
-                                         IEEE80211_MESH_PEER_PROTO_AH_VALUE }
 #ifdef notyet
 /* Mesh Channel Switch Annoucement */
 struct ieee80211_meshcsa_ie {
@@ -158,37 +193,50 @@ struct ieee80211_meshbeacont_ie {
 } __packed;
 #endif
 
-/* Portal (MP) Annoucement */
-struct ieee80211_meshpann_ie {
-       uint8_t         pann_ie;                /* IEEE80211_ELEMID_MESHPANN */
-       uint8_t         pann_len;
-       uint8_t         pann_flags;
-       uint8_t         pann_hopcount;
-       uint8_t         pann_ttl;
-       uint8_t         pann_addr[IEEE80211_ADDR_LEN];
-       uint8_t         pann_seq;               /* PANN Sequence Number */
+/* Gate (GANN) Annoucement */
+/*
+ * NB: these macros used for the length in the IEs does not include 2 bytes
+ * for _ie and _len fields as is defined by the standard.
+ */
+#define        IEEE80211_MESHGANN_BASE_SZ      (15)
+struct ieee80211_meshgann_ie {
+       uint8_t         gann_ie;                /* IEEE80211_ELEMID_MESHGANN */
+       uint8_t         gann_len;
+       uint8_t         gann_flags;
+       uint8_t         gann_hopcount;
+       uint8_t         gann_ttl;
+       uint8_t         gann_addr[IEEE80211_ADDR_LEN];
+       uint32_t        gann_seq;               /* GANN Sequence Number */
+       uint16_t        gann_interval;          /* GANN Interval */
 } __packed;
 
 /* Root (MP) Annoucement */
+#define        IEEE80211_MESHRANN_BASE_SZ      (21)
 struct ieee80211_meshrann_ie {
        uint8_t         rann_ie;                /* IEEE80211_ELEMID_MESHRANN */
        uint8_t         rann_len;
        uint8_t         rann_flags;
-#define        IEEE80211_MESHRANN_FLAGS_PR     0x01    /* Portal Role */
+#define        IEEE80211_MESHRANN_FLAGS_GATE   0x01    /* Mesh Gate */
        uint8_t         rann_hopcount;
        uint8_t         rann_ttl;
        uint8_t         rann_addr[IEEE80211_ADDR_LEN];
        uint32_t        rann_seq;               /* HWMP Sequence Number */
+       uint32_t        rann_interval;
        uint32_t        rann_metric;
 } __packed;
 
 /* Mesh Path Request */
+#define        IEEE80211_MESHPREQ_BASE_SZ              (26)
+#define        IEEE80211_MESHPREQ_BASE_SZ_AE           (32)
+#define        IEEE80211_MESHPREQ_TRGT_SZ              (11)
+#define        IEEE80211_MESHPREQ_TCNT_OFFSET          (27)
+#define        IEEE80211_MESHPREQ_TCNT_OFFSET_AE       (33)
 struct ieee80211_meshpreq_ie {
        uint8_t         preq_ie;        /* IEEE80211_ELEMID_MESHPREQ */
        uint8_t         preq_len;
        uint8_t         preq_flags;
-#define        IEEE80211_MESHPREQ_FLAGS_PR     0x01    /* Portal Role */
-#define        IEEE80211_MESHPREQ_FLAGS_AM     0x02    /* 0 = ucast / 1 = bcast */
+#define        IEEE80211_MESHPREQ_FLAGS_GATE   0x01    /* Mesh Gate */
+#define        IEEE80211_MESHPREQ_FLAGS_AM     0x02    /* 0 = bcast / 1 = ucast */
 #define        IEEE80211_MESHPREQ_FLAGS_PP     0x04    /* Proactive PREP */
 #define        IEEE80211_MESHPREQ_FLAGS_AE     0x40    /* Address Extension */
        uint8_t         preq_hopcount;
@@ -196,14 +244,14 @@ struct ieee80211_meshpreq_ie {
        uint32_t        preq_id;
        uint8_t         preq_origaddr[IEEE80211_ADDR_LEN];
        uint32_t        preq_origseq;   /* HWMP Sequence Number */
-       /* NB: may have Originator Proxied Address */
+       /* NB: may have Originator External Address */
+       uint8_t         preq_orig_ext_addr[IEEE80211_ADDR_LEN];
        uint32_t        preq_lifetime;
        uint32_t        preq_metric;
        uint8_t         preq_tcount;    /* target count */
        struct {
                uint8_t         target_flags;
 #define        IEEE80211_MESHPREQ_TFLAGS_TO    0x01    /* Target Only */
-#define        IEEE80211_MESHPREQ_TFLAGS_RF    0x02    /* Reply and Forward */
 #define        IEEE80211_MESHPREQ_TFLAGS_USN   0x04    /* Unknown HWMP seq number */
                uint8_t         target_addr[IEEE80211_ADDR_LEN];
                uint32_t        target_seq;     /* HWMP Sequence Number */
@@ -211,15 +259,19 @@ struct ieee80211_meshpreq_ie {
 } __packed;
 
 /* Mesh Path Reply */
+#define        IEEE80211_MESHPREP_BASE_SZ      (31)
+#define        IEEE80211_MESHPREP_BASE_SZ_AE   (37)
 struct ieee80211_meshprep_ie {
        uint8_t         prep_ie;        /* IEEE80211_ELEMID_MESHPREP */
        uint8_t         prep_len;
        uint8_t         prep_flags;
+#define        IEEE80211_MESHPREP_FLAGS_AE     0x40    /* Address Extension */
        uint8_t         prep_hopcount;
        uint8_t         prep_ttl;
        uint8_t         prep_targetaddr[IEEE80211_ADDR_LEN];
        uint32_t        prep_targetseq;
-       /* NB: May have Target Proxied Address */
+       /* NB: May have Target External Address */
+       uint8_t         prep_target_ext_addr[IEEE80211_ADDR_LEN];
        uint32_t        prep_lifetime;
        uint32_t        prep_metric;
        uint8_t         prep_origaddr[IEEE80211_ADDR_LEN];
@@ -227,6 +279,11 @@ struct ieee80211_meshprep_ie {
 } __packed;
 
 /* Mesh Path Error */
+#define        IEEE80211_MESHPERR_MAXDEST      (19)
+#define        IEEE80211_MESHPERR_NDEST_OFFSET (3)
+#define        IEEE80211_MESHPERR_BASE_SZ      (2)
+#define        IEEE80211_MESHPERR_DEST_SZ      (13)
+#define        IEEE80211_MESHPERR_DEST_SZ_AE   (19)
 struct ieee80211_meshperr_ie {
        uint8_t         perr_ie;        /* IEEE80211_ELEMID_MESHPERR */
        uint8_t         perr_len;
@@ -234,10 +291,13 @@ struct ieee80211_meshperr_ie {
        uint8_t         perr_ndests;    /* Number of Destinations */
        struct {
                uint8_t         dest_flags;
-#define        IEEE80211_MESHPERR_DFLAGS_USN   0x01
-#define        IEEE80211_MESHPERR_DFLAGS_RC    0x02
+#define        IEEE80211_MESHPERR_DFLAGS_USN   0x01    /* XXX: not part of standard */
+#define        IEEE80211_MESHPERR_DFLAGS_RC    0x02    /* XXX: not part of standard */
+#define        IEEE80211_MESHPERR_FLAGS_AE     0x40    /* Address Extension */
                uint8_t         dest_addr[IEEE80211_ADDR_LEN];
                uint32_t        dest_seq;       /* HWMP Sequence Number */
+               /* NB: May have Destination External Address */
+               uint8_t         dest_ext_addr[IEEE80211_ADDR_LEN];
                uint16_t        dest_rcode;
        } __packed perr_dests[1];               /* NB: variable size */
 } __packed;
@@ -269,10 +329,9 @@ struct ieee80211_meshpuc_ie {
 
 /*
  * 802.11s Action Frames
+ * XXX: these are wrong, and some of them should be
+ * under MESH category while PROXY is under MULTIHOP category.
  */
-#define        IEEE80211_ACTION_CAT_MESHPEERING        30      /* XXX Linux */
-#define        IEEE80211_ACTION_CAT_MESHLMETRIC        13
-#define        IEEE80211_ACTION_CAT_MESHPATH           32      /* XXX Linux */
 #define        IEEE80211_ACTION_CAT_INTERWORK          15
 #define        IEEE80211_ACTION_CAT_RESOURCE           16
 #define        IEEE80211_ACTION_CAT_PROXY              17
@@ -281,35 +340,29 @@ struct ieee80211_meshpuc_ie {
  * Mesh Peering Action codes.
  */
 enum {
-       IEEE80211_ACTION_MESHPEERING_OPEN       = 0,
-       IEEE80211_ACTION_MESHPEERING_CONFIRM    = 1,
-       IEEE80211_ACTION_MESHPEERING_CLOSE      = 2,
-       /* 3-255 reserved */
-};
-
-/*
- * Mesh Path Selection Action code.
- */
-enum {
-       IEEE80211_ACTION_MESHPATH_SEL   = 0,
-       /* 1-255 reserved */
-};
-
-/*
- * Mesh Link Metric Action codes.
- */
-enum {
-       IEEE80211_ACTION_MESHLMETRIC_REQ = 0,   /* Link Metric Request */
-       IEEE80211_ACTION_MESHLMETRIC_REP = 1,   /* Link Metric Report */
-       /* 2-255 reserved */
+       /* 0 reserved */
+       IEEE80211_ACTION_MESHPEERING_OPEN       = 1,
+       IEEE80211_ACTION_MESHPEERING_CONFIRM    = 2,
+       IEEE80211_ACTION_MESHPEERING_CLOSE      = 3,
+       /* 4-255 reserved */
 };
 
 /*
- * Mesh Portal Annoucement Action codes.
+ * Mesh Action code.
  */
 enum {
-       IEEE80211_ACTION_MESHPANN       = 0,
-       /* 1-255 reserved */
+       IEEE80211_ACTION_MESH_LMETRIC   = 0,    /* Mesh Link Metric Report */
+       IEEE80211_ACTION_MESH_HWMP      = 1,    /* HWMP Mesh Path Selection */
+       IEEE80211_ACTION_MESH_GANN      = 2,    /* Gate Announcement */
+       IEEE80211_ACTION_MESH_CC        = 3,    /* Congestion Control */
+       IEEE80211_ACTION_MESH_MCCA_SREQ = 4,    /* MCCA Setup Request */
+       IEEE80211_ACTION_MESH_MCCA_SREP = 5,    /* MCCA Setup Reply */
+       IEEE80211_ACTION_MESH_MCCA_AREQ = 6,    /* MCCA Advertisement Req. */
+       IEEE80211_ACTION_MESH_MCCA_ADVER =7,    /* MCCA Advertisement */
+       IEEE80211_ACTION_MESH_MCCA_TRDOWN = 8,  /* MCCA Teardown */
+       IEEE80211_ACTION_MESH_TBTT_REQ  = 9,    /* TBTT Adjustment Request */
+       IEEE80211_ACTION_MESH_TBTT_RES  = 10,   /* TBTT Adjustment Response */
+       /* 11-255 reserved */
 };
 
 /*
@@ -334,37 +387,71 @@ struct ieee80211_meshcntl_ae10 {
        uint8_t         mc_flags;       /* Address Extension 10 */
        uint8_t         mc_ttl;         /* TTL */
        uint8_t         mc_seq[4];      /* Sequence No. */
-       uint8_t         mc_addr4[IEEE80211_ADDR_LEN];
-       uint8_t         mc_addr5[IEEE80211_ADDR_LEN];
-} __packed;
-
-struct ieee80211_meshcntl_ae11 {
-       uint8_t         mc_flags;       /* Address Extension 11 */
-       uint8_t         mc_ttl;         /* TTL */
-       uint8_t         mc_seq[4];      /* Sequence No. */
-       uint8_t         mc_addr4[IEEE80211_ADDR_LEN];
        uint8_t         mc_addr5[IEEE80211_ADDR_LEN];
        uint8_t         mc_addr6[IEEE80211_ADDR_LEN];
 } __packed;
 
+#define IEEE80211_MESH_AE_MASK         0x03
+enum {
+       IEEE80211_MESH_AE_00            = 0,    /* MC has no AE subfield */
+       IEEE80211_MESH_AE_01            = 1,    /* MC contain addr4 */
+       IEEE80211_MESH_AE_10            = 2,    /* MC contain addr5 & addr6 */
+       IEEE80211_MESH_AE_11            = 3,    /* RESERVED */
+};
+
 #ifdef _KERNEL
+MALLOC_DECLARE(M_80211_MESH_PREQ);
+MALLOC_DECLARE(M_80211_MESH_PREP);
+MALLOC_DECLARE(M_80211_MESH_PERR);
+
 MALLOC_DECLARE(M_80211_MESH_RT);
+MALLOC_DECLARE(M_80211_MESH_GT_RT);
+/*
+ * Basic forwarding information:
+ * o Destination MAC
+ * o Next-hop MAC
+ * o Precursor list (not implemented yet)
+ * o Path timeout
+ * The rest is part of the active Mesh path selection protocol.
+ * XXX: to be moved out later.
+ */
 struct ieee80211_mesh_route {
        TAILQ_ENTRY(ieee80211_mesh_route)       rt_next;
-       int                     rt_crtime;      /* creation time */
+       struct ieee80211vap     *rt_vap;
+#if defined(__DragonFly__)
+       struct lock             rt_lock;        /* fine grained route lock */
+#else
+       struct mtx              rt_lock;        /* fine grained route lock */
+#endif
+       struct callout          rt_discovery;   /* discovery timeout */
+       int                     rt_updtime;     /* last update time */
        uint8_t                 rt_dest[IEEE80211_ADDR_LEN];
+       uint8_t                 rt_mesh_gate[IEEE80211_ADDR_LEN]; /* meshDA */
        uint8_t                 rt_nexthop[IEEE80211_ADDR_LEN];
        uint32_t                rt_metric;      /* path metric */
        uint16_t                rt_nhops;       /* number of hops */
        uint16_t                rt_flags;
-#define        IEEE80211_MESHRT_FLAGS_VALID    0x01    /* patch discovery complete */
-#define        IEEE80211_MESHRT_FLAGS_PROXY    0x02    /* proxy entry */
-       uint32_t                rt_lifetime;
+#define        IEEE80211_MESHRT_FLAGS_DISCOVER 0x01    /* path discovery */
+#define        IEEE80211_MESHRT_FLAGS_VALID    0x02    /* path discovery complete */
+#define        IEEE80211_MESHRT_FLAGS_PROXY    0x04    /* proxy entry */
+#define        IEEE80211_MESHRT_FLAGS_GATE     0x08    /* mesh gate entry */
+       uint32_t                rt_lifetime;    /* route timeout */
        uint32_t                rt_lastmseq;    /* last seq# seen dest */
+       uint32_t                rt_ext_seq;     /* proxy seq number */
        void                    *rt_priv;       /* private data */
 };
 #define        IEEE80211_MESH_ROUTE_PRIV(rt, cast)     ((cast *)rt->rt_priv)
 
+/*
+ * Stored information about known mesh gates.
+ */
+struct ieee80211_mesh_gate_route {
+       TAILQ_ENTRY(ieee80211_mesh_gate_route)  gr_next;
+       uint8_t                         gr_addr[IEEE80211_ADDR_LEN];
+       uint32_t                        gr_lastseq;
+       struct ieee80211_mesh_route     *gr_route;
+};
+
 #define        IEEE80211_MESH_PROTO_DSZ        12      /* description size */
 /*
  * Mesh Path Selection Protocol.
@@ -379,6 +466,9 @@ struct ieee80211_mesh_proto_path {
                                const uint8_t [IEEE80211_ADDR_LEN],
                                struct mbuf *);
        void            (*mpp_peerdown)(struct ieee80211_node *);
+       void            (*mpp_senderror)(struct ieee80211vap *,
+                               const uint8_t [IEEE80211_ADDR_LEN],
+                               struct ieee80211_mesh_route *, int);
        void            (*mpp_vattach)(struct ieee80211vap *);
        void            (*mpp_vdetach)(struct ieee80211vap *);
        int             (*mpp_newstate)(struct ieee80211vap *,
@@ -425,10 +515,19 @@ struct ieee80211_mesh_state {
        uint16_t                        ms_neighbors;
        uint8_t                         ms_ttl; /* mesh ttl set in packets */
 #define IEEE80211_MESHFLAGS_AP         0x01    /* accept peers */
-#define IEEE80211_MESHFLAGS_PORTAL     0x02    /* mesh portal role */
+#define IEEE80211_MESHFLAGS_GATE       0x02    /* mesh gate role */
 #define IEEE80211_MESHFLAGS_FWD                0x04    /* forward packets */
+#define IEEE80211_MESHFLAGS_ROOT       0x08    /* configured as root */
        uint8_t                         ms_flags;
+#if defined(__DragonFly__)
+       struct lock                     ms_rt_lock;
+#else
+       struct mtx                      ms_rt_lock;
+#endif
        struct callout                  ms_cleantimer;
+       struct callout                  ms_gatetimer;
+       ieee80211_mesh_seq              ms_gateseq;
+       TAILQ_HEAD(, ieee80211_mesh_gate_route) ms_known_gates;
        TAILQ_HEAD(, ieee80211_mesh_route)  ms_routes;
        struct ieee80211_mesh_proto_metric *ms_pmetric;
        struct ieee80211_mesh_proto_path   *ms_ppath;
@@ -447,6 +546,7 @@ void                ieee80211_mesh_rt_del(struct ieee80211vap *,
 void           ieee80211_mesh_rt_flush(struct ieee80211vap *);
 void           ieee80211_mesh_rt_flush_peer(struct ieee80211vap *,
                    const uint8_t [IEEE80211_ADDR_LEN]);
+int            ieee80211_mesh_rt_update(struct ieee80211_mesh_route *rt, int);
 void           ieee80211_mesh_proxy_check(struct ieee80211vap *,
                    const uint8_t [IEEE80211_ADDR_LEN]);
 
@@ -459,7 +559,9 @@ uint8_t *   ieee80211_add_meshid(uint8_t *, struct ieee80211vap *);
 uint8_t *      ieee80211_add_meshconf(uint8_t *, struct ieee80211vap *);
 uint8_t *      ieee80211_add_meshpeer(uint8_t *, uint8_t, uint16_t, uint16_t,
                    uint16_t);
-uint8_t *      ieee80211_add_meshlmetric(uint8_t *, uint32_t);
+uint8_t *      ieee80211_add_meshlmetric(uint8_t *, uint8_t, uint32_t);
+uint8_t *      ieee80211_add_meshgate(uint8_t *,
+                   struct ieee80211_meshgann_ie *);
 
 void           ieee80211_mesh_node_init(struct ieee80211vap *,
                    struct ieee80211_node *);
@@ -472,6 +574,14 @@ void               ieee80211_mesh_init_neighbor(struct ieee80211_node *,
                   const struct ieee80211_scanparams *);
 void           ieee80211_mesh_update_beacon(struct ieee80211vap *,
                    struct ieee80211_beacon_offsets *);
+struct ieee80211_mesh_gate_route *
+               ieee80211_mesh_mark_gate(struct ieee80211vap *,
+                   const uint8_t *, struct ieee80211_mesh_route *);
+void           ieee80211_mesh_forward_to_gates(struct ieee80211vap *,
+                   struct ieee80211_mesh_route *);
+struct ieee80211_node *
+               ieee80211_mesh_find_txnode(struct ieee80211vap *,
+                   const uint8_t [IEEE80211_ADDR_LEN]);
 
 /*
  * Return non-zero if proxy operation is enabled.
@@ -481,7 +591,7 @@ ieee80211_mesh_isproxyena(struct ieee80211vap *vap)
 {
        struct ieee80211_mesh_state *ms = vap->iv_mesh;
        return (ms->ms_flags &
-           (IEEE80211_MESHFLAGS_AP | IEEE80211_MESHFLAGS_PORTAL)) != 0;
+           (IEEE80211_MESHFLAGS_AP | IEEE80211_MESHFLAGS_GATE)) != 0;
 }
 
 /*
index 76e3035..d7dd8e9 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_monitor.h 178354 2008-04-20 20:35:46Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_MONITOR_H_
 #define _NET80211_IEEE80211_MONITOR_H_
index 4479f32..13eb22f 100644 (file)
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_node.h 206358 2010-04-07 15:29:13Z rpaulo $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_NODE_H_
 #define _NET80211_IEEE80211_NODE_H_
@@ -151,7 +151,7 @@ struct ieee80211_node {
 #define IEEE80211_NODE_BOOST   0x0080          /* Dynamic Turbo boosted */
        uint16_t                ni_ath_defkeyix;/* Atheros def key index */
        const struct ieee80211_txparam *ni_txparms;
-       time_t                  ni_jointime;    /* time of join (time_uptime) */
+       uint32_t                ni_jointime;    /* time of join (secs) */
        uint32_t                *ni_challenge;  /* shared-key challenge */
        struct ieee80211_ies    ni_ies;         /* captured ie's */
                                                /* tx seq per-tid */
@@ -166,6 +166,13 @@ struct ieee80211_node {
        uint32_t                ni_avgrssi;     /* recv ssi state */
        int8_t                  ni_noise;       /* noise floor */
 
+       /* mimo statistics */
+       uint32_t                ni_mimo_rssi_ctl[IEEE80211_MAX_CHAINS];
+       uint32_t                ni_mimo_rssi_ext[IEEE80211_MAX_CHAINS];
+       uint8_t                 ni_mimo_noise_ctl[IEEE80211_MAX_CHAINS];
+       uint8_t                 ni_mimo_noise_ext[IEEE80211_MAX_CHAINS];
+       uint8_t                 ni_mimo_chains;
+
        /* header */
        uint8_t                 ni_macaddr[IEEE80211_ADDR_LEN];
        uint8_t                 ni_bssid[IEEE80211_ADDR_LEN];
@@ -197,6 +204,8 @@ struct ieee80211_node {
        struct callout          ni_mltimer;     /* link mesh timer */
        uint8_t                 ni_mlrcnt;      /* link mesh retry counter */
        uint8_t                 ni_mltval;      /* link mesh timer value */
+       struct callout          ni_mlhtimer;    /* link mesh backoff timer */
+       uint8_t                 ni_mlhcnt;      /* link mesh holding counter */
 
        /* 11n state */
        uint16_t                ni_htcap;       /* HT capabilities */
@@ -207,7 +216,7 @@ struct ieee80211_node {
        uint8_t                 ni_htstbc;      /* HT */
        uint8_t                 ni_chw;         /* negotiated channel width */
        struct ieee80211_htrateset ni_htrates;  /* negotiated ht rate set */
-       struct ieee80211_tx_ampdu ni_tx_ampdu[WME_NUM_AC];
+       struct ieee80211_tx_ampdu ni_tx_ampdu[WME_NUM_TID];
        struct ieee80211_rx_ampdu ni_rx_ampdu[WME_NUM_TID];
 
        /* others */
@@ -292,8 +301,6 @@ ieee80211_unref_node(struct ieee80211_node **ni)
        *ni = NULL;                     /* guard against use */
 }
 
-struct ieee80211com;
-
 void   ieee80211_node_attach(struct ieee80211com *);
 void   ieee80211_node_lateattach(struct ieee80211com *);
 void   ieee80211_node_detach(struct ieee80211com *);
@@ -319,6 +326,7 @@ void        ieee80211_sync_curchan(struct ieee80211com *);
 void   ieee80211_setupcurchan(struct ieee80211com *,
            struct ieee80211_channel *);
 void   ieee80211_setcurchan(struct ieee80211com *, struct ieee80211_channel *);
+void   ieee80211_update_chw(struct ieee80211com *);
 int    ieee80211_ibss_merge(struct ieee80211_node *);
 struct ieee80211_scan_entry;
 int    ieee80211_sta_join(struct ieee80211vap *, struct ieee80211_channel *,
@@ -342,11 +350,13 @@ void      ieee80211_ies_expand(struct ieee80211_ies *);
  */
 struct ieee80211_node_table {
        struct ieee80211com     *nt_ic;         /* back reference */
+       ieee80211_node_lock_t   nt_nodelock;    /* on node table */
        TAILQ_HEAD(, ieee80211_node) nt_node;   /* information of all nodes */
        LIST_HEAD(, ieee80211_node) nt_hash[IEEE80211_NODE_HASHSIZE];
        struct ieee80211_node   **nt_keyixmap;  /* key ix -> node map */
        int                     nt_keyixmax;    /* keyixmap size */
        const char              *nt_name;       /* table name for debug msgs */
+       ieee80211_scan_lock_t   nt_scanlock;    /* on nt_scangen */
        u_int                   nt_scangen;     /* gen# for iterators */
        int                     nt_inact_init;  /* initial node inact setting */
 };
@@ -427,8 +437,11 @@ struct ieee80211_node *ieee80211_find_txnode(struct ieee80211vap *,
                const uint8_t macaddr[IEEE80211_ADDR_LEN]);
 #endif
 int    ieee80211_node_delucastkey(struct ieee80211_node *);
+void   ieee80211_node_timeout(void *arg);
 
 typedef void ieee80211_iter_func(void *, struct ieee80211_node *);
+int    ieee80211_iterate_nt(struct ieee80211_node_table *,
+               struct ieee80211_node **, uint16_t);
 void   ieee80211_iterate_nodes(struct ieee80211_node_table *,
                ieee80211_iter_func *, void *);
 
index f89d824..bf39cdd 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_phy.h 193072 2009-05-29 23:39:16Z sam $
+ * $FreeBSD$
  */
 
 #ifndef _NET80211_IEEE80211_PHY_H_
@@ -60,6 +60,8 @@
 
 struct ieee80211_channel;
 
+#define        IEEE80211_RATE_TABLE_SIZE       128
+
 struct ieee80211_rate_table {
        int             rateCount;              /* NB: for proper padding */
        uint8_t         rateCodeToIndex[256];   /* back mapping */
@@ -74,7 +76,7 @@ struct ieee80211_rate_table {
                                                 * rate; used for dur. calcs */
                uint16_t        lpAckDuration;  /* long preamble ACK dur. */
                uint16_t        spAckDuration;  /* short preamble ACK dur. */
-       } info[32];
+       } info[IEEE80211_RATE_TABLE_SIZE];
 };
 
 const struct ieee80211_rate_table *ieee80211_get_ratetable(
@@ -83,7 +85,14 @@ const struct ieee80211_rate_table *ieee80211_get_ratetable(
 static __inline__ uint8_t
 ieee80211_ack_rate(const struct ieee80211_rate_table *rt, uint8_t rate)
 {
-       uint8_t cix = rt->info[rt->rateCodeToIndex[rate]].ctlRateIndex;
+       /*
+        * XXX Assert this is for a legacy rate; not for an MCS rate.
+        * If the caller wishes to use it for a basic rate, they should
+        * clear the high bit first.
+        */
+       KASSERT(! (rate & 0x80), ("rate %d is basic/mcs?", rate));
+
+       uint8_t cix = rt->info[rt->rateCodeToIndex[rate & IEEE80211_RATE_VAL]].ctlRateIndex;
        KASSERT(cix != (uint8_t)-1, ("rate %d has no info", rate));
        return rt->info[cix].dot11Rate;
 }
@@ -91,7 +100,14 @@ ieee80211_ack_rate(const struct ieee80211_rate_table *rt, uint8_t rate)
 static __inline__ uint8_t
 ieee80211_ctl_rate(const struct ieee80211_rate_table *rt, uint8_t rate)
 {
-       uint8_t cix = rt->info[rt->rateCodeToIndex[rate]].ctlRateIndex;
+       /*
+        * XXX Assert this is for a legacy rate; not for an MCS rate.
+        * If the caller wishes to use it for a basic rate, they should
+        * clear the high bit first.
+        */
+       KASSERT(! (rate & 0x80), ("rate %d is basic/mcs?", rate));
+
+       uint8_t cix = rt->info[rt->rateCodeToIndex[rate & IEEE80211_RATE_VAL]].ctlRateIndex;
        KASSERT(cix != (uint8_t)-1, ("rate %d has no info", rate));
        return rt->info[cix].dot11Rate;
 }
@@ -99,7 +115,14 @@ ieee80211_ctl_rate(const struct ieee80211_rate_table *rt, uint8_t rate)
 static __inline__ enum ieee80211_phytype
 ieee80211_rate2phytype(const struct ieee80211_rate_table *rt, uint8_t rate)
 {
-       uint8_t rix = rt->rateCodeToIndex[rate];
+       /*
+        * XXX Assert this is for a legacy rate; not for an MCS rate.
+        * If the caller wishes to use it for a basic rate, they should
+        * clear the high bit first.
+        */
+       KASSERT(! (rate & 0x80), ("rate %d is basic/mcs?", rate));
+
+       uint8_t rix = rt->rateCodeToIndex[rate & IEEE80211_RATE_VAL];
        KASSERT(rix != (uint8_t)-1, ("rate %d has no info", rate));
        return rt->info[rix].phy;
 }
@@ -107,6 +130,13 @@ ieee80211_rate2phytype(const struct ieee80211_rate_table *rt, uint8_t rate)
 static __inline__ int
 ieee80211_isratevalid(const struct ieee80211_rate_table *rt, uint8_t rate)
 {
+       /*
+        * XXX Assert this is for a legacy rate; not for an MCS rate.
+        * If the caller wishes to use it for a basic rate, they should
+        * clear the high bit first.
+        */
+       KASSERT(! (rate & 0x80), ("rate %d is basic/mcs?", rate));
+
        return rt->rateCodeToIndex[rate] != (uint8_t)-1;
 }
 
@@ -125,19 +155,20 @@ ieee80211_ack_duration(const struct ieee80211_rate_table *rt,
        KASSERT(rix != (uint8_t)-1, ("rate %d has no info", rate));
        if (isShortPreamble) {
                KASSERT(rt->info[rix].spAckDuration != 0,
-                       ("shpreamble ack dur is not computed!"));
+                       ("shpreamble ack dur is not computed!\n"));
                return rt->info[rix].spAckDuration;
        } else {
                KASSERT(rt->info[rix].lpAckDuration != 0,
-                       ("lgpreamble ack dur is not computed!"));
+                       ("lgpreamble ack dur is not computed!\n"));
                return rt->info[rix].lpAckDuration;
        }
 }
 
 static __inline__ uint8_t
 ieee80211_legacy_rate_lookup(const struct ieee80211_rate_table *rt,
-                            uint8_t rate)
+    uint8_t rate)
 {
+
        return (rt->rateCodeToIndex[rate & IEEE80211_RATE_VAL]);
 }
 
@@ -158,5 +189,10 @@ uint8_t            ieee80211_plcp2rate(uint8_t, enum ieee80211_phytype);
  * Convert 802.11 rate code to PLCP signal.
  */
 uint8_t                ieee80211_rate2plcp(int, enum ieee80211_phytype);
+
+uint32_t       ieee80211_compute_duration_ht(uint32_t frameLen,
+                       uint16_t rate, int streams, int isht40,
+                       int isShortGI);
+
 #endif /* _KERNEL */
 #endif /* !_NET80211_IEEE80211_PHY_H_ */
index c23cf24..d9bbaa5 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_power.h 184288 2008-10-26 01:04:46Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_POWER_H_
 #define _NET80211_IEEE80211_POWER_H_
@@ -48,6 +48,7 @@ struct mbuf;
  * frames are required to handle them when they come back.
  */
 struct ieee80211_psq {
+       ieee80211_psq_lock_t psq_lock;
        int     psq_len;
        int     psq_maxlen;
        int     psq_drops;
@@ -70,6 +71,11 @@ void ieee80211_power_latevattach(struct ieee80211vap *);
 struct mbuf *ieee80211_node_psq_dequeue(struct ieee80211_node *ni, int *qlen);
 int    ieee80211_node_psq_drain(struct ieee80211_node *);
 int    ieee80211_node_psq_age(struct ieee80211_node *);
+
+/*
+ * Don't call these directly from the stack; they are vap methods
+ * that should be overridden.
+ */
 int    ieee80211_pwrsave(struct ieee80211_node *, struct mbuf *);
 void   ieee80211_node_pwrsave(struct ieee80211_node *, int enable);
 void   ieee80211_sta_pwrsave(struct ieee80211vap *, int enable);
index b61f6d4..cc774a0 100644 (file)
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_proto.h 199187 2009-11-11 15:00:56Z antoine $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_PROTO_H_
 #define _NET80211_IEEE80211_PROTO_H_
@@ -61,20 +61,65 @@ void        ieee80211_syncflag(struct ieee80211vap *, int flag);
 void   ieee80211_syncflag_ht(struct ieee80211vap *, int flag);
 void   ieee80211_syncflag_ext(struct ieee80211vap *, int flag);
 
+#define        IEEE80211_R_NF          0x0000001       /* global NF value valid */
+#define        IEEE80211_R_RSSI        0x0000002       /* global RSSI value valid */
+#define        IEEE80211_R_C_CHAIN     0x0000004       /* RX chain count valid */
+#define        IEEE80211_R_C_NF        0x0000008       /* per-chain NF value valid */
+#define        IEEE80211_R_C_RSSI      0x0000010       /* per-chain RSSI value valid */
+#define        IEEE80211_R_C_EVM       0x0000020       /* per-chain EVM valid */
+#define        IEEE80211_R_C_HT40      0x0000040       /* RX'ed packet is 40mhz, pilots 4,5 valid */
+
+struct ieee80211_rx_stats {
+       uint32_t r_flags;               /* IEEE80211_R_* flags */
+       uint8_t c_chain;                /* number of RX chains involved */
+       int16_t c_nf_ctl[IEEE80211_MAX_CHAINS]; /* per-chain NF */
+       int16_t c_nf_ext[IEEE80211_MAX_CHAINS]; /* per-chain NF */
+       int16_t c_rssi_ctl[IEEE80211_MAX_CHAINS];       /* per-chain RSSI */
+       int16_t c_rssi_ext[IEEE80211_MAX_CHAINS];       /* per-chain RSSI */
+       uint8_t nf;                     /* global NF */
+       uint8_t rssi;                   /* global RSSI */
+       uint8_t evm[IEEE80211_MAX_CHAINS][IEEE80211_MAX_EVM_PILOTS];
+                                       /* per-chain, per-pilot EVM values */
+};
+
+#if defined(__DragonFly__)
+struct route;
+#endif
+
 #define        ieee80211_input(ni, m, rssi, nf) \
        ((ni)->ni_vap->iv_input(ni, m, rssi, nf))
 int    ieee80211_input_all(struct ieee80211com *, struct mbuf *, int, int);
+
+int    ieee80211_input_mimo(struct ieee80211_node *, struct mbuf *,
+           struct ieee80211_rx_stats *);
+int    ieee80211_input_mimo_all(struct ieee80211com *, struct mbuf *,
+           struct ieee80211_rx_stats *);
+
 struct ieee80211_bpf_params;
 int    ieee80211_mgmt_output(struct ieee80211_node *, struct mbuf *, int,
                struct ieee80211_bpf_params *);
 int    ieee80211_raw_xmit(struct ieee80211_node *, struct mbuf *,
                const struct ieee80211_bpf_params *);
+#if defined(__DragonFly__)
 int    ieee80211_output(struct ifnet *, struct mbuf *,
                struct sockaddr *, struct rtentry *rt);
+#elif __FreeBSD_version >= 1000031
+int    ieee80211_output(struct ifnet *, struct mbuf *,
+               const struct sockaddr *, struct route *ro);
+#else
+int    ieee80211_output(struct ifnet *, struct mbuf *,
+               struct sockaddr *, struct route *ro);
+#endif
+int    ieee80211_vap_pkt_send_dest(struct ieee80211vap *, struct mbuf *,
+               struct ieee80211_node *);
+int    ieee80211_raw_output(struct ieee80211vap *, struct ieee80211_node *,
+               struct mbuf *, const struct ieee80211_bpf_params *);
 void   ieee80211_send_setup(struct ieee80211_node *, struct mbuf *, int, int,
         const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
         const uint8_t [IEEE80211_ADDR_LEN]);
-void   ieee80211_start(struct ifnet *, struct ifaltq_subque *);
+void   ieee80211_vap_start(struct ifnet *ifp, struct ifaltq_subque *ifsq);
+int    ieee80211_vap_transmit(struct ifnet *ifp, struct mbuf *m);
+void   ieee80211_vap_qflush(struct ifnet *ifp);
 int    ieee80211_send_nulldata(struct ieee80211_node *);
 int    ieee80211_classify(struct ieee80211_node *, struct mbuf *m);
 struct mbuf *ieee80211_mbuf_adjust(struct ieee80211vap *, int,
@@ -88,7 +133,9 @@ int  ieee80211_send_probereq(struct ieee80211_node *ni,
                const uint8_t da[IEEE80211_ADDR_LEN],
                const uint8_t bssid[IEEE80211_ADDR_LEN],
                const uint8_t *ssid, size_t ssidlen);
-void    ieee80211_tx_complete(struct ieee80211_node *,
+struct mbuf *  ieee80211_ff_encap1(struct ieee80211vap *, struct mbuf *,
+               const struct ether_header *);
+void   ieee80211_tx_complete(struct ieee80211_node *,
                struct mbuf *, int);
 
 /*
@@ -110,6 +157,9 @@ struct mbuf *ieee80211_alloc_cts(struct ieee80211com *,
 
 uint8_t *ieee80211_add_rates(uint8_t *, const struct ieee80211_rateset *);
 uint8_t *ieee80211_add_xrates(uint8_t *, const struct ieee80211_rateset *);
+uint8_t *ieee80211_add_wpa(uint8_t *, const struct ieee80211vap *);
+uint8_t *ieee80211_add_rsn(uint8_t *, const struct ieee80211vap *);
+uint8_t *ieee80211_add_qos(uint8_t *, const struct ieee80211_node *);
 uint16_t ieee80211_getcapinfo(struct ieee80211vap *,
                struct ieee80211_channel *);
 
@@ -191,7 +241,7 @@ struct ieee80211_aclator {
        int     (*iac_attach)(struct ieee80211vap *);
        void    (*iac_detach)(struct ieee80211vap *);
        int     (*iac_check)(struct ieee80211vap *,
-                       const uint8_t mac[IEEE80211_ADDR_LEN]);
+                       const struct ieee80211_frame *wh);
        int     (*iac_add)(struct ieee80211vap *,
                        const uint8_t mac[IEEE80211_ADDR_LEN]);
        int     (*iac_remove)(struct ieee80211vap *,
@@ -287,10 +337,10 @@ void      ieee80211_stop_all(struct ieee80211com *);
 void   ieee80211_suspend_all(struct ieee80211com *);
 void   ieee80211_resume_all(struct ieee80211com *);
 void   ieee80211_dturbo_switch(struct ieee80211vap *, int newflags);
-void   ieee80211_swbmiss_callout(void *arg);
+void   ieee80211_swbmiss(void *arg);
 void   ieee80211_beacon_miss(struct ieee80211com *);
 int    ieee80211_new_state(struct ieee80211vap *, enum ieee80211_state, int);
-int     ieee80211_new_state_locked(struct ieee80211vap *, enum ieee80211_state,
+int    ieee80211_new_state_locked(struct ieee80211vap *, enum ieee80211_state,
                int);
 void   ieee80211_print_essid(const uint8_t *, int);
 void   ieee80211_dump_pkt(struct ieee80211com *,
@@ -322,6 +372,7 @@ struct ieee80211_beacon_offsets {
        uint16_t        bo_appie_len;   /* AppIE length in bytes */
        uint16_t        bo_csa_trailer_len;
        uint8_t         *bo_csa;        /* start of CSA element */
+       uint8_t         *bo_quiet;      /* start of Quiet element */
        uint8_t         *bo_meshconf;   /* start of MESHCONF element */
        uint8_t         *bo_spare[3];
 };
index e87378d..388d70e 100644 (file)
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/net80211/ieee80211_radiotap.h 174568 2007-12-13 01:23:40Z sam $ */
+/* $FreeBSD$ */
 /* $NetBSD: ieee80211_radiotap.h,v 1.16 2007/01/06 05:51:15 dyoung Exp $ */
 
 /*-
 
 #define        IEEE80211_RADIOTAP_HDRLEN       64      /* XXX deprecated */
 
+struct ieee80211_radiotap_vendor_header {
+       uint8_t         vh_oui[3];      /* 3 byte vendor OUI */
+       uint8_t         vh_sub_ns;      /* Sub namespace of this section */
+       uint16_t        vh_skip_len;    /* Length of this vendor section */
+} __packed;
+
 /*
  * The radio capture header precedes the 802.11 header.
  *
@@ -188,8 +194,21 @@ enum ieee80211_radiotap_type {
        IEEE80211_RADIOTAP_ANTENNA = 11,
        IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
        IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
-       /* NB: gap for netbsd definitions */
+       /*
+        * 14-17 are from Linux, they overlap the netbsd-specific
+        * fields.
+        */
+       IEEE80211_RADIOTAP_RX_FLAGS = 14,
+       IEEE80211_RADIOTAP_TX_FLAGS = 15,
+       IEEE80211_RADIOTAP_RTS_RETRIES = 16,
+       IEEE80211_RADIOTAP_DATA_RETRIES = 17,
+
        IEEE80211_RADIOTAP_XCHANNEL = 18,
+       IEEE80211_RADIOTAP_MCS = 19,
+       IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
+
+        IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
+       IEEE80211_RADIOTAP_VENDOREXT = 30,
        IEEE80211_RADIOTAP_EXT = 31,
 };
 
index 37e80e4..da43084 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_ratectl.h 215289 2010-11-14 09:59:52Z bschmidt $
+ * $FreeBSD$
  */
 
 enum ieee80211_ratealgs {
@@ -34,8 +34,8 @@ enum ieee80211_ratealgs {
        IEEE80211_RATECTL_MAX
 };
 
-#define        IEEE80211_RATECTL_TX_SUCCESS    0
-#define        IEEE80211_RATECTL_TX_FAILURE    1
+#define        IEEE80211_RATECTL_TX_SUCCESS    1
+#define        IEEE80211_RATECTL_TX_FAILURE    0
 
 struct ieee80211_ratectl {
        const char *ir_name;
index 67ebb8d..cfb3146 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_regdomain.h 187799 2009-01-27 23:09:55Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_REGDOMAIN_H_
 #define _NET80211_IEEE80211_REGDOMAIN_H_
@@ -258,7 +258,17 @@ enum RegdomainCode {
        SKU_SR9                 = 0x0298, /* Ubiquiti SR9 (900MHz/GSM) */
        SKU_XR9                 = 0x0299, /* Ubiquiti XR9 (900MHz/GSM) */
        SKU_GZ901               = 0x029a, /* Zcomax GZ-901 (900MHz/GSM) */
-       SKU_XC900M              = 0x029b, /* Xagyl XC900M (900MHz/GSM) */
+       SKU_XC900M              = 0x029b, /* Xagyl XC900M (900MHz/GSM) */
+                                         /*
+                                          * The XC900M by default uses the
+                                          * same mapping as the XR9.  It
+                                          * can optionally use a slightly
+                                          * offset channel spacing (905MHz-
+                                          * 925MHz) versus the XR9 (907MHz-
+                                          * 922MHz), giving an extra channel.
+                                          * This requires a jumper on the
+                                          * NIC to be changed.
+                                          */
 };
 
 #if defined(__KERNEL__) || defined(_KERNEL)
index 44f6b50..ee1d2d9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $FreeBSD: head/sys/net80211/ieee80211_rssadapt.h 206358 2010-04-07 15:29:13Z rpaulo $   */
+/*     $FreeBSD$       */
 /* $NetBSD: ieee80211_rssadapt.h,v 1.4 2005/02/26 22:45:09 perry Exp $ */
 /*-
  * Copyright (c) 2003, 2004 David Young.  All rights reserved.
index ce7ef6e..3f13e17 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_scan.h 195618 2009-07-11 15:02:45Z rpaulo $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_SCAN_H_
 #define _NET80211_IEEE80211_SCAN_H_
@@ -213,6 +213,7 @@ struct ieee80211_scanparams {
        uint8_t         *ath;
        uint8_t         *tdma;
        uint8_t         *csa;
+       uint8_t         *quiet;
        uint8_t         *meshid;
        uint8_t         *meshconf;
        uint8_t         *spare[3];
index 184ddab..e97e181 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_sta.h 178354 2008-04-20 20:35:46Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_STA_H_
 #define _NET80211_IEEE80211_STA_H_
 void   ieee80211_sta_attach(struct ieee80211com *);
 void   ieee80211_sta_detach(struct ieee80211com *);
 void   ieee80211_sta_vattach(struct ieee80211vap *);
+
+/*
+ * Used by the adhoc/mesh/tdma paths.
+ */
+extern int ieee80211_parse_wmeparams(struct ieee80211vap *vap, uint8_t *frm,
+           const struct ieee80211_frame *wh);
 #endif /* !_NET80211_IEEE80211_STA_H_ */
index 0251d5c..4df1386 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_superg.h 191753 2009-05-02 20:16:55Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_SUPERG_H_
 #define _NET80211_IEEE80211_SUPERG_H_
@@ -66,7 +66,6 @@ struct ieee80211_stageq {
 struct ieee80211_superg {
        /* fast-frames staging q */
        struct ieee80211_stageq ff_stageq[WME_NUM_AC];
-       int                     ff_stageqdepth; /* cumulative depth */
 };
 
 void   ieee80211_superg_attach(struct ieee80211com *);
@@ -87,6 +86,10 @@ struct mbuf *ieee80211_ff_check(struct ieee80211_node *, struct mbuf *);
 void   ieee80211_ff_age(struct ieee80211com *, struct ieee80211_stageq *,
             int quanta);
 
+/*
+ * See ieee80211_ff_age() for a description of the locking
+ * expectation here.
+ */
 static __inline void
 ieee80211_ff_flush(struct ieee80211com *ic, int ac)
 {
@@ -96,12 +99,16 @@ ieee80211_ff_flush(struct ieee80211com *ic, int ac)
                ieee80211_ff_age(ic, &sg->ff_stageq[ac], 0x7fffffff);
 }
 
+/*
+ * See ieee80211_ff_age() for a description of the locking
+ * expectation here.
+ */
 static __inline void
 ieee80211_ff_age_all(struct ieee80211com *ic, int quanta)
 {
        struct ieee80211_superg *sg = ic->ic_superg;
 
-       if (sg != NULL && sg->ff_stageqdepth) {
+       if (sg != NULL) {
                if (sg->ff_stageq[WME_AC_VO].depth)
                        ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_VO], quanta);
                if (sg->ff_stageq[WME_AC_VI].depth)
index 1542c5e..2fe591f 100644 (file)
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_tdma.h 192468 2009-05-20 20:00:40Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_TDMA_H_
 #define _NET80211_IEEE80211_TDMA_H_
index f16c97a..65c3719 100644 (file)
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_var.h 206358 2010-04-07 15:29:13Z rpaulo $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_VAR_H_
 #define _NET80211_IEEE80211_VAR_H_
  */
 /* NB: portability glue must go first */
 #if defined(__NetBSD__)
-#include <net80211/ieee80211_netbsd.h>
+#include <netproto/802_11/ieee80211_netbsd.h>
 #elif defined(__FreeBSD__)
-#include <net80211/ieee80211_freebsd.h>
-#elif defined(__linux__)
-#include <net80211/ieee80211_linux.h>
+#include <netproto/802_11/ieee80211_freebsd.h>
 #elif defined(__DragonFly__)
 #include <netproto/802_11/ieee80211_dragonfly.h>
+#elif defined(__linux__)
+#include <netproto/802_11/ieee80211_linux.h>
 #else
 #error "No support for your operating system!"
 #endif
@@ -57,7 +57,7 @@
 #include <netproto/802_11/ieee80211_radiotap.h>
 #include <netproto/802_11/ieee80211_scan.h>
 
-#define        IEEE80211_TXPOWER_MAX   100     /* .5 dbM (XXX units?) */
+#define        IEEE80211_TXPOWER_MAX   100     /* .5 dBm (XXX units?) */
 #define        IEEE80211_TXPOWER_MIN   0       /* kill radio */
 
 #define        IEEE80211_DTIM_DEFAULT  1       /* default DTIM period */
@@ -119,6 +119,8 @@ struct ieee80211_frame;
 
 struct ieee80211com {
        struct ifnet            *ic_ifp;        /* associated device */
+       ieee80211_com_lock_t    ic_comlock;     /* state update lock */
+       ieee80211_tx_lock_t     ic_txlock;      /* ic/vap TX lock */
        TAILQ_HEAD(, ieee80211vap) ic_vaps;     /* list of vap instances */
        int                     ic_headroom;    /* driver tx headroom needs */
        enum ieee80211_phytype  ic_phytype;     /* XXX wrong for multi-mode */
@@ -131,6 +133,7 @@ struct ieee80211com {
        struct task             ic_mcast_task;  /* deferred mcast update */
        struct task             ic_chan_task;   /* deferred channel change */
        struct task             ic_bmiss_task;  /* deferred beacon miss hndlr */
+       struct task             ic_chw_task;    /* deferred HT CHW update */
 
        uint32_t                ic_flags;       /* state flags */
        uint32_t                ic_flags_ext;   /* extended state flags */
@@ -214,6 +217,8 @@ struct ieee80211com {
        enum ieee80211_protmode ic_htprotmode;  /* HT protection mode */
        int                     ic_lastnonerp;  /* last time non-ERP sta noted*/
        int                     ic_lastnonht;   /* last time non-HT sta noted */
+       uint8_t                 ic_rxstream;    /* # RX streams */
+       uint8_t                 ic_txstream;    /* # TX streams */
 
        /* optional state for Atheros SuperG protocol extensions */
        struct ieee80211_superg *ic_superg;
@@ -227,10 +232,10 @@ struct ieee80211com {
 
        /* virtual ap create/delete */
        struct ieee80211vap*    (*ic_vap_create)(struct ieee80211com *,
-                                   const char name[IFNAMSIZ], int unit,
-                                   enum ieee80211_opmode opmode, int flags,
-                                   const uint8_t bssid[IEEE80211_ADDR_LEN],
-                                   const uint8_t macaddr[IEEE80211_ADDR_LEN]);
+                                   const char [IFNAMSIZ], int,
+                                   enum ieee80211_opmode, int,
+                                   const uint8_t [IEEE80211_ADDR_LEN],
+                                   const uint8_t [IEEE80211_ADDR_LEN]);
        void                    (*ic_vap_delete)(struct ieee80211vap *);
        /* operating mode attachment */
        ieee80211vap_attach     ic_vattach[IEEE80211_OPMODE_MAX];
@@ -241,6 +246,10 @@ struct ieee80211com {
        int                     (*ic_setregdomain)(struct ieee80211com *,
                                    struct ieee80211_regdomain *,
                                    int, struct ieee80211_channel []);
+
+       int                     (*ic_set_quiet)(struct ieee80211_node *,
+                                   u_int8_t *quiet_elm);
+
        /* send/recv 802.11 management frame */
        int                     (*ic_send_mgmt)(struct ieee80211_node *,
                                     int, int);
@@ -306,6 +315,8 @@ struct ieee80211com {
                                    int status, int baparamset, int batimeout);
        void                    (*ic_addba_stop)(struct ieee80211_node *,
                                    struct ieee80211_tx_ampdu *);
+       void                    (*ic_addba_response_timeout)(struct ieee80211_node *,
+                                   struct ieee80211_tx_ampdu *);
        /* BAR response received */
        void                    (*ic_bar_response)(struct ieee80211_node *,
                                    struct ieee80211_tx_ampdu *, int status);
@@ -315,8 +326,11 @@ struct ieee80211com {
                                    int batimeout, int baseqctl);
        void                    (*ic_ampdu_rx_stop)(struct ieee80211_node *,
                                    struct ieee80211_rx_ampdu *);
+
+       /* The channel width has changed (20<->2040) */
+       void                    (*ic_update_chw)(struct ieee80211com *);
+
        uint64_t                ic_spare[7];
-       uint32_t                ic_spare2;
 };
 
 struct ieee80211_aclator;
@@ -401,6 +415,12 @@ struct ieee80211vap {
        uint8_t                 iv_dtim_period; /* DTIM period */
        uint8_t                 iv_dtim_count;  /* DTIM count from last bcn */
                                                /* set/unset aid pwrsav state */
+       uint8_t                 iv_quiet;       /* Quiet Element */
+       uint8_t                 iv_quiet_count; /* constant count for Quiet Element */
+       uint8_t                 iv_quiet_count_value;   /* variable count for Quiet Element */
+       uint8_t                 iv_quiet_period;        /* period for Quiet Element */
+       uint16_t                iv_quiet_duration;      /* duration for Quiet Element */
+       uint16_t                iv_quiet_offset;        /* offset for Quiet Element */
        int                     iv_csa_count;   /* count for doing CSA */
 
        struct ieee80211_node   *iv_bss;        /* information for this node */
@@ -471,12 +491,23 @@ struct ieee80211vap {
        int                     (*iv_set_tim)(struct ieee80211_node *, int);
        void                    (*iv_node_ps)(struct ieee80211_node *, int);
        void                    (*iv_sta_ps)(struct ieee80211vap *, int);
+       void                    (*iv_recv_pspoll)(struct ieee80211_node *,
+                                   struct mbuf *);
+
        /* state machine processing */
        int                     (*iv_newstate)(struct ieee80211vap *,
                                    enum ieee80211_state, int);
        /* 802.3 output method for raw frame xmit */
+#if defined(__DragonFly__)
        int                     (*iv_output)(struct ifnet *, struct mbuf *,
                                    struct sockaddr *, struct rtentry *);
+#elif __FreeBSD_version >= 1000031
+       int                     (*iv_output)(struct ifnet *, struct mbuf *,
+                                   const struct sockaddr *, struct route *);
+#else
+       int                     (*iv_output)(struct ifnet *, struct mbuf *,
+                                   struct sockaddr *, struct route *);
+#endif
        uint64_t                iv_spare[6];
 };
 MALLOC_DECLARE(M_80211_VAP);
@@ -580,7 +611,7 @@ MALLOC_DECLARE(M_80211_VAP);
 
 #define        IEEE80211_FHT_BITS \
        "\20\1NONHT_PR" \
-       "\23GF\24HT\25AMDPU_TX\26AMPDU_TX" \
+       "\23GF\24HT\25AMPDU_TX\26AMPDU_TX" \
        "\27AMSDU_TX\30AMSDU_RX\31USEHT40\32PUREN\33SHORTGI20\34SHORTGI40" \
        "\35HTCOMPAT\36RIFS\37STBC_TX\40STBC_RX"
 
@@ -603,7 +634,7 @@ MALLOC_DECLARE(M_80211_VAP);
 #define        IEEE80211_C_MONITOR     0x00010000      /* CAPABILITY: monitor mode */
 #define        IEEE80211_C_DFS         0x00020000      /* CAPABILITY: DFS/radar avail*/
 #define        IEEE80211_C_MBSS        0x00040000      /* CAPABILITY: MBSS available */
-#define IEEE80211_C_SWSLEEP    0x00080000      /* CAPABILITY: do sleep here */
+#define        IEEE80211_C_SWSLEEP     0x00080000      /* CAPABILITY: do sleep here */
 /* 0x7c0000 available */
 #define        IEEE80211_C_WPA1        0x00800000      /* CAPABILITY: WPA1 avail */
 #define        IEEE80211_C_WPA2        0x01000000      /* CAPABILITY: WPA2 avail */
@@ -640,6 +671,10 @@ MALLOC_DECLARE(M_80211_VAP);
 #define        IEEE80211_HTC_HT        0x00040000      /* CAPABILITY: HT operation */
 #define        IEEE80211_HTC_SMPS      0x00080000      /* CAPABILITY: MIMO power save*/
 #define        IEEE80211_HTC_RIFS      0x00100000      /* CAPABILITY: RIFS support */
+#define        IEEE80211_HTC_RXUNEQUAL 0x00200000      /* CAPABILITY: RX unequal MCS */
+#define        IEEE80211_HTC_RXMCS32   0x00400000      /* CAPABILITY: MCS32 support */
+#define        IEEE80211_HTC_TXUNEQUAL 0x00800000      /* CAPABILITY: TX unequal MCS */
+#define        IEEE80211_HTC_TXMCS32   0x01000000      /* CAPABILITY: MCS32 suport */
 
 #define        IEEE80211_C_HTCAP_BITS \
        "\20\1LDPC\2CHWIDTH40\5GREENFIELD\6SHORTGI20\7SHORTGI40\10TXSTBC" \
@@ -649,7 +684,8 @@ void        ieee80211_ifattach(struct ieee80211com *,
                const uint8_t macaddr[IEEE80211_ADDR_LEN]);
 void   ieee80211_ifdetach(struct ieee80211com *);
 int    ieee80211_vap_setup(struct ieee80211com *, struct ieee80211vap *,
-               const char name[IFNAMSIZ], int unit, int opmode, int flags,
+               const char name[IFNAMSIZ], int unit,
+               enum ieee80211_opmode opmode, int flags,
                const uint8_t bssid[IEEE80211_ADDR_LEN],
                const uint8_t macaddr[IEEE80211_ADDR_LEN]);
 int    ieee80211_vap_attach(struct ieee80211vap *,
@@ -664,7 +700,11 @@ void       ieee80211_media_init(struct ieee80211com *);
 struct ieee80211com *ieee80211_find_vap(const uint8_t mac[IEEE80211_ADDR_LEN]);
 int    ieee80211_media_change(struct ifnet *);
 void   ieee80211_media_status(struct ifnet *, struct ifmediareq *);
+#if defined(__DragonFly__)
 int    ieee80211_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
+#else
+int    ieee80211_ioctl(struct ifnet *, u_long, caddr_t);
+#endif
 int    ieee80211_rate2media(struct ieee80211com *, int,
                enum ieee80211_phymode);
 int    ieee80211_media2rate(int);
@@ -686,6 +726,11 @@ void       ieee80211_radiotap_attach(struct ieee80211com *,
                uint32_t tx_radiotap,
            struct ieee80211_radiotap_header *rh, int rlen,
                uint32_t rx_radiotap);
+void   ieee80211_radiotap_attachv(struct ieee80211com *,
+           struct ieee80211_radiotap_header *th,
+           int tlen, int n_tx_v, uint32_t tx_radiotap,
+           struct ieee80211_radiotap_header *rh,
+           int rlen, int n_rx_v, uint32_t rx_radiotap);
 void   ieee80211_radiotap_detach(struct ieee80211com *);
 void   ieee80211_radiotap_vattach(struct ieee80211vap *);
 void   ieee80211_radiotap_vdetach(struct ieee80211vap *);
@@ -863,24 +908,6 @@ ieee80211_get_node_txpower(struct ieee80211_node *ni)
        "\23POWER\24STATE\25OUTPUT\26SCAN\27AUTH\30ASSOC\31NODE\32ELEMID" \
        "\33XRATE\34INPUT\35CRYPTO\36DUPMPKTS\37DEBUG\04011N"
 
-void   ieee80211_note(const struct ieee80211vap *, const char *, ...)
-               __printflike(2, 3);
-void   ieee80211_note_mac(const struct ieee80211vap *,
-               const uint8_t mac[IEEE80211_ADDR_LEN], const char *, ...)
-               __printflike(3, 4);
-void   ieee80211_note_frame(const struct ieee80211vap *,
-               const struct ieee80211_frame *, const char *, ...)
-               __printflike(3, 4);
-void ieee80211_discard_frame(const struct ieee80211vap *,
-       const struct ieee80211_frame *, const char *type, const char *fmt, ...)
-       __printflike(4, 5);
-void ieee80211_discard_ie(const struct ieee80211vap *,
-       const struct ieee80211_frame *, const char *type, const char *fmt, ...)
-       __printflike(4, 5);
-void ieee80211_discard_mac(const struct ieee80211vap *,
-       const uint8_t mac[IEEE80211_ADDR_LEN], const char *type,
-       const char *fmt, ...) __printflike(4, 5);
-
 #ifdef IEEE80211_DEBUG
 #define        ieee80211_msg(_vap, _m) ((_vap)->iv_debug & (_m))
 #define        IEEE80211_DPRINTF(_vap, _m, _fmt, ...) do {                     \
@@ -899,6 +926,11 @@ void ieee80211_discard_mac(const struct ieee80211vap *,
        if (ieee80211_msg(_vap, _m))                                    \
                ieee80211_note_frame(_vap, _wh, _fmt, __VA_ARGS__);     \
 } while (0)
+void   ieee80211_note(const struct ieee80211vap *, const char *, ...);
+void   ieee80211_note_mac(const struct ieee80211vap *,
+               const uint8_t mac[IEEE80211_ADDR_LEN], const char *, ...);
+void   ieee80211_note_frame(const struct ieee80211vap *,
+               const struct ieee80211_frame *, const char *, ...);
 #define        ieee80211_msg_debug(_vap) \
        ((_vap)->iv_debug & IEEE80211_MSG_DEBUG)
 #define        ieee80211_msg_dumppkts(_vap) \
@@ -935,6 +967,13 @@ void ieee80211_discard_mac(const struct ieee80211vap *,
                ieee80211_discard_mac(_vap, _mac, _type, _fmt, __VA_ARGS__);\
 } while (0)
 
+void ieee80211_discard_frame(const struct ieee80211vap *,
+       const struct ieee80211_frame *, const char *type, const char *fmt, ...);
+void ieee80211_discard_ie(const struct ieee80211vap *,
+       const struct ieee80211_frame *, const char *type, const char *fmt, ...);
+void ieee80211_discard_mac(const struct ieee80211vap *,
+       const uint8_t mac[IEEE80211_ADDR_LEN], const char *type,
+       const char *fmt, ...);
 #else
 #define        IEEE80211_DPRINTF(_vap, _m, _fmt, ...)
 #define        IEEE80211_NOTE(_vap, _m, _ni, _fmt, ...)
index dd1a0d0..c34fb6e 100644 (file)
@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/net80211/ieee80211_wds.h 178354 2008-04-20 20:35:46Z sam $
+ * $FreeBSD$
  */
 #ifndef _NET80211_IEEE80211_WDS_H_
 #define _NET80211_IEEE80211_WDS_H_
index f183202..a60379c 100644 (file)
@@ -1,6 +1,6 @@
 KMOD    = wlan
 SRCS    = ieee80211.c ieee80211_action.c ieee80211_adhoc.c ieee80211_ageq.c
-#SRCS  += ieee80211_amrr.c
+#SRCS  += ieee80211_amrr.c ieee80211_alq.c
 SRCS   += ieee80211_crypto.c ieee80211_crypto_none.c ieee80211_ddb.c
 SRCS   += ieee80211_dfs.c ieee80211_dragonfly.c ieee80211_hostap.c
 SRCS   += ieee80211_ht.c ieee80211_hwmp.c ieee80211_input.c ieee80211_ioctl.c
index 826d714..784dca0 100644 (file)
  * 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.
- *
- * $FreeBSD: head/sys/net80211/ieee80211.c 206358 2010-04-07 15:29:13Z rpaulo $
  */
 
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 /*
  * IEEE 802.11 generic handler
  */
 #include <sys/kernel.h>
 
 #include <sys/socket.h>
-#include <sys/thread.h>
 
 #include <net/if.h>
+#include <net/if_var.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
 #include <net/if_types.h>
-#include <net/ifq_var.h>
 #include <net/ethernet.h>
-#include <net/route.h>
 
 #include <netproto/802_11/ieee80211_var.h>
 #include <netproto/802_11/ieee80211_regdomain.h>
@@ -115,9 +114,6 @@ static const struct ieee80211_rateset ieee80211_rateset_11g =
        { 12, { B(2), B(4), B(11), B(22), 12, 18, 24, 36, 48, 72, 96, 108 } };
 #undef B
 
-/* Global token used for wlan layer and wireless NIC driver layer */
-lwkt_token wlan_token;
-
 /*
  * Fill in 802.11 available channel set, mark
  * all available channels as active, and pick
@@ -210,6 +206,15 @@ ieee80211_chan_init(struct ieee80211com *ic)
        DEFAULTRATES(IEEE80211_MODE_11NA,        ieee80211_rateset_11a);
        DEFAULTRATES(IEEE80211_MODE_11NG,        ieee80211_rateset_11g);
 
+       /*
+        * Setup required information to fill the mcsset field, if driver did
+        * not. Assume a 2T2R setup for historic reasons.
+        */
+       if (ic->ic_rxstream == 0)
+               ic->ic_rxstream = 2;
+       if (ic->ic_txstream == 0)
+               ic->ic_txstream = 2;
+
        /*
         * Set auto mode to reset active channel state and any desired channel.
         */
@@ -237,22 +242,52 @@ null_transmit(struct ifnet *ifp, struct mbuf *m)
        return EACCES;          /* XXX EIO/EPERM? */
 }
 
+#if defined(__DragonFly__)
+static int
+null_output(struct ifnet *ifp, struct mbuf *m,
+           struct sockaddr *dst, struct rtentry *ro)
+#elif __FreeBSD_version >= 1000031
+static int
+null_output(struct ifnet *ifp, struct mbuf *m,
+       const struct sockaddr *dst, struct route *ro)
+#else
 static int
 null_output(struct ifnet *ifp, struct mbuf *m,
-       struct sockaddr *dst, struct rtentry *ro)
+       struct sockaddr *dst, struct route *ro)
+#endif
 {
        if_printf(ifp, "discard raw packet\n");
        return null_transmit(ifp, m);
 }
 
+#if defined(__DragonFly__)
+
 static void
 null_input(struct ifnet *ifp, struct mbuf *m,
-       const struct pktinfo *pi, int cpuid)
+          const struct pktinfo *pi, int cpuid)
+{
+       if_printf(ifp, "if_input should not be called\n");
+       m_freem(m);
+}
+
+#else
+
+static void
+null_input(struct ifnet *ifp, struct mbuf *m)
 {
        if_printf(ifp, "if_input should not be called\n");
        m_freem(m);
 }
 
+#endif
+
+static void
+null_update_chw(struct ieee80211com *ic)
+{
+
+       if_printf(ic->ic_ifp, "%s: need callback\n", __func__);
+}
+
 /*
  * Attach/setup the common net80211 state.  Called by
  * the driver on attach to prior to creating any vap's.
@@ -267,13 +302,20 @@ ieee80211_ifattach(struct ieee80211com *ic,
 
        KASSERT(ifp->if_type == IFT_IEEE80211, ("if_type %d", ifp->if_type));
 
+       IEEE80211_LOCK_INIT(ic, ifp->if_xname);
+       IEEE80211_TX_LOCK_INIT(ic, ifp->if_xname);
        TAILQ_INIT(&ic->ic_vaps);
 
        /* Create a taskqueue for all state changes */
        ic->ic_tq = taskqueue_create("ic_taskq", M_WAITOK | M_ZERO,
            taskqueue_thread_enqueue, &ic->ic_tq);
+#if defined(__DragonFly__)
        taskqueue_start_threads(&ic->ic_tq, 1, TDPRI_KERN_DAEMON, -1,
-           "%s taskq", ifp->if_xname);
+                               "%s net80211 taskq", ifp->if_xname);
+#else
+       taskqueue_start_threads(&ic->ic_tq, 1, PI_NET, "%s net80211 taskq",
+           ifp->if_xname);
+#endif
        /*
         * Fill in 802.11 available channel set, mark all
         * available channels as active, and pick a default
@@ -283,8 +325,9 @@ ieee80211_ifattach(struct ieee80211com *ic,
 
        ic->ic_update_mcast = null_update_mcast;
        ic->ic_update_promisc = null_update_promisc;
+       ic->ic_update_chw = null_update_chw;
 
-       ic->ic_hash_key = karc4random();
+       ic->ic_hash_key = arc4random();
        ic->ic_bintval = IEEE80211_BINTVAL_DEFAULT;
        ic->ic_lintval = ic->ic_bintval;
        ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;
@@ -305,7 +348,15 @@ ieee80211_ifattach(struct ieee80211com *ic,
 
        ifp->if_addrlen = IEEE80211_ADDR_LEN;
        ifp->if_hdrlen = 0;
+
+       CURVNET_SET(vnet0);
+
+#if defined(__DragonFly__)
        if_attach(ifp, &wlan_global_serializer);
+#else
+       if_attach(ifp);
+#endif
+
        ifp->if_mtu = IEEE80211_MTU_MAX;
        ifp->if_broadcastaddr = ieee80211broadcastaddr;
        ifp->if_output = null_output;
@@ -317,6 +368,8 @@ ieee80211_ifattach(struct ieee80211com *ic,
        sdl->sdl_type = IFT_ETHER;              /* XXX IFT_IEEE80211? */
        sdl->sdl_alen = IEEE80211_ADDR_LEN;
        IEEE80211_ADDR_COPY(LLADDR(sdl), macaddr);
+
+       CURVNET_RESTORE();
 }
 
 /*
@@ -331,10 +384,18 @@ ieee80211_ifdetach(struct ieee80211com *ic)
        struct ifnet *ifp = ic->ic_ifp;
        struct ieee80211vap *vap;
 
-       wlan_serialize_exit();
+       /*
+        * This detaches the main interface, but not the vaps.
+        * Each VAP may be in a separate VIMAGE.
+        */
+       CURVNET_SET(ifp->if_vnet);
        if_detach(ifp);
-       wlan_serialize_enter();
+       CURVNET_RESTORE();
 
+       /*
+        * The VAP is responsible for setting and clearing
+        * the VIMAGE context.
+        */
        while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL)
                ieee80211_vap_destroy(vap);
        ieee80211_waitfor_parent(ic);
@@ -353,8 +414,12 @@ ieee80211_ifdetach(struct ieee80211com *ic)
        ieee80211_power_detach(ic);
        ieee80211_node_detach(ic);
 
+       /* XXX VNET needed? */
        ifmedia_removeall(&ic->ic_media);
+
        taskqueue_free(ic->ic_tq);
+       IEEE80211_TX_LOCK_DESTROY(ic);
+       IEEE80211_LOCK_DESTROY(ic);
 }
 
 /*
@@ -379,9 +444,9 @@ default_reset(struct ieee80211vap *vap, u_long cmd)
  */
 int
 ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
-       const char name[IFNAMSIZ], int unit, int opmode, int flags,
-       const uint8_t bssid[IEEE80211_ADDR_LEN],
-       const uint8_t macaddr[IEEE80211_ADDR_LEN])
+    const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode,
+    int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
+    const uint8_t macaddr[IEEE80211_ADDR_LEN])
 {
        struct ifnet *ifp;
 
@@ -394,14 +459,13 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
        if_initname(ifp, name, unit);
        ifp->if_softc = vap;                    /* back pointer */
        ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
-       ifp->if_start = ieee80211_start;
+       ifp->if_start = ieee80211_vap_start;
+#if 0
+       ifp->if_transmit = ieee80211_vap_transmit;
+       ifp->if_qflush = ieee80211_vap_qflush;
+#endif
        ifp->if_ioctl = ieee80211_ioctl;
        ifp->if_init = ieee80211_init;
-       /* NB: input+output filled in by ether_ifattach */
-       ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
-#ifdef notyet
-       ifq_set_ready(&ifp->if_snd);
-#endif
 
        vap->iv_ifp = ifp;
        vap->iv_ic = ic;
@@ -410,6 +474,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
        vap->iv_flags_ven = ic->ic_flags_ven;
        vap->iv_caps = ic->ic_caps &~ IEEE80211_C_OPMODE;
        vap->iv_htcaps = ic->ic_htcaps;
+       vap->iv_htextcaps = ic->ic_htextcaps;
        vap->iv_opmode = opmode;
        vap->iv_caps |= ieee80211_opcap[opmode];
        switch (opmode) {
@@ -442,6 +507,8 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
                }
                break;
 #endif
+       default:
+               break;
        }
        /* auto-enable s/w beacon miss support */
        if (flags & IEEE80211_CLONE_NOBEACONS)
@@ -457,13 +524,11 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
                vap->iv_flags |= IEEE80211_F_WME;
        if (vap->iv_caps & IEEE80211_C_BURST)
                vap->iv_flags |= IEEE80211_F_BURST;
+       /* NB: bg scanning only makes sense for station mode right now */
 #if 0
        /*
-        * NB: bg scanning only makes sense for station mode right now
-        *
-        * XXX: bgscan is not necessarily stable, so do not enable it by
-        *      default.  It messes up atheros drivers for sure.
-        *      (tested w/ AR9280).
+        * DISABLE BGSCAN BY DEFAULT, many issues can crop up including
+        * the link going dead.
         */
        if (vap->iv_opmode == IEEE80211_M_STA &&
            (vap->iv_caps & IEEE80211_C_BGSCAN))
@@ -538,20 +603,17 @@ ieee80211_vap_attach(struct ieee80211vap *vap,
        if (maxrate)
                ifp->if_baudrate = IF_Mbps(maxrate);
 
+#if defined(__DragonFly__)
        ether_ifattach(ifp, vap->iv_myaddr, &wlan_global_serializer);
-       if (vap->iv_opmode == IEEE80211_M_MONITOR) {
-               /* NB: disallow transmit */
-#ifdef __FreeBSD__
-               ifp->if_transmit = null_transmit;
+#else
+       ether_ifattach(ifp, vap->iv_myaddr);
 #endif
-               ifp->if_output = null_output;
-       } else {
-               /* hook output method setup by ether_ifattach */
-               vap->iv_output = ifp->if_output;
-               ifp->if_output = ieee80211_output;
-       }
+       /* hook output method setup by ether_ifattach */
+       vap->iv_output = ifp->if_output;
+       ifp->if_output = ieee80211_output;
        /* NB: if_mtu set by ether_ifattach to ETHERMTU */
 
+       IEEE80211_LOCK(ic);
        TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next);
        ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
 #ifdef IEEE80211_SUPPORT_SUPERG
@@ -563,6 +625,7 @@ ieee80211_vap_attach(struct ieee80211vap *vap,
        ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40);
        ieee80211_syncifflag_locked(ic, IFF_PROMISC);
        ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
+       IEEE80211_UNLOCK(ic);
 
        return 1;
 }
@@ -579,35 +642,29 @@ ieee80211_vap_detach(struct ieee80211vap *vap)
        struct ieee80211com *ic = vap->iv_ic;
        struct ifnet *ifp = vap->iv_ifp;
 
+       CURVNET_SET(ifp->if_vnet);
+
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s parent %s\n",
            __func__, ieee80211_opmode_name[vap->iv_opmode],
            ic->ic_ifp->if_xname);
 
-       /*
-        * NB: bpfdetach is called by ether_ifdetach and claims all taps
-        *
-        * ether_ifdetach() must be called without the serializer held.
-        */
-       wlan_assert_serialized();
-       wlan_serialize_exit();  /* exit to block */
+       /* NB: bpfdetach is called by ether_ifdetach and claims all taps */
        ether_ifdetach(ifp);
 
-       wlan_serialize_enter(); /* then reenter */
        ieee80211_stop(vap);
 
        /*
         * Flush any deferred vap tasks.
         */
-       wlan_serialize_exit();  /* exit to block */
        ieee80211_draintask(ic, &vap->iv_nstate_task);
        ieee80211_draintask(ic, &vap->iv_swbmiss_task);
-       wlan_serialize_enter(); /* then reenter */
 
-#ifdef __FreeBSD__
+#if !defined(__DragonFly__)
        /* XXX band-aid until ifnet handles this for us */
        taskqueue_drain(taskqueue_swi, &ifp->if_linktask);
 #endif
 
+       IEEE80211_LOCK(ic);
        KASSERT(vap->iv_state == IEEE80211_S_INIT , ("vap still running"));
        TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next);
        ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
@@ -622,6 +679,7 @@ ieee80211_vap_detach(struct ieee80211vap *vap)
        ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_BPF);
        ieee80211_syncifflag_locked(ic, IFF_PROMISC);
        ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
+       IEEE80211_UNLOCK(ic);
 
        ifmedia_removeall(&vap->iv_media);
 
@@ -640,6 +698,8 @@ ieee80211_vap_detach(struct ieee80211vap *vap)
        ieee80211_sysctl_vdetach(vap);
 
        if_free(ifp);
+
+       CURVNET_RESTORE();
 }
 
 /*
@@ -654,6 +714,8 @@ ieee80211_syncifflag_locked(struct ieee80211com *ic, int flag)
        struct ieee80211vap *vap;
        int bit, oflags;
 
+       IEEE80211_LOCK_ASSERT(ic);
+
        bit = 0;
        TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
                if (vap->iv_ifp->if_flags & flag) {
@@ -677,7 +739,7 @@ ieee80211_syncifflag_locked(struct ieee80211com *ic, int flag)
                ifp->if_flags &= ~flag;
        if ((ifp->if_flags ^ oflags) & flag) {
                /* XXX should we return 1/0 and let caller do this? */
-               if (ifp->if_flags & IFF_RUNNING) {
+               if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
                        if (flag == IFF_PROMISC)
                                ieee80211_runtask(ic, &ic->ic_promisc_task);
                        else if (flag == IFF_ALLMULTI)
@@ -697,6 +759,8 @@ ieee80211_syncflag_locked(struct ieee80211com *ic, int flag)
        struct ieee80211vap *vap;
        int bit;
 
+       IEEE80211_LOCK_ASSERT(ic);
+
        bit = 0;
        TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
                if (vap->iv_flags & flag) {
@@ -714,12 +778,14 @@ ieee80211_syncflag(struct ieee80211vap *vap, int flag)
 {
        struct ieee80211com *ic = vap->iv_ic;
 
+       IEEE80211_LOCK(ic);
        if (flag < 0) {
                flag = -flag;
                vap->iv_flags &= ~flag;
        } else
                vap->iv_flags |= flag;
        ieee80211_syncflag_locked(ic, flag);
+       IEEE80211_UNLOCK(ic);
 }
 
 /*
@@ -733,6 +799,8 @@ ieee80211_syncflag_ht_locked(struct ieee80211com *ic, int flag)
        struct ieee80211vap *vap;
        int bit;
 
+       IEEE80211_LOCK_ASSERT(ic);
+
        bit = 0;
        TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
                if (vap->iv_flags_ht & flag) {
@@ -750,12 +818,14 @@ ieee80211_syncflag_ht(struct ieee80211vap *vap, int flag)
 {
        struct ieee80211com *ic = vap->iv_ic;
 
+       IEEE80211_LOCK(ic);
        if (flag < 0) {
                flag = -flag;
                vap->iv_flags_ht &= ~flag;
        } else
                vap->iv_flags_ht |= flag;
        ieee80211_syncflag_ht_locked(ic, flag);
+       IEEE80211_UNLOCK(ic);
 }
 
 /*
@@ -769,6 +839,8 @@ ieee80211_syncflag_ext_locked(struct ieee80211com *ic, int flag)
        struct ieee80211vap *vap;
        int bit;
 
+       IEEE80211_LOCK_ASSERT(ic);
+
        bit = 0;
        TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
                if (vap->iv_flags_ext & flag) {
@@ -786,12 +858,14 @@ ieee80211_syncflag_ext(struct ieee80211vap *vap, int flag)
 {
        struct ieee80211com *ic = vap->iv_ic;
 
+       IEEE80211_LOCK(ic);
        if (flag < 0) {
                flag = -flag;
                vap->iv_flags_ext &= ~flag;
        } else
                vap->iv_flags_ext |= flag;
        ieee80211_syncflag_ext_locked(ic, flag);
+       IEEE80211_UNLOCK(ic);
 }
 
 static __inline int
@@ -1006,7 +1080,8 @@ ieee80211_media_setup(struct ieee80211com *ic,
        struct ifmedia *media, int caps, int addsta,
        ifm_change_cb_t media_change, ifm_stat_cb_t media_stat)
 {
-       int i, j, mode, rate, maxrate, mword, r;
+       int i, j, rate, maxrate, mword, r;
+       enum ieee80211_phymode mode;
        const struct ieee80211_rateset *rs;
        struct ieee80211_rateset allrates;
 
@@ -1074,10 +1149,18 @@ ieee80211_media_setup(struct ieee80211com *ic,
            isset(ic->ic_modecaps, IEEE80211_MODE_11NG)) {
                addmedia(media, caps, addsta,
                    IEEE80211_MODE_AUTO, IFM_IEEE80211_MCS);
-               /* XXX could walk htrates */
-               /* XXX known array size */
-               if (ieee80211_htrates[15].ht40_rate_400ns > maxrate)
-                       maxrate = ieee80211_htrates[15].ht40_rate_400ns;
+               i = ic->ic_txstream * 8 - 1;
+               if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) &&
+                   (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40))
+                       rate = ieee80211_htrates[i].ht40_rate_400ns;
+               else if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40))
+                       rate = ieee80211_htrates[i].ht40_rate_800ns;
+               else if ((ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20))
+                       rate = ieee80211_htrates[i].ht20_rate_400ns;
+               else
+                       rate = ieee80211_htrates[i].ht20_rate_800ns;
+               if (rate > maxrate)
+                       maxrate = rate;
        }
        return maxrate;
 }
@@ -1127,7 +1210,8 @@ void
 ieee80211_announce(struct ieee80211com *ic)
 {
        struct ifnet *ifp = ic->ic_ifp;
-       int i, mode, rate, mword;
+       int i, rate, mword;
+       enum ieee80211_phymode mode;
        const struct ieee80211_rateset *rs;
 
        /* NB: skip AUTO since it has no rates */
@@ -1520,6 +1604,67 @@ ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode m
                {  13, IFM_IEEE80211_MCS },
                {  14, IFM_IEEE80211_MCS },
                {  15, IFM_IEEE80211_MCS },
+               {  16, IFM_IEEE80211_MCS },
+               {  17, IFM_IEEE80211_MCS },
+               {  18, IFM_IEEE80211_MCS },
+               {  19, IFM_IEEE80211_MCS },
+               {  20, IFM_IEEE80211_MCS },
+               {  21, IFM_IEEE80211_MCS },
+               {  22, IFM_IEEE80211_MCS },
+               {  23, IFM_IEEE80211_MCS },
+               {  24, IFM_IEEE80211_MCS },
+               {  25, IFM_IEEE80211_MCS },
+               {  26, IFM_IEEE80211_MCS },
+               {  27, IFM_IEEE80211_MCS },
+               {  28, IFM_IEEE80211_MCS },
+               {  29, IFM_IEEE80211_MCS },
+               {  30, IFM_IEEE80211_MCS },
+               {  31, IFM_IEEE80211_MCS },
+               {  32, IFM_IEEE80211_MCS },
+               {  33, IFM_IEEE80211_MCS },
+               {  34, IFM_IEEE80211_MCS },
+               {  35, IFM_IEEE80211_MCS },
+               {  36, IFM_IEEE80211_MCS },
+               {  37, IFM_IEEE80211_MCS },
+               {  38, IFM_IEEE80211_MCS },
+               {  39, IFM_IEEE80211_MCS },
+               {  40, IFM_IEEE80211_MCS },
+               {  41, IFM_IEEE80211_MCS },
+               {  42, IFM_IEEE80211_MCS },
+               {  43, IFM_IEEE80211_MCS },
+               {  44, IFM_IEEE80211_MCS },
+               {  45, IFM_IEEE80211_MCS },
+               {  46, IFM_IEEE80211_MCS },
+               {  47, IFM_IEEE80211_MCS },
+               {  48, IFM_IEEE80211_MCS },
+               {  49, IFM_IEEE80211_MCS },
+               {  50, IFM_IEEE80211_MCS },
+               {  51, IFM_IEEE80211_MCS },
+               {  52, IFM_IEEE80211_MCS },
+               {  53, IFM_IEEE80211_MCS },
+               {  54, IFM_IEEE80211_MCS },
+               {  55, IFM_IEEE80211_MCS },
+               {  56, IFM_IEEE80211_MCS },
+               {  57, IFM_IEEE80211_MCS },
+               {  58, IFM_IEEE80211_MCS },
+               {  59, IFM_IEEE80211_MCS },
+               {  60, IFM_IEEE80211_MCS },
+               {  61, IFM_IEEE80211_MCS },
+               {  62, IFM_IEEE80211_MCS },
+               {  63, IFM_IEEE80211_MCS },
+               {  64, IFM_IEEE80211_MCS },
+               {  65, IFM_IEEE80211_MCS },
+               {  66, IFM_IEEE80211_MCS },
+               {  67, IFM_IEEE80211_MCS },
+               {  68, IFM_IEEE80211_MCS },
+               {  69, IFM_IEEE80211_MCS },
+               {  70, IFM_IEEE80211_MCS },
+               {  71, IFM_IEEE80211_MCS },
+               {  72, IFM_IEEE80211_MCS },
+               {  73, IFM_IEEE80211_MCS },
+               {  74, IFM_IEEE80211_MCS },
+               {  75, IFM_IEEE80211_MCS },
+               {  76, IFM_IEEE80211_MCS },
        };
        int m;
 
@@ -1529,7 +1674,7 @@ ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode m
        if (mode == IEEE80211_MODE_11NA) {
                if (rate & IEEE80211_RATE_MCS) {
                        rate &= ~IEEE80211_RATE_MCS;
-                       m = findmedia(htrates, NELEM(htrates), rate);
+                       m = findmedia(htrates, nitems(htrates), rate);
                        if (m != IFM_AUTO)
                                return m | IFM_IEEE80211_11NA;
                }
@@ -1537,7 +1682,7 @@ ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode m
                /* NB: 12 is ambiguous, it will be treated as an MCS */
                if (rate & IEEE80211_RATE_MCS) {
                        rate &= ~IEEE80211_RATE_MCS;
-                       m = findmedia(htrates, NELEM(htrates), rate);
+                       m = findmedia(htrates, nitems(htrates), rate);
                        if (m != IFM_AUTO)
                                return m | IFM_IEEE80211_11NG;
                }
@@ -1550,22 +1695,25 @@ ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode m
        case IEEE80211_MODE_11NA:
        case IEEE80211_MODE_TURBO_A:
        case IEEE80211_MODE_STURBO_A:
-               return findmedia(rates, NELEM(rates), rate | IFM_IEEE80211_11A);
+               return findmedia(rates, nitems(rates),
+                   rate | IFM_IEEE80211_11A);
        case IEEE80211_MODE_11B:
-               return findmedia(rates, NELEM(rates), rate | IFM_IEEE80211_11B);
+               return findmedia(rates, nitems(rates),
+                   rate | IFM_IEEE80211_11B);
        case IEEE80211_MODE_FH:
-               return findmedia(rates, NELEM(rates), rate | IFM_IEEE80211_FH);
+               return findmedia(rates, nitems(rates),
+                   rate | IFM_IEEE80211_FH);
        case IEEE80211_MODE_AUTO:
                /* NB: ic may be NULL for some drivers */
                if (ic != NULL && ic->ic_phytype == IEEE80211_T_FH)
-                       return findmedia(rates, NELEM(rates),
+                       return findmedia(rates, nitems(rates),
                            rate | IFM_IEEE80211_FH);
                /* NB: hack, 11g matches both 11b+11a rates */
                /* fall thru... */
        case IEEE80211_MODE_11G:
        case IEEE80211_MODE_11NG:
        case IEEE80211_MODE_TURBO_G:
-               return findmedia(rates, NELEM(rates), rate | IFM_IEEE80211_11G);
+               return findmedia(rates, nitems(rates), rate | IFM_IEEE80211_11G);
        }
        return IFM_AUTO;
 }
@@ -1600,7 +1748,7 @@ ieee80211_media2rate(int mword)
                54,             /* IFM_IEEE80211_OFDM27 */
                -1,             /* IFM_IEEE80211_MCS */
        };
-       return IFM_SUBTYPE(mword) < NELEM(ieeerates) ?
+       return IFM_SUBTYPE(mword) < nitems(ieeerates) ?
                ieeerates[IFM_SUBTYPE(mword)] : 0;
 }
 
index a1674bd..ddd2c39 100644 (file)
  * 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.
- * 
- * $FreeBSD: head/sys/net80211/ieee80211_action.c 199186 2009-11-11 14:58:48Z antoine $
  */
 
+#include <sys/cdefs.h>
+#ifdef __FreeBSD__
+__FBSDID("$FreeBSD$");
+#endif
+
 /*
  * IEEE 802.11 send/recv action frame support.
  */
@@ -39,9 +42,9 @@
 #include <sys/socket.h>
 
 #include <net/if.h>
+#include <net/if_var.h>
 #include <net/if_media.h>
 #include <net/ethernet.h>
-#include <net/route.h>
 
 #include <netproto/802_11/ieee80211_var.h>
 #include <netproto/802_11/ieee80211_action.h>
@@ -65,10 +68,8 @@ static ieee80211_send_action_func *meshpl_send_action[8] = {
        send_inval, send_inval, send_inval, send_inval,
        send_inval, send_inval, send_inval, send_inval,
 };
-static ieee80211_send_action_func *meshlm_send_action[4] = {
+static ieee80211_send_action_func *meshaction_send_action[12] = {
        send_inval, send_inval, send_inval, send_inval,
-};
-static ieee80211_send_action_func *hwmp_send_action[8] = {
        send_inval, send_inval, send_inval, send_inval,
        send_inval, send_inval, send_inval, send_inval,
 };
@@ -82,32 +83,28 @@ ieee80211_send_action_register(int cat, int act, ieee80211_send_action_func *f)
 {
        switch (cat) {
        case IEEE80211_ACTION_CAT_BA:
-               if (act >= NELEM(ba_send_action))
+               if (act >= nitems(ba_send_action))
                        break;
                ba_send_action[act] = f;
                return 0;
        case IEEE80211_ACTION_CAT_HT:
-               if (act >= NELEM(ht_send_action))
+               if (act >= nitems(ht_send_action))
                        break;
                ht_send_action[act] = f;
                return 0;
-       case IEEE80211_ACTION_CAT_MESHPEERING:
-               if (act >= NELEM(meshpl_send_action))
+       case IEEE80211_ACTION_CAT_SELF_PROT:
+               if (act >= nitems(meshpl_send_action))
                        break;
                meshpl_send_action[act] = f;
                return 0;
-       case IEEE80211_ACTION_CAT_MESHLMETRIC:
-               if (act >= NELEM(meshlm_send_action))
-                       break;
-               meshlm_send_action[act] = f;
-               return 0;
-       case IEEE80211_ACTION_CAT_MESHPATH:
-               if (act >= NELEM(hwmp_send_action))
+       case IEEE80211_ACTION_CAT_MESH:
+               if (act >= nitems(meshaction_send_action))
                        break;
-               hwmp_send_action[act] = f;
+               meshaction_send_action[act] = f;
                return 0;
+               break;
        case IEEE80211_ACTION_CAT_VENDOR:
-               if (act >= NELEM(vendor_send_action))
+               if (act >= nitems(vendor_send_action))
                        break;
                vendor_send_action[act] = f;
                return 0;
@@ -128,27 +125,23 @@ ieee80211_send_action(struct ieee80211_node *ni, int cat, int act, void *sa)
 
        switch (cat) {
        case IEEE80211_ACTION_CAT_BA:
-               if (act < NELEM(ba_send_action))
+               if (act < nitems(ba_send_action))
                        f = ba_send_action[act];
                break;
        case IEEE80211_ACTION_CAT_HT:
-               if (act < NELEM(ht_send_action))
+               if (act < nitems(ht_send_action))
                        f = ht_send_action[act];
                break;
-       case IEEE80211_ACTION_CAT_MESHPEERING:
-               if (act < NELEM(meshpl_send_action))
+       case IEEE80211_ACTION_CAT_SELF_PROT:
+               if (act < nitems(meshpl_send_action))
                        f = meshpl_send_action[act];
                break;
-       case IEEE80211_ACTION_CAT_MESHLMETRIC:
-               if (act < NELEM(meshlm_send_action))
-                       f = meshlm_send_action[act];
-               break;
-       case IEEE80211_ACTION_CAT_MESHPATH:
-               if (act < NELEM(hwmp_send_action))
-                       f = hwmp_send_action[act];
+       case IEEE80211_ACTION_CAT_MESH:
+               if (act < nitems(meshaction_send_action))
+                       f = meshaction_send_action[act];
                break;
        case IEEE80211_ACTION_CAT_VENDOR:
-               if (act < NELEM(vendor_send_action))
+               if (act < nitems(vendor_send_action))
                        f = vendor_send_action[act];
                break;
        }
@@ -174,10 +167,8 @@ static ieee80211_recv_action_func *meshpl_recv_action[8] = {
        recv_inval, recv_inval, recv_inval, recv_inval,
        recv_inval, recv_inval, recv_inval, recv_inval,
 };
-static ieee80211_recv_action_func *meshlm_recv_action[4] = {
+static ieee80211_recv_action_func *meshaction_recv_action[12] = {
        recv_inval, recv_inval, recv_inval, recv_inval,
-};
-static ieee80211_recv_action_func *hwmp_recv_action[8] = {
        recv_inval, recv_inval, recv_inval, recv_inval,
        recv_inval, recv_inval, recv_inval, recv_inval,
 };
@@ -191,32 +182,27 @@ ieee80211_recv_action_register(int cat, int act, ieee80211_recv_action_func *f)
 {
        switch (cat) {
        case IEEE80211_ACTION_CAT_BA:
-               if (act >= NELEM(ba_recv_action))
+               if (act >= nitems(ba_recv_action))
                        break;
                ba_recv_action[act] = f;
                return 0;
        case IEEE80211_ACTION_CAT_HT:
-               if (act >= NELEM(ht_recv_action))
+               if (act >= nitems(ht_recv_action))
                        break;
                ht_recv_action[act] = f;
                return 0;
-       case IEEE80211_ACTION_CAT_MESHPEERING:
-               if (act >= NELEM(meshpl_recv_action))
+       case IEEE80211_ACTION_CAT_SELF_PROT:
+               if (act >= nitems(meshpl_recv_action))
                        break;
                meshpl_recv_action[act] = f;
                return 0;
-       case IEEE80211_ACTION_CAT_MESHLMETRIC:
-               if (act >= NELEM(meshlm_recv_action))
-                       break;
-               meshlm_recv_action[act] = f;
-               return 0;
-       case IEEE80211_ACTION_CAT_MESHPATH:
-               if (act >= NELEM(hwmp_recv_action))
+       case IEEE80211_ACTION_CAT_MESH:
+               if (act >= nitems(meshaction_recv_action))
                        break;
-               hwmp_recv_action[act] = f;
+               meshaction_recv_action[act] = f;
                return 0;
        case IEEE80211_ACTION_CAT_VENDOR:
-               if (act >= NELEM(vendor_recv_action))
+               if (act >= nitems(vendor_recv_action))
                        break;
                vendor_recv_action[act] = f;
                return 0;
@@ -236,32 +222,38 @@ ieee80211_recv_action(struct ieee80211_node *ni,
        const uint8_t *frm, const uint8_t *efrm)
 {
        ieee80211_recv_action_func *f = recv_inval;
+       struct ieee80211vap *vap = ni->ni_vap;
        const struct ieee80211_action *ia =
            (const struct ieee80211_action *) frm;
 
        switch (ia->ia_category) {
        case IEEE80211_ACTION_CAT_BA:
-               if (ia->ia_action < NELEM(ba_recv_action))
+               if (ia->ia_action < nitems(ba_recv_action))
                        f = ba_recv_action[ia->ia_action];
                break;
        case IEEE80211_ACTION_CAT_HT:
-               if (ia->ia_action < NELEM(ht_recv_action))
+               if (ia->ia_action < nitems(ht_recv_action))
                        f = ht_recv_action[ia->ia_action];
                break;
-       case IEEE80211_ACTION_CAT_MESHPEERING:
-               if (ia->ia_action < NELEM(meshpl_recv_action))
+       case IEEE80211_ACTION_CAT_SELF_PROT:
+               if (ia->ia_action < nitems(meshpl_recv_action))
                        f = meshpl_recv_action[ia->ia_action];
                break;
-       case IEEE80211_ACTION_CAT_MESHLMETRIC:
-               if (ia->ia_action < NELEM(meshlm_recv_action))
-                       f = meshlm_recv_action[ia->ia_action];
-               break;
-       case IEEE80211_ACTION_CAT_MESHPATH:
-               if (ia->ia_action < NELEM(hwmp_recv_action))
-                       f = hwmp_recv_action[ia->ia_action];
+       case IEEE80211_ACTION_CAT_MESH:
+               if (ni == vap->iv_bss ||
+                   ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) {
+                       IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
+                           ni->ni_macaddr, NULL,
+                           "peer link not yet established (%d), cat %s act %u",
+                           ni->ni_mlstate, "mesh action", ia->ia_action);
+                       vap->iv_stats.is_mesh_nolink++;
+                       break;
+               }
+               if (ia->ia_action < nitems(meshaction_recv_action))
+                       f = meshaction_recv_action[ia->ia_action];
                break;
        case IEEE80211_ACTION_CAT_VENDOR:
-               if (ia->ia_action < NELEM(vendor_recv_action))
+               if (ia->ia_action < nitems(vendor_recv_action))
                        f = vendor_recv_action[ia->ia_action];
                break;
        }
index 5b7edad..248499e 100644 (file)
  * 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.
- * 
- * $FreeBSD: head/sys/net80211/ieee80211_adhoc.c 203422 2010-02-03 10:07:43Z rpaulo $
  */
 
+#include <sys/cdefs.h>
+#ifdef __FreeBSD__
+__FBSDID("$FreeBSD$");
+#endif
+
 /*
  * IEEE 802.11 IBSS mode support.
  */
 #include <sys/sysctl.h>
 
 #include <net/if.h>
+#include <net/if_var.h>
 #include <net/if_media.h>
 #include <net/if_llc.h>
 #include <net/ethernet.h>
-#include <net/route.h>
 
 #include <net/bpf.h>
 
@@ -61,6 +64,7 @@
 #ifdef IEEE80211_SUPPORT_TDMA
 #include <netproto/802_11/ieee80211_tdma.h>
 #endif
+#include <netproto/802_11/ieee80211_sta.h>
 
 #define        IEEE80211_RATE2MBS(r)   (((r) & IEEE80211_RATE_VAL) / 2)
 
@@ -130,9 +134,8 @@ adhoc_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211_node *ni;
        enum ieee80211_state ostate;
-#ifdef IEEE80211_DEBUG
-       char ethstr[ETHER_ADDRSTRLEN + 1];
-#endif
+
+       IEEE80211_LOCK_ASSERT(vap->iv_ic);
 
        ostate = vap->iv_state;
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n",
@@ -169,7 +172,9 @@ adhoc_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
                                 * Already have a channel; bypass the
                                 * scan and startup immediately.
                                 */
-                               ieee80211_create_ibss(vap, vap->iv_des_chan);
+                               ieee80211_create_ibss(vap,
+                                   ieee80211_ht_adjust_channel(ic,
+                                   vap->iv_des_chan, vap->iv_flags_ht));
                                break;
                        }
                        /*
@@ -214,7 +219,7 @@ adhoc_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
                        if (ieee80211_msg_debug(vap)) {
                                ieee80211_note(vap,
                                    "synchronized with %s ssid ",
-                                   kether_ntoa(ni->ni_bssid, ethstr));
+                                   ether_sprintf(ni->ni_bssid));
                                ieee80211_print_essid(vap->iv_bss->ni_essid,
                                    ni->ni_esslen);
                                /* XXX MCS/HT */
@@ -241,7 +246,7 @@ adhoc_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
                        ic->ic_newassoc(ni, ostate != IEEE80211_S_RUN);
                break;
        case IEEE80211_S_SLEEP:
-               ieee80211_sta_pwrsave(vap, 0);
+               vap->iv_sta_ps(vap, 0);
                break;
        default:
        invalid:
@@ -284,7 +289,6 @@ doprint(struct ieee80211vap *vap, int subtype)
 static int
 adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
 {
-#define        SEQ_LEQ(a,b)    ((int)((a)-(b)) <= 0)
 #define        HAS_SEQ(type)   ((type & 0x4) == 0)
        struct ieee80211vap *vap = ni->ni_vap;
        struct ieee80211com *ic = ni->ni_ic;
@@ -296,9 +300,6 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
        uint8_t dir, type, subtype, qos;
        uint8_t *bssid;
        uint16_t rxseq;
-#ifdef IEEE80211_DEBUG
-       char ethstr[ETHER_ADDRSTRLEN + 1];
-#endif
 
        if (m->m_flags & M_AMPDU_MPDU) {
                /*
@@ -414,9 +415,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
                            TID_TO_WME_AC(tid) >= WME_AC_VI)
                                ic->ic_wme.wme_hipri_traffic++;
                        rxseq = le16toh(*(uint16_t *)wh->i_seq);
-                       if ((ni->ni_flags & IEEE80211_NODE_HT) == 0 &&
-                           (wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
-                           SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) {
+                       if (! ieee80211_check_rxseq(ni, wh)) {
                                /* duplicate, discard */
                                IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
                                    bssid, "duplicate",
@@ -476,7 +475,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
                 * crypto cipher modules used to do delayed update
                 * of replay sequence numbers.
                 */
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                        if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) {
                                /*
                                 * Discard encrypted frames when privacy is off.
@@ -494,7 +493,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
                                goto out;
                        }
                        wh = mtod(m, struct ieee80211_frame *);
-                       wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
+                       wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
                } else {
                        /* XXX M_WEP and IEEE80211_F_PRIVACY */
                        key = NULL;
@@ -629,10 +628,10 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
                        if_printf(ifp, "received %s from %s rssi %d\n",
                            ieee80211_mgt_subtype_name[subtype >>
                                IEEE80211_FC0_SUBTYPE_SHIFT],
-                           kether_ntoa(wh->i_addr2, ethstr), rssi);
+                           ether_sprintf(wh->i_addr2), rssi);
                }
 #endif
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                        IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
                            wh, NULL, "%s", "WEP set but not permitted");
                        vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
@@ -662,7 +661,6 @@ out:
                m_freem(m);
        }
        return type;
-#undef SEQ_LEQ
 }
 
 static int
@@ -689,8 +687,11 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
        struct ieee80211vap *vap = ni->ni_vap;
        struct ieee80211com *ic = ni->ni_ic;
        struct ieee80211_frame *wh;
-       uint8_t *frm, *efrm;
+       uint8_t *frm, *efrm, *sfrm;
        uint8_t *ssid, *rates, *xrates;
+#if 0
+       int ht_state_change = 0;
+#endif
 
        wh = mtod(m0, struct ieee80211_frame *);
        frm = (uint8_t *)&wh[1];
@@ -751,10 +752,42 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
                                memcpy(ni->ni_tstamp.data, scan.tstamp,
                                        sizeof(ni->ni_tstamp));
                        }
+                       /*
+                        * This isn't enabled yet - otherwise it would
+                        * update the HT parameters and channel width
+                        * from any node, which could lead to lots of
+                        * strange behaviour if the 11n nodes aren't
+                        * exactly configured to match.
+                        */
+#if 0
+                       if (scan.htcap != NULL && scan.htinfo != NULL &&
+                           (vap->iv_flags_ht & IEEE80211_FHT_HT)) {
+                               if (ieee80211_ht_updateparams(ni,
+                                   scan.htcap, scan.htinfo))
+                                       ht_state_change = 1;
+                       }
+#endif
                        if (ni != NULL) {
                                IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
                                ni->ni_noise = nf;
                        }
+                       /*
+                        * Same here - the channel width change should
+                        * be applied to the specific peer node, not
+                        * to the ic.  Ie, the interface configuration
+                        * should stay in its current channel width;
+                        * but it should change the rate control and
+                        * any queued frames for the given node only.
+                        *
+                        * Since there's no (current) way to inform
+                        * the driver that a channel width change has
+                        * occured for a single node, just stub this
+                        * out.
+                        */
+#if 0
+                       if (ht_state_change)
+                               ieee80211_update_chw(ic);
+#endif
                }
                break;
        }
@@ -782,6 +815,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
                 *      [tlv] extended supported rates
                 */
                ssid = rates = xrates = NULL;
+               sfrm = frm;
                while (efrm - frm > 1) {
                        IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return);
                        switch (*frm) {
@@ -824,80 +858,44 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
                    is11bclient(rates, xrates) ? IEEE80211_SEND_LEGACY_11B : 0);
                break;
 
-       case IEEE80211_FC0_SUBTYPE_ACTION: {
-               const struct ieee80211_action *ia;
-
-               if (vap->iv_state != IEEE80211_S_RUN) {
+       case IEEE80211_FC0_SUBTYPE_ACTION:
+       case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
+               if (ni == vap->iv_bss) {
+                       IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+                           wh, NULL, "%s", "unknown node");
+                       vap->iv_stats.is_rx_mgtdiscard++;
+               } else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) &&
+                   !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+                       IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+                           wh, NULL, "%s", "not for us");
+                       vap->iv_stats.is_rx_mgtdiscard++;
+               } else if (vap->iv_state != IEEE80211_S_RUN) {
                        IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
                            wh, NULL, "wrong state %s",
                            ieee80211_state_name[vap->iv_state]);
                        vap->iv_stats.is_rx_mgtdiscard++;
-                       return;
-               }
-               /*
-                * action frame format:
-                *      [1] category
-                *      [1] action
-                *      [tlv] parameters
-                */
-               IEEE80211_VERIFY_LENGTH(efrm - frm,
-                       sizeof(struct ieee80211_action), return);
-               ia = (const struct ieee80211_action *) frm;
-
-               vap->iv_stats.is_rx_action++;
-               IEEE80211_NODE_STAT(ni, rx_action);
-
-               /* verify frame payloads but defer processing */
-               /* XXX maybe push this to method */
-               switch (ia->ia_category) {
-               case IEEE80211_ACTION_CAT_BA:
-                       switch (ia->ia_action) {
-                       case IEEE80211_ACTION_BA_ADDBA_REQUEST:
-                               IEEE80211_VERIFY_LENGTH(efrm - frm,
-                                   sizeof(struct ieee80211_action_ba_addbarequest),
-                                   return);
-                               break;
-                       case IEEE80211_ACTION_BA_ADDBA_RESPONSE:
-                               IEEE80211_VERIFY_LENGTH(efrm - frm,
-                                   sizeof(struct ieee80211_action_ba_addbaresponse),
-                                   return);
-                               break;
-                       case IEEE80211_ACTION_BA_DELBA:
-                               IEEE80211_VERIFY_LENGTH(efrm - frm,
-                                   sizeof(struct ieee80211_action_ba_delba),
-                                   return);
-                               break;
-                       }
-                       break;
-               case IEEE80211_ACTION_CAT_HT:
-                       switch (ia->ia_action) {
-                       case IEEE80211_ACTION_HT_TXCHWIDTH:
-                               IEEE80211_VERIFY_LENGTH(efrm - frm,
-                                   sizeof(struct ieee80211_action_ht_txchwidth),
-                                   return);
-                               break;
-                       }
-                       break;
+               } else {
+                       if (ieee80211_parse_action(ni, m0) == 0)
+                               (void)ic->ic_recv_action(ni, wh, frm, efrm);
                }
-               ic->ic_recv_action(ni, wh, frm, efrm);
                break;
-       }
 
-       case IEEE80211_FC0_SUBTYPE_AUTH:
        case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
-       case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
        case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
+       case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
        case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
-       case IEEE80211_FC0_SUBTYPE_DEAUTH:
+       case IEEE80211_FC0_SUBTYPE_ATIM:
        case IEEE80211_FC0_SUBTYPE_DISASSOC:
+       case IEEE80211_FC0_SUBTYPE_AUTH:
+       case IEEE80211_FC0_SUBTYPE_DEAUTH:
                IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
-                    wh, NULL, "%s", "not handled");
+                   wh, NULL, "%s", "not handled");
                vap->iv_stats.is_rx_mgtdiscard++;
-               return;
+               break;
 
        default:
                IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
-                    wh, "mgt", "subtype 0x%x not handled", subtype);
+                   wh, "mgt", "subtype 0x%x not handled", subtype);
                vap->iv_stats.is_rx_badsubtype++;
                break;
        }
@@ -911,6 +909,7 @@ ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
 {
        struct ieee80211vap *vap = ni->ni_vap;
        struct ieee80211com *ic = ni->ni_ic;
+       struct ieee80211_frame *wh;
 
        /*
         * Process management frames when scanning; useful for doing
@@ -918,11 +917,42 @@ ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
         */
        if (ic->ic_flags & IEEE80211_F_SCAN)
                adhoc_recv_mgmt(ni, m0, subtype, rssi, nf);
-       else
-               vap->iv_stats.is_rx_mgtdiscard++;
+       else {
+               wh = mtod(m0, struct ieee80211_frame *);
+               switch (subtype) {
+               case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
+               case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
+               case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
+               case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
+               case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
+               case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
+               case IEEE80211_FC0_SUBTYPE_BEACON:
+               case IEEE80211_FC0_SUBTYPE_ATIM:
+               case IEEE80211_FC0_SUBTYPE_DISASSOC:
+               case IEEE80211_FC0_SUBTYPE_AUTH:
+               case IEEE80211_FC0_SUBTYPE_DEAUTH:
+               case IEEE80211_FC0_SUBTYPE_ACTION:
+               case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
+                       IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+                            wh, NULL, "%s", "not handled");
+                       vap->iv_stats.is_rx_mgtdiscard++;
+                       break;
+               default:
+                       IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
+                            wh, "mgt", "subtype 0x%x not handled", subtype);
+                       vap->iv_stats.is_rx_badsubtype++;
+                       break;
+               }
+       }
 }
 
 static void
-adhoc_recv_ctl(struct ieee80211_node *ni, struct mbuf *m0, int subtype)
+adhoc_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
 {
+
+       switch (subtype) {
+       case IEEE80211_FC0_SUBTYPE_BAR:
+               ieee80211_recv_bar(ni, m);
+               break;
+       }
 }
index ea9095a..db1d8db 100644 (file)
  * 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.
- *
- * $FreeBSD: head/sys/net80211/ieee80211_ageq.c 195527 2009-07-10 02:19:57Z sam $
  */
 
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 /*
  * IEEE 802.11 age queue support.
  */
@@ -37,9 +38,9 @@
 #include <sys/socket.h>
 
 #include <net/if.h>
+#include <net/if_var.h>
 #include <net/if_media.h>
 #include <net/ethernet.h>
-#include <net/route.h>
 
 #include <netproto/802_11/ieee80211_var.h>
 
@@ -51,6 +52,7 @@ ieee80211_ageq_init(struct ieee80211_ageq *aq, int maxlen, const char *name)
 {
        memset(aq, 0, sizeof(*aq));
        aq->aq_maxlen = maxlen;
+       IEEE80211_AGEQ_INIT(aq, name);          /* OS-dependent setup */
 }
 
 /*
@@ -61,6 +63,7 @@ void
 ieee80211_ageq_cleanup(struct ieee80211_ageq *aq)
 {
        KASSERT(aq->aq_len == 0, ("%d frames on ageq", aq->aq_len));
+       IEEE80211_AGEQ_DESTROY(aq);             /* OS-dependent cleanup */
 }
 
 /*
@@ -101,6 +104,7 @@ ieee80211_ageq_mfree(struct mbuf *m)
 int
 ieee80211_ageq_append(struct ieee80211_ageq *aq, struct mbuf *m, int age)
 {
+       IEEE80211_AGEQ_LOCK(aq);
        if (__predict_true(aq->aq_len < aq->aq_maxlen)) {
                if (aq->aq_tail == NULL) {
                        aq->aq_head = m;
@@ -113,12 +117,14 @@ ieee80211_ageq_append(struct ieee80211_ageq *aq, struct mbuf *m, int age)
                m->m_nextpkt = NULL;
                aq->aq_tail = m;
                aq->aq_len++;
+               IEEE80211_AGEQ_UNLOCK(aq);
                return 0;
        } else {
                /*
                 * No space, drop and cleanup references.
                 */
                aq->aq_drops++;
+               IEEE80211_AGEQ_UNLOCK(aq);
                /* XXX tail drop? */
                ageq_mfree(m);
                return ENOSPC;
@@ -149,7 +155,7 @@ ieee80211_ageq_drain_node(struct ieee80211_ageq *aq,
  * deltas (in seconds) relative to the head so we can check
  * and/or adjust only the head of the list.  If a frame's age
  * exceeds the time quanta then remove it.  The list of removed
- * frames is is returned to the caller joined by m_nextpkt.
+ * frames is returned to the caller joined by m_nextpkt.
  */
 struct mbuf *
 ieee80211_ageq_age(struct ieee80211_ageq *aq, int quanta)
@@ -159,6 +165,7 @@ ieee80211_ageq_age(struct ieee80211_ageq *aq, int quanta)
 
        phead = &head;
        if (aq->aq_len != 0) {
+               IEEE80211_AGEQ_LOCK(aq);
                while ((m = aq->aq_head) != NULL && M_AGE_GET(m) < quanta) {
                        if ((aq->aq_head = m->m_nextpkt) == NULL)
                                aq->aq_tail = NULL;
@@ -170,6 +177,7 @@ ieee80211_ageq_age(struct ieee80211_ageq *aq, int quanta)
                }
                if (m != NULL)
                        M_AGE_SUB(m, quanta);
+               IEEE80211_AGEQ_UNLOCK(aq);
        }
        *phead = NULL;
        return head;
@@ -187,6 +195,7 @@ ieee80211_ageq_remove(struct ieee80211_ageq *aq,
        struct mbuf *m, **prev, *ohead;
        struct mbuf *head, **phead;
 
+       IEEE80211_AGEQ_LOCK(aq);
        ohead = aq->aq_head;
        prev = &aq->aq_head;
        phead = &head;
@@ -222,6 +231,7 @@ ieee80211_ageq_remove(struct ieee80211_ageq *aq,
        }
        if (head == ohead && aq->aq_head != NULL)       /* correct age */
                M_AGE_SET(aq->aq_head, M_AGE_GET(head));
+       IEEE80211_AGEQ_UNLOCK(aq);
 
        *phead = NULL;
        return head;
diff --git a/sys/netproto/802_11/wlan/ieee80211_alq.c b/sys/netproto/802_11/wlan/ieee80211_alq.c
new file mode 100644 (file)
index 0000000..7604395
--- /dev/null
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (c) 2011 Adrian Chadd, Xenion Lty Ltd
+ * 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.
+ *
+ * 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>
+#ifdef __FreeBSD__
+__FBSDID("$FreeBSD$");
+#endif
+
+/*
+ * net80211 fast-logging support, primarily for debugging.
+ *
+ * This implements a single debugging queue which includes
+ * per-device enumeration where needed.
+ */
+
+#include "opt_wlan.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/ucred.h>
+#include <sys/alq.h>
+
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_media.h>
+#include <net/ethernet.h>
+
+#include <netproto/802_11/ieee80211_var.h>
+#include <netproto/802_11/ieee80211_freebsd.h>
+#include <netproto/802_11/ieee80211_alq.h>
+
+static struct alq *ieee80211_alq;
+static int ieee80211_alq_lost;
+static int ieee80211_alq_logged;
+static char ieee80211_alq_logfile[MAXPATHLEN] = "/tmp/net80211.log";
+static unsigned int ieee80211_alq_qsize = 64*1024;
+
+static int
+ieee80211_alq_setlogging(int enable)
+{
+       int error;
+
+       if (enable) {
+               if (ieee80211_alq)
+                       alq_close(ieee80211_alq);
+
+               error = alq_open(&ieee80211_alq,
+                   ieee80211_alq_logfile,
+                   curthread->td_ucred,
+                   ALQ_DEFAULT_CMODE,
+                   sizeof (struct ieee80211_alq_rec),
+                   ieee80211_alq_qsize);
+               ieee80211_alq_lost = 0;
+               ieee80211_alq_logged = 0;
+               kprintf("net80211: logging to %s enabled; "
+                   "struct size %d bytes\n",
+                   ieee80211_alq_logfile,
+                   sizeof(struct ieee80211_alq_rec));
+       } else {
+               if (ieee80211_alq)
+                       alq_close(ieee80211_alq);
+               ieee80211_alq = NULL;
+               kprintf("net80211: logging disabled\n");
+               error = 0;
+       }
+       return (error);
+}
+
+static int
+sysctl_ieee80211_alq_log(SYSCTL_HANDLER_ARGS)
+{
+       int error, enable;
+
+       enable = (ieee80211_alq != NULL);
+       error = sysctl_handle_int(oidp, &enable, 0, req);
+       if (error || !req->newptr)
+               return (error);
+       else
+               return (ieee80211_alq_setlogging(enable));
+}
+
+SYSCTL_PROC(_net_wlan, OID_AUTO, alq, CTLTYPE_INT|CTLFLAG_RW,
+       0, 0, sysctl_ieee80211_alq_log, "I", "Enable net80211 alq logging");
+SYSCTL_INT(_net_wlan, OID_AUTO, alq_size, CTLFLAG_RW,
+       &ieee80211_alq_qsize, 0, "In-memory log size (#records)");
+SYSCTL_INT(_net_wlan, OID_AUTO, alq_lost, CTLFLAG_RW,
+       &ieee80211_alq_lost, 0, "Debugging operations not logged");
+SYSCTL_INT(_net_wlan, OID_AUTO, alq_logged, CTLFLAG_RW,
+       &ieee80211_alq_logged, 0, "Debugging operations logged");
+
+static struct ale *
+ieee80211_alq_get(void)
+{
+       struct ale *ale;
+
+       ale = alq_get(ieee80211_alq, ALQ_NOWAIT);
+       if (!ale)
+               ieee80211_alq_lost++;
+       else
+               ieee80211_alq_logged++;
+       return ale;
+}
+
+void
+ieee80211_alq_log(struct ieee80211vap *vap, uint8_t op, u_char *p, int l)
+{
+       struct ale *ale;
+       struct ieee80211_alq_rec *r;
+
+       if (ieee80211_alq == NULL)
+               return;
+
+       ale = ieee80211_alq_get();
+       if (! ale)
+               return;
+
+       r = (struct ieee80211_alq_rec *) ale->ae_data;
+       r->r_timestamp = htonl(ticks);
+       r->r_version = 1;
+       r->r_wlan = htons(vap->iv_ifp->if_dunit);
+       r->r_op = op;
+       r->r_threadid = htonl((uint32_t) curthread->td_tid);
+       memcpy(&r->r_payload, p, MIN(l, sizeof(r->r_payload)));
+       alq_post(ieee80211_alq, ale);
+}
index 084f858..36d7ed5 100644 (file)
  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $FreeBSD: head/sys/net80211/ieee80211_amrr.c 206358 2010-04-07 15:29:13Z rpaulo $
  */
 
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
 /*-
  * Naive implementation of the Adaptive Multi Rate Retry algorithm:
@@ -38,7 +38,9 @@
 #include <sys/sysctl.h>
 
 #include <net/if.h>
+#include <net/if_var.h>
 #include <net/if_media.h>
+#include <net/ethernet.h>
 
 #ifdef INET
 #include <netinet/in.h>
@@ -46,6 +48,7 @@
 #endif
 
 #include <netproto/802_11/ieee80211_var.h>
+#include <netproto/802_11/ieee80211_ht.h>
 #include <netproto/802_11/ieee80211_amrr.h>
 #include <netproto/802_11/ieee80211_ratectl.h>
 
@@ -110,9 +113,12 @@ amrr_init(struct ieee80211vap *vap)
 
        KASSERT(vap->iv_rs == NULL, ("%s called multiple times", __func__));
 
-       vap->iv_rs = kmalloc(sizeof(struct ieee80211_amrr), M_80211_RATECTL,
-           M_WAITOK|M_ZERO);
-       amrr = vap->iv_rs;
+       amrr = vap->iv_rs = kmalloc(sizeof(struct ieee80211_amrr),
+           M_80211_RATECTL, M_INTWAIT|M_ZERO);
+       if (amrr == NULL) {
+               if_printf(vap->iv_ifp, "couldn't alloc ratectl structure\n");
+               return;
+       }
        amrr->amrr_min_success_threshold = IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD;
        amrr->amrr_max_success_threshold = IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD;
        amrr_setinterval(vap, 500 /* ms */);
@@ -125,44 +131,101 @@ amrr_deinit(struct ieee80211vap *vap)
        kfree(vap->iv_rs, M_80211_RATECTL);
 }
 
+/*
+ * Return whether 11n rates are possible.
+ *
+ * Some 11n devices may return HT information but no HT rates.
+ * Thus, we shouldn't treat them as an 11n node.
+ */
+static int
+amrr_node_is_11n(struct ieee80211_node *ni)
+{
+
+       if (ni->ni_chan == NULL)
+               return (0);
+       if (ni->ni_chan == IEEE80211_CHAN_ANYC)
+               return (0);
+       if (IEEE80211_IS_CHAN_HT(ni->ni_chan) && ni->ni_htrates.rs_nrates == 0)
+               return (0);
+       return (IEEE80211_IS_CHAN_HT(ni->ni_chan));
+}
+
 static void
 amrr_node_init(struct ieee80211_node *ni)
 {
-       const struct ieee80211_rateset *rs = &ni->ni_rates;
+       const struct ieee80211_rateset *rs = NULL;
        struct ieee80211vap *vap = ni->ni_vap;
        struct ieee80211_amrr *amrr = vap->iv_rs;
        struct ieee80211_amrr_node *amn;
+       uint8_t rate;
 
        if (ni->ni_rctls == NULL) {
-               ni->ni_rctls = amn =
-                   kmalloc(sizeof(struct ieee80211_amrr_node),
-                       M_80211_RATECTL, M_WAITOK|M_ZERO);
-       } else {
+               ni->ni_rctls = amn = kmalloc(sizeof(struct ieee80211_amrr_node),
+                   M_80211_RATECTL, M_INTWAIT|M_ZERO);
+               if (amn == NULL) {
+                       if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl "
+                           "structure\n");
+                       return;
+               }
+       } else
                amn = ni->ni_rctls;
-       }
        amn->amn_amrr = amrr;
        amn->amn_success = 0;
        amn->amn_recovery = 0;
        amn->amn_txcnt = amn->amn_retrycnt = 0;
        amn->amn_success_threshold = amrr->amrr_min_success_threshold;
 
-       /* pick initial rate */
-       for (amn->amn_rix = rs->rs_nrates - 1;
-            amn->amn_rix > 0 && (rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL) > 72;
-            amn->amn_rix--)
-               ;
-       ni->ni_txrate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL;
+       /* 11n or not? Pick the right rateset */
+       if (amrr_node_is_11n(ni)) {
+               /* XXX ew */
+               IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+                   "%s: 11n node", __func__);
+               rs = (struct ieee80211_rateset *) &ni->ni_htrates;
+       } else {
+               IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+                   "%s: non-11n node", __func__);
+               rs = &ni->ni_rates;
+       }
+
+       /* Initial rate - lowest */
+       rate = rs->rs_rates[0];
+
+       /* XXX clear the basic rate flag if it's not 11n */
+       if (! amrr_node_is_11n(ni))
+               rate &= IEEE80211_RATE_VAL;
+
+       /* pick initial rate from the rateset - HT or otherwise */
+       /* Pick something low that's likely to succeed */
+       for (amn->amn_rix = rs->rs_nrates - 1; amn->amn_rix > 0;
+           amn->amn_rix--) {
+               /* legacy - anything < 36mbit, stop searching */
+               /* 11n - stop at MCS4 */
+               if (amrr_node_is_11n(ni)) {
+                       if ((rs->rs_rates[amn->amn_rix] & 0x1f) < 4)
+                               break;
+               } else if ((rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL) <= 72)
+                       break;
+       }
+       rate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL;
+
+       /* if the rate is an 11n rate, ensure the MCS bit is set */
+       if (amrr_node_is_11n(ni))
+               rate |= IEEE80211_RATE_MCS;
+
+       /* Assign initial rate from the rateset */
+       ni->ni_txrate = rate;
        amn->amn_ticks = ticks;
 
        IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
-           "AMRR initial rate %d", ni->ni_txrate);
+           "AMRR: nrates=%d, initial rate %d",
+           rs->rs_nrates,
+           rate);
 }
 
 static void
 amrr_node_deinit(struct ieee80211_node *ni)
 {
        kfree(ni->ni_rctls, M_80211_RATECTL);
-       ni->ni_rctls = NULL;
 }
 
 static int
@@ -170,19 +233,42 @@ amrr_update(struct ieee80211_amrr *amrr, struct ieee80211_amrr_node *amn,
     struct ieee80211_node *ni)
 {
        int rix = amn->amn_rix;
+       const struct ieee80211_rateset *rs = NULL;
 
        KASSERT(is_enough(amn), ("txcnt %d", amn->amn_txcnt));
 
+       /* 11n or not? Pick the right rateset */
+       if (amrr_node_is_11n(ni)) {
+               /* XXX ew */
+               rs = (struct ieee80211_rateset *) &ni->ni_htrates;
+       } else {
+               rs = &ni->ni_rates;
+       }
+
+       IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
+           "AMRR: current rate %d, txcnt=%d, retrycnt=%d",
+           rs->rs_rates[rix] & IEEE80211_RATE_VAL,
+           amn->amn_txcnt,
+           amn->amn_retrycnt);
+
+       /*
+        * XXX This is totally bogus for 11n, as although high MCS
+        * rates for each stream may be failing, the next stream
+        * should be checked.
+        *
+        * Eg, if MCS5 is ok but MCS6/7 isn't, and we can go up to
+        * MCS23, we should skip 6/7 and try 8 onwards.
+        */
        if (is_success(amn)) {
                amn->amn_success++;
                if (amn->amn_success >= amn->amn_success_threshold &&
-                   rix + 1 < ni->ni_rates.rs_nrates) {
+                   rix + 1 < rs->rs_nrates) {
                        amn->amn_recovery = 1;
                        amn->amn_success = 0;
                        rix++;
                        IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
                            "AMRR increasing rate %d (txcnt=%d retrycnt=%d)",
-                           ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL,
+                           rs->rs_rates[rix] & IEEE80211_RATE_VAL,
                            amn->amn_txcnt, amn->amn_retrycnt);
                } else {
                        amn->amn_recovery = 0;
@@ -203,7 +289,7 @@ amrr_update(struct ieee80211_amrr *amrr, struct ieee80211_amrr_node *amn,
                        rix--;
                        IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
                            "AMRR decreasing rate %d (txcnt=%d retrycnt=%d)",
-                           ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL,
+                           rs->rs_rates[rix] & IEEE80211_RATE_VAL,
                            amn->amn_txcnt, amn->amn_retrycnt);
                }
                amn->amn_recovery = 0;
@@ -226,14 +312,27 @@ amrr_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg __unused)
 {
        struct ieee80211_amrr_node *amn = ni->ni_rctls;
        struct ieee80211_amrr *amrr = amn->amn_amrr;
+       const struct ieee80211_rateset *rs = NULL;
        int rix;
 
+       /* 11n or not? Pick the right rateset */
+       if (amrr_node_is_11n(ni)) {
+               /* XXX ew */
+               rs = (struct ieee80211_rateset *) &ni->ni_htrates;
+       } else {
+               rs = &ni->ni_rates;
+       }
+
        if (is_enough(amn) && (ticks - amn->amn_ticks) > amrr->amrr_interval) {
                rix = amrr_update(amrr, amn, ni);
                if (rix != amn->amn_rix) {
                        /* update public rate */
-                       ni->ni_txrate =
-                           ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL;
+                       ni->ni_txrate = rs->rs_rates[rix];
+                       /* XXX strip basic rate flag from txrate, if non-11n */
+                       if (amrr_node_is_11n(ni))
+                               ni->ni_txrate |= IEEE80211_RATE_MCS;
+                       else
+                               ni->ni_txrate &= IEEE80211_RATE_VAL;
                        amn->amn_rix = rix;
                }
                amn->amn_ticks = ticks;
@@ -287,12 +386,10 @@ amrr_sysctl_interval(SYSCTL_HANDLER_ARGS)
        int error;
 
        error = sysctl_handle_int(oidp, &msecs, 0, req);
-       wlan_serialize_enter();
-       if (error == 0 && req->newptr)
-               amrr_setinterval(vap, msecs);
-       wlan_serialize_exit();
-
-       return error;
+       if (error || !req->newptr)
+               return error;
+       amrr_setinterval(vap, msecs);
+       return 0;
 }
 
 static void
@@ -305,10 +402,10 @@ amrr_sysctlattach(struct ieee80211vap *vap,
            "amrr_rate_interval", CTLTYPE_INT | CTLFLAG_RW, vap,
            0, amrr_sysctl_interval, "I", "amrr operation interval (ms)");
        /* XXX bounds check values */
-       SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+       SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
            "amrr_max_sucess_threshold", CTLFLAG_RW,
            &amrr->amrr_max_success_threshold, 0, "");
-       SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+       SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
            "amrr_min_sucess_threshold", CTLFLAG_RW,
            &amrr->amrr_min_success_threshold, 0, "");
 }
index bea62df..6d213d2 100644 (file)
  * 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.
- *
- * $FreeBSD: head/sys/net80211/ieee80211_crypto.c 195812 2009-07-21 19:36:32Z sam $
  */
 
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 /*
  * IEEE 802.11 generic crypto support.
  */
@@ -41,7 +42,6 @@
 #include <net/if.h>
 #include <net/if_media.h>
 #include <net/ethernet.h>              /* XXX ETHER_HDR_LEN */
-#include <net/route.h>
 
 #include <netproto/802_11/ieee80211_var.h>
 
@@ -323,10 +323,6 @@ ieee80211_crypto_newkey(struct ieee80211vap *vap,
                    __func__, cip->ic_name);
                flags |= IEEE80211_KEY_SWCRYPT;
        }
-       if (ieee80211_force_swcrypto) {
-               flags |= IEEE80211_KEY_SWCRYPT;
-               flags |= IEEE80211_KEY_SWMIC;
-       }
        /*
         * Hardware TKIP with software MIC is an important
         * combination; we handle it by flagging each key,
@@ -492,16 +488,13 @@ int
 ieee80211_crypto_setkey(struct ieee80211vap *vap, struct ieee80211_key *key)
 {
        const struct ieee80211_cipher *cip = key->wk_cipher;
-#ifdef IEEE80211_DEBUG
-       char ethstr[ETHER_ADDRSTRLEN + 1];
-#endif
 
        KASSERT(cip != NULL, ("No cipher!"));
 
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO,
            "%s: %s keyix %u flags 0x%x mac %s rsc %ju tsc %ju len %u\n",
            __func__, cip->ic_name, key->wk_keyix,
-           key->wk_flags, kether_ntoa(key->wk_macaddr, ethstr),
+           key->wk_flags, ether_sprintf(key->wk_macaddr),
            key->wk_keyrsc[IEEE80211_NONQOS_TID], key->wk_keytsc,
            key->wk_keylen);
 
index f9ba1f7..da799a9 100644 (file)
  * 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.
- *
- * $FreeBSD: head/sys/net80211/ieee80211_crypto_none.c 178354 2008-04-20 20:35:46Z sam $
  */
 
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 /*
  * IEEE 802.11 NULL crypto support.
  */
@@ -41,7 +42,6 @@
 #include <net/if.h>
 #include <net/if_media.h>
 #include <net/ethernet.h>
-#include <net/route.h>
 
 #include <netproto/802_11/ieee80211_var.h>
 
index 104e5bc..8a53b12 100644 (file)
  * 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.
- *
- * $FreeBSD: head/sys/net80211/ieee80211_ddb.c 196019 2009-08-01 19:26:27Z rwatson $
  */
 
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include "opt_ddb.h"
 #include "opt_wlan.h"
 
 #include <sys/socket.h>
 
 #include <net/if.h>
+#include <net/if_var.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
 #include <net/if_types.h>
 #include <net/ethernet.h>
-#include <net/route.h>
+/*#include <net/vnet.h>*/
 
 #include <netproto/802_11/ieee80211_var.h>
 #ifdef IEEE80211_SUPPORT_TDMA
@@ -62,9 +64,9 @@
 } while (0)
 
 static void _db_show_sta(const struct ieee80211_node *);
-static void _db_show_vap(const struct ieee80211vap *, int);
+static void _db_show_vap(const struct ieee80211vap *, int, int);
 static void _db_show_com(const struct ieee80211com *,
-       int showvaps, int showsta, int showprocs);
+       int showvaps, int showsta, int showmesh, int showprocs);
 
 static void _db_show_node_table(const char *tag,
        const struct ieee80211_node_table *);
@@ -78,11 +80,9 @@ static void _db_show_txparams(const char *tag, const void *arg,
        const struct ieee80211_txparam *tp);
 static void _db_show_ageq(const char *tag, const struct ieee80211_ageq *q);
 static void _db_show_stats(const struct ieee80211_stats *);
-#if 0
 #ifdef IEEE80211_SUPPORT_MESH
 static void _db_show_mesh(const struct ieee80211_mesh_state *);
 #endif
-#endif
 
 DB_SHOW_COMMAND(sta, db_show_sta)
 {
@@ -104,7 +104,7 @@ DB_SHOW_COMMAND(statab, db_show_statab)
 
 DB_SHOW_COMMAND(vap, db_show_vap)
 {
-       int i, showprocs = 0;
+       int i, showmesh = 0, showprocs = 0;
 
        if (!have_addr) {
                db_printf("usage: show vap <addr>\n");
@@ -114,18 +114,22 @@ DB_SHOW_COMMAND(vap, db_show_vap)
                switch (modif[i]) {
                case 'a':
                        showprocs = 1;
+                       showmesh = 1;
+                       break;
+               case 'm':
+                       showmesh = 1;
                        break;
                case 'p':
                        showprocs = 1;
                        break;
                }
-       _db_show_vap((const struct ieee80211vap *) addr, showprocs);
+       _db_show_vap((const struct ieee80211vap *) addr, showmesh, showprocs);
 }
 
 DB_SHOW_COMMAND(com, db_show_com)
 {
        const struct ieee80211com *ic;
-       int i, showprocs = 0, showvaps = 0, showsta = 0;
+       int i, showprocs = 0, showvaps = 0, showsta = 0, showmesh = 0;
 
        if (!have_addr) {
                db_printf("usage: show com <addr>\n");
@@ -134,11 +138,14 @@ DB_SHOW_COMMAND(com, db_show_com)
        for (i = 0; modif[i] != '\0'; i++)
                switch (modif[i]) {
                case 'a':
-                       showsta = showvaps = showprocs = 1;
+                       showsta = showmesh = showvaps = showprocs = 1;
                        break;
                case 's':
                        showsta = 1;
                        break;
+               case 'm':
+                       showmesh = 1;
+                       break;
                case 'v':
                        showvaps = 1;
                        break;
@@ -148,12 +155,14 @@ DB_SHOW_COMMAND(com, db_show_com)
                }
 
        ic = (const struct ieee80211com *) addr;
-       _db_show_com(ic, showvaps, showsta, showprocs);
+       _db_show_com(ic, showvaps, showsta, showmesh, showprocs);
 }
 
-#ifdef __FreeBSD__
+#if !defined(__DragonFly__)
+
 DB_SHOW_ALL_COMMAND(vaps, db_show_all_vaps)
 {
+       VNET_ITERATOR_DECL(vnet_iter);
        const struct ifnet *ifp;
        int i, showall = 0;
 
@@ -164,27 +173,26 @@ DB_SHOW_ALL_COMMAND(vaps, db_show_all_vaps)
                        break;
                }
 
-       TAILQ_FOREACH(ifp, &ifnet, if_list) {
-               if (ifp->if_type == IFT_IEEE80211) {
-                       const struct ieee80211com *ic = ifp->if_l2com;
-
-                       if (!showall) {
-                               const struct ieee80211vap *vap;
-                               db_printf("%s: com %p vaps:",
-                                   ifp->if_xname, ic);
-                               TAILQ_FOREACH(vap, &ic->ic_vaps,
-                                   iv_next)
-                                       db_printf(" %s(%p)",
-                                           vap->iv_ifp->if_xname, vap);
-                               db_printf("\n");
-                       } else
-                               _db_show_com(ic, 1, 1, 1);
-               }
+       VNET_FOREACH(vnet_iter) {
+               TAILQ_FOREACH(ifp, &V_ifnet, if_list)
+                       if (ifp->if_type == IFT_IEEE80211) {
+                               const struct ieee80211com *ic = ifp->if_l2com;
+
+                               if (!showall) {
+                                       const struct ieee80211vap *vap;
+                                       db_printf("%s: com %p vaps:",
+                                           ifp->if_xname, ic);
+                                       TAILQ_FOREACH(vap, &ic->ic_vaps,
+                                           iv_next)
+                                               db_printf(" %s(%p)",
+                                                   vap->iv_ifp->if_xname, vap);
+                                       db_printf("\n");
+                               } else
+                                       _db_show_com(ic, 1, 1, 1, 1);
+                       }
        }
 }
-#endif
 
-#if 0
 #ifdef IEEE80211_SUPPORT_MESH
 DB_SHOW_ALL_COMMAND(mesh, db_show_mesh)
 {
@@ -198,6 +206,7 @@ DB_SHOW_ALL_COMMAND(mesh, db_show_mesh)
        _db_show_mesh(ms);
 }
 #endif /* IEEE80211_SUPPORT_MESH */
+
 #endif
 
 static void
@@ -205,7 +214,7 @@ _db_show_txampdu(const char *sep, int ix, const struct ieee80211_tx_ampdu *tap)
 {
        db_printf("%stxampdu[%d]: %p flags %b %s\n",
                sep, ix, tap, tap->txa_flags, IEEE80211_AGGR_BITS,
-               ieee80211_wme_acnames[tap->txa_ac]);
+               ieee80211_wme_acnames[TID_TO_WME_AC(tap->txa_tid)]);
        db_printf("%s  token %u lastsample %d pkts %d avgpps %d qbytes %d qframes %d\n",
                sep, tap->txa_token, tap->txa_lastsample, tap->txa_pkts,
                tap->txa_avgpps, tap->txa_qbytes, tap->txa_qframes);
@@ -238,10 +247,9 @@ static void
 _db_show_sta(const struct ieee80211_node *ni)
 {
        int i;
-       char ethstr[ETHER_ADDRSTRLEN + 1];
 
        db_printf("0x%p: mac %s refcnt %d\n", ni,
-               kether_ntoa(ni->ni_macaddr, ethstr), ieee80211_node_refcnt(ni));
+               ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni));
        db_printf("\tvap %p wdsvap %p ic %p table %p\n",
                ni->ni_vap, ni->ni_wdsvap, ni->ni_ic, ni->ni_table);
        db_printf("\tflags=%b\n", ni->ni_flags, IEEE80211_NODE_BITS);
@@ -250,8 +258,8 @@ _db_show_sta(const struct ieee80211_node *ni)
                ni->ni_ath_flags, ni->ni_ath_defkeyix);
        db_printf("\tassocid 0x%x txpower %u vlan %u\n",
                ni->ni_associd, ni->ni_txpower, ni->ni_vlan);
-       db_printf("\tjointime %lu (%lu secs) challenge %p\n",
-               (unsigned long)ni->ni_jointime, (unsigned long)(time_uptime - ni->ni_jointime),
+       db_printf("\tjointime %d (%lu secs) challenge %p\n",
+               ni->ni_jointime, (unsigned long)(time_uptime - ni->ni_jointime),
                ni->ni_challenge);
        db_printf("\ties: data %p len %d\n", ni->ni_ies.data, ni->ni_ies.len);
        db_printf("\t[wpa_ie %p rsn_ie %p wme_ie %p ath_ie %p\n",
@@ -281,7 +289,7 @@ _db_show_sta(const struct ieee80211_node *ni)
                ni->ni_noise);
        db_printf("\tintval %u capinfo %b\n",
                ni->ni_intval, ni->ni_capinfo, IEEE80211_CAPINFO_BITS);
-       db_printf("\tbssid %s", kether_ntoa(ni->ni_bssid, ethstr));
+       db_printf("\tbssid %s", ether_sprintf(ni->ni_bssid));
        _db_show_ssid(" essid ", 0, ni->ni_esslen, ni->ni_essid);
        db_printf("\n");
        _db_show_channel("\tchannel", ni->ni_chan);
@@ -297,7 +305,7 @@ _db_show_sta(const struct ieee80211_node *ni)
                ni->ni_htopmode, ni->ni_htstbc, ni->ni_chw);
 
        /* XXX ampdu state */
-       for (i = 0; i < WME_NUM_AC; i++)
+       for (i = 0; i < WME_NUM_TID; i++)
                if (ni->ni_tx_ampdu[i].txa_flags & IEEE80211_AGGR_SETUP)
                        _db_show_txampdu("\t", i, &ni->ni_tx_ampdu[i]);
        for (i = 0; i < WME_NUM_TID; i++)
@@ -334,18 +342,21 @@ _db_show_tdma(const char *sep, const struct ieee80211_tdma_state *ts, int showpr
 #endif /* IEEE80211_SUPPORT_TDMA */
 
 static void
-_db_show_vap(const struct ieee80211vap *vap, int showprocs)
+_db_show_vap(const struct ieee80211vap *vap, int showmesh, int showprocs)
 {
        const struct ieee80211com *ic = vap->iv_ic;
-       char ethstr[ETHER_ADDRSTRLEN + 1];
        int i;
 
        db_printf("%p:", vap);
        db_printf(" bss %p", vap->iv_bss);
-       db_printf(" myaddr %s", kether_ntoa(vap->iv_myaddr, ethstr));
+       db_printf(" myaddr %s", ether_sprintf(vap->iv_myaddr));
        db_printf("\n");
 
        db_printf("\topmode %s", ieee80211_opmode_name[vap->iv_opmode]);
+#ifdef IEEE80211_SUPPORT_MESH
+       if (vap->iv_opmode == IEEE80211_M_MBSS)
+               db_printf("(%p)", vap->iv_mesh);
+#endif
        db_printf(" state %s", ieee80211_state_name[vap->iv_state]);
        db_printf(" ifp %p(%s)", vap->iv_ifp, vap->iv_ifp->if_xname);
        db_printf("\n");
@@ -379,7 +390,7 @@ _db_show_vap(const struct ieee80211vap *vap, int showprocs)
        if (vap->iv_des_nssid)
                _db_show_ssid(" des_ssid[%u] ", 0,
                    vap->iv_des_ssid[0].len, vap->iv_des_ssid[0].ssid);
-       db_printf(" des_bssid %s", kether_ntoa(vap->iv_des_bssid, ethstr));
+       db_printf(" des_bssid %s", ether_sprintf(vap->iv_des_bssid));
        db_printf("\n");
        db_printf("\tdes_mode %d", vap->iv_des_mode);
        _db_show_channel(" des_chan", vap->iv_des_chan);
@@ -477,6 +488,10 @@ _db_show_vap(const struct ieee80211vap *vap, int showprocs)
        db_printf(" acl %p", vap->iv_acl);
        db_printf(" as %p", vap->iv_as);
        db_printf("\n");
+#ifdef IEEE80211_SUPPORT_MESH
+       if (showmesh && vap->iv_mesh != NULL)
+               _db_show_mesh(vap->iv_mesh);
+#endif
 #ifdef IEEE80211_SUPPORT_TDMA
        if (vap->iv_tdma != NULL)
                _db_show_tdma("\t", vap->iv_tdma, showprocs);
@@ -500,7 +515,8 @@ _db_show_vap(const struct ieee80211vap *vap, int showprocs)
 }
 
 static void
-_db_show_com(const struct ieee80211com *ic, int showvaps, int showsta, int showprocs)
+_db_show_com(const struct ieee80211com *ic, int showvaps, int showsta,
+    int showmesh, int showprocs)
 {
        struct ieee80211vap *vap;
 
@@ -509,6 +525,7 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta, int showp
                db_printf(" %s(%p)", vap->iv_ifp->if_xname, vap);
        db_printf("\n");
        db_printf("\tifp %p(%s)", ic->ic_ifp, ic->ic_ifp->if_xname);
+       db_printf(" comlock %p", &ic->ic_comlock);
        db_printf("\n");
        db_printf("\theadroom %d", ic->ic_headroom);
        db_printf(" phytype %d", ic->ic_phytype);
@@ -655,7 +672,7 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta, int showp
        if (showvaps && !TAILQ_EMPTY(&ic->ic_vaps)) {
                db_printf("\n");
                TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
-                       _db_show_vap(vap, showprocs);
+                       _db_show_vap(vap, showmesh, showprocs);
        }
        if (showsta && !TAILQ_EMPTY(&ic->ic_sta.nt_node)) {
                const struct ieee80211_node_table *nt = &ic->ic_sta;
@@ -671,11 +688,12 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta, int showp
 static void
 _db_show_node_table(const char *tag, const struct ieee80211_node_table *nt)
 {
-       char ethstr[ETHER_ADDRSTRLEN + 1];
        int i;
 
        db_printf("%s%s@%p:\n", tag, nt->nt_name, nt);
+       db_printf("%s nodelock %p", tag, &nt->nt_nodelock);
        db_printf(" inact_init %d", nt->nt_inact_init);
+       db_printf(" scanlock %p", &nt->nt_scanlock);
        db_printf(" scangen %u\n", nt->nt_scangen);
        db_printf("%s keyixmax %d keyixmap %p\n",
            tag, nt->nt_keyixmax, nt->nt_keyixmap);
@@ -683,7 +701,7 @@ _db_show_node_table(const char *tag, const struct ieee80211_node_table *nt)
                const struct ieee80211_node *ni = nt->nt_keyixmap[i];
                if (ni != NULL)
                        db_printf("%s [%3u] %p %s\n", tag, i, ni,
-                           kether_ntoa(ni->ni_macaddr, ethstr));
+                           ether_sprintf(ni->ni_macaddr));
        }
 }
 
@@ -844,8 +862,8 @@ _db_show_ageq(const char *tag, const struct ieee80211_ageq *q)
 {
        const struct mbuf *m;
 
-       db_printf("%s len %d maxlen %d drops %d head %p tail %p\n",
-           tag, q->aq_len, q->aq_maxlen, q->aq_drops,
+       db_printf("%s lock %p len %d maxlen %d drops %d head %p tail %p\n",
+           tag, &q->aq_lock, q->aq_len, q->aq_maxlen, q->aq_drops,
            q->aq_head, q->aq_tail);
        for (m = q->aq_head; m != NULL; m = m->m_nextpkt)
                db_printf("%s %p (len %d, %b)\n", tag, m, m->m_len,
@@ -858,13 +876,11 @@ _db_show_stats(const struct ieee80211_stats *is)
 {
 }
 
-#if 0
 #ifdef IEEE80211_SUPPORT_MESH
 static void
 _db_show_mesh(const struct ieee80211_mesh_state *ms)
 {
        struct ieee80211_mesh_route *rt;
-       char ethstr[2][ETHER_ADDRSTRLEN + 1];
        int i;
 
        _db_show_ssid(" meshid ", 0, ms->ms_idlen, ms->ms_id);
@@ -873,15 +889,14 @@ _db_show_mesh(const struct ieee80211_mesh_state *ms)
        db_printf("routing table:\n");
        i = 0;
        TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) {
-               db_printf("entry %d:\tdest: %s nexthop: %s metric: %u", i,
-                   kether_ntoa(rt->rt_dest, ethstr[0]),
-                   kether_ntoa(rt->rt_nexthop, ethstr[1]),
-                   rt->rt_metric);
+               db_printf("entry %d:\tdest: %6D nexthop: %6D metric: %u", i,
+                   rt->rt_dest, ":", rt->rt_nexthop, ":", rt->rt_metric);
+
                db_printf("\tlifetime: %u lastseq: %u priv: %p\n",
-                   rt->rt_lifetime, rt->rt_lastmseq, rt->rt_priv);
+                   ieee80211_mesh_rt_update(rt, 0),
+                   rt->rt_lastmseq, rt->rt_priv);
                i++;
        }
 }
 #endif /* IEEE80211_SUPPORT_MESH */
-#endif
 #endif /* DDB */
index 20ca044..f5c2309 100644 (file)
  * 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.
- *
- * $FreeBSD: head/sys/net80211/ieee80211_dfs.c 196785 2009-09-03 16:29:02Z sam $
  */
 
+#include <sys/cdefs.h>
+#ifdef __FreeBSD__
+__FBSDID("$FreeBSD$");
+#endif
+
 /*
  * IEEE 802.11 DFS/Radar support.
  */
@@ -34,6 +37,7 @@
 #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/sysctl.h>
 
 #include <net/if.h>
+#include <net/if_var.h>
 #include <net/if_media.h>
-#include <net/route.h>
+#include <net/ethernet.h>
 
 #include <netproto/802_11/ieee80211_var.h>
 
+static MALLOC_DEFINE(M_80211_DFS, "80211dfs", "802.11 DFS state");
+
 static int ieee80211_nol_timeout = 30*60;              /* 30 minutes */
 SYSCTL_INT(_net_wlan, OID_AUTO, nol_timeout, CTLFLAG_RW,
        &ieee80211_nol_timeout, 0, "NOL timeout (secs)");
@@ -59,13 +66,43 @@ SYSCTL_INT(_net_wlan, OID_AUTO, cac_timeout, CTLFLAG_RW,
        &ieee80211_cac_timeout, 0, "CAC timeout (secs)");
 #define        CAC_TIMEOUT     msecs_to_ticks(ieee80211_cac_timeout*1000)
 
+/*
+ DFS* In order to facilitate  debugging, a couple of operating
+ * modes aside from the default are needed.
+ *
+ * 0 - default CAC/NOL behaviour - ie, start CAC, place
+ *     channel on NOL list.
+ * 1 - send CAC, but don't change channel or add the channel
+ *     to the NOL list.
+ * 2 - just match on radar, don't send CAC or place channel in
+ *     the NOL list.
+ */
+static int ieee80211_dfs_debug = DFS_DBG_NONE;
+
+/*
+ * This option must not be included in the default kernel
+ * as it allows users to plainly disable CAC/NOL handling.
+ */
+#ifdef IEEE80211_DFS_DEBUG
+SYSCTL_INT(_net_wlan, OID_AUTO, dfs_debug, CTLFLAG_RW,
+       &ieee80211_dfs_debug, 0, "DFS debug behaviour");
+#endif
+
+static int
+null_set_quiet(struct ieee80211_node *ni, u_int8_t *quiet_elm)
+{
+       return ENOSYS;
+}
+
 void
 ieee80211_dfs_attach(struct ieee80211com *ic)
 {
        struct ieee80211_dfs_state *dfs = &ic->ic_dfs;
 
-       callout_init(&dfs->nol_timer);
-       callout_init(&dfs->cac_timer);
+       callout_init_mtx(&dfs->nol_timer, IEEE80211_LOCK_OBJ(ic), 0);
+       callout_init_mtx(&dfs->cac_timer, IEEE80211_LOCK_OBJ(ic), 0);
+
+       ic->ic_set_quiet = null_set_quiet;
 }
 
 void
@@ -83,27 +120,24 @@ ieee80211_dfs_reset(struct ieee80211com *ic)
 
        /* NB: we assume no locking is needed */
        /* NB: cac_timer should be cleared by the state machine */
-       callout_stop(&dfs->nol_timer);
+       callout_drain(&dfs->nol_timer);
        for (i = 0; i < ic->ic_nchans; i++)
                ic->ic_channels[i].ic_state = 0;
        dfs->lastchan = NULL;
 }
 
 static void
-cac_timeout_callout(void *arg)
+cac_timeout(void *arg)
 {
        struct ieee80211vap *vap = arg;
-       struct ieee80211com *ic;
-       struct ieee80211_dfs_state *dfs;
+       struct ieee80211com *ic = vap->iv_ic;
+       struct ieee80211_dfs_state *dfs = &ic->ic_dfs;
        int i;
 
-       wlan_serialize_enter();
-       ic = vap->iv_ic;
-       dfs = &ic->ic_dfs;
-       if (vap->iv_state != IEEE80211_S_CAC) { /* NB: just in case */
-               wlan_serialize_exit();
+       IEEE80211_LOCK_ASSERT(ic);
+
+       if (vap->iv_state != IEEE80211_S_CAC)   /* NB: just in case */
                return;
-       }
        /*
         * When radar is detected during a CAC we are woken
         * up prematurely to switch to a new channel.
@@ -141,7 +175,6 @@ cac_timeout_callout(void *arg)
                    IEEE80211_NOTIFY_CAC_EXPIRE);
                ieee80211_cac_completeswitch(vap);
        }
-       wlan_serialize_exit();
 }
 
 /*
@@ -155,7 +188,9 @@ ieee80211_dfs_cac_start(struct ieee80211vap *vap)
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211_dfs_state *dfs = &ic->ic_dfs;
 
-       callout_reset(&dfs->cac_timer, CAC_TIMEOUT, cac_timeout_callout, vap);
+       IEEE80211_LOCK_ASSERT(ic);
+
+       callout_reset(&dfs->cac_timer, CAC_TIMEOUT, cac_timeout, vap);
        if_printf(vap->iv_ifp, "start %d second CAC timer on channel %u (%u MHz)\n",
            ticks_to_secs(CAC_TIMEOUT),
            ic->ic_curchan->ic_ieee, ic->ic_curchan->ic_freq);
@@ -171,6 +206,8 @@ ieee80211_dfs_cac_stop(struct ieee80211vap *vap)
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211_dfs_state *dfs = &ic->ic_dfs;
 
+       IEEE80211_LOCK_ASSERT(ic);
+
        /* NB: racey but not important */
        if (callout_pending(&dfs->cac_timer)) {
                if_printf(vap->iv_ifp, "stop CAC timer on channel %u (%u MHz)\n",
@@ -195,14 +232,15 @@ ieee80211_dfs_cac_clear(struct ieee80211com *ic,
 }
 
 static void
-dfs_timeout_callout(void *arg)
+dfs_timeout(void *arg)
 {
        struct ieee80211com *ic = arg;
        struct ieee80211_dfs_state *dfs = &ic->ic_dfs;
        struct ieee80211_channel *c;
        int i, oldest, now;
 
-       wlan_serialize_enter();
+       IEEE80211_LOCK_ASSERT(ic);
+
        now = oldest = ticks;
        for (i = 0; i < ic->ic_nchans; i++) {
                c = &ic->ic_channels[i];
@@ -229,10 +267,9 @@ dfs_timeout_callout(void *arg)
        }
        if (oldest != now) {
                /* arrange to process next channel up for a status change */
-               callout_reset(&dfs->nol_timer, oldest + NOL_TIMEOUT - now,
-                   dfs_timeout_callout, ic);
+               callout_schedule_dfly(&dfs->nol_timer, oldest + NOL_TIMEOUT - now,
+                               dfs_timeout, ic);
        }
-       wlan_serialize_exit();
 }
 
 static void
@@ -263,26 +300,46 @@ ieee80211_dfs_notify_radar(struct ieee80211com *ic, struct ieee80211_channel *ch
        struct ieee80211_dfs_state *dfs = &ic->ic_dfs;
        int i, now;
 
+       IEEE80211_LOCK_ASSERT(ic);
+
        /*
-        * Mark all entries with this frequency.  Notify user
-        * space and arrange for notification when the radar
-        * indication is cleared.  Then kick the NOL processing
-        * thread if not already running.
+        * If doing DFS debugging (mode 2), don't bother
+        * running the rest of this function.
+        *
+        * Simply announce the presence of the radar and continue
+        * along merrily.
         */
-       now = ticks;
-       for (i = 0; i < ic->ic_nchans; i++) {
-               struct ieee80211_channel *c = &ic->ic_channels[i];
-               if (c->ic_freq == chan->ic_freq) {
-                       c->ic_state &= ~IEEE80211_CHANSTATE_CACDONE;
-                       c->ic_state |= IEEE80211_CHANSTATE_RADAR;
-                       dfs->nol_event[i] = now;
-               }
+       if (ieee80211_dfs_debug == DFS_DBG_NOCSANOL) {
+               announce_radar(ic->ic_ifp, chan, chan);
+               ieee80211_notify_radar(ic, chan);
+               return;
        }
-       ieee80211_notify_radar(ic, chan);
-       chan->ic_state |= IEEE80211_CHANSTATE_NORADAR;
-       if (!callout_pending(&dfs->nol_timer)) {
-               callout_reset(&dfs->nol_timer, NOL_TIMEOUT,
-                               dfs_timeout_callout, ic);
+
+       /*
+        * Don't mark the channel and don't put it into NOL
+        * if we're doing DFS debugging.
+        */
+       if (ieee80211_dfs_debug == DFS_DBG_NONE) {
+               /*
+                * Mark all entries with this frequency.  Notify user
+                * space and arrange for notification when the radar
+                * indication is cleared.  Then kick the NOL processing
+                * thread if not already running.
+                */
+               now = ticks;
+               for (i = 0; i < ic->ic_nchans; i++) {
+                       struct ieee80211_channel *c = &ic->ic_channels[i];
+                       if (c->ic_freq == chan->ic_freq) {
+                               c->ic_state &= ~IEEE80211_CHANSTATE_CACDONE;
+                               c->ic_state |= IEEE80211_CHANSTATE_RADAR;
+                               dfs->nol_event[i] = now;
+                       }
+               }
+               ieee80211_notify_radar(ic, chan);
+               chan->ic_state |= IEEE80211_CHANSTATE_NORADAR;
+               if (!callout_pending(&dfs->nol_timer))
+                       callout_reset(&dfs->nol_timer, NOL_TIMEOUT,
+                           dfs_timeout, ic);
        }
 
        /*
@@ -298,15 +355,20 @@ ieee80211_dfs_notify_radar(struct ieee80211com *ic, struct ieee80211_channel *ch
         */
        if (chan == ic->ic_bsschan) {
                /* XXX need a way to defer to user app */
-               dfs->newchan = ieee80211_dfs_pickchannel(ic);
+
+               /*
+                * Don't flip over to a new channel if
+                * we are currently doing DFS debugging.
+                */
+               if (ieee80211_dfs_debug == DFS_DBG_NONE)
+                       dfs->newchan = ieee80211_dfs_pickchannel(ic);
+               else
+                       dfs->newchan = chan;
 
                announce_radar(ic->ic_ifp, chan, dfs->newchan);
 
-#ifdef notyet
-               if (callout_pending(&dfs->cac_timer)) {
-                       callout_reset(&dfs->cac_timer, 0,
-                                       cac_timeout_callout, vap);
-               }
+               if (callout_pending(&dfs->cac_timer))
+                       callout_schedule_dfly(&dfs->cac_timer, 0, cac_timeout, dfs->cac_timer.c_arg);
                else if (dfs->newchan != NULL) {
                        /* XXX mode 1, switch count 2 */
                        /* XXX calculate switch count based on max
@@ -319,8 +381,9 @@ ieee80211_dfs_notify_radar(struct ieee80211com *ic, struct ieee80211_channel *ch
                         * on the NOL to expire.
                         */
                        /*XXX*/
+                       if_printf(ic->ic_ifp, "%s: No free channels; waiting for entry "
+                           "on NOL to expire\n", __func__);
                }
-#endif
        } else {
                /*
                 * Issue rate-limited console msgs.
index 12e05a3..4d62fe8 100644 (file)
@@ -155,17 +155,20 @@ wlan_clone_destroy(struct ifnet *ifp)
        struct ieee80211vap *vap = ifp->if_softc;
        struct ieee80211com *ic = vap->iv_ic;
 
-       wlan_serialize_enter(); /* WARNING must be global serializer */
        ic->ic_vap_delete(vap);
-       wlan_serialize_exit();
 
        return 0;
 }
 
 const char *wlan_last_enter_func;
 const char *wlan_last_exit_func;
+
 /*
  * These serializer functions are used by wlan and all drivers.
+ * They are not recursive.  The serializer must be held on
+ * any OACTIVE interactions.  Dragonfly automatically holds
+ * the serializer on most ifp->if_*() calls but calls made
+ * from wlan into ath might not.
  */
 void
 _wlan_serialize_enter(const char *funcname)
@@ -181,6 +184,36 @@ _wlan_serialize_exit(const char *funcname)
        wlan_last_exit_func = funcname;
 }
 
+int
+_wlan_is_serialized(void)
+{
+       return (IS_SERIALIZED(&wlan_global_serializer));
+}
+
+/*
+ * Push/pop allows the wlan serializer to be entered recursively.
+ */
+int
+_wlan_serialize_push(const char *funcname)
+{
+       if (IS_SERIALIZED(&wlan_global_serializer)) {
+               return 0;
+       } else {
+               _wlan_serialize_enter(funcname);
+               return 1;
+       }
+}
+
+void
+_wlan_serialize_pop(const char *funcname, int wst)
+{
+       if (wst) {
+               _wlan_serialize_exit(funcname);
+       }
+}
+
+#if 0
+
 int
 wlan_serialize_sleep(void *ident, int flags, const char *wmesg, int timo)
 {
@@ -229,16 +262,59 @@ wlan_cv_signal(struct cv *cv, int broadcast)
        }
 }
 
+#endif
+
 /*
  * Misc
  */
+int
+ieee80211_vap_xmitpkt(struct ieee80211vap *vap, struct mbuf *m)
+{
+       struct ifnet *ifp = vap->iv_ifp;
+       struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
+       int error;
+       int wst;
+
+       /*
+        * When transmitting via the VAP, we shouldn't hold
+        * any IC TX lock as the VAP TX path will acquire it.
+        */
+       IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
+
+       error = ifsq_enqueue(ifsq, m, NULL);
+       wst = wlan_serialize_push();
+       ifp->if_start(ifp, ifsq);
+       wlan_serialize_pop(wst);
+
+       return error;
+}
+
+int
+ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
+{
+       struct ifnet *parent = ic->ic_ifp;
+       struct ifaltq_subque *ifsq = ifq_get_subq_default(&parent->if_snd);
+       int error;
+       int wst;
+
+       /*
+        * Assert the IC TX lock is held - this enforces the
+        * processing -> queuing order is maintained
+        */
+       IEEE80211_TX_LOCK_ASSERT(ic);
+
+       error = ifsq_enqueue(ifsq, m, NULL);
+       wst = wlan_serialize_push();
+       parent->if_start(parent, ifsq);
+       wlan_serialize_pop(wst);
+
+       return error;
+}
+
 void
 ieee80211_vap_destroy(struct ieee80211vap *vap)
 {
-       wlan_assert_serialized();
-       wlan_serialize_exit();
        if_clone_destroy(vap->iv_ifp->if_xname);
-       wlan_serialize_enter();
 }
 
 /*
@@ -268,10 +344,8 @@ ieee80211_sysctl_inact(SYSCTL_HANDLER_ARGS)
        int error;
 
        error = sysctl_handle_int(oidp, &inact, 0, req);
-       wlan_serialize_enter();
        if (error == 0 && req->newptr)
                *(int *)arg1 = inact / IEEE80211_INACT_WAIT;
-       wlan_serialize_exit();
 
        return error;
 }
@@ -292,10 +366,8 @@ ieee80211_sysctl_radar(SYSCTL_HANDLER_ARGS)
        int t = 0, error;
 
        error = sysctl_handle_int(oidp, &t, 0, req);
-       wlan_serialize_enter();
        if (error == 0 && req->newptr)
                ieee80211_dfs_notify_radar(ic, ic->ic_curchan);
-       wlan_serialize_exit();
 
        return error;
 }
@@ -407,6 +479,7 @@ ieee80211_node_dectestref(struct ieee80211_node *ni)
        return atomic_cmpset_int(&ni->ni_refcnt, 0, 1);
 }
 
+#if 0
 /* XXX this breaks ALTQ's packet scheduler */
 void
 ieee80211_flush_ifq(struct ifaltq *ifq, struct ieee80211vap *vap)
@@ -464,6 +537,7 @@ ieee80211_flush_ifq(struct ifaltq *ifq, struct ieee80211vap *vap)
 
        ALTQ_SQ_UNLOCK(ifsq);
 }
+#endif
 
 /*
  * As above, for mbufs allocated with m_gethdr/MGETHDR
@@ -576,17 +650,6 @@ ieee80211_add_callback(struct mbuf *m,
        return 1;
 }
 
-void
-ieee80211_tx_complete(struct ieee80211_node *ni, struct mbuf *m, int status)
-{
-       if (ni != NULL) {
-               if (m->m_flags & M_TXCB)
-                       ieee80211_process_callback(ni, m, status);
-               ieee80211_free_node(ni);
-       }
-       m_freem(m);
-}
-
 void
 ieee80211_process_callback(struct ieee80211_node *ni,
        struct mbuf *m, int status)
@@ -827,30 +890,6 @@ ieee80211_notify_radio(struct ieee80211com *ic, int state)
        rt_ieee80211msg(ifp, RTM_IEEE80211_RADIO, &iev, sizeof(iev));
 }
 
-int
-ieee80211_handoff(struct ifnet *dst_ifp, struct mbuf *m)
-{
-        struct mbuf *m0;
-
-       /* We may be sending a fragment so traverse the mbuf */
-       wlan_assert_serialized();
-       wlan_serialize_exit();
-       for (; m; m = m0) {
-               struct altq_pktattr pktattr;
-
-               m0 = m->m_nextpkt;
-               m->m_nextpkt = NULL;
-
-               if (ifq_is_enabled(&dst_ifp->if_snd))
-                       altq_etherclassify(&dst_ifp->if_snd, m, &pktattr);
-
-               ifq_dispatch(dst_ifp, m, &pktattr);
-       }
-       wlan_serialize_enter();
-
-       return (0);
-}
-
 /* IEEE Std 802.11a-1999, page 9, table 79 */
 #define IEEE80211_OFDM_SYM_TIME                 4
 #define IEEE80211_OFDM_PREAMBLE_TIME            16
@@ -950,8 +989,8 @@ bpf_track_event(void *arg, struct ifnet *ifp, int dlt, int attach)
 {
        /* NB: identify vap's by if_start */
 
-       wlan_serialize_enter();
-       if (dlt == DLT_IEEE802_11_RADIO && ifp->if_start == ieee80211_start) {
+       if (dlt == DLT_IEEE802_11_RADIO &&
+           ifp->if_start == ieee80211_vap_start) {
                struct ieee80211vap *vap = ifp->if_softc;
                /*
                 * Track bpf radiotap listener state.  We mark the vap
@@ -970,7 +1009,16 @@ bpf_track_event(void *arg, struct ifnet *ifp, int dlt, int attach)
                                atomic_subtract_int(&vap->iv_ic->ic_montaps, 1);
                }
        }
-       wlan_serialize_exit();
+}
+
+const char *
+ether_sprintf(const u_char *buf)
+{
+       static char ethstr[MAXCPU][ETHER_ADDRSTRLEN + 1];
+       char *ptr = ethstr[mycpu->gd_cpuid];
+
+       kether_ntoa(buf, ptr);
+       return (ptr);
 }
 
 static void
@@ -979,9 +1027,7 @@ wlan_iflladdr_event(void *arg __unused, struct ifnet *ifp)
        struct ieee80211com *ic = ifp->if_l2com;
        struct ieee80211vap *vap, *next;
 
-       wlan_serialize_enter();
        if (ifp->if_type != IFT_IEEE80211 || ic == NULL) {
-               wlan_serialize_exit();
                return;
        }
 
@@ -993,13 +1039,10 @@ wlan_iflladdr_event(void *arg __unused, struct ifnet *ifp)
                if (vap->iv_ic == ic &&
                    (vap->iv_flags_ext & IEEE80211_FEXT_UNIQMAC) == 0) {
                        IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp));
-                       wlan_serialize_exit();
                        if_setlladdr(vap->iv_ifp, IF_LLADDR(ifp),
                                     IEEE80211_ADDR_LEN);
-                       wlan_serialize_enter();
                }
        }
-       wlan_serialize_exit();
 }
 
 /*
@@ -1012,8 +1055,6 @@ wlan_modevent(module_t mod, int type, void *unused)
 {
        int error;
 
-       wlan_serialize_enter();
-
        switch (type) {
        case MOD_LOAD:
                if (bootverbose)
@@ -1048,8 +1089,6 @@ wlan_modevent(module_t mod, int type, void *unused)
                error = EINVAL;
                break;
        }
-       wlan_serialize_exit();
-
        return error;
 }
 
index fdd1667..2469813 100644 (file)
  * 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.
- *
- * $FreeBSD: head/sys/net80211/ieee80211_hostap.c 203422 2010-02-03 10:07:43Z rpaulo $
  */
 
+#include <sys/cdefs.h>
+#ifdef __FreeBSD__
+__FBSDID("$FreeBSD$");
+#endif
+
 /*
  * IEEE 802.11 HOSTAP mode support.
  */
 #include <sys/sysctl.h>
 
 #include <net/if.h>
+#include <net/if_var.h>
 #include <net/if_media.h>
 #include <net/if_llc.h>
-#include <net/ifq_var.h>
 #include <net/ethernet.h>
-#include <net/route.h>
 
 #include <net/bpf.h>
 
@@ -72,7 +74,6 @@ static void hostap_deliver_data(struct ieee80211vap *,
 static void hostap_recv_mgmt(struct ieee80211_node *, struct mbuf *,
            int subtype, int rssi, int nf);
 static void hostap_recv_ctl(struct ieee80211_node *, struct mbuf *, int);
-static void hostap_recv_pspoll(struct ieee80211_node *, struct mbuf *);
 
 void
 ieee80211_hostap_attach(struct ieee80211com *ic)
@@ -99,6 +100,7 @@ hostap_vattach(struct ieee80211vap *vap)
        vap->iv_recv_ctl = hostap_recv_ctl;
        vap->iv_opdetach = hostap_vdetach;
        vap->iv_deliver_data = hostap_deliver_data;
+       vap->iv_recv_pspoll = ieee80211_recv_pspoll;
 }
 
 static void
@@ -156,9 +158,8 @@ hostap_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 {
        struct ieee80211com *ic = vap->iv_ic;
        enum ieee80211_state ostate;
-#ifdef IEEE80211_DEBUG
-       char ethstr[ETHER_ADDRSTRLEN + 1];
-#endif
+
+       IEEE80211_LOCK_ASSERT(ic);
 
        ostate = vap->iv_state;
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n",
@@ -304,7 +305,7 @@ hostap_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
                                struct ieee80211_node *ni = vap->iv_bss;
                                ieee80211_note(vap,
                                    "synchronized with %s ssid ",
-                                   kether_ntoa(ni->ni_bssid, ethstr));
+                                   ether_sprintf(ni->ni_bssid));
                                ieee80211_print_essid(ni->ni_essid,
                                    ni->ni_esslen);
                                /* XXX MCS/HT */
@@ -355,7 +356,12 @@ hostap_deliver_data(struct ieee80211vap *vap,
        struct ifnet *ifp = vap->iv_ifp;
 
        /* clear driver/net80211 flags before passing up */
+#if __FreeBSD_version >= 1000046
+       m->m_flags &= ~(M_MCAST | M_BCAST);
+       m_clrprotoflags(m);
+#else
        m->m_flags &= ~(M_80211_RX | M_MCAST | M_BCAST);
+#endif
 
        KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP,
            ("gack, opmode %d", vap->iv_opmode));
@@ -410,8 +416,9 @@ hostap_deliver_data(struct ieee80211vap *vap,
                        }
                }
                if (mcopy != NULL) {
-                       int err;
-                       err = ieee80211_handoff(ifp, mcopy);
+                       int len, err;
+                       len = mcopy->m_pkthdr.len;
+                       err = ieee80211_vap_xmitpkt(vap, mcopy);
                        if (err) {
                                /* NB: IFQ_HANDOFF reclaims mcopy */
                        } else {
@@ -433,7 +440,12 @@ hostap_deliver_data(struct ieee80211vap *vap,
                }
                if (ni->ni_vlan != 0) {
                        /* attach vlan tag */
+#if defined(__DragonFly__)
+                       /* XXX ntohs() needed? */
                        m->m_pkthdr.ether_vlantag = ni->ni_vlan;
+#else
+                       m->m_pkthdr.ether_vtag = ni->ni_vlan;
+#endif
                        m->m_flags |= M_VLANTAG;
                }
                ifp->if_input(ifp, m, NULL, -1);
@@ -471,7 +483,6 @@ doprint(struct ieee80211vap *vap, int subtype)
 static int
 hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
 {
-#define        SEQ_LEQ(a,b)    ((int)((a)-(b)) <= 0)
 #define        HAS_SEQ(type)   ((type & 0x4) == 0)
        struct ieee80211vap *vap = ni->ni_vap;
        struct ieee80211com *ic = ni->ni_ic;
@@ -483,9 +494,6 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
        uint8_t dir, type, subtype, qos;
        uint8_t *bssid;
        uint16_t rxseq;
-#ifdef IEEE80211_DEBUG
-       char ethstr[ETHER_ADDRSTRLEN + 1];
-#endif
 
        if (m->m_flags & M_AMPDU_MPDU) {
                /*
@@ -574,9 +582,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
                            TID_TO_WME_AC(tid) >= WME_AC_VI)
                                ic->ic_wme.wme_hipri_traffic++;
                        rxseq = le16toh(*(uint16_t *)wh->i_seq);
-                       if ((ni->ni_flags & IEEE80211_NODE_HT) == 0 &&
-                           (wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
-                           SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) {
+                       if (! ieee80211_check_rxseq(ni, wh)) {
                                /* duplicate, discard */
                                IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
                                    bssid, "duplicate",
@@ -650,7 +656,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
                 */
                if (((wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) ^
                    (ni->ni_flags & IEEE80211_NODE_PWR_MGT)))
-                       ieee80211_node_pwrsave(ni,
+                       vap->iv_node_ps(ni,
                                wh->i_fc[1] & IEEE80211_FC1_PWR_MGT);
                /*
                 * For 4-address packets handle WDS discovery
@@ -693,7 +699,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
                 * crypto cipher modules used to do delayed update
                 * of replay sequence numbers.
                 */
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                        if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) {
                                /*
                                 * Discard encrypted frames when privacy is off.
@@ -711,7 +717,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
                                goto out;
                        }
                        wh = mtod(m, struct ieee80211_frame *);
-                       wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
+                       wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
                } else {
                        /* XXX M_WEP and IEEE80211_F_PRIVACY */
                        key = NULL;
@@ -842,7 +848,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
                        /* ensure return frames are unicast */
                        IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
                            wh, NULL, "source is multicast: %s",
-                           kether_ntoa(wh->i_addr2, ethstr));
+                           ether_sprintf(wh->i_addr2));
                        vap->iv_stats.is_rx_mgtdiscard++;       /* XXX stat */
                        goto out;
                }
@@ -852,10 +858,10 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
                        if_printf(ifp, "received %s from %s rssi %d\n",
                            ieee80211_mgt_subtype_name[subtype >>
                                IEEE80211_FC0_SUBTYPE_SHIFT],
-                           kether_ntoa(wh->i_addr2, ethstr), rssi);
+                           ether_sprintf(wh->i_addr2), rssi);
                }
 #endif
-               if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+               if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
                        if (subtype != IEEE80211_FC0_SUBTYPE_AUTH) {
                                /*
                                 * Only shared key auth frames with a challenge
@@ -883,8 +889,16 @@ hostap_input(struct ieee80211