Changeset a241ea8 in rtems-libbsd


Ignore:
Timestamp:
Nov 14, 2016, 12:46:13 PM (3 years ago)
Author:
Christian Mauderer <Christian.Mauderer@…>
Branches:
fd86c091b97759106da7355ce1dd81ebe030e285, f020f08430150c1656a0ad0a1de13699db9b980b
Children:
efc782b
Parents:
172f2ac
git-author:
Christian Mauderer <Christian.Mauderer@…> (11/14/16 12:46:13)
git-committer:
Christian Mauderer <Christian.Mauderer@…> (01/17/17 11:50:57)
Message:

Import IEEE 802.11 from FreeBSD.

Location:
freebsd/sys/net80211
Files:
4 added
60 edited

Legend:

Unmodified
Added
Removed
  • freebsd/sys/net80211/_ieee80211.h

    r172f2ac ra241ea8  
    4646        IEEE80211_T_OFDM_HALF,          /* 1/2 rate OFDM */
    4747        IEEE80211_T_OFDM_QUARTER,       /* 1/4 rate OFDM */
     48        IEEE80211_T_VHT,                /* VHT PHY */
    4849};
    4950#define IEEE80211_T_CCK IEEE80211_T_DS  /* more common nomenclature */
     
    6970        IEEE80211_MODE_HALF     = 10,   /* OFDM, 1/2x clock */
    7071        IEEE80211_MODE_QUARTER  = 11,   /* OFDM, 1/4x clock */
    71 };
    72 #define IEEE80211_MODE_MAX      (IEEE80211_MODE_QUARTER+1)
     72        IEEE80211_MODE_VHT_2GHZ = 12,   /* 2GHz, VHT */
     73        IEEE80211_MODE_VHT_5GHZ = 13,   /* 5GHz, VHT */
     74};
     75#define IEEE80211_MODE_MAX      (IEEE80211_MODE_VHT_5GHZ+1)
     76#define IEEE80211_MODE_BYTES    howmany(IEEE80211_MODE_MAX, NBBY)
    7377
    7478/*
     
    134138struct ieee80211_channel {
    135139        uint32_t        ic_flags;       /* see below */
    136         uint16_t        ic_freq;        /* setting in MHz */
     140        uint16_t        ic_freq;        /* primary centre frequency in MHz */
    137141        uint8_t         ic_ieee;        /* IEEE channel number */
    138142        int8_t          ic_maxregpower; /* maximum regulatory tx power in dBm */
     
    144148        uint8_t         ic_pad;
    145149        uint16_t        ic_devdata;     /* opaque device/driver data */
    146 };
    147 
    148 #define IEEE80211_CHAN_MAX      256
    149 #define IEEE80211_CHAN_BYTES    32      /* howmany(IEEE80211_CHAN_MAX, NBBY) */
     150        uint8_t         ic_vht_ch_freq1; /* VHT primary freq1 IEEE value */
     151        uint8_t         ic_vht_ch_freq2; /* VHT secondary 80MHz freq2 IEEE value */
     152        uint16_t        ic_freq2;       /* VHT secondary 80MHz freq2 MHz */
     153};
     154
     155/*
     156 * Note: for VHT operation we will need significantly more than
     157 * IEEE80211_CHAN_MAX channels because of the combinations of
     158 * VHT20, VHT40, VHT80, VHT80+80 and VHT160.
     159 */
     160#define IEEE80211_CHAN_MAX      1024
     161#define IEEE80211_CHAN_BYTES    howmany(IEEE80211_CHAN_MAX, NBBY)
    150162#define IEEE80211_CHAN_ANY      0xffff  /* token for ``any channel'' */
    151163#define IEEE80211_CHAN_ANYC \
     
    177189#define IEEE80211_CHAN_NOHOSTAP 0x00400000 /* hostap mode not allowed */
    178190#define IEEE80211_CHAN_11D      0x00800000 /* 802.11d required */
     191#define IEEE80211_CHAN_VHT20    0x01000000 /* VHT20 channel */
     192#define IEEE80211_CHAN_VHT40U   0x02000000 /* VHT40 channel, ext above */
     193#define IEEE80211_CHAN_VHT40D   0x04000000 /* VHT40 channel, ext below */
     194#define IEEE80211_CHAN_VHT80    0x08000000 /* VHT80 channel */
     195#define IEEE80211_CHAN_VHT80_80 0x10000000 /* VHT80+80 channel */
     196#define IEEE80211_CHAN_VHT160   0x20000000 /* VHT160 channel */
     197/* XXX note: 0x80000000 is used in src/sbin/ifconfig/ifieee80211.c :( */
    179198
    180199#define IEEE80211_CHAN_HT40     (IEEE80211_CHAN_HT40U | IEEE80211_CHAN_HT40D)
    181200#define IEEE80211_CHAN_HT       (IEEE80211_CHAN_HT20 | IEEE80211_CHAN_HT40)
     201
     202#define IEEE80211_CHAN_VHT40    (IEEE80211_CHAN_VHT40U | IEEE80211_CHAN_VHT40D)
     203#define IEEE80211_CHAN_VHT      (IEEE80211_CHAN_VHT20 | IEEE80211_CHAN_VHT40 \
     204                                | IEEE80211_CHAN_VHT80 | IEEE80211_CHAN_VHT80_80 \
     205                                | IEEE80211_CHAN_VHT160)
    182206
    183207#define IEEE80211_CHAN_BITS \
    184208        "\20\1PRIV0\2PRIV2\3PRIV3\4PRIV4\5TURBO\6CCK\7OFDM\0102GHZ\0115GHZ" \
    185209        "\12PASSIVE\13DYN\14GFSK\15GSM\16STURBO\17HALF\20QUARTER\21HT20" \
    186         "\22HT40U\23HT40D\24DFS\0254MSXMIT\26NOADHOC\27NOHOSTAP\03011D"
     210        "\22HT40U\23HT40D\24DFS\0254MSXMIT\26NOADHOC\27NOHOSTAP\03011D" \
     211        "\031VHT20\032VHT40U\033VHT40D\034VHT80\035VHT80_80\036VHT160"
    187212
    188213/*
     
    210235         IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN | \
    211236         IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER | \
    212          IEEE80211_CHAN_HT)
     237         IEEE80211_CHAN_HT | IEEE80211_CHAN_VHT)
    213238#define IEEE80211_CHAN_ALLTURBO \
    214239        (IEEE80211_CHAN_ALL | IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO)
     
    243268#define IEEE80211_IS_CHAN_CCK(_c) \
    244269        (((_c)->ic_flags & (IEEE80211_CHAN_CCK | IEEE80211_CHAN_DYN)) != 0)
     270#define IEEE80211_IS_CHAN_DYN(_c) \
     271        (((_c)->ic_flags & IEEE80211_CHAN_DYN) == IEEE80211_CHAN_DYN)
    245272#define IEEE80211_IS_CHAN_GFSK(_c) \
    246273        (((_c)->ic_flags & IEEE80211_CHAN_GFSK) != 0)
     
    285312        (((_c)->ic_flags & IEEE80211_CHAN_11D) != 0)
    286313
     314#define IEEE80211_IS_CHAN_VHT(_c) \
     315        (((_c)->ic_flags & IEEE80211_CHAN_VHT) != 0)
     316#define IEEE80211_IS_CHAN_VHT20(_c) \
     317        (((_c)->ic_flags & IEEE80211_CHAN_VHT20) != 0)
     318#define IEEE80211_IS_CHAN_VHT40(_c) \
     319        (((_c)->ic_flags & IEEE80211_CHAN_VHT40) != 0)
     320#define IEEE80211_IS_CHAN_VHT40U(_c) \
     321        (((_c)->ic_flags & IEEE80211_CHAN_VHT40U) != 0)
     322#define IEEE80211_IS_CHAN_VHT40D(_c) \
     323        (((_c)->ic_flags & IEEE80211_CHAN_VHT40D) != 0)
     324#define IEEE80211_IS_CHAN_VHTA(_c) \
     325        (IEEE80211_IS_CHAN_5GHZ(_c) && \
     326         ((_c)->ic_flags & IEEE80211_CHAN_VHT) != 0)
     327#define IEEE80211_IS_CHAN_VHTG(_c) \
     328        (IEEE80211_IS_CHAN_2GHZ(_c) && \
     329         ((_c)->ic_flags & IEEE80211_CHAN_VHT) != 0)
     330#define IEEE80211_IS_CHAN_VHT80(_c) \
     331        (((_c)->ic_flags & IEEE80211_CHAN_VHT80) != 0)
     332#define IEEE80211_IS_CHAN_VHT80_80(_c) \
     333        (((_c)->ic_flags & IEEE80211_CHAN_VHT80_80) != 0)
     334#define IEEE80211_IS_CHAN_VHT160(_c) \
     335        (((_c)->ic_flags & IEEE80211_CHAN_VHT160) != 0)
     336
    287337#define IEEE80211_CHAN2IEEE(_c)         (_c)->ic_ieee
    288338
     
    389439 */
    390440
    391 #define IEEE80211_MAX_CHAINS            3
    392 #define IEEE80211_MAX_EVM_PILOTS        6
    393 
    394441/*
    395442 * XXX This doesn't yet export both ctl/ext chain details
     443 * XXX TODO: IEEE80211_MAX_CHAINS is defined in _freebsd.h, not here;
     444 * figure out how to pull it in!
    396445 */
    397446struct ieee80211_mimo_info {
    398         int8_t          rssi[IEEE80211_MAX_CHAINS];     /* per-antenna rssi */
    399         int8_t          noise[IEEE80211_MAX_CHAINS];    /* per-antenna noise floor */
     447        int8_t          rssi[3];        /* per-antenna rssi */
     448        int8_t          noise[3];       /* per-antenna noise floor */
    400449        uint8_t         pad[2];
    401450        uint32_t        evm[3];         /* EVM data */
    402451};
     452
     453/*
     454 * ic_caps/iv_caps: device driver capabilities
     455 */
     456/* 0x2e available */
     457#define IEEE80211_C_STA         0x00000001      /* CAPABILITY: STA available */
     458#define IEEE80211_C_8023ENCAP   0x00000002      /* CAPABILITY: 802.3 encap */
     459#define IEEE80211_C_FF          0x00000040      /* CAPABILITY: ATH FF avail */
     460#define IEEE80211_C_TURBOP      0x00000080      /* CAPABILITY: ATH Turbo avail*/
     461#define IEEE80211_C_IBSS        0x00000100      /* CAPABILITY: IBSS available */
     462#define IEEE80211_C_PMGT        0x00000200      /* CAPABILITY: Power mgmt */
     463#define IEEE80211_C_HOSTAP      0x00000400      /* CAPABILITY: HOSTAP avail */
     464#define IEEE80211_C_AHDEMO      0x00000800      /* CAPABILITY: Old Adhoc Demo */
     465#define IEEE80211_C_SWRETRY     0x00001000      /* CAPABILITY: sw tx retry */
     466#define IEEE80211_C_TXPMGT      0x00002000      /* CAPABILITY: tx power mgmt */
     467#define IEEE80211_C_SHSLOT      0x00004000      /* CAPABILITY: short slottime */
     468#define IEEE80211_C_SHPREAMBLE  0x00008000      /* CAPABILITY: short preamble */
     469#define IEEE80211_C_MONITOR     0x00010000      /* CAPABILITY: monitor mode */
     470#define IEEE80211_C_DFS         0x00020000      /* CAPABILITY: DFS/radar avail*/
     471#define IEEE80211_C_MBSS        0x00040000      /* CAPABILITY: MBSS available */
     472#define IEEE80211_C_SWSLEEP     0x00080000      /* CAPABILITY: do sleep here */
     473#define IEEE80211_C_SWAMSDUTX   0x00100000      /* CAPABILITY: software A-MSDU TX */
     474/* 0x7c0000 available */
     475#define IEEE80211_C_WPA1        0x00800000      /* CAPABILITY: WPA1 avail */
     476#define IEEE80211_C_WPA2        0x01000000      /* CAPABILITY: WPA2 avail */
     477#define IEEE80211_C_WPA         0x01800000      /* CAPABILITY: WPA1+WPA2 avail*/
     478#define IEEE80211_C_BURST       0x02000000      /* CAPABILITY: frame bursting */
     479#define IEEE80211_C_WME         0x04000000      /* CAPABILITY: WME avail */
     480#define IEEE80211_C_WDS         0x08000000      /* CAPABILITY: 4-addr support */
     481/* 0x10000000 reserved */
     482#define IEEE80211_C_BGSCAN      0x20000000      /* CAPABILITY: bg scanning */
     483#define IEEE80211_C_TXFRAG      0x40000000      /* CAPABILITY: tx fragments */
     484#define IEEE80211_C_TDMA        0x80000000      /* CAPABILITY: TDMA avail */
     485/* XXX protection/barker? */
     486
     487#define IEEE80211_C_OPMODE \
     488        (IEEE80211_C_STA | IEEE80211_C_IBSS | IEEE80211_C_HOSTAP | \
     489         IEEE80211_C_AHDEMO | IEEE80211_C_MONITOR | IEEE80211_C_WDS | \
     490         IEEE80211_C_TDMA | IEEE80211_C_MBSS)
     491
     492#define IEEE80211_C_BITS \
     493        "\20\1STA\002803ENCAP\7FF\10TURBOP\11IBSS\12PMGT" \
     494        "\13HOSTAP\14AHDEMO\15SWRETRY\16TXPMGT\17SHSLOT\20SHPREAMBLE" \
     495        "\21MONITOR\22DFS\23MBSS\30WPA1\31WPA2\32BURST\33WME\34WDS\36BGSCAN" \
     496        "\37TXFRAG\40TDMA"
     497
     498/*
     499 * ic_htcaps/iv_htcaps: HT-specific device/driver capabilities
     500 *
     501 * NB: the low 16-bits are the 802.11 definitions, the upper
     502 *     16-bits are used to define s/w/driver capabilities.
     503 */
     504#define IEEE80211_HTC_AMPDU     0x00010000      /* CAPABILITY: A-MPDU tx */
     505#define IEEE80211_HTC_AMSDU     0x00020000      /* CAPABILITY: A-MSDU tx */
     506/* NB: HT40 is implied by IEEE80211_HTCAP_CHWIDTH40 */
     507#define IEEE80211_HTC_HT        0x00040000      /* CAPABILITY: HT operation */
     508#define IEEE80211_HTC_SMPS      0x00080000      /* CAPABILITY: MIMO power save*/
     509#define IEEE80211_HTC_RIFS      0x00100000      /* CAPABILITY: RIFS support */
     510#define IEEE80211_HTC_RXUNEQUAL 0x00200000      /* CAPABILITY: RX unequal MCS */
     511#define IEEE80211_HTC_RXMCS32   0x00400000      /* CAPABILITY: MCS32 support */
     512#define IEEE80211_HTC_TXUNEQUAL 0x00800000      /* CAPABILITY: TX unequal MCS */
     513#define IEEE80211_HTC_TXMCS32   0x01000000      /* CAPABILITY: MCS32 support */
     514
     515#define IEEE80211_C_HTCAP_BITS \
     516        "\20\1LDPC\2CHWIDTH40\5GREENFIELD\6SHORTGI20\7SHORTGI40\10TXSTBC" \
     517        "\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS"
     518
    403519#endif /* _NET80211__IEEE80211_H_ */
  • freebsd/sys/net80211/ieee80211.c

    r172f2ac ra241ea8  
    3838#include <sys/systm.h>
    3939#include <sys/kernel.h>
    40 
     40#include <sys/malloc.h>
    4141#include <sys/socket.h>
     42#include <sys/sbuf.h>
     43
     44#include <machine/stdarg.h>
    4245
    4346#include <net/if.h>
     47#include <net/if_var.h>
    4448#include <net/if_dl.h>
    4549#include <net/if_media.h>
     
    8387};
    8488
    85 static const uint8_t ieee80211broadcastaddr[IEEE80211_ADDR_LEN] =
     89const uint8_t ieee80211broadcastaddr[IEEE80211_ADDR_LEN] =
    8690        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
    8791
     
    8993static  void ieee80211_syncflag_ht_locked(struct ieee80211com *ic, int flag);
    9094static  void ieee80211_syncflag_ext_locked(struct ieee80211com *ic, int flag);
     95static  void ieee80211_syncflag_vht_locked(struct ieee80211com *ic, int flag);
    9196static  int ieee80211_media_setup(struct ieee80211com *ic,
    9297                struct ifmedia *media, int caps, int addsta,
    9398                ifm_change_cb_t media_change, ifm_stat_cb_t media_stat);
    94 static  void ieee80211com_media_status(struct ifnet *, struct ifmediareq *);
    95 static  int ieee80211com_media_change(struct ifnet *);
    9699static  int media_status(enum ieee80211_opmode,
    97100                const struct ieee80211_channel *);
     101static uint64_t ieee80211_get_counter(struct ifnet *, ift_counter);
    98102
    99103MALLOC_DEFINE(M_80211_VAP, "80211vap", "802.11 vap state");
     
    121125 * a default channel if not already specified.
    122126 */
    123 static void
     127void
    124128ieee80211_chan_init(struct ieee80211com *ic)
    125129{
     
    225229
    226230static void
    227 null_update_mcast(struct ifnet *ifp)
    228 {
    229         if_printf(ifp, "need multicast update callback\n");
     231null_update_mcast(struct ieee80211com *ic)
     232{
     233
     234        ic_printf(ic, "need multicast update callback\n");
    230235}
    231236
    232237static void
    233 null_update_promisc(struct ifnet *ifp)
    234 {
    235         if_printf(ifp, "need promiscuous mode update callback\n");
    236 }
     238null_update_promisc(struct ieee80211com *ic)
     239{
     240
     241        ic_printf(ic, "need promiscuous mode update callback\n");
     242}
     243
     244static void
     245null_update_chw(struct ieee80211com *ic)
     246{
     247
     248        ic_printf(ic, "%s: need callback\n", __func__);
     249}
     250
     251int
     252ic_printf(struct ieee80211com *ic, const char * fmt, ...)
     253{
     254        va_list ap;
     255        int retval;
     256
     257        retval = printf("%s: ", ic->ic_name);
     258        va_start(ap, fmt);
     259        retval += vprintf(fmt, ap);
     260        va_end(ap); 
     261        return (retval);
     262}
     263
     264static LIST_HEAD(, ieee80211com) ic_head = LIST_HEAD_INITIALIZER(ic_head);
     265static struct mtx ic_list_mtx;
     266MTX_SYSINIT(ic_list, &ic_list_mtx, "ieee80211com list", MTX_DEF);
    237267
    238268static int
    239 null_transmit(struct ifnet *ifp, struct mbuf *m)
    240 {
    241         m_freem(m);
    242         ifp->if_oerrors++;
    243         return EACCES;          /* XXX EIO/EPERM? */
    244 }
    245 
    246 static int
    247 null_output(struct ifnet *ifp, struct mbuf *m,
    248         struct sockaddr *dst, struct route *ro)
    249 {
    250         if_printf(ifp, "discard raw packet\n");
    251         return null_transmit(ifp, m);
    252 }
    253 
    254 static void
    255 null_input(struct ifnet *ifp, struct mbuf *m)
    256 {
    257         if_printf(ifp, "if_input should not be called\n");
    258         m_freem(m);
    259 }
     269sysctl_ieee80211coms(SYSCTL_HANDLER_ARGS)
     270{
     271        struct ieee80211com *ic;
     272        struct sbuf sb;
     273        char *sp;
     274        int error;
     275
     276        error = sysctl_wire_old_buffer(req, 0);
     277        if (error)
     278                return (error);
     279        sbuf_new_for_sysctl(&sb, NULL, 8, req);
     280        sbuf_clear_flags(&sb, SBUF_INCLUDENUL);
     281        sp = "";
     282        mtx_lock(&ic_list_mtx);
     283        LIST_FOREACH(ic, &ic_head, ic_next) {
     284                sbuf_printf(&sb, "%s%s", sp, ic->ic_name);
     285                sp = " ";
     286        }
     287        mtx_unlock(&ic_list_mtx);
     288        error = sbuf_finish(&sb);
     289        sbuf_delete(&sb);
     290        return (error);
     291}
     292
     293SYSCTL_PROC(_net_wlan, OID_AUTO, devices,
     294    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
     295    sysctl_ieee80211coms, "A", "names of available 802.11 devices");
    260296
    261297/*
     
    264300 */
    265301void
    266 ieee80211_ifattach(struct ieee80211com *ic,
    267         const uint8_t macaddr[IEEE80211_ADDR_LEN])
    268 {
    269         struct ifnet *ifp = ic->ic_ifp;
    270         struct sockaddr_dl *sdl;
    271         struct ifaddr *ifa;
    272 
    273         KASSERT(ifp->if_type == IFT_IEEE80211, ("if_type %d", ifp->if_type));
    274 
    275         IEEE80211_LOCK_INIT(ic, ifp->if_xname);
     302ieee80211_ifattach(struct ieee80211com *ic)
     303{
     304
     305        IEEE80211_LOCK_INIT(ic, ic->ic_name);
     306        IEEE80211_TX_LOCK_INIT(ic, ic->ic_name);
    276307        TAILQ_INIT(&ic->ic_vaps);
    277308
     
    279310        ic->ic_tq = taskqueue_create("ic_taskq", M_WAITOK | M_ZERO,
    280311            taskqueue_thread_enqueue, &ic->ic_tq);
    281         taskqueue_start_threads(&ic->ic_tq, 1, PI_NET, "%s taskq",
    282             ifp->if_xname);
     312        taskqueue_start_threads(&ic->ic_tq, 1, PI_NET, "%s net80211 taskq",
     313            ic->ic_name);
     314        ic->ic_ierrors = counter_u64_alloc(M_WAITOK);
     315        ic->ic_oerrors = counter_u64_alloc(M_WAITOK);
    283316        /*
    284317         * Fill in 802.11 available channel set, mark all
     
    286319         * channel if not already specified.
    287320         */
    288         ieee80211_media_init(ic);
     321        ieee80211_chan_init(ic);
    289322
    290323        ic->ic_update_mcast = null_update_mcast;
    291324        ic->ic_update_promisc = null_update_promisc;
     325        ic->ic_update_chw = null_update_chw;
    292326
    293327        ic->ic_hash_key = arc4random();
     
    310344        ieee80211_sysctl_attach(ic);
    311345
    312         ifp->if_addrlen = IEEE80211_ADDR_LEN;
    313         ifp->if_hdrlen = 0;
    314         if_attach(ifp);
    315         ifp->if_mtu = IEEE80211_MTU_MAX;
    316         ifp->if_broadcastaddr = ieee80211broadcastaddr;
    317         ifp->if_output = null_output;
    318         ifp->if_input = null_input;     /* just in case */
    319         ifp->if_resolvemulti = NULL;    /* NB: callers check */
    320 
    321         ifa = ifaddr_byindex(ifp->if_index);
    322         KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__));
    323         sdl = (struct sockaddr_dl *)ifa->ifa_addr;
    324         sdl->sdl_type = IFT_ETHER;              /* XXX IFT_IEEE80211? */
    325         sdl->sdl_alen = IEEE80211_ADDR_LEN;
    326         IEEE80211_ADDR_COPY(LLADDR(sdl), macaddr);
    327         ifa_free(ifa);
     346        mtx_lock(&ic_list_mtx);
     347        LIST_INSERT_HEAD(&ic_head, ic, ic_next);
     348        mtx_unlock(&ic_list_mtx);
    328349}
    329350
     
    337358ieee80211_ifdetach(struct ieee80211com *ic)
    338359{
    339         struct ifnet *ifp = ic->ic_ifp;
    340360        struct ieee80211vap *vap;
    341361
    342         if_detach(ifp);
    343 
     362        mtx_lock(&ic_list_mtx);
     363        LIST_REMOVE(ic, ic_next);
     364        mtx_unlock(&ic_list_mtx);
     365
     366        taskqueue_drain(taskqueue_thread, &ic->ic_restart_task);
     367
     368        /*
     369         * The VAP is responsible for setting and clearing
     370         * the VIMAGE context.
     371         */
    344372        while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL)
    345373                ieee80211_vap_destroy(vap);
     
    360388        ieee80211_node_detach(ic);
    361389
    362         ifmedia_removeall(&ic->ic_media);
     390        counter_u64_free(ic->ic_ierrors);
     391        counter_u64_free(ic->ic_oerrors);
     392
    363393        taskqueue_free(ic->ic_tq);
     394        IEEE80211_TX_LOCK_DESTROY(ic);
    364395        IEEE80211_LOCK_DESTROY(ic);
     396}
     397
     398struct ieee80211com *
     399ieee80211_find_com(const char *name)
     400{
     401        struct ieee80211com *ic;
     402
     403        mtx_lock(&ic_list_mtx);
     404        LIST_FOREACH(ic, &ic_head, ic_next)
     405                if (strcmp(ic->ic_name, name) == 0)
     406                        break;
     407        mtx_unlock(&ic_list_mtx);
     408
     409        return (ic);
     410}
     411
     412void
     413ieee80211_iterate_coms(ieee80211_com_iter_func *f, void *arg)
     414{
     415        struct ieee80211com *ic;
     416
     417        mtx_lock(&ic_list_mtx);
     418        LIST_FOREACH(ic, &ic_head, ic_next)
     419                (*f)(arg, ic);
     420        mtx_unlock(&ic_list_mtx);
    365421}
    366422
     
    381437
    382438/*
     439 * Default for updating the VAP default TX key index.
     440 *
     441 * Drivers that support TX offload as well as hardware encryption offload
     442 * may need to be informed of key index changes separate from the key
     443 * update.
     444 */
     445static void
     446default_update_deftxkey(struct ieee80211vap *vap, ieee80211_keyix kid)
     447{
     448
     449        /* XXX assert validity */
     450        /* XXX assert we're in a key update block */
     451        vap->iv_def_txkey = kid;
     452}
     453
     454/*
     455 * Add underlying device errors to vap errors.
     456 */
     457static uint64_t
     458ieee80211_get_counter(struct ifnet *ifp, ift_counter cnt)
     459{
     460        struct ieee80211vap *vap = ifp->if_softc;
     461        struct ieee80211com *ic = vap->iv_ic;
     462        uint64_t rv;
     463
     464        rv = if_get_counter_default(ifp, cnt);
     465        switch (cnt) {
     466        case IFCOUNTER_OERRORS:
     467                rv += counter_u64_fetch(ic->ic_oerrors);
     468                break;
     469        case IFCOUNTER_IERRORS:
     470                rv += counter_u64_fetch(ic->ic_ierrors);
     471                break;
     472        default:
     473                break;
     474        }
     475
     476        return (rv);
     477}
     478
     479/*
    383480 * Prepare a vap for use.  Drivers use this call to
    384481 * setup net80211 state in new vap's prior attaching
     
    388485ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
    389486    const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode,
    390     int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
    391     const uint8_t macaddr[IEEE80211_ADDR_LEN])
     487    int flags, const uint8_t bssid[IEEE80211_ADDR_LEN])
    392488{
    393489        struct ifnet *ifp;
     
    395491        ifp = if_alloc(IFT_ETHER);
    396492        if (ifp == NULL) {
    397                 if_printf(ic->ic_ifp, "%s: unable to allocate ifnet\n",
     493                ic_printf(ic, "%s: unable to allocate ifnet\n",
    398494                    __func__);
    399495                return ENOMEM;
     
    402498        ifp->if_softc = vap;                    /* back pointer */
    403499        ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
    404         ifp->if_start = ieee80211_start;
     500        ifp->if_transmit = ieee80211_vap_transmit;
     501        ifp->if_qflush = ieee80211_vap_qflush;
    405502        ifp->if_ioctl = ieee80211_ioctl;
    406503        ifp->if_init = ieee80211_init;
    407         /* NB: input+output filled in by ether_ifattach */
    408         IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
    409         ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
    410         IFQ_SET_READY(&ifp->if_snd);
     504        ifp->if_get_counter = ieee80211_get_counter;
    411505
    412506        vap->iv_ifp = ifp;
     
    420514        vap->iv_opmode = opmode;
    421515        vap->iv_caps |= ieee80211_opcap[opmode];
     516        IEEE80211_ADDR_COPY(vap->iv_myaddr, ic->ic_macaddr);
    422517        switch (opmode) {
    423518        case IEEE80211_M_WDS:
     
    486581        vap->iv_reset = default_reset;
    487582
    488         IEEE80211_ADDR_COPY(vap->iv_myaddr, macaddr);
     583        /*
     584         * Install a default crypto key update method, the driver
     585         * can override this.
     586         */
     587        vap->iv_update_deftxkey = default_update_deftxkey;
    489588
    490589        ieee80211_sysctl_vattach(vap);
     
    511610 */
    512611int
    513 ieee80211_vap_attach(struct ieee80211vap *vap,
    514         ifm_change_cb_t media_change, ifm_stat_cb_t media_stat)
     612ieee80211_vap_attach(struct ieee80211vap *vap, ifm_change_cb_t media_change,
     613    ifm_stat_cb_t media_stat, const uint8_t macaddr[IEEE80211_ADDR_LEN])
    515614{
    516615        struct ifnet *ifp = vap->iv_ifp;
     
    522621            "%s: %s parent %s flags 0x%x flags_ext 0x%x\n",
    523622            __func__, ieee80211_opmode_name[vap->iv_opmode],
    524             ic->ic_ifp->if_xname, vap->iv_flags, vap->iv_flags_ext);
     623            ic->ic_name, vap->iv_flags, vap->iv_flags_ext);
    525624
    526625        /*
     
    540639                ifp->if_baudrate = IF_Mbps(maxrate);
    541640
    542         ether_ifattach(ifp, vap->iv_myaddr);
    543         if (vap->iv_opmode == IEEE80211_M_MONITOR) {
    544                 /* NB: disallow transmit */
    545                 ifp->if_transmit = null_transmit;
    546                 ifp->if_output = null_output;
    547         } else {
    548                 /* hook output method setup by ether_ifattach */
    549                 vap->iv_output = ifp->if_output;
    550                 ifp->if_output = ieee80211_output;
    551         }
     641        ether_ifattach(ifp, macaddr);
     642        IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp));
     643        /* hook output method setup by ether_ifattach */
     644        vap->iv_output = ifp->if_output;
     645        ifp->if_output = ieee80211_output;
    552646        /* NB: if_mtu set by ether_ifattach to ETHERMTU */
    553647
     
    562656        ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT);
    563657        ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40);
    564         ieee80211_syncifflag_locked(ic, IFF_PROMISC);
    565         ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
     658
     659        ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_VHT);
     660        ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT40);
     661        ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT80);
     662        ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT80P80);
     663        ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT160);
    566664        IEEE80211_UNLOCK(ic);
    567665
     
    581679        struct ifnet *ifp = vap->iv_ifp;
    582680
     681        CURVNET_SET(ifp->if_vnet);
     682
    583683        IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s parent %s\n",
    584             __func__, ieee80211_opmode_name[vap->iv_opmode],
    585             ic->ic_ifp->if_xname);
     684            __func__, ieee80211_opmode_name[vap->iv_opmode], ic->ic_name);
    586685
    587686        /* NB: bpfdetach is called by ether_ifdetach and claims all taps */
     
    610709        ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT);
    611710        ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40);
     711
     712        ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_VHT);
     713        ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT40);
     714        ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT80);
     715        ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT80P80);
     716        ieee80211_syncflag_vht_locked(ic, IEEE80211_FVHT_USEVHT160);
     717
    612718        /* NB: this handles the bpfdetach done below */
    613719        ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_BPF);
    614         ieee80211_syncifflag_locked(ic, IFF_PROMISC);
    615         ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
     720        if (vap->iv_ifflags & IFF_PROMISC)
     721                ieee80211_promisc(vap, false);
     722        if (vap->iv_ifflags & IFF_ALLMULTI)
     723                ieee80211_allmulti(vap, false);
    616724        IEEE80211_UNLOCK(ic);
    617725
     
    633741
    634742        if_free(ifp);
    635 }
    636 
    637 /*
    638  * Synchronize flag bit state in the parent ifnet structure
    639  * according to the state of all vap ifnet's.  This is used,
    640  * for example, to handle IFF_PROMISC and IFF_ALLMULTI.
     743
     744        CURVNET_RESTORE();
     745}
     746
     747/*
     748 * Count number of vaps in promisc, and issue promisc on
     749 * parent respectively.
    641750 */
    642751void
    643 ieee80211_syncifflag_locked(struct ieee80211com *ic, int flag)
    644 {
    645         struct ifnet *ifp = ic->ic_ifp;
    646         struct ieee80211vap *vap;
    647         int bit, oflags;
     752ieee80211_promisc(struct ieee80211vap *vap, bool on)
     753{
     754        struct ieee80211com *ic = vap->iv_ic;
    648755
    649756        IEEE80211_LOCK_ASSERT(ic);
    650757
    651         bit = 0;
    652         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
    653                 if (vap->iv_ifp->if_flags & flag) {
    654                         /*
    655                          * XXX the bridge sets PROMISC but we don't want to
    656                          * enable it on the device, discard here so all the
    657                          * drivers don't need to special-case it
    658                          */
    659                         if (flag == IFF_PROMISC &&
    660                             !(vap->iv_opmode == IEEE80211_M_MONITOR ||
    661                               (vap->iv_opmode == IEEE80211_M_AHDEMO &&
    662                                (vap->iv_caps & IEEE80211_C_TDMA) == 0)))
    663                                 continue;
    664                         bit = 1;
    665                         break;
    666                 }
    667         oflags = ifp->if_flags;
    668         if (bit)
    669                 ifp->if_flags |= flag;
    670         else
    671                 ifp->if_flags &= ~flag;
    672         if ((ifp->if_flags ^ oflags) & flag) {
    673                 /* XXX should we return 1/0 and let caller do this? */
    674                 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
    675                         if (flag == IFF_PROMISC)
    676                                 ieee80211_runtask(ic, &ic->ic_promisc_task);
    677                         else if (flag == IFF_ALLMULTI)
    678                                 ieee80211_runtask(ic, &ic->ic_mcast_task);
    679                 }
     758        if (on) {
     759                if (++ic->ic_promisc == 1)
     760                        ieee80211_runtask(ic, &ic->ic_promisc_task);
     761        } else {
     762                KASSERT(ic->ic_promisc > 0, ("%s: ic %p not promisc",
     763                    __func__, ic));
     764                if (--ic->ic_promisc == 0)
     765                        ieee80211_runtask(ic, &ic->ic_promisc_task);
     766        }
     767}
     768
     769/*
     770 * Count number of vaps in allmulti, and issue allmulti on
     771 * parent respectively.
     772 */
     773void
     774ieee80211_allmulti(struct ieee80211vap *vap, bool on)
     775{
     776        struct ieee80211com *ic = vap->iv_ic;
     777
     778        IEEE80211_LOCK_ASSERT(ic);
     779
     780        if (on) {
     781                if (++ic->ic_allmulti == 1)
     782                        ieee80211_runtask(ic, &ic->ic_mcast_task);
     783        } else {
     784                KASSERT(ic->ic_allmulti > 0, ("%s: ic %p not allmulti",
     785                    __func__, ic));
     786                if (--ic->ic_allmulti == 0)
     787                        ieee80211_runtask(ic, &ic->ic_mcast_task);
    680788        }
    681789}
     
    758866                vap->iv_flags_ht |= flag;
    759867        ieee80211_syncflag_ht_locked(ic, flag);
     868        IEEE80211_UNLOCK(ic);
     869}
     870
     871/*
     872 * Synchronize flags_vht bit state in the com structure
     873 * according to the state of all vap's.  This is used,
     874 * for example, to handle state changes via ioctls.
     875 */
     876static void
     877ieee80211_syncflag_vht_locked(struct ieee80211com *ic, int flag)
     878{
     879        struct ieee80211vap *vap;
     880        int bit;
     881
     882        IEEE80211_LOCK_ASSERT(ic);
     883
     884        bit = 0;
     885        TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
     886                if (vap->iv_flags_vht & flag) {
     887                        bit = 1;
     888                        break;
     889                }
     890        if (bit)
     891                ic->ic_flags_vht |= flag;
     892        else
     893                ic->ic_flags_vht &= ~flag;
     894}
     895
     896void
     897ieee80211_syncflag_vht(struct ieee80211vap *vap, int flag)
     898{
     899        struct ieee80211com *ic = vap->iv_ic;
     900
     901        IEEE80211_LOCK(ic);
     902        if (flag < 0) {
     903                flag = -flag;
     904                vap->iv_flags_vht &= ~flag;
     905        } else
     906                vap->iv_flags_vht |= flag;
     907        ieee80211_syncflag_vht_locked(ic, flag);
    760908        IEEE80211_UNLOCK(ic);
    761909}
     
    8731021{
    8741022        if (c == NULL) {
    875                 if_printf(ic->ic_ifp, "invalid channel (NULL)\n");
     1023                ic_printf(ic, "invalid channel (NULL)\n");
    8761024                return 0;               /* XXX */
    8771025        }
     
    9121060}
    9131061
     1062static __inline void
     1063set_extchan(struct ieee80211_channel *c)
     1064{
     1065
     1066        /*
     1067         * IEEE Std 802.11-2012, page 1738, subclause 20.3.15.4:
     1068         * "the secondary channel number shall be 'N + [1,-1] * 4'
     1069         */
     1070        if (c->ic_flags & IEEE80211_CHAN_HT40U)
     1071                c->ic_extieee = c->ic_ieee + 4;
     1072        else if (c->ic_flags & IEEE80211_CHAN_HT40D)
     1073                c->ic_extieee = c->ic_ieee - 4;
     1074        else
     1075                c->ic_extieee = 0;
     1076}
     1077
     1078static int
     1079addchan(struct ieee80211_channel chans[], int maxchans, int *nchans,
     1080    uint8_t ieee, uint16_t freq, int8_t maxregpower, uint32_t flags)
     1081{
     1082        struct ieee80211_channel *c;
     1083
     1084        if (*nchans >= maxchans)
     1085                return (ENOBUFS);
     1086
     1087        c = &chans[(*nchans)++];
     1088        c->ic_ieee = ieee;
     1089        c->ic_freq = freq != 0 ? freq : ieee80211_ieee2mhz(ieee, flags);
     1090        c->ic_maxregpower = maxregpower;
     1091        c->ic_maxpower = 2 * maxregpower;
     1092        c->ic_flags = flags;
     1093        set_extchan(c);
     1094
     1095        return (0);
     1096}
     1097
     1098static int
     1099copychan_prev(struct ieee80211_channel chans[], int maxchans, int *nchans,
     1100    uint32_t flags)
     1101{
     1102        struct ieee80211_channel *c;
     1103
     1104        KASSERT(*nchans > 0, ("channel list is empty\n"));
     1105
     1106        if (*nchans >= maxchans)
     1107                return (ENOBUFS);
     1108
     1109        c = &chans[(*nchans)++];
     1110        c[0] = c[-1];
     1111        c->ic_flags = flags;
     1112        set_extchan(c);
     1113
     1114        return (0);
     1115}
     1116
     1117static void
     1118getflags_2ghz(const uint8_t bands[], uint32_t flags[], int ht40)
     1119{
     1120        int nmodes;
     1121
     1122        nmodes = 0;
     1123        if (isset(bands, IEEE80211_MODE_11B))
     1124                flags[nmodes++] = IEEE80211_CHAN_B;
     1125        if (isset(bands, IEEE80211_MODE_11G))
     1126                flags[nmodes++] = IEEE80211_CHAN_G;
     1127        if (isset(bands, IEEE80211_MODE_11NG))
     1128                flags[nmodes++] = IEEE80211_CHAN_G | IEEE80211_CHAN_HT20;
     1129        if (ht40) {
     1130                flags[nmodes++] = IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U;
     1131                flags[nmodes++] = IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D;
     1132        }
     1133        flags[nmodes] = 0;
     1134}
     1135
     1136static void
     1137getflags_5ghz(const uint8_t bands[], uint32_t flags[], int ht40)
     1138{
     1139        int nmodes;
     1140
     1141        nmodes = 0;
     1142        if (isset(bands, IEEE80211_MODE_11A))
     1143                flags[nmodes++] = IEEE80211_CHAN_A;
     1144        if (isset(bands, IEEE80211_MODE_11NA))
     1145                flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
     1146        if (ht40) {
     1147                flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U;
     1148                flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D;
     1149        }
     1150        flags[nmodes] = 0;
     1151}
     1152
     1153static void
     1154getflags(const uint8_t bands[], uint32_t flags[], int ht40)
     1155{
     1156
     1157        flags[0] = 0;
     1158        if (isset(bands, IEEE80211_MODE_11A) ||
     1159            isset(bands, IEEE80211_MODE_11NA)) {
     1160                if (isset(bands, IEEE80211_MODE_11B) ||
     1161                    isset(bands, IEEE80211_MODE_11G) ||
     1162                    isset(bands, IEEE80211_MODE_11NG))
     1163                        return;
     1164
     1165                getflags_5ghz(bands, flags, ht40);
     1166        } else
     1167                getflags_2ghz(bands, flags, ht40);
     1168}
     1169
     1170/*
     1171 * Add one 20 MHz channel into specified channel list.
     1172 */
     1173int
     1174ieee80211_add_channel(struct ieee80211_channel chans[], int maxchans,
     1175    int *nchans, uint8_t ieee, uint16_t freq, int8_t maxregpower,
     1176    uint32_t chan_flags, const uint8_t bands[])
     1177{
     1178        uint32_t flags[IEEE80211_MODE_MAX];
     1179        int i, error;
     1180
     1181        getflags(bands, flags, 0);
     1182        KASSERT(flags[0] != 0, ("%s: no correct mode provided\n", __func__));
     1183
     1184        error = addchan(chans, maxchans, nchans, ieee, freq, maxregpower,
     1185            flags[0] | chan_flags);
     1186        for (i = 1; flags[i] != 0 && error == 0; i++) {
     1187                error = copychan_prev(chans, maxchans, nchans,
     1188                    flags[i] | chan_flags);
     1189        }
     1190
     1191        return (error);
     1192}
     1193
     1194static struct ieee80211_channel *
     1195findchannel(struct ieee80211_channel chans[], int nchans, uint16_t freq,
     1196    uint32_t flags)
     1197{
     1198        struct ieee80211_channel *c;
     1199        int i;
     1200
     1201        flags &= IEEE80211_CHAN_ALLTURBO;
     1202        /* brute force search */
     1203        for (i = 0; i < nchans; i++) {
     1204                c = &chans[i];
     1205                if (c->ic_freq == freq &&
     1206                    (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags)
     1207                        return c;
     1208        }
     1209        return NULL;
     1210}
     1211
     1212/*
     1213 * Add 40 MHz channel pair into specified channel list.
     1214 */
     1215int
     1216ieee80211_add_channel_ht40(struct ieee80211_channel chans[], int maxchans,
     1217    int *nchans, uint8_t ieee, int8_t maxregpower, uint32_t flags)
     1218{
     1219        struct ieee80211_channel *cent, *extc;
     1220        uint16_t freq;
     1221        int error;
     1222
     1223        freq = ieee80211_ieee2mhz(ieee, flags);
     1224
     1225        /*
     1226         * Each entry defines an HT40 channel pair; find the
     1227         * center channel, then the extension channel above.
     1228         */
     1229        flags |= IEEE80211_CHAN_HT20;
     1230        cent = findchannel(chans, *nchans, freq, flags);
     1231        if (cent == NULL)
     1232                return (EINVAL);
     1233
     1234        extc = findchannel(chans, *nchans, freq + 20, flags);
     1235        if (extc == NULL)
     1236                return (ENOENT);
     1237
     1238        flags &= ~IEEE80211_CHAN_HT;
     1239        error = addchan(chans, maxchans, nchans, cent->ic_ieee, cent->ic_freq,
     1240            maxregpower, flags | IEEE80211_CHAN_HT40U);
     1241        if (error != 0)
     1242                return (error);
     1243
     1244        error = addchan(chans, maxchans, nchans, extc->ic_ieee, extc->ic_freq,
     1245            maxregpower, flags | IEEE80211_CHAN_HT40D);
     1246
     1247        return (error);
     1248}
     1249
     1250/*
     1251 * Fetch the center frequency for the primary channel.
     1252 */
     1253uint32_t
     1254ieee80211_get_channel_center_freq(const struct ieee80211_channel *c)
     1255{
     1256
     1257        return (c->ic_freq);
     1258}
     1259
     1260/*
     1261 * Fetch the center frequency for the primary BAND channel.
     1262 *
     1263 * For 5, 10, 20MHz channels it'll be the normally configured channel
     1264 * frequency.
     1265 *
     1266 * For 40MHz, 80MHz, 160Mhz channels it'll the the centre of the
     1267 * wide channel, not the centre of the primary channel (that's ic_freq).
     1268 *
     1269 * For 80+80MHz channels this will be the centre of the primary
     1270 * 80MHz channel; the secondary 80MHz channel will be center_freq2().
     1271 */
     1272
     1273uint32_t
     1274ieee80211_get_channel_center_freq1(const struct ieee80211_channel *c)
     1275{
     1276
     1277        if (IEEE80211_IS_CHAN_HT40U(c)) {
     1278                return (c->ic_freq + 10);
     1279        }
     1280        if (IEEE80211_IS_CHAN_HT40D(c)) {
     1281                return (c->ic_freq - 10);
     1282        }
     1283
     1284        return (c->ic_freq);
     1285}
     1286
     1287/*
     1288 * For now, no 80+80 support; this is zero.
     1289 */
     1290uint32_t
     1291ieee80211_get_channel_center_freq2(const struct ieee80211_channel *c)
     1292{
     1293
     1294        return (0);
     1295}
     1296
     1297/*
     1298 * Adds channels into specified channel list (ieee[] array must be sorted).
     1299 * Channels are already sorted.
     1300 */
     1301static int
     1302add_chanlist(struct ieee80211_channel chans[], int maxchans, int *nchans,
     1303    const uint8_t ieee[], int nieee, uint32_t flags[])
     1304{
     1305        uint16_t freq;
     1306        int i, j, error;
     1307
     1308        for (i = 0; i < nieee; i++) {
     1309                freq = ieee80211_ieee2mhz(ieee[i], flags[0]);
     1310                for (j = 0; flags[j] != 0; j++) {
     1311                        if (flags[j] & IEEE80211_CHAN_HT40D)
     1312                                if (i == 0 || ieee[i] < ieee[0] + 4 ||
     1313                                    freq - 20 !=
     1314                                    ieee80211_ieee2mhz(ieee[i] - 4, flags[j]))
     1315                                        continue;
     1316                        if (flags[j] & IEEE80211_CHAN_HT40U)
     1317                                if (i == nieee - 1 ||
     1318                                    ieee[i] + 4 > ieee[nieee - 1] ||
     1319                                    freq + 20 !=
     1320                                    ieee80211_ieee2mhz(ieee[i] + 4, flags[j]))
     1321                                        continue;
     1322
     1323                        if (j == 0) {
     1324                                error = addchan(chans, maxchans, nchans,
     1325                                    ieee[i], freq, 0, flags[j]);
     1326                        } else {
     1327                                error = copychan_prev(chans, maxchans, nchans,
     1328                                    flags[j]);
     1329                        }
     1330                        if (error != 0)
     1331                                return (error);
     1332                }
     1333        }
     1334
     1335        return (0);
     1336}
     1337
     1338int
     1339ieee80211_add_channel_list_2ghz(struct ieee80211_channel chans[], int maxchans,
     1340    int *nchans, const uint8_t ieee[], int nieee, const uint8_t bands[],
     1341    int ht40)
     1342{
     1343        uint32_t flags[IEEE80211_MODE_MAX];
     1344
     1345        getflags_2ghz(bands, flags, ht40);
     1346        KASSERT(flags[0] != 0, ("%s: no correct mode provided\n", __func__));
     1347
     1348        return (add_chanlist(chans, maxchans, nchans, ieee, nieee, flags));
     1349}
     1350
     1351int
     1352ieee80211_add_channel_list_5ghz(struct ieee80211_channel chans[], int maxchans,
     1353    int *nchans, const uint8_t ieee[], int nieee, const uint8_t bands[],
     1354    int ht40)
     1355{
     1356        uint32_t flags[IEEE80211_MODE_MAX];
     1357
     1358        getflags_5ghz(bands, flags, ht40);
     1359        KASSERT(flags[0] != 0, ("%s: no correct mode provided\n", __func__));
     1360
     1361        return (add_chanlist(chans, maxchans, nchans, ieee, nieee, flags));
     1362}
     1363
    9141364/*
    9151365 * Locate a channel given a frequency+flags.  We cache
     
    9211371{
    9221372        struct ieee80211_channel *c;
    923         int i;
    9241373
    9251374        flags &= IEEE80211_CHAN_ALLTURBO;
     
    9291378                return c;
    9301379        /* brute force search */
    931         for (i = 0; i < ic->ic_nchans; i++) {
    932                 c = &ic->ic_channels[i];
    933                 if (c->ic_freq == freq &&
    934                     (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags)
    935                         return c;
    936         }
    937         return NULL;
     1380        return (findchannel(ic->ic_channels, ic->ic_nchans, freq, flags));
    9381381}
    9391382
     
    9621405        }
    9631406        return NULL;
     1407}
     1408
     1409/*
     1410 * Lookup a channel suitable for the given rx status.
     1411 *
     1412 * This is used to find a channel for a frame (eg beacon, probe
     1413 * response) based purely on the received PHY information.
     1414 *
     1415 * For now it tries to do it based on R_FREQ / R_IEEE.
     1416 * This is enough for 11bg and 11a (and thus 11ng/11na)
     1417 * but it will not be enough for GSM, PSB channels and the
     1418 * like.  It also doesn't know about legacy-turbog and
     1419 * legacy-turbo modes, which some offload NICs actually
     1420 * support in weird ways.
     1421 *
     1422 * Takes the ic and rxstatus; returns the channel or NULL
     1423 * if not found.
     1424 *
     1425 * XXX TODO: Add support for that when the need arises.
     1426 */
     1427struct ieee80211_channel *
     1428ieee80211_lookup_channel_rxstatus(struct ieee80211vap *vap,
     1429    const struct ieee80211_rx_stats *rxs)
     1430{
     1431        struct ieee80211com *ic = vap->iv_ic;
     1432        uint32_t flags;
     1433        struct ieee80211_channel *c;
     1434
     1435        if (rxs == NULL)
     1436                return (NULL);
     1437
     1438        /*
     1439         * Strictly speaking we only use freq for now,
     1440         * however later on we may wish to just store
     1441         * the ieee for verification.
     1442         */
     1443        if ((rxs->r_flags & IEEE80211_R_FREQ) == 0)
     1444                return (NULL);
     1445        if ((rxs->r_flags & IEEE80211_R_IEEE) == 0)
     1446                return (NULL);
     1447
     1448        /*
     1449         * If the rx status contains a valid ieee/freq, then
     1450         * ensure we populate the correct channel information
     1451         * in rxchan before passing it up to the scan infrastructure.
     1452         * Offload NICs will pass up beacons from all channels
     1453         * during background scans.
     1454         */
     1455
     1456        /* Determine a band */
     1457        /* XXX should be done by the driver? */
     1458        if (rxs->c_freq < 3000) {
     1459                flags = IEEE80211_CHAN_G;
     1460        } else {
     1461                flags = IEEE80211_CHAN_A;
     1462        }
     1463
     1464        /* Channel lookup */
     1465        c = ieee80211_find_channel(ic, rxs->c_freq, flags);
     1466
     1467        IEEE80211_DPRINTF(vap, IEEE80211_MSG_INPUT,
     1468            "%s: freq=%d, ieee=%d, flags=0x%08x; c=%p\n",
     1469            __func__,
     1470            (int) rxs->c_freq,
     1471            (int) rxs->c_ieee,
     1472            flags,
     1473            c);
     1474
     1475        return (c);
    9641476}
    9651477
     
    10981610}
    10991611
    1100 void
    1101 ieee80211_media_init(struct ieee80211com *ic)
    1102 {
    1103         struct ifnet *ifp = ic->ic_ifp;
    1104         int maxrate;
    1105 
    1106         /* NB: this works because the structure is initialized to zero */
    1107         if (!LIST_EMPTY(&ic->ic_media.ifm_list)) {
    1108                 /*
    1109                  * We are re-initializing the channel list; clear
    1110                  * the existing media state as the media routines
    1111                  * don't suppress duplicates.
    1112                  */
    1113                 ifmedia_removeall(&ic->ic_media);
    1114         }
    1115         ieee80211_chan_init(ic);
    1116 
    1117         /*
    1118          * Recalculate media settings in case new channel list changes
    1119          * the set of available modes.
    1120          */
    1121         maxrate = ieee80211_media_setup(ic, &ic->ic_media, ic->ic_caps, 1,
    1122                 ieee80211com_media_change, ieee80211com_media_status);
    1123         /* NB: strip explicit mode; we're actually in autoselect */
    1124         ifmedia_set(&ic->ic_media,
    1125             media_status(ic->ic_opmode, ic->ic_curchan) &~
    1126                 (IFM_MMASK | IFM_IEEE80211_TURBO));
    1127         if (maxrate)
    1128                 ifp->if_baudrate = IF_Mbps(maxrate);
    1129 
    1130         /* XXX need to propagate new media settings to vap's */
    1131 }
    1132 
    11331612/* XXX inline or eliminate? */
    11341613const struct ieee80211_rateset *
     
    11421621ieee80211_announce(struct ieee80211com *ic)
    11431622{
    1144         struct ifnet *ifp = ic->ic_ifp;
    11451623        int i, rate, mword;
    11461624        enum ieee80211_phymode mode;
     
    11511629                if (isclr(ic->ic_modecaps, mode))
    11521630                        continue;
    1153                 if_printf(ifp, "%s rates: ", ieee80211_phymode_name[mode]);
     1631                ic_printf(ic, "%s rates: ", ieee80211_phymode_name[mode]);
    11541632                rs = &ic->ic_sup_rates[mode];
    11551633                for (i = 0; i < rs->rs_nrates; i++) {
     
    12601738
    12611739/*
    1262  * Handle a media change request on the underlying interface.
    1263  */
    1264 int
    1265 ieee80211com_media_change(struct ifnet *ifp)
    1266 {
    1267         return EINVAL;
    1268 }
    1269 
    1270 /*
    12711740 * Handle a media change request on the vap interface.
    12721741 */
     
    13451814}
    13461815
    1347 static void
    1348 ieee80211com_media_status(struct ifnet *ifp, struct ifmediareq *imr)
    1349 {
    1350         struct ieee80211com *ic = ifp->if_l2com;
    1351         struct ieee80211vap *vap;
    1352 
    1353         imr->ifm_status = IFM_AVALID;
    1354         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
    1355                 if (vap->iv_ifp->if_flags & IFF_UP) {
    1356                         imr->ifm_status |= IFM_ACTIVE;
    1357                         break;
    1358                 }
    1359         imr->ifm_active = media_status(ic->ic_opmode, ic->ic_curchan);
    1360         if (imr->ifm_status & IFM_ACTIVE)
    1361                 imr->ifm_current = imr->ifm_active;
    1362 }
    1363 
    13641816void
    13651817ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr)
     
    13751827         * in which case the rate will not be convertible.
    13761828         */
    1377         if (vap->iv_state == IEEE80211_S_RUN) {
     1829        if (vap->iv_state == IEEE80211_S_RUN ||
     1830            vap->iv_state == IEEE80211_S_SLEEP) {
    13781831                imr->ifm_status |= IFM_ACTIVE;
    13791832                mode = ieee80211_chan2mode(ic->ic_curchan);
     
    14861939ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode mode)
    14871940{
    1488 #define N(a)    (sizeof(a) / sizeof(a[0]))
    14891941        static const struct ratemedia rates[] = {
    14901942                {   2 | IFM_IEEE80211_FH, IFM_IEEE80211_FH1 },
     
    15181970                {   9 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM4 },
    15191971                {  54 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM27 },
    1520                 /* NB: OFDM72 doesn't realy exist so we don't handle it */
     1972                /* NB: OFDM72 doesn't really exist so we don't handle it */
    15211973        };
    15221974        static const struct ratemedia htrates[] = {
     
    16072059                if (rate & IEEE80211_RATE_MCS) {
    16082060                        rate &= ~IEEE80211_RATE_MCS;
    1609                         m = findmedia(htrates, N(htrates), rate);
     2061                        m = findmedia(htrates, nitems(htrates), rate);
    16102062                        if (m != IFM_AUTO)
    16112063                                return m | IFM_IEEE80211_11NA;
     
    16152067                if (rate & IEEE80211_RATE_MCS) {
    16162068                        rate &= ~IEEE80211_RATE_MCS;
    1617                         m = findmedia(htrates, N(htrates), rate);
     2069                        m = findmedia(htrates, nitems(htrates), rate);
    16182070                        if (m != IFM_AUTO)
    16192071                                return m | IFM_IEEE80211_11NG;
     
    16282080        case IEEE80211_MODE_TURBO_A:
    16292081        case IEEE80211_MODE_STURBO_A:
    1630                 return findmedia(rates, N(rates), rate | IFM_IEEE80211_11A);
     2082                return findmedia(rates, nitems(rates),
     2083                    rate | IFM_IEEE80211_11A);
    16312084        case IEEE80211_MODE_11B:
    1632                 return findmedia(rates, N(rates), rate | IFM_IEEE80211_11B);
     2085                return findmedia(rates, nitems(rates),
     2086                    rate | IFM_IEEE80211_11B);
    16332087        case IEEE80211_MODE_FH:
    1634                 return findmedia(rates, N(rates), rate | IFM_IEEE80211_FH);
     2088                return findmedia(rates, nitems(rates),
     2089                    rate | IFM_IEEE80211_FH);
    16352090        case IEEE80211_MODE_AUTO:
    16362091                /* NB: ic may be NULL for some drivers */
    16372092                if (ic != NULL && ic->ic_phytype == IEEE80211_T_FH)
    1638                         return findmedia(rates, N(rates),
     2093                        return findmedia(rates, nitems(rates),
    16392094                            rate | IFM_IEEE80211_FH);
    16402095                /* NB: hack, 11g matches both 11b+11a rates */
     
    16432098        case IEEE80211_MODE_11NG:
    16442099        case IEEE80211_MODE_TURBO_G:
    1645                 return findmedia(rates, N(rates), rate | IFM_IEEE80211_11G);
     2100                return findmedia(rates, nitems(rates), rate | IFM_IEEE80211_11G);
     2101        case IEEE80211_MODE_VHT_2GHZ:
     2102        case IEEE80211_MODE_VHT_5GHZ:
     2103                /* XXX TODO: need to figure out mapping for VHT rates */
     2104                return IFM_AUTO;
    16462105        }
    16472106        return IFM_AUTO;
    1648 #undef N
    16492107}
    16502108
     
    16522110ieee80211_media2rate(int mword)
    16532111{
    1654 #define N(a)    (sizeof(a) / sizeof(a[0]))
    16552112        static const int ieeerates[] = {
    16562113                -1,             /* IFM_AUTO */
     
    16792136                54,             /* IFM_IEEE80211_OFDM27 */
    16802137                -1,             /* IFM_IEEE80211_MCS */
     2138                -1,             /* IFM_IEEE80211_VHT */
    16812139        };
    1682         return IFM_SUBTYPE(mword) < N(ieeerates) ?
     2140        return IFM_SUBTYPE(mword) < nitems(ieeerates) ?
    16832141                ieeerates[IFM_SUBTYPE(mword)] : 0;
    1684 #undef N
    16852142}
    16862143
     
    17202177}
    17212178#undef mix
     2179
     2180char
     2181ieee80211_channel_type_char(const struct ieee80211_channel *c)
     2182{
     2183        if (IEEE80211_IS_CHAN_ST(c))
     2184                return 'S';
     2185        if (IEEE80211_IS_CHAN_108A(c))
     2186                return 'T';
     2187        if (IEEE80211_IS_CHAN_108G(c))
     2188                return 'G';
     2189        if (IEEE80211_IS_CHAN_VHT(c))
     2190                return 'v';
     2191        if (IEEE80211_IS_CHAN_HT(c))
     2192                return 'n';
     2193        if (IEEE80211_IS_CHAN_A(c))
     2194                return 'a';
     2195        if (IEEE80211_IS_CHAN_ANYG(c))
     2196                return 'g';
     2197        if (IEEE80211_IS_CHAN_B(c))
     2198                return 'b';
     2199        return 'f';
     2200}
  • freebsd/sys/net80211/ieee80211.h

    r172f2ac ra241ea8  
    3737#define IEEE80211_IS_MULTICAST(_a)      (*(_a) & 0x01)
    3838
     39#ifdef _KERNEL
     40extern const uint8_t ieee80211broadcastaddr[];
     41#endif
     42
    3943typedef uint16_t ieee80211_seq;
    4044
     
    126130#define IEEE80211_FC0_SUBTYPE_PROBE_REQ         0x40
    127131#define IEEE80211_FC0_SUBTYPE_PROBE_RESP        0x50
     132#define IEEE80211_FC0_SUBTYPE_TIMING_ADV        0x60
    128133#define IEEE80211_FC0_SUBTYPE_BEACON            0x80
    129134#define IEEE80211_FC0_SUBTYPE_ATIM              0x90
     
    134139#define IEEE80211_FC0_SUBTYPE_ACTION_NOACK      0xe0
    135140/* for TYPE_CTL */
     141#define IEEE80211_FC0_SUBTYPE_CONTROL_WRAP      0x70
    136142#define IEEE80211_FC0_SUBTYPE_BAR               0x80
    137143#define IEEE80211_FC0_SUBTYPE_BA                0x90
     
    152158#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK     0x70
    153159#define IEEE80211_FC0_SUBTYPE_QOS               0x80
     160#define IEEE80211_FC0_SUBTYPE_QOS_CFACK         0x90
     161#define IEEE80211_FC0_SUBTYPE_QOS_CFPOLL        0xa0
     162#define IEEE80211_FC0_SUBTYPE_QOS_CFACKPOLL     0xb0
    154163#define IEEE80211_FC0_SUBTYPE_QOS_NULL          0xc0
     164
     165#define IEEE80211_IS_MGMT(wh)                                   \
     166        (!! (((wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK)          \
     167            == IEEE80211_FC0_TYPE_MGT))
     168
     169#define IEEE80211_FC0_QOSDATA \
     170        (IEEE80211_FC0_TYPE_DATA|IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_VERSION_0)
     171
     172#define IEEE80211_IS_QOSDATA(wh) \
     173        ((wh)->i_fc[0] == IEEE80211_FC0_QOSDATA)
    155174
    156175#define IEEE80211_FC1_DIR_MASK                  0x03
     
    167186#define IEEE80211_FC1_PWR_MGT                   0x10
    168187#define IEEE80211_FC1_MORE_DATA                 0x20
    169 #define IEEE80211_FC1_WEP                       0x40
     188#define IEEE80211_FC1_PROTECTED                 0x40
    170189#define IEEE80211_FC1_ORDER                     0x80
    171190
     191#define IEEE80211_HAS_SEQ(type, subtype) \
     192        ((type) != IEEE80211_FC0_TYPE_CTL && \
     193        !((type) == IEEE80211_FC0_TYPE_DATA && \
     194         ((subtype) & IEEE80211_FC0_SUBTYPE_QOS_NULL) == \
     195                      IEEE80211_FC0_SUBTYPE_QOS_NULL))
    172196#define IEEE80211_SEQ_FRAG_MASK                 0x000f
    173197#define IEEE80211_SEQ_FRAG_SHIFT                0
     
    188212#define IEEE80211_NWID_LEN                      32
    189213#define IEEE80211_MESHID_LEN                    32
     214
     215#define IEEE80211_QOS_CTL_LEN                   2
    190216
    191217#define IEEE80211_QOS_TXOP                      0x00ff
     
    200226#define IEEE80211_QOS_EOSP_S                    4
    201227#define IEEE80211_QOS_TID                       0x0f
     228/* qos[1] byte used for all frames sent by mesh STAs in a mesh BSS */
     229#define IEEE80211_QOS_MC                        0x01    /* Mesh control */
     230/* Mesh power save level*/
     231#define IEEE80211_QOS_MESH_PSL                  0x02
     232/* Mesh Receiver Service Period Initiated */
     233#define IEEE80211_QOS_RSPI                      0x04
     234/* bits 11 to 15 reserved */
    202235
    203236/* does frame have QoS sequence control data */
     
    300333
    301334/*
     335 * WME U-APSD qos info field defines
     336 */
     337#define WME_CAPINFO_UAPSD_EN                    0x00000080
     338#define WME_CAPINFO_UAPSD_VO                    0x00000001
     339#define WME_CAPINFO_UAPSD_VI                    0x00000002
     340#define WME_CAPINFO_UAPSD_BK                    0x00000004
     341#define WME_CAPINFO_UAPSD_BE                    0x00000008
     342#define WME_CAPINFO_UAPSD_ACFLAGS_SHIFT         0
     343#define WME_CAPINFO_UAPSD_ACFLAGS_MASK          0xF
     344#define WME_CAPINFO_UAPSD_MAXSP_SHIFT           5
     345#define WME_CAPINFO_UAPSD_MAXSP_MASK            0x3
     346#define WME_CAPINFO_IE_OFFSET                   8
     347#define WME_UAPSD_MAXSP(_qosinfo)                               \
     348            (((_qosinfo) >> WME_CAPINFO_UAPSD_MAXSP_SHIFT) &    \
     349            WME_CAPINFO_UAPSD_MAXSP_MASK)
     350#define WME_UAPSD_AC_ENABLED(_ac, _qosinfo)                     \
     351            ((1 << (3 - (_ac))) & (                             \
     352            ((_qosinfo) >> WME_CAPINFO_UAPSD_ACFLAGS_SHIFT) &   \
     353            WME_CAPINFO_UAPSD_ACFLAGS_MASK))
     354
     355/*
    302356 * Management Notification Frame
    303357 */
     
    326380#define IEEE80211_ACTION_CAT_BA         3       /* BA */
    327381#define IEEE80211_ACTION_CAT_HT         7       /* HT */
     382#define IEEE80211_ACTION_CAT_MESH       13      /* Mesh */
     383#define IEEE80211_ACTION_CAT_SELF_PROT  15      /* Self-protected */
     384/* 16 - 125 reserved */
     385#define IEEE80211_ACTION_CAT_VHT        21
    328386#define IEEE80211_ACTION_CAT_VENDOR     127     /* Vendor Specific */
    329387
     
    675733#define IEEE80211_HTINFO_DUALPROTECTED  0x80
    676734
     735
     736/*
     737 * 802.11ac definitions - 802.11ac-2013 .
     738 */
     739
     740/*
     741 * Maximum length of A-MPDU that the STA can RX in VHT.
     742 * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
     743 */
     744#define IEEE80211_VHTCAP_MAX_AMPDU_8K           0
     745#define IEEE80211_VHTCAP_MAX_AMPDU_16K          1
     746#define IEEE80211_VHTCAP_MAX_AMPDU_32K          2
     747#define IEEE80211_VHTCAP_MAX_AMPDU_64K          3
     748#define IEEE80211_VHTCAP_MAX_AMPDU_128K         4
     749#define IEEE80211_VHTCAP_MAX_AMPDU_256K         5
     750#define IEEE80211_VHTCAP_MAX_AMPDU_512K         6
     751#define IEEE80211_VHTCAP_MAX_AMPDU_1024K        7
     752
     753/*
     754 * VHT MCS information.
     755 * + rx_highest/tx_highest: optional; maximum long GI VHT PPDU
     756 *    data rate.  1Mbit/sec units.
     757 * + rx_mcs_map/tx_mcs_map: bitmap of per-stream supported MCS;
     758 *    2 bits each.
     759 */
     760#define IEEE80211_VHT_MCS_SUPPORT_0_7           0       /* MCS0-7 */
     761#define IEEE80211_VHT_MCS_SUPPORT_0_8           1       /* MCS0-8 */
     762#define IEEE80211_VHT_MCS_SUPPORT_0_9           2       /* MCS0-9 */
     763#define IEEE80211_VHT_MCS_NOT_SUPPORTED         3       /* not supported */
     764
     765struct ieee80211_vht_mcs_info {
     766        uint16_t rx_mcs_map;
     767        uint16_t rx_highest;
     768        uint16_t tx_mcs_map;
     769        uint16_t tx_highest;
     770} __packed;
     771
     772/* VHT capabilities element: 802.11ac-2013 8.4.2.160 */
     773struct ieee80211_ie_vhtcap {
     774        uint8_t ie;
     775        uint8_t len;
     776        uint32_t vht_cap_info;
     777        struct ieee80211_vht_mcs_info supp_mcs;
     778} __packed;
     779
     780/* VHT operation mode subfields - 802.11ac-2013 Table 8.183x */
     781#define IEEE80211_VHT_CHANWIDTH_USE_HT          0       /* Use HT IE for chw */
     782#define IEEE80211_VHT_CHANWIDTH_80MHZ           1       /* 80MHz */
     783#define IEEE80211_VHT_CHANWIDTH_160MHZ          2       /* 160MHz */
     784#define IEEE80211_VHT_CHANWIDTH_80P80MHZ        3       /* 80+80MHz */
     785
     786/* VHT operation IE - 802.11ac-2013 8.4.2.161 */
     787struct ieee80211_ie_vht_operation {
     788        uint8_t ie;
     789        uint8_t len;
     790        uint8_t chan_width;
     791        uint8_t center_freq_seg1_idx;
     792        uint8_t center_freq_seg2_idx;
     793        uint16_t basic_mcs_set;
     794} __packed;
     795
     796/* 802.11ac VHT Capabilities */
     797#define IEEE80211_VHTCAP_MAX_MPDU_LENGTH_3895   0x00000000
     798#define IEEE80211_VHTCAP_MAX_MPDU_LENGTH_7991   0x00000001
     799#define IEEE80211_VHTCAP_MAX_MPDU_LENGTH_11454  0x00000002
     800#define IEEE80211_VHTCAP_MAX_MPDU_MASK          0x00000003
     801#define IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160MHZ 0x00000004
     802#define IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ        0x00000008
     803#define IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK   0x0000000C
     804#define IEEE80211_VHTCAP_RXLDPC         0x00000010
     805#define IEEE80211_VHTCAP_SHORT_GI_80            0x00000020
     806#define IEEE80211_VHTCAP_SHORT_GI_160           0x00000040
     807#define IEEE80211_VHTCAP_TXSTBC         0x00000080
     808#define IEEE80211_VHTCAP_RXSTBC_1               0x00000100
     809#define IEEE80211_VHTCAP_RXSTBC_2               0x00000200
     810#define IEEE80211_VHTCAP_RXSTBC_3               0x00000300
     811#define IEEE80211_VHTCAP_RXSTBC_4               0x00000400
     812#define IEEE80211_VHTCAP_RXSTBC_MASK            0x00000700
     813#define IEEE80211_VHTCAP_SU_BEAMFORMER_CAPABLE  0x00000800
     814#define IEEE80211_VHTCAP_SU_BEAMFORMEE_CAPABLE  0x00001000
     815#define IEEE80211_VHTCAP_BEAMFORMEE_STS_SHIFT   13
     816#define IEEE80211_VHTCAP_BEAMFORMEE_STS_MASK \
     817            (7 << IEEE80211_VHTCAP_BEAMFORMEE_STS_SHIFT)
     818#define IEEE80211_VHTCAP_SOUNDING_DIMENSIONS_SHIFT      16
     819#define IEEE80211_VHTCAP_SOUNDING_DIMENSIONS_MASK \
     820            (7 << IEEE80211_VHTCAP_SOUNDING_DIMENSIONS_SHIFT)
     821#define IEEE80211_VHTCAP_MU_BEAMFORMER_CAPABLE  0x00080000
     822#define IEEE80211_VHTCAP_MU_BEAMFORMEE_CAPABLE  0x00100000
     823#define IEEE80211_VHTCAP_VHT_TXOP_PS            0x00200000
     824#define IEEE80211_VHTCAP_HTC_VHT                0x00400000
     825#define IEEE80211_VHTCAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT       23
     826#define IEEE80211_VHTCAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK \
     827            (7 << IEEE80211_VHTCAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT)
     828#define IEEE80211_VHTCAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB      0x08000000
     829#define IEEE80211_VHTCAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB        0x0c000000
     830#define IEEE80211_VHTCAP_RX_ANTENNA_PATTERN     0x10000000
     831#define IEEE80211_VHTCAP_TX_ANTENNA_PATTERN     0x20000000
     832
     833/*
     834 * XXX TODO: add the rest of the bits
     835 */
     836#define IEEE80211_VHTCAP_BITS \
     837        "\20\1MPDU7991\2MPDU11454\3CHAN160\4CHAN8080\5RXLDPC\6SHORTGI80" \
     838        "\7SHORTGI160\10RXSTBC1\11RXSTBC2\12RXSTBC3\13RXSTBC4\14BFERCAP" \
     839        "\15BFEECAP\27VHT\37RXANTPTN\40TXANTPTN"
     840
     841/*
     842 * VHT Transmit Power Envelope element - 802.11ac-2013 8.4.2.164
     843 *
     844 * This defines the maximum transmit power for various bandwidths.
     845 */
     846/*
     847 * Count is how many elements follow and what they're for:
     848 *
     849 * 0 - 20 MHz
     850 * 1 - 20+40 MHz
     851 * 2 - 20+40+80 MHz
     852 * 3 - 20+40+80+(160, 80+80) MHz
     853 */
     854#define IEEE80211_VHT_TXPWRENV_INFO_COUNT_SHIFT 0
     855#define IEEE80211_VHT_TXPWRENV_INFO_COUNT_MASK  0x07
     856
     857/*
     858 * Unit is the tx power representation.  It should be EIRP for now;
     859 * other values are reserved.
     860 */
     861#define IEEE80211_VHT_TXPWRENV_UNIT_MASK        0x38
     862#define IEEE80211_VHT_TXPWRENV_UNIT_SHIFT       3
     863
     864/* This value is within the unit mask/shift above */
     865#define IEEE80211_VHT_TXPWRENV_UNIT_EIRP        0
     866
     867struct ieee80211_ie_vht_txpwrenv {
     868        uint8_t ie;
     869        uint8_t len;
     870        uint8_t tx_info;
     871        int8_t tx_elem[0];      /* TX power elements, 1/2 dB, signed */
     872};
     873
     874/* VHT action codes */
     875#define WLAN_ACTION_VHT_COMPRESSED_BF           0
     876#define WLAN_ACTION_VHT_GROUPID_MGMT            1
     877#define WLAN_ACTION_VHT_OPMODE_NOTIF            2
     878
    677879/*
    678880 * Management information element payloads.
     
    688890        IEEE80211_ELEMID_IBSSPARMS      = 6,
    689891        IEEE80211_ELEMID_COUNTRY        = 7,
     892        IEEE80211_ELEMID_BSSLOAD        = 11,
     893        IEEE80211_ELEMID_TSPEC          = 13,
     894        IEEE80211_ELEMID_TCLAS          = 14,
    690895        IEEE80211_ELEMID_CHALLENGE      = 16,
    691896        /* 17-31 reserved for challenge text extension */
     
    705910        IEEE80211_ELEMID_RSN            = 48,
    706911        IEEE80211_ELEMID_XRATES         = 50,
     912        IEEE80211_ELEMID_APCHANREP      = 51,
    707913        IEEE80211_ELEMID_HTINFO         = 61,
     914        IEEE80211_ELEMID_SECCHAN_OFFSET = 62,
     915        IEEE80211_ELEMID_RRM_ENACAPS    = 70,
     916        IEEE80211_ELEMID_MULTIBSSID     = 71,
     917        IEEE80211_ELEMID_COEX_2040      = 72,
     918        IEEE80211_ELEMID_INTOL_CHN_REPORT       = 73,
     919        IEEE80211_ELEMID_OVERLAP_BSS_SCAN_PARAM = 74,
     920        IEEE80211_ELEMID_TSF_REQ        = 91,
     921        IEEE80211_ELEMID_TSF_RESP       = 92,
     922        IEEE80211_ELEMID_WNM_SLEEP_MODE = 93,
     923        IEEE80211_ELEMID_TIM_BCAST_REQ  = 94,
     924        IEEE80211_ELEMID_TIM_BCAST_RESP = 95,
    708925        IEEE80211_ELEMID_TPC            = 150,
    709926        IEEE80211_ELEMID_CCKM           = 156,
     
    726943        IEEE80211_ELEMID_MESHBEACONT    = 120,
    727944        /* 121-124 MMCAOP not implemented yet */
    728         IEEE80211_ELEMID_MESHPANN       = 125, /* XXX: is GANN now, not used */
     945        IEEE80211_ELEMID_MESHGANN       = 125,
    729946        IEEE80211_ELEMID_MESHRANN       = 126,
    730947        /* 127 Extended Capabilities */
     948        IEEE80211_ELEMID_EXTCAP         = 127,
    731949        /* 128-129 reserved */
    732950        IEEE80211_ELEMID_MESHPREQ       = 130,
     
    737955        IEEE80211_ELEMID_MESHPXUC       = 138,
    738956        IEEE80211_ELEMID_MESHAH         = 60, /* XXX: remove */
     957
     958        /* 802.11ac */
     959        IEEE80211_ELEMID_VHT_CAP        = 191,
     960        IEEE80211_ELEMID_VHT_OPMODE     = 192,
     961        IEEE80211_ELEMID_VHT_PWR_ENV    = 195,
    739962};
    740963
     
    763986        (sizeof(struct ieee80211_country_ie) + 3*(IEEE80211_COUNTRY_MAX_BANDS-1))
    764987
     988struct ieee80211_bss_load_ie {
     989        uint8_t         ie;
     990        uint8_t         len;
     991        uint16_t        sta_count;      /* station count */
     992        uint8_t         chan_load;      /* channel utilization */
     993        uint8_t         aac;            /* available admission capacity */
     994} __packed;
     995
     996struct ieee80211_ap_chan_report_ie {
     997        uint8_t         ie;
     998        uint8_t         len;
     999        uint8_t         i_class; /* operating class */
     1000        /* Annex E, E.1 Country information and operating classes */
     1001        uint8_t         chan_list[0];
     1002} __packed;
     1003
     1004#define IEEE80211_EXTCAP_CMS                    (1ULL <<  0) /* 20/40 BSS coexistence management support */
     1005#define IEEE80211_EXTCAP_RSVD_1                 (1ULL <<  1)
     1006#define IEEE80211_EXTCAP_ECS                    (1ULL <<  2) /* extended channel switching */
     1007#define IEEE80211_EXTCAP_RSVD_3                 (1ULL <<  3)
     1008#define IEEE80211_EXTCAP_PSMP_CAP               (1ULL <<  4) /* PSMP capability */
     1009#define IEEE80211_EXTCAP_RSVD_5                 (1ULL <<  5)
     1010#define IEEE80211_EXTCAP_S_PSMP_SUPP            (1ULL <<  6)
     1011#define IEEE80211_EXTCAP_EVENT                  (1ULL <<  7)
     1012#define IEEE80211_EXTCAP_DIAGNOSTICS            (1ULL <<  8)
     1013#define IEEE80211_EXTCAP_MCAST_DIAG             (1ULL <<  9)
     1014#define IEEE80211_EXTCAP_LOC_TRACKING           (1ULL << 10)
     1015#define IEEE80211_EXTCAP_FMS                    (1ULL << 11)
     1016#define IEEE80211_EXTCAP_PROXY_ARP              (1ULL << 12)
     1017#define IEEE80211_EXTCAP_CIR                    (1ULL << 13) /* collocated interference reporting */
     1018#define IEEE80211_EXTCAP_CIVIC_LOC              (1ULL << 14)
     1019#define IEEE80211_EXTCAP_GEOSPATIAL_LOC         (1ULL << 15)
     1020#define IEEE80211_EXTCAP_TFS                    (1ULL << 16)
     1021#define IEEE80211_EXTCAP_WNM_SLEEPMODE          (1ULL << 17)
     1022#define IEEE80211_EXTCAP_TIM_BROADCAST          (1ULL << 18)
     1023#define IEEE80211_EXTCAP_BSS_TRANSITION         (1ULL << 19)
     1024#define IEEE80211_EXTCAP_QOS_TRAF_CAP           (1ULL << 20)
     1025#define IEEE80211_EXTCAP_AC_STA_COUNT           (1ULL << 21)
     1026#define IEEE80211_EXTCAP_M_BSSID                (1ULL << 22) /* multiple BSSID field */
     1027#define IEEE80211_EXTCAP_TIMING_MEAS            (1ULL << 23)
     1028#define IEEE80211_EXTCAP_CHAN_USAGE             (1ULL << 24)
     1029#define IEEE80211_EXTCAP_SSID_LIST              (1ULL << 25)
     1030#define IEEE80211_EXTCAP_DMS                    (1ULL << 26)
     1031#define IEEE80211_EXTCAP_UTC_TSF_OFFSET         (1ULL << 27)
     1032#define IEEE80211_EXTCAP_TLDS_BUF_STA_SUPP      (1ULL << 28) /* TDLS peer U-APSP buffer STA support */
     1033#define IEEE80211_EXTCAP_TLDS_PPSM_SUPP         (1ULL << 29) /* TDLS peer PSM support */
     1034#define IEEE80211_EXTCAP_TLDS_CH_SW             (1ULL << 30) /* TDLS channel switching */
     1035#define IEEE80211_EXTCAP_INTERWORKING           (1ULL << 31)
     1036#define IEEE80211_EXTCAP_QOSMAP                 (1ULL << 32)
     1037#define IEEE80211_EXTCAP_EBR                    (1ULL << 33)
     1038#define IEEE80211_EXTCAP_SSPN_IF                (1ULL << 34)
     1039#define IEEE80211_EXTCAP_RSVD_35                (1ULL << 35)
     1040#define IEEE80211_EXTCAP_MSGCF_CAP              (1ULL << 36)
     1041#define IEEE80211_EXTCAP_TLDS_SUPP              (1ULL << 37)
     1042#define IEEE80211_EXTCAP_TLDS_PROHIB            (1ULL << 38)
     1043#define IEEE80211_EXTCAP_TLDS_CH_SW_PROHIB      (1ULL << 39) /* TDLS channel switching prohibited */
     1044#define IEEE80211_EXTCAP_RUF                    (1ULL << 40) /* reject unadmitted frame */
     1045/* service interval granularity */
     1046#define IEEE80211_EXTCAP_SIG \
     1047                                ((1ULL << 41) | (1ULL << 42) | (1ULL << 43))
     1048#define IEEE80211_EXTCAP_ID_LOC                 (1ULL << 44)
     1049#define IEEE80211_EXTCAP_U_APSD_COEX            (1ULL << 45)
     1050#define IEEE80211_EXTCAP_WNM_NOTIFICATION       (1ULL << 46)
     1051#define IEEE80211_EXTCAP_RSVD_47                (1ULL << 47)
     1052#define IEEE80211_EXTCAP_SSID                   (1ULL << 48) /* UTF-8 SSID */
     1053/* bits 49-n are reserved */
     1054
     1055struct ieee80211_extcap_ie {
     1056        uint8_t         ie;
     1057        uint8_t         len;
     1058} __packed;
     1059
     1060/*
     1061 * 802.11h Quiet Time Element.
     1062 */
     1063struct ieee80211_quiet_ie {
     1064        uint8_t         quiet_ie;               /* IEEE80211_ELEMID_QUIET */
     1065        uint8_t         len;
     1066        uint8_t         tbttcount;              /* quiet start */
     1067        uint8_t         period;                 /* beacon intervals between quiets */
     1068        uint16_t        duration;               /* TUs of each quiet*/
     1069        uint16_t        offset;                 /* TUs of from TBTT of quiet start */
     1070} __packed;
     1071
    7651072/*
    7661073 * 802.11h Channel Switch Announcement (CSA).
     
    7851092#define IEEE80211_RATE_BASIC            0x80
    7861093#define IEEE80211_RATE_VAL              0x7f
    787 
    788 /* EPR information element flags */
     1094#define IEEE80211_RV(v)                 ((v) & IEEE80211_RATE_VAL)
     1095
     1096/* ERP information element flags */
    7891097#define IEEE80211_ERP_NON_ERP_PRESENT   0x01
    7901098#define IEEE80211_ERP_USE_PROTECTION    0x02
     
    9221230        IEEE80211_REASON_TIMEOUT                = 39,   /* 11e */
    9231231
    924         /* values not yet allocated by ANA */
    925         IEEE80211_REASON_PEER_LINK_CANCELED     = 2,    /* 11s */
    926         IEEE80211_REASON_MESH_MAX_PEERS         = 3,    /* 11s */
    927         IEEE80211_REASON_MESH_CPVIOLATION       = 4,    /* 11s */
    928         IEEE80211_REASON_MESH_CLOSE_RCVD        = 5,    /* 11s */
    929         IEEE80211_REASON_MESH_MAX_RETRIES       = 6,    /* 11s */
    930         IEEE80211_REASON_MESH_CONFIRM_TIMEOUT   = 7,    /* 11s */
    931         IEEE80211_REASON_MESH_INVALID_GTK       = 8,    /* 11s */
    932         IEEE80211_REASON_MESH_INCONS_PARAMS     = 9,    /* 11s */
    933         IEEE80211_REASON_MESH_INVALID_SECURITY  = 10,   /* 11s */
    934         IEEE80211_REASON_MESH_PERR_UNSPEC       = 11,   /* 11s */
    935         IEEE80211_REASON_MESH_PERR_NO_FI        = 12,   /* 11s */
    936         IEEE80211_REASON_MESH_PERR_DEST_UNREACH = 13,   /* 11s */
     1232        IEEE80211_REASON_PEER_LINK_CANCELED     = 52,   /* 11s */
     1233        IEEE80211_REASON_MESH_MAX_PEERS         = 53,   /* 11s */
     1234        IEEE80211_REASON_MESH_CPVIOLATION       = 54,   /* 11s */
     1235        IEEE80211_REASON_MESH_CLOSE_RCVD        = 55,   /* 11s */
     1236        IEEE80211_REASON_MESH_MAX_RETRIES       = 56,   /* 11s */
     1237        IEEE80211_REASON_MESH_CONFIRM_TIMEOUT   = 57,   /* 11s */
     1238        IEEE80211_REASON_MESH_INVALID_GTK       = 58,   /* 11s */
     1239        IEEE80211_REASON_MESH_INCONS_PARAMS     = 59,   /* 11s */
     1240        IEEE80211_REASON_MESH_INVALID_SECURITY  = 60,   /* 11s */
     1241        IEEE80211_REASON_MESH_PERR_NO_PROXY     = 61,   /* 11s */
     1242        IEEE80211_REASON_MESH_PERR_NO_FI        = 62,   /* 11s */
     1243        IEEE80211_REASON_MESH_PERR_DEST_UNREACH = 63,   /* 11s */
     1244        IEEE80211_REASON_MESH_MAC_ALRDY_EXISTS_MBSS = 64, /* 11s */
     1245        IEEE80211_REASON_MESH_CHAN_SWITCH_REG   = 65,   /* 11s */
     1246        IEEE80211_REASON_MESH_CHAN_SWITCH_UNSPEC = 66,  /* 11s */
    9371247
    9381248        IEEE80211_STATUS_SUCCESS                = 0,
  • freebsd/sys/net80211/ieee80211_acl.c

    r172f2ac ra241ea8  
    4545#include <sys/kernel.h>
    4646#include <sys/systm.h>
     47#include <sys/malloc.h>   
    4748#include <sys/mbuf.h>   
    4849#include <sys/module.h>
     
    102103        struct aclstate *as;
    103104
    104         as = (struct aclstate *) malloc(sizeof(struct aclstate),
    105                 M_80211_ACL, M_NOWAIT | M_ZERO);
     105        as = (struct aclstate *) IEEE80211_MALLOC(sizeof(struct aclstate),
     106                M_80211_ACL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
    106107        if (as == NULL)
    107108                return 0;
     
    126127        vap->iv_as = NULL;
    127128        ACL_LOCK_DESTROY(as);
    128         free(as, M_80211_ACL);
     129        IEEE80211_FREE(as, M_80211_ACL);
    129130}
    130131
     
    150151        TAILQ_REMOVE(&as->as_list, acl, acl_list);
    151152        LIST_REMOVE(acl, acl_hash);
    152         free(acl, M_80211_ACL);
     153        IEEE80211_FREE(acl, M_80211_ACL);
    153154        as->as_nacls--;
    154155}
    155156
    156157static int
    157 acl_check(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
     158acl_check(struct ieee80211vap *vap, const struct ieee80211_frame *wh)
    158159{
    159160        struct aclstate *as = vap->iv_as;
     
    164165                return 1;
    165166        case ACL_POLICY_ALLOW:
    166                 return _find_acl(as, mac) != NULL;
     167                return _find_acl(as, wh->i_addr2) != NULL;
    167168        case ACL_POLICY_DENY:
    168                 return _find_acl(as, mac) == NULL;
     169                return _find_acl(as, wh->i_addr2) == NULL;
    169170        }
    170171        return 0;               /* should not happen */
     
    178179        int hash;
    179180
    180         new = (struct acl *) malloc(sizeof(struct acl), M_80211_ACL, M_NOWAIT | M_ZERO);
     181        new = (struct acl *) IEEE80211_MALLOC(sizeof(struct acl),
     182            M_80211_ACL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
    181183        if (new == NULL) {
    182184                IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
     
    191193                if (IEEE80211_ADDR_EQ(acl->acl_macaddr, mac)) {
    192194                        ACL_UNLOCK(as);
    193                         free(new, M_80211_ACL);
     195                        IEEE80211_FREE(new, M_80211_ACL);
    194196                        IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
    195197                                "ACL: add %s failed, already present\n",
     
    305307                        return 0;               /* NB: must not error */
    306308                }
    307                 ap = (struct ieee80211req_maclist *) malloc(space,
    308                     M_TEMP, M_NOWAIT);
     309                ap = (struct ieee80211req_maclist *) IEEE80211_MALLOC(space,
     310                    M_TEMP, IEEE80211_M_NOWAIT);
    309311                if (ap == NULL)
    310312                        return ENOMEM;
     
    321323                } else
    322324                        error = copyout(ap, ireq->i_data, ireq->i_len);
    323                 free(ap, M_TEMP);
     325                IEEE80211_FREE(ap, M_TEMP);
    324326                return error;
    325327        }
  • freebsd/sys/net80211/ieee80211_action.c

    r172f2ac ra241ea8  
    4040#include <rtems/bsd/sys/param.h>
    4141#include <sys/kernel.h>
     42#include <sys/malloc.h>
    4243#include <sys/systm.h>
    4344 
     
    4546
    4647#include <net/if.h>
     48#include <net/if_var.h>
    4749#include <net/if_media.h>
    4850#include <net/ethernet.h>
     
    7072        send_inval, send_inval, send_inval, send_inval,
    7173};
    72 static ieee80211_send_action_func *meshlm_send_action[4] = {
    73         send_inval, send_inval, send_inval, send_inval,
    74 };
    75 static ieee80211_send_action_func *hwmp_send_action[8] = {
     74static ieee80211_send_action_func *meshaction_send_action[12] = {
     75        send_inval, send_inval, send_inval, send_inval,
    7676        send_inval, send_inval, send_inval, send_inval,
    7777        send_inval, send_inval, send_inval, send_inval,
     
    8282};
    8383
     84static ieee80211_send_action_func *vht_send_action[3] = {
     85        send_inval, send_inval, send_inval,
     86};
     87
    8488int
    8589ieee80211_send_action_register(int cat, int act, ieee80211_send_action_func *f)
    8690{
    87 #define N(a)    (sizeof(a) / sizeof(a[0]))
    8891        switch (cat) {
    8992        case IEEE80211_ACTION_CAT_BA:
    90                 if (act >= N(ba_send_action))
     93                if (act >= nitems(ba_send_action))
    9194                        break;
    9295                ba_send_action[act] = f;
    9396                return 0;
    9497        case IEEE80211_ACTION_CAT_HT:
    95                 if (act >= N(ht_send_action))
     98                if (act >= nitems(ht_send_action))
    9699                        break;
    97100                ht_send_action[act] = f;
    98101                return 0;
    99         case IEEE80211_ACTION_CAT_MESHPEERING:
    100                 if (act >= N(meshpl_send_action))
     102        case IEEE80211_ACTION_CAT_SELF_PROT:
     103                if (act >= nitems(meshpl_send_action))
    101104                        break;
    102105                meshpl_send_action[act] = f;
    103106                return 0;
    104         case IEEE80211_ACTION_CAT_MESHLMETRIC:
    105                 if (act >= N(meshlm_send_action))
    106                         break;
    107                 meshlm_send_action[act] = f;
    108                 return 0;
    109         case IEEE80211_ACTION_CAT_MESHPATH:
    110                 if (act >= N(hwmp_send_action))
    111                         break;
    112                 hwmp_send_action[act] = f;
    113                 return 0;
    114         case IEEE80211_ACTION_CAT_VENDOR:
    115                 if (act >= N(vendor_send_action))
     107        case IEEE80211_ACTION_CAT_MESH:
     108                if (act >= nitems(meshaction_send_action))
     109                        break;
     110                meshaction_send_action[act] = f;
     111                return 0;
     112        case IEEE80211_ACTION_CAT_VENDOR:
     113                if (act >= nitems(vendor_send_action))
    116114                        break;
    117115                vendor_send_action[act] = f;
    118116                return 0;
    119         }
    120         return EINVAL;
    121 #undef N
     117        case IEEE80211_ACTION_CAT_VHT:
     118                if (act >= nitems(vht_send_action))
     119                        break;
     120                vht_send_action[act] = f;
     121                return 0;
     122        }
     123        return EINVAL;
    122124}
    123125
     
    131133ieee80211_send_action(struct ieee80211_node *ni, int cat, int act, void *sa)
    132134{
    133 #define N(a)    (sizeof(a) / sizeof(a[0]))
    134135        ieee80211_send_action_func *f = send_inval;
    135136
    136137        switch (cat) {
    137138        case IEEE80211_ACTION_CAT_BA:
    138                 if (act < N(ba_send_action))
     139                if (act < nitems(ba_send_action))
    139140                        f = ba_send_action[act];
    140141                break;
    141142        case IEEE80211_ACTION_CAT_HT:
    142                 if (act < N(ht_send_action))
     143                if (act < nitems(ht_send_action))
    143144                        f = ht_send_action[act];
    144145                break;
    145         case IEEE80211_ACTION_CAT_MESHPEERING:
    146                 if (act < N(meshpl_send_action))
     146        case IEEE80211_ACTION_CAT_SELF_PROT:
     147                if (act < nitems(meshpl_send_action))
    147148                        f = meshpl_send_action[act];
    148149                break;
    149         case IEEE80211_ACTION_CAT_MESHLMETRIC:
    150                 if (act < N(meshlm_send_action))
    151                         f = meshlm_send_action[act];
    152                 break;
    153         case IEEE80211_ACTION_CAT_MESHPATH:
    154                 if (act < N(hwmp_send_action))
    155                         f = hwmp_send_action[act];
    156                 break;
    157         case IEEE80211_ACTION_CAT_VENDOR:
    158                 if (act < N(vendor_send_action))
     150        case IEEE80211_ACTION_CAT_MESH:
     151                if (act < nitems(meshaction_send_action))
     152                        f = meshaction_send_action[act];
     153                break;
     154        case IEEE80211_ACTION_CAT_VENDOR:
     155                if (act < nitems(vendor_send_action))
    159156                        f = vendor_send_action[act];
    160157                break;
     158        case IEEE80211_ACTION_CAT_VHT:
     159                if (act < nitems(vht_send_action))
     160                        f = vht_send_action[act];
     161                break;
    161162        }
    162163        return f(ni, cat, act, sa);
    163 #undef N
    164164}
    165165
     
    183183        recv_inval, recv_inval, recv_inval, recv_inval,
    184184};
    185 static ieee80211_recv_action_func *meshlm_recv_action[4] = {
    186         recv_inval, recv_inval, recv_inval, recv_inval,
    187 };
    188 static ieee80211_recv_action_func *hwmp_recv_action[8] = {
     185static ieee80211_recv_action_func *meshaction_recv_action[12] = {
     186        recv_inval, recv_inval, recv_inval, recv_inval,
    189187        recv_inval, recv_inval, recv_inval, recv_inval,
    190188        recv_inval, recv_inval, recv_inval, recv_inval,
     
    195193};
    196194
     195static ieee80211_recv_action_func *vht_recv_action[3] = {
     196        recv_inval, recv_inval, recv_inval
     197};
     198
    197199int
    198200ieee80211_recv_action_register(int cat, int act, ieee80211_recv_action_func *f)
    199201{
    200 #define N(a)    (sizeof(a) / sizeof(a[0]))
    201202        switch (cat) {
    202203        case IEEE80211_ACTION_CAT_BA:
    203                 if (act >= N(ba_recv_action))
     204                if (act >= nitems(ba_recv_action))
    204205                        break;
    205206                ba_recv_action[act] = f;
    206207                return 0;
    207208        case IEEE80211_ACTION_CAT_HT:
    208                 if (act >= N(ht_recv_action))
     209                if (act >= nitems(ht_recv_action))
    209210                        break;
    210211                ht_recv_action[act] = f;
    211212                return 0;
    212         case IEEE80211_ACTION_CAT_MESHPEERING:
    213                 if (act >= N(meshpl_recv_action))
     213        case IEEE80211_ACTION_CAT_SELF_PROT:
     214                if (act >= nitems(meshpl_recv_action))
    214215                        break;
    215216                meshpl_recv_action[act] = f;
    216217                return 0;
    217         case IEEE80211_ACTION_CAT_MESHLMETRIC:
    218                 if (act >= N(meshlm_recv_action))
    219                         break;
    220                 meshlm_recv_action[act] = f;
    221                 return 0;
    222         case IEEE80211_ACTION_CAT_MESHPATH:
    223                 if (act >= N(hwmp_recv_action))
    224                         break;
    225                 hwmp_recv_action[act] = f;
    226                 return 0;
    227         case IEEE80211_ACTION_CAT_VENDOR:
    228                 if (act >= N(vendor_recv_action))
     218        case IEEE80211_ACTION_CAT_MESH:
     219                if (act >= nitems(meshaction_recv_action))
     220                        break;
     221                meshaction_recv_action[act] = f;
     222                return 0;
     223        case IEEE80211_ACTION_CAT_VENDOR:
     224                if (act >= nitems(vendor_recv_action))
    229225                        break;
    230226                vendor_recv_action[act] = f;
    231227                return 0;
    232         }
    233         return EINVAL;
    234 #undef N
     228        case IEEE80211_ACTION_CAT_VHT:
     229                if (act >= nitems(vht_recv_action))
     230                        break;
     231                vht_recv_action[act] = f;
     232                return 0;
     233        }
     234        return EINVAL;
    235235}
    236236
     
    246246        const uint8_t *frm, const uint8_t *efrm)
    247247{
    248 #define N(a)    (sizeof(a) / sizeof(a[0]))
    249248        ieee80211_recv_action_func *f = recv_inval;
     249        struct ieee80211vap *vap = ni->ni_vap;
    250250        const struct ieee80211_action *ia =
    251251            (const struct ieee80211_action *) frm;
     
    253253        switch (ia->ia_category) {
    254254        case IEEE80211_ACTION_CAT_BA:
    255                 if (ia->ia_action < N(ba_recv_action))
     255                if (ia->ia_action < nitems(ba_recv_action))
    256256                        f = ba_recv_action[ia->ia_action];
    257257                break;
    258258        case IEEE80211_ACTION_CAT_HT:
    259                 if (ia->ia_action < N(ht_recv_action))
     259                if (ia->ia_action < nitems(ht_recv_action))
    260260                        f = ht_recv_action[ia->ia_action];
    261261                break;
    262         case IEEE80211_ACTION_CAT_MESHPEERING:
    263                 if (ia->ia_action < N(meshpl_recv_action))
     262        case IEEE80211_ACTION_CAT_SELF_PROT:
     263                if (ia->ia_action < nitems(meshpl_recv_action))
    264264                        f = meshpl_recv_action[ia->ia_action];
    265265                break;
    266         case IEEE80211_ACTION_CAT_MESHLMETRIC:
    267                 if (ia->ia_action < N(meshlm_recv_action))
    268                         f = meshlm_recv_action[ia->ia_action];
    269                 break;
    270         case IEEE80211_ACTION_CAT_MESHPATH:
    271                 if (ia->ia_action < N(hwmp_recv_action))
    272                         f = hwmp_recv_action[ia->ia_action];
    273                 break;
    274         case IEEE80211_ACTION_CAT_VENDOR:
    275                 if (ia->ia_action < N(vendor_recv_action))
     266        case IEEE80211_ACTION_CAT_MESH:
     267                if (ni == vap->iv_bss ||
     268                    ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) {
     269                        IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
     270                            ni->ni_macaddr, NULL,
     271                            "peer link not yet established (%d), cat %s act %u",
     272                            ni->ni_mlstate, "mesh action", ia->ia_action);
     273                        vap->iv_stats.is_mesh_nolink++;
     274                        break;
     275                }
     276                if (ia->ia_action < nitems(meshaction_recv_action))
     277                        f = meshaction_recv_action[ia->ia_action];
     278                break;
     279        case IEEE80211_ACTION_CAT_VENDOR:
     280                if (ia->ia_action < nitems(vendor_recv_action))
    276281                        f = vendor_recv_action[ia->ia_action];
    277282                break;
     283        case IEEE80211_ACTION_CAT_VHT:
     284                if (ia->ia_action < nitems(vht_recv_action))
     285                        f = vht_recv_action[ia->ia_action];
     286                break;
    278287        }
    279288        return f(ni, wh, frm, efrm);
    280 #undef N
    281 }
     289}
  • freebsd/sys/net80211/ieee80211_adhoc.c

    r172f2ac ra241ea8  
    5151
    5252#include <net/if.h>
     53#include <net/if_var.h>
    5354#include <net/if_media.h>
    5455#include <net/if_llc.h>
     
    6667#include <net80211/ieee80211_tdma.h>
    6768#endif
     69#include <net80211/ieee80211_sta.h>
    6870
    6971#define IEEE80211_RATE2MBS(r)   (((r) & IEEE80211_RATE_VAL) / 2)
     
    7173static  void adhoc_vattach(struct ieee80211vap *);
    7274static  int adhoc_newstate(struct ieee80211vap *, enum ieee80211_state, int);
    73 static int adhoc_input(struct ieee80211_node *, struct mbuf *, int, int);
     75static int adhoc_input(struct ieee80211_node *, struct mbuf *,
     76            const struct ieee80211_rx_stats *, int, int);
    7477static void adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *,
    75         int subtype, int, int);
     78        int subtype, const struct ieee80211_rx_stats *, int, int);
    7679static void ahdemo_recv_mgmt(struct ieee80211_node *, struct mbuf *,
    77         int subtype, int, int);
     80            int subtype, const struct ieee80211_rx_stats *rxs, int, int);
    7881static void adhoc_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype);
    7982
     
    120123sta_leave(void *arg, struct ieee80211_node *ni)
    121124{
    122         struct ieee80211vap *vap = arg;
    123 
    124         if (ni->ni_vap == vap && ni != vap->iv_bss)
     125        struct ieee80211vap *vap = ni->ni_vap;
     126
     127        if (ni != vap->iv_bss)
    125128                ieee80211_node_leave(ni);
    126129}
     
    164167                case IEEE80211_S_RUN:           /* beacon miss */
    165168                        /* purge station table; entries are stale */
    166                         ieee80211_iterate_nodes(&ic->ic_sta, sta_leave, vap);
     169                        ieee80211_iterate_nodes_vap(&ic->ic_sta, vap,
     170                            sta_leave, NULL);
    167171                        /* fall thru... */
    168172                case IEEE80211_S_INIT:
     
    173177                                 * scan and startup immediately.
    174178                                 */
    175                                 ieee80211_create_ibss(vap, vap->iv_des_chan);
     179                                ieee80211_create_ibss(vap,
     180                                    ieee80211_ht_adjust_channel(ic,
     181                                    vap->iv_des_chan, vap->iv_flags_ht));
    176182                                break;
    177183                        }
     
    213219                }
    214220                switch (ostate) {
     221                case IEEE80211_S_INIT:
     222                        /*
     223                         * Already have a channel; bypass the
     224                         * scan and startup immediately.
     225                         * Note that ieee80211_create_ibss will call
     226                         * back to do a RUN->RUN state change.
     227                         */
     228                        ieee80211_create_ibss(vap,
     229                            ieee80211_ht_adjust_channel(ic,
     230                                ic->ic_curchan, vap->iv_flags_ht));
     231                        /* NB: iv_bss is changed on return */
     232                        ni = vap->iv_bss;
     233                        break;
    215234                case IEEE80211_S_SCAN:
    216235#ifdef IEEE80211_DEBUG
     
    228247#endif
    229248                        break;
     249                case IEEE80211_S_RUN:   /* IBSS merge */
     250                        break;
    230251                default:
    231252                        goto invalid;
     
    245266                break;
    246267        case IEEE80211_S_SLEEP:
    247                 ieee80211_sta_pwrsave(vap, 0);
     268                vap->iv_sta_ps(vap, 0);
    248269                break;
    249270        default:
     
    286307 */
    287308static int
    288 adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
    289 {
    290 #define HAS_SEQ(type)   ((type & 0x4) == 0)
     309adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
     310    const struct ieee80211_rx_stats *rxs, int rssi, int nf)
     311{
    291312        struct ieee80211vap *vap = ni->ni_vap;
    292313        struct ieee80211com *ic = ni->ni_ic;
     
    298319        uint8_t dir, type, subtype, qos;
    299320        uint8_t *bssid;
    300         uint16_t rxseq;
     321        int is_hw_decrypted = 0;
     322        int has_decrypted = 0;
     323
     324        /*
     325         * Some devices do hardware decryption all the way through
     326         * to pretending the frame wasn't encrypted in the first place.
     327         * So, tag it appropriately so it isn't discarded inappropriately.
     328         */
     329        if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_DECRYPTED))
     330                is_hw_decrypted = 1;
    301331
    302332        if (m->m_flags & M_AMPDU_MPDU) {
     
    368398                 * Validate the bssid.
    369399                 */
    370                 if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bss->ni_bssid) &&
     400                if (!(type == IEEE80211_FC0_TYPE_MGT &&
     401                     (subtype == IEEE80211_FC0_SUBTYPE_BEACON ||
     402                      subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)) &&
     403                    !IEEE80211_ADDR_EQ(bssid, vap->iv_bss->ni_bssid) &&
    371404                    !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) {
    372405                        /* not interested in */
     
    397430                        }
    398431                        /*
    399                          * Fake up a node for this newly
    400                          * discovered member of the IBSS.
     432                         * Fake up a node for this newly discovered member
     433                         * of the IBSS.
     434                         *
     435                         * Note: This doesn't "upgrade" the node to 11n;
     436                         * that will happen after a probe request/response
     437                         * exchange.
    401438                         */
    402439                        ni = ieee80211_fakeup_adhoc_node(vap, wh->i_addr2);
     
    408445                IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
    409446                ni->ni_noise = nf;
    410                 if (HAS_SEQ(type)) {
     447                if (IEEE80211_HAS_SEQ(type, subtype) &&
     448                    IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
    411449                        uint8_t tid = ieee80211_gettid(wh);
    412450                        if (IEEE80211_QOS_HAS_SEQ(wh) &&
    413451                            TID_TO_WME_AC(tid) >= WME_AC_VI)
    414452                                ic->ic_wme.wme_hipri_traffic++;
    415                         rxseq = le16toh(*(uint16_t *)wh->i_seq);
    416                         if (! ieee80211_check_rxseq(ni, wh)) {
    417                                 /* duplicate, discard */
    418                                 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
    419                                     bssid, "duplicate",
    420                                     "seqno <%u,%u> fragno <%u,%u> tid %u",
    421                                     rxseq >> IEEE80211_SEQ_SEQ_SHIFT,
    422                                     ni->ni_rxseqs[tid] >>
    423                                         IEEE80211_SEQ_SEQ_SHIFT,
    424                                     rxseq & IEEE80211_SEQ_FRAG_MASK,
    425                                     ni->ni_rxseqs[tid] &
    426                                         IEEE80211_SEQ_FRAG_MASK,
    427                                     tid);
    428                                 vap->iv_stats.is_rx_dup++;
    429                                 IEEE80211_NODE_STAT(ni, rx_dup);
     453                        if (! ieee80211_check_rxseq(ni, wh, bssid))
    430454                                goto out;
    431                         }
    432                         ni->ni_rxseqs[tid] = rxseq;
    433455                }
    434456        }
     
    474496                 * of replay sequence numbers.
    475497                 */
    476                 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
     498                if (is_hw_decrypted || wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
    477499                        if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) {
    478500                                /*
     
    485507                                goto out;
    486508                        }
    487                         key = ieee80211_crypto_decap(ni, m, hdrspace);
    488                         if (key == NULL) {
     509                        if (ieee80211_crypto_decap(ni, m, hdrspace, &key) == 0) {
    489510                                /* NB: stats+msgs handled in crypto_decap */
    490511                                IEEE80211_NODE_STAT(ni, rx_wepfail);
     
    492513                        }
    493514                        wh = mtod(m, struct ieee80211_frame *);
    494                         wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
     515                        wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
     516                        has_decrypted = 1;
    495517                } else {
    496518                        /* XXX M_WEP and IEEE80211_F_PRIVACY */
     
    523545                 * Next strip any MSDU crypto bits.
    524546                 */
    525                 if (key != NULL && !ieee80211_crypto_demic(vap, key, m, 0)) {
     547                if (!ieee80211_crypto_demic(vap, key, m, 0)) {
    526548                        IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
    527549                            ni->ni_macaddr, "data", "%s", "demic error");
     
    577599                         */
    578600                        if ((vap->iv_flags & IEEE80211_F_DROPUNENC) &&
    579                             (key == NULL && (m->m_flags & M_WEP) == 0) &&
     601                            ((has_decrypted == 0) && (m->m_flags & M_WEP) == 0) &&
     602                            (is_hw_decrypted == 0) &&
    580603                            eh->ether_type != htons(ETHERTYPE_PAE)) {
    581604                                /*
     
    625648                    ieee80211_msg_dumppkts(vap)) {
    626649                        if_printf(ifp, "received %s from %s rssi %d\n",
    627                             ieee80211_mgt_subtype_name[subtype >>
    628                                 IEEE80211_FC0_SUBTYPE_SHIFT],
     650                            ieee80211_mgt_subtype_name(subtype),
    629651                            ether_sprintf(wh->i_addr2), rssi);
    630652                }
    631653#endif
    632                 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
     654                if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
    633655                        IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
    634656                            wh, NULL, "%s", "WEP set but not permitted");
     
    636658                        goto out;
    637659                }
    638                 vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
     660                vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
    639661                goto out;
    640662
     
    652674        }
    653675err:
    654         ifp->if_ierrors++;
     676        if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
    655677out:
    656678        if (m != NULL) {
     
    681703static void
    682704adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
    683         int subtype, int rssi, int nf)
     705        int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
    684706{
    685707        struct ieee80211vap *vap = ni->ni_vap;
    686708        struct ieee80211com *ic = ni->ni_ic;
     709        struct ieee80211_channel *rxchan = ic->ic_curchan;
    687710        struct ieee80211_frame *wh;
    688         uint8_t *frm, *efrm, *sfrm;
     711        uint8_t *frm, *efrm;
    689712        uint8_t *ssid, *rates, *xrates;
     713#if 0
     714        int ht_state_change = 0;
     715#endif
    690716
    691717        wh = mtod(m0, struct ieee80211_frame *);
     
    696722        case IEEE80211_FC0_SUBTYPE_BEACON: {
    697723                struct ieee80211_scanparams scan;
     724                struct ieee80211_channel *c;
    698725                /*
    699726                 * We process beacon/probe response
    700727                 * frames to discover neighbors.
    701728                 */
    702                 if (ieee80211_parse_beacon(ni, m0, &scan) != 0)
     729                if (rxs != NULL) {
     730                        c = ieee80211_lookup_channel_rxstatus(vap, rxs);
     731                        if (c != NULL)
     732                                rxchan = c;
     733                }
     734                if (ieee80211_parse_beacon(ni, m0, rxchan, &scan) != 0)
    703735                        return;
    704736                /*
     
    726758                                ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
    727759                        }
    728                         ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf);
     760                        ieee80211_add_scan(vap, rxchan, &scan, wh,
     761                            subtype, rssi, nf);
    729762                        return;
    730763                }
     
    733766                                /*
    734767                                 * Create a new entry in the neighbor table.
     768                                 *
     769                                 * XXX TODO:
     770                                 *
     771                                 * Here we're not scanning; so if we have an
     772                                 * SSID then make sure it matches our SSID.
     773                                 * Otherwise this code will match on all IBSS
     774                                 * beacons/probe requests for all SSIDs,
     775                                 * filling the node table with nodes that
     776                                 * aren't ours.
    735777                                 */
    736                                 ni = ieee80211_add_neighbor(vap, wh, &scan);
     778                                if (ieee80211_ibss_node_check_new(ni, &scan)) {
     779                                        ni = ieee80211_add_neighbor(vap, wh, &scan);
     780                                        /*
     781                                         * Send a probe request so we announce 11n
     782                                         * capabilities.
     783                                         */
     784                                        ieee80211_send_probereq(ni, /* node */
     785                                            vap->iv_myaddr, /* SA */
     786                                            ni->ni_macaddr, /* DA */
     787                                            vap->iv_bss->ni_bssid, /* BSSID */
     788                                            vap->iv_bss->ni_essid,
     789                                            vap->iv_bss->ni_esslen); /* SSID */
     790                                } else
     791                                        ni = NULL;
     792
    737793                        } else if (ni->ni_capinfo == 0) {
    738794                                /*
     
    741797                                 */
    742798                                ieee80211_init_neighbor(ni, wh, &scan);
     799
     800                                /*
     801                                 * Send a probe request so we announce 11n
     802                                 * capabilities.
     803                                 */
     804                                ieee80211_send_probereq(ni, /* node */
     805                                        vap->iv_myaddr, /* SA */
     806                                        ni->ni_macaddr, /* DA */
     807                                        vap->iv_bss->ni_bssid, /* BSSID */
     808                                        vap->iv_bss->ni_essid,
     809                                        vap->iv_bss->ni_esslen); /* SSID */
    743810                        } else {
    744811                                /*
     
    748815                                        sizeof(ni->ni_tstamp));
    749816                        }
     817                        /*
     818                         * This isn't enabled yet - otherwise it would
     819                         * update the HT parameters and channel width
     820                         * from any node, which could lead to lots of
     821                         * strange behaviour if the 11n nodes aren't
     822                         * exactly configured to match.
     823                         */
     824#if 0
     825                        if (scan.htcap != NULL && scan.htinfo != NULL &&
     826                            (vap->iv_flags_ht & IEEE80211_FHT_HT)) {
     827                                if (ieee80211_ht_updateparams(ni,
     828                                    scan.htcap, scan.htinfo))
     829                                        ht_state_change = 1;
     830                        }
     831#endif
    750832                        if (ni != NULL) {
    751833                                IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
    752834                                ni->ni_noise = nf;
    753835                        }
     836                        /*
     837                         * Same here - the channel width change should
     838                         * be applied to the specific peer node, not
     839                         * to the ic.  Ie, the interface configuration
     840                         * should stay in its current channel width;
     841                         * but it should change the rate control and
     842                         * any queued frames for the given node only.
     843                         *
     844                         * Since there's no (current) way to inform
     845                         * the driver that a channel width change has
     846                         * occurred for a single node, just stub this
     847                         * out.
     848                         */
     849#if 0
     850                        if (ht_state_change)
     851                                ieee80211_update_chw(ic);
     852#endif
    754853                }
    755854                break;
     
    779878                 */
    780879                ssid = rates = xrates = NULL;
    781                 sfrm = frm;
    782880                while (efrm - frm > 1) {
    783881                        IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return);
     
    820918                ieee80211_send_proberesp(vap, wh->i_addr2,
    821919                    is11bclient(rates, xrates) ? IEEE80211_SEND_LEGACY_11B : 0);
     920
     921                /*
     922                 * Note: we don't benefit from stashing the probe request
     923                 * IEs away to use for IBSS negotiation, because we
     924                 * typically don't get all of the IEs.
     925                 */
    822926                break;
    823927
    824928        case IEEE80211_FC0_SUBTYPE_ACTION:
    825929        case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
    826                 if (ni == vap->iv_bss) {
     930                if ((ni == vap->iv_bss) &&
     931                    !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
    827932                        IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
    828933                            wh, NULL, "%s", "unknown node");
     
    848953        case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
    849954        case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
     955        case IEEE80211_FC0_SUBTYPE_TIMING_ADV:
    850956        case IEEE80211_FC0_SUBTYPE_ATIM:
    851957        case IEEE80211_FC0_SUBTYPE_DISASSOC:
     
    869975static void
    870976ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
    871         int subtype, int rssi, int nf)
     977        int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
    872978{
    873979        struct ieee80211vap *vap = ni->ni_vap;
     
    880986         */
    881987        if (ic->ic_flags & IEEE80211_F_SCAN)
    882                 adhoc_recv_mgmt(ni, m0, subtype, rssi, nf);
     988                adhoc_recv_mgmt(ni, m0, subtype, rxs, rssi, nf);
    883989        else {
    884990                wh = mtod(m0, struct ieee80211_frame *);
     
    890996                case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
    891997                case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
     998                case IEEE80211_FC0_SUBTYPE_TIMING_ADV:
    892999                case IEEE80211_FC0_SUBTYPE_BEACON:
    8931000                case IEEE80211_FC0_SUBTYPE_ATIM:
  • freebsd/sys/net80211/ieee80211_ageq.c

    r172f2ac ra241ea8  
    3737#include <sys/systm.h>
    3838#include <sys/kernel.h>
     39#include <sys/malloc.h>
    3940 
    4041#include <sys/socket.h>
    4142
    4243#include <net/if.h>
     44#include <net/if_var.h>
    4345#include <net/if_media.h>
    4446#include <net/ethernet.h>
  • freebsd/sys/net80211/ieee80211_amrr.c

    r172f2ac ra241ea8  
    3636#include <rtems/bsd/sys/param.h>
    3737#include <sys/kernel.h>
     38#include <sys/malloc.h>
    3839#include <sys/module.h>
     40#include <sys/sbuf.h>
    3941#include <sys/socket.h>
    4042#include <sys/sysctl.h>
    4143
    4244#include <net/if.h>
     45#include <net/if_var.h>
    4346#include <net/if_media.h>
     47#include <net/ethernet.h>
    4448
    4549#ifdef INET
     
    4953
    5054#include <net80211/ieee80211_var.h>
     55#include <net80211/ieee80211_ht.h>
    5156#include <net80211/ieee80211_amrr.h>
    5257#include <net80211/ieee80211_ratectl.h>
     
    6772                        struct ieee80211_amrr_node *, struct ieee80211_node *);
    6873static int      amrr_rate(struct ieee80211_node *, void *, uint32_t);
    69 static void     amrr_tx_complete(const struct ieee80211vap *,
    70                         const struct ieee80211_node *, int,
    71                         void *, void *);
    72 static void     amrr_tx_update(const struct ieee80211vap *vap,
    73                         const struct ieee80211_node *, void *, void *, void *);
     74static void     amrr_tx_complete(const struct ieee80211_node *,
     75                        const struct ieee80211_ratectl_tx_status *);
     76static void     amrr_tx_update_cb(void *, struct ieee80211_node *);
     77static void     amrr_tx_update(struct ieee80211vap *vap,
     78                        struct ieee80211_ratectl_tx_stats *);
    7479static void     amrr_sysctlattach(struct ieee80211vap *,
    7580                        struct sysctl_ctx_list *, struct sysctl_oid *);
     81static void     amrr_node_stats(struct ieee80211_node *ni, struct sbuf *s);
    7682
    7783/* number of references from net80211 layer */
     
    9096        .ir_tx_update   = amrr_tx_update,
    9197        .ir_setinterval = amrr_setinterval,
     98        .ir_node_stats  = amrr_node_stats,
    9299};
    93100IEEE80211_RATECTL_MODULE(amrr, 1);
     
    113120        KASSERT(vap->iv_rs == NULL, ("%s called multiple times", __func__));
    114121
    115         amrr = vap->iv_rs = malloc(sizeof(struct ieee80211_amrr),
    116             M_80211_RATECTL, M_NOWAIT|M_ZERO);
     122        amrr = vap->iv_rs = IEEE80211_MALLOC(sizeof(struct ieee80211_amrr),
     123            M_80211_RATECTL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
    117124        if (amrr == NULL) {
    118125                if_printf(vap->iv_ifp, "couldn't alloc ratectl structure\n");
     
    128135amrr_deinit(struct ieee80211vap *vap)
    129136{
    130         free(vap->iv_rs, M_80211_RATECTL);
     137        IEEE80211_FREE(vap->iv_rs, M_80211_RATECTL);
     138}
     139
     140/*
     141 * Return whether 11n rates are possible.
     142 *
     143 * Some 11n devices may return HT information but no HT rates.
     144 * Thus, we shouldn't treat them as an 11n node.
     145 */
     146static int
     147amrr_node_is_11n(struct ieee80211_node *ni)
     148{
     149
     150        if (ni->ni_chan == NULL)
     151                return (0);
     152        if (ni->ni_chan == IEEE80211_CHAN_ANYC)
     153                return (0);
     154        if (IEEE80211_IS_CHAN_HT(ni->ni_chan) && ni->ni_htrates.rs_nrates == 0)
     155                return (0);
     156        return (IEEE80211_IS_CHAN_HT(ni->ni_chan));
    131157}
    132158
     
    134160amrr_node_init(struct ieee80211_node *ni)
    135161{
    136         const struct ieee80211_rateset *rs = &ni->ni_rates;
     162        const struct ieee80211_rateset *rs = NULL;
    137163        struct ieee80211vap *vap = ni->ni_vap;
    138164        struct ieee80211_amrr *amrr = vap->iv_rs;
    139165        struct ieee80211_amrr_node *amn;
     166        uint8_t rate;
    140167
    141168        if (ni->ni_rctls == NULL) {
    142                 ni->ni_rctls = amn = malloc(sizeof(struct ieee80211_amrr_node),
    143                     M_80211_RATECTL, M_NOWAIT|M_ZERO);
     169                ni->ni_rctls = amn = IEEE80211_MALLOC(sizeof(struct ieee80211_amrr_node),
     170                    M_80211_RATECTL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
    144171                if (amn == NULL) {
    145172                        if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl "
     
    155182        amn->amn_success_threshold = amrr->amrr_min_success_threshold;
    156183
    157         /* pick initial rate */
    158         for (amn->amn_rix = rs->rs_nrates - 1;
    159              amn->amn_rix > 0 && (rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL) > 72;
    160              amn->amn_rix--)
    161                 ;
    162         ni->ni_txrate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL;
     184        /* 11n or not? Pick the right rateset */
     185        if (amrr_node_is_11n(ni)) {
     186                /* XXX ew */
     187                IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
     188                    "%s: 11n node", __func__);
     189                rs = (struct ieee80211_rateset *) &ni->ni_htrates;
     190        } else {
     191                IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
     192                    "%s: non-11n node", __func__);
     193                rs = &ni->ni_rates;
     194        }
     195
     196        /* Initial rate - lowest */
     197        rate = rs->rs_rates[0];
     198
     199        /* XXX clear the basic rate flag if it's not 11n */
     200        if (! amrr_node_is_11n(ni))
     201                rate &= IEEE80211_RATE_VAL;
     202
     203        /* pick initial rate from the rateset - HT or otherwise */
     204        /* Pick something low that's likely to succeed */
     205        for (amn->amn_rix = rs->rs_nrates - 1; amn->amn_rix > 0;
     206            amn->amn_rix--) {
     207                /* legacy - anything < 36mbit, stop searching */
     208                /* 11n - stop at MCS4 */
     209                if (amrr_node_is_11n(ni)) {
     210                        if ((rs->rs_rates[amn->amn_rix] & 0x1f) < 4)
     211                                break;
     212                } else if ((rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL) <= 72)
     213                        break;
     214        }
     215        rate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL;
     216
     217        /* if the rate is an 11n rate, ensure the MCS bit is set */
     218        if (amrr_node_is_11n(ni))
     219                rate |= IEEE80211_RATE_MCS;
     220
     221        /* Assign initial rate from the rateset */
     222        ni->ni_txrate = rate;
    163223        amn->amn_ticks = ticks;
    164224
     225        /* XXX TODO: we really need a rate-to-string method */
     226        /* XXX TODO: non-11n rate should be divided by two.. */
    165227        IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
    166             "AMRR initial rate %d", ni->ni_txrate);
     228            "AMRR: nrates=%d, initial rate %s%d",
     229            rs->rs_nrates,
     230            amrr_node_is_11n(ni) ? "MCS " : "",
     231            rate & IEEE80211_RATE_VAL);
    167232}
    168233
     
    170235amrr_node_deinit(struct ieee80211_node *ni)
    171236{
    172         free(ni->ni_rctls, M_80211_RATECTL);
     237        IEEE80211_FREE(ni->ni_rctls, M_80211_RATECTL);
    173238}
    174239
     
    178243{
    179244        int rix = amn->amn_rix;
     245        const struct ieee80211_rateset *rs = NULL;
    180246
    181247        KASSERT(is_enough(amn), ("txcnt %d", amn->amn_txcnt));
    182248
     249        /* 11n or not? Pick the right rateset */
     250        if (amrr_node_is_11n(ni)) {
     251                /* XXX ew */
     252                rs = (struct ieee80211_rateset *) &ni->ni_htrates;
     253        } else {
     254                rs = &ni->ni_rates;
     255        }
     256
     257        /* XXX TODO: we really need a rate-to-string method */
     258        /* XXX TODO: non-11n rate should be divided by two.. */
     259        IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
     260            "AMRR: current rate %d, txcnt=%d, retrycnt=%d",
     261            rs->rs_rates[rix] & IEEE80211_RATE_VAL,
     262            amn->amn_txcnt,
     263            amn->amn_retrycnt);
     264
     265        /*
     266         * XXX This is totally bogus for 11n, as although high MCS
     267         * rates for each stream may be failing, the next stream
     268         * should be checked.
     269         *
     270         * Eg, if MCS5 is ok but MCS6/7 isn't, and we can go up to
     271         * MCS23, we should skip 6/7 and try 8 onwards.
     272         */
    183273        if (is_success(amn)) {
    184274                amn->amn_success++;
    185275                if (amn->amn_success >= amn->amn_success_threshold &&
    186                     rix + 1 < ni->ni_rates.rs_nrates) {
     276                    rix + 1 < rs->rs_nrates) {
    187277                        amn->amn_recovery = 1;
    188278                        amn->amn_success = 0;
    189279                        rix++;
     280                        /* XXX TODO: we really need a rate-to-string method */
     281                        /* XXX TODO: non-11n rate should be divided by two.. */
    190282                        IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
    191283                            "AMRR increasing rate %d (txcnt=%d retrycnt=%d)",
    192                             ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL,
     284                            rs->rs_rates[rix] & IEEE80211_RATE_VAL,
    193285                            amn->amn_txcnt, amn->amn_retrycnt);
    194286                } else {
     
    209301                        }
    210302                        rix--;
     303                        /* XXX TODO: we really need a rate-to-string method */
     304                        /* XXX TODO: non-11n rate should be divided by two.. */
    211305                        IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
    212306                            "AMRR decreasing rate %d (txcnt=%d retrycnt=%d)",
    213                             ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL,
     307                            rs->rs_rates[rix] & IEEE80211_RATE_VAL,
    214308                            amn->amn_txcnt, amn->amn_retrycnt);
    215309                }
     
    234328        struct ieee80211_amrr_node *amn = ni->ni_rctls;
    235329        struct ieee80211_amrr *amrr = amn->amn_amrr;
     330        const struct ieee80211_rateset *rs = NULL;
    236331        int rix;
     332
     333        /* 11n or not? Pick the right rateset */
     334        if (amrr_node_is_11n(ni)) {
     335                /* XXX ew */
     336                rs = (struct ieee80211_rateset *) &ni->ni_htrates;
     337        } else {
     338                rs = &ni->ni_rates;
     339        }
    237340
    238341        if (is_enough(amn) && (ticks - amn->amn_ticks) > amrr->amrr_interval) {
     
    240343                if (rix != amn->amn_rix) {
    241344                        /* update public rate */
    242                         ni->ni_txrate =
    243                             ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL;
     345                        ni->ni_txrate = rs->rs_rates[rix];
     346                        /* XXX strip basic rate flag from txrate, if non-11n */
     347                        if (amrr_node_is_11n(ni))
     348                                ni->ni_txrate |= IEEE80211_RATE_MCS;
     349                        else
     350                                ni->ni_txrate &= IEEE80211_RATE_VAL;
    244351                        amn->amn_rix = rix;
    245352                }
     
    256363 */
    257364static void
    258 amrr_tx_complete(const struct ieee80211vap *vap,
    259     const struct ieee80211_node *ni, int ok,
    260     void *arg1, void *arg2 __unused)
     365amrr_tx_complete(const struct ieee80211_node *ni,
     366    const struct ieee80211_ratectl_tx_status *status)
    261367{
    262368        struct ieee80211_amrr_node *amn = ni->ni_rctls;
    263         int retries = *(int *)arg1;
     369        int retries;
     370
     371        retries = 0;
     372        if (status->flags & IEEE80211_RATECTL_STATUS_LONG_RETRY)
     373                retries = status->long_retries;
    264374
    265375        amn->amn_txcnt++;
    266         if (ok)
     376        if (status->status == IEEE80211_RATECTL_TX_SUCCESS)
    267377                amn->amn_success++;
    268378        amn->amn_retrycnt += retries;
     379}
     380
     381static void
     382amrr_tx_update_cb(void *arg, struct ieee80211_node *ni)
     383{
     384        struct ieee80211_ratectl_tx_stats *stats = arg;
     385        struct ieee80211_amrr_node *amn = ni->ni_rctls;
     386        int txcnt, success, retrycnt;
     387
     388        txcnt = stats->nframes;
     389        success = stats->nsuccess;
     390        retrycnt = 0;
     391        if (stats->flags & IEEE80211_RATECTL_TX_STATS_RETRIES)
     392                retrycnt = stats->nretries;
     393
     394        amn->amn_txcnt += txcnt;
     395        amn->amn_success += success;
     396        amn->amn_retrycnt += retrycnt;
    269397}
    270398
     
    275403 */
    276404static void
    277 amrr_tx_update(const struct ieee80211vap *vap, const struct ieee80211_node *ni,
    278     void *arg1, void *arg2, void *arg3)
    279 {
    280         struct ieee80211_amrr_node *amn = ni->ni_rctls;
    281         int txcnt = *(int *)arg1, success = *(int *)arg2, retrycnt = *(int *)arg3;
    282 
    283         amn->amn_txcnt = txcnt;
    284         amn->amn_success = success;
    285         amn->amn_retrycnt = retrycnt;
     405amrr_tx_update(struct ieee80211vap *vap,
     406    struct ieee80211_ratectl_tx_stats *stats)
     407{
     408
     409        if (stats->flags & IEEE80211_RATECTL_TX_STATS_NODE)
     410                amrr_tx_update_cb(stats, stats->ni);
     411        else {
     412                ieee80211_iterate_nodes_vap(&vap->iv_ic->ic_sta, vap,
     413                    amrr_tx_update_cb, stats);
     414        }
    286415}
    287416
     
    318447            &amrr->amrr_min_success_threshold, 0, "");
    319448}
     449
     450static void
     451amrr_node_stats(struct ieee80211_node *ni, struct sbuf *s)
     452{
     453        int rate;
     454        struct ieee80211_amrr_node *amn = ni->ni_rctls;
     455        struct ieee80211_rateset *rs;
     456
     457        /* XXX TODO: check locking? */
     458
     459        /* XXX TODO: this should be a method */
     460        if (amrr_node_is_11n(ni)) {
     461                rs = (struct ieee80211_rateset *) &ni->ni_htrates;
     462                rate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL;
     463                sbuf_printf(s, "rate: MCS %d\n", rate);
     464        } else {
     465                rs = &ni->ni_rates;
     466                rate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL;
     467                sbuf_printf(s, "rate: %d Mbit\n", rate / 2);
     468        }
     469
     470        sbuf_printf(s, "ticks: %d\n", amn->amn_ticks);
     471        sbuf_printf(s, "txcnt: %u\n", amn->amn_txcnt);
     472        sbuf_printf(s, "success: %u\n", amn->amn_success);
     473        sbuf_printf(s, "success_threshold: %u\n", amn->amn_success_threshold);
     474        sbuf_printf(s, "recovery: %u\n", amn->amn_recovery);
     475        sbuf_printf(s, "retry_cnt: %u\n", amn->amn_retrycnt);
     476}
  • freebsd/sys/net80211/ieee80211_crypto.c

    r172f2ac ra241ea8  
    8181                *keyix = 0;     /* NB: use key index 0 for ucast key */
    8282        } else {
    83                 *keyix = k - vap->iv_nw_keys;
     83                *keyix = ieee80211_crypto_get_key_wepidx(vap, k);
    8484        }
    8585        *rxkeyix = IEEE80211_KEYIX_NONE;        /* XXX maybe *keyix? */
     
    9292}
    9393static  int
    94 null_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k,
    95         const uint8_t mac[IEEE80211_ADDR_LEN])
     94null_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
    9695{
    9796        return 1;
     
    135134dev_key_set(struct ieee80211vap *vap, const struct ieee80211_key *key)
    136135{
    137         return vap->iv_key_set(vap, key, key->wk_macaddr);
     136        return vap->iv_key_set(vap, key);
    138137}
    139138
     
    525524
    526525/*
    527  * Add privacy headers appropriate for the specified key.
    528  */
     526 * Return index if the key is a WEP key (0..3); -1 otherwise.
     527 *
     528 * This is different to "get_keyid" which defaults to returning
     529 * 0 for unicast keys; it assumes that it won't be used for WEP.
     530 */
     531int
     532ieee80211_crypto_get_key_wepidx(const struct ieee80211vap *vap,
     533    const struct ieee80211_key *k)
     534{
     535
     536        if (k >= &vap->iv_nw_keys[0] &&
     537            k <  &vap->iv_nw_keys[IEEE80211_WEP_NKID])
     538                return (k - vap->iv_nw_keys);
     539        return (-1);
     540}
     541
     542/*
     543 * Note: only supports a single unicast key (0).
     544 */
     545uint8_t
     546ieee80211_crypto_get_keyid(struct ieee80211vap *vap, struct ieee80211_key *k)
     547{
     548        if (k >= &vap->iv_nw_keys[0] &&
     549            k <  &vap->iv_nw_keys[IEEE80211_WEP_NKID])
     550                return (k - vap->iv_nw_keys);
     551        else
     552                return (0);
     553}
     554
    529555struct ieee80211_key *
    530 ieee80211_crypto_encap(struct ieee80211_node *ni, struct mbuf *m)
     556ieee80211_crypto_get_txkey(struct ieee80211_node *ni, struct mbuf *m)
    531557{
    532558        struct ieee80211vap *vap = ni->ni_vap;
    533         struct ieee80211_key *k;
    534559        struct ieee80211_frame *wh;
    535         const struct ieee80211_cipher *cip;
    536         uint8_t keyid;
    537560
    538561        /*
     
    553576                        return NULL;
    554577                }
    555                 keyid = vap->iv_def_txkey;
    556                 k = &vap->iv_nw_keys[vap->iv_def_txkey];
    557         } else {
    558                 keyid = 0;
    559                 k = &ni->ni_ucastkey;
    560         }
    561         cip = k->wk_cipher;
    562         return (cip->ic_encap(k, m, keyid<<6) ? k : NULL);
     578                return &vap->iv_nw_keys[vap->iv_def_txkey];
     579        }
     580
     581        return &ni->ni_ucastkey;
     582}
     583
     584/*
     585 * Add privacy headers appropriate for the specified key.
     586 */
     587struct ieee80211_key *
     588ieee80211_crypto_encap(struct ieee80211_node *ni, struct mbuf *m)
     589{
     590        struct ieee80211_key *k;
     591        const struct ieee80211_cipher *cip;
     592
     593        if ((k = ieee80211_crypto_get_txkey(ni, m)) != NULL) {
     594                cip = k->wk_cipher;
     595                return (cip->ic_encap(k, m) ? k : NULL);
     596        }
     597
     598        return NULL;
    563599}
    564600
     
    567603 * received frame that has the WEP/Privacy bit set.
    568604 */
    569 struct ieee80211_key *
    570 ieee80211_crypto_decap(struct ieee80211_node *ni, struct mbuf *m, int hdrlen)
     605int
     606ieee80211_crypto_decap(struct ieee80211_node *ni, struct mbuf *m, int hdrlen,
     607    struct ieee80211_key **key)
    571608{
    572609#define IEEE80211_WEP_HDRLEN    (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN)
     
    577614        struct ieee80211_key *k;
    578615        struct ieee80211_frame *wh;
     616        const struct ieee80211_rx_stats *rxs;
    579617        const struct ieee80211_cipher *cip;
    580618        uint8_t keyid;
     619
     620        /*
     621         * Check for hardware decryption and IV stripping.
     622         * If the IV is stripped then we definitely can't find a key.
     623         * Set the key to NULL but return true; upper layers
     624         * will need to handle a NULL key for a successful
     625         * decrypt.
     626         */
     627        rxs = ieee80211_get_rx_params_ptr(m);
     628        if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_DECRYPTED)) {
     629                if (rxs->c_pktflags & IEEE80211_RX_F_IV_STRIP) {
     630                        /*
     631                         * Hardware decrypted, IV stripped.
     632                         * We can't find a key with a stripped IV.
     633                         * Return successful.
     634                         */
     635                        *key = NULL;
     636                        return (1);
     637                }
     638        }
    581639
    582640        /* NB: this minimum size data frame could be bigger */
     
    586644                        __func__, m->m_pkthdr.len);
    587645                vap->iv_stats.is_rx_tooshort++; /* XXX need unique stat? */
    588                 return NULL;
     646                *key = NULL;
     647                return (0);
    589648        }
    590649
     
    612671                    "unable to pullup %s header", cip->ic_name);
    613672                vap->iv_stats.is_rx_wepfail++;  /* XXX */
    614                 return NULL;
    615         }
    616 
    617         return (cip->ic_decap(k, m, hdrlen) ? k : NULL);
     673                *key = NULL;
     674                return (0);
     675        }
     676
     677        /*
     678         * Attempt decryption.
     679         *
     680         * If we fail then don't return the key - return NULL
     681         * and an error.
     682         */
     683        if (cip->ic_decap(k, m, hdrlen)) {
     684                /* success */
     685                *key = k;
     686                return (1);
     687        }
     688
     689        /* Failure */
     690        *key = NULL;
     691        return (0);
    618692#undef IEEE80211_WEP_MINLEN
    619693#undef IEEE80211_WEP_HDRLEN
    620694}
     695
     696/*
     697 * Check and remove any MIC.
     698 */
     699int
     700ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k,
     701    struct mbuf *m, int force)
     702{
     703        const struct ieee80211_cipher *cip;
     704        const struct ieee80211_rx_stats *rxs;
     705        struct ieee80211_frame *wh;
     706
     707        rxs = ieee80211_get_rx_params_ptr(m);
     708        wh = mtod(m, struct ieee80211_frame *);
     709
     710        /*
     711         * Handle demic / mic errors from hardware-decrypted offload devices.
     712         */
     713        if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_DECRYPTED)) {
     714                if (rxs->c_pktflags & IEEE80211_RX_F_FAIL_MIC) {
     715                        /*
     716                         * Hardware has said MIC failed.  We don't care about
     717                         * whether it was stripped or not.
     718                         *
     719                         * Eventually - teach the demic methods in crypto
     720                         * modules to handle a NULL key and not to dereference
     721                         * it.
     722                         */
     723                        ieee80211_notify_michael_failure(vap, wh, -1);
     724                        return (0);
     725                }
     726
     727                if (rxs->c_pktflags & IEEE80211_RX_F_MMIC_STRIP) {
     728                        /*
     729                         * Hardware has decrypted and not indicated a
     730                         * MIC failure and has stripped the MIC.
     731                         * We may not have a key, so for now just
     732                         * return OK.
     733                         */
     734                        return (1);
     735                }
     736        }
     737
     738        /*
     739         * If we don't have a key at this point then we don't
     740         * have to demic anything.
     741         */
     742        if (k == NULL)
     743                return (1);
     744
     745        cip = k->wk_cipher;
     746        return (cip->ic_miclen > 0 ? cip->ic_demic(k, m, force) : 1);
     747}
     748
    621749
    622750static void
     
    662790        ieee80211_iterate_nodes(&ic->ic_sta, load_ucastkey, NULL);
    663791}
     792
     793/*
     794 * Set the default key index for WEP, or KEYIX_NONE for no default TX key.
     795 *
     796 * This should be done as part of a key update block (iv_key_update_begin /
     797 * iv_key_update_end.)
     798 */
     799void
     800ieee80211_crypto_set_deftxkey(struct ieee80211vap *vap, ieee80211_keyix kid)
     801{
     802
     803        /* XXX TODO: assert we're in a key update block */
     804
     805        vap->iv_update_deftxkey(vap, kid);
     806}
  • freebsd/sys/net80211/ieee80211_crypto.h

    r172f2ac ra241ea8  
    7474struct ieee80211_key {
    7575        uint8_t         wk_keylen;      /* key length in bytes */
    76         uint8_t         wk_pad;
    77         uint16_t        wk_flags;
    78 #define IEEE80211_KEY_XMIT      0x0001  /* key used for xmit */
    79 #define IEEE80211_KEY_RECV      0x0002  /* key used for recv */
    80 #define IEEE80211_KEY_GROUP     0x0004  /* key used for WPA group operation */
    81 #define IEEE80211_KEY_NOREPLAY  0x0008  /* ignore replay failures */
    82 #define IEEE80211_KEY_SWENCRYPT 0x0010  /* host-based encrypt */
    83 #define IEEE80211_KEY_SWDECRYPT 0x0020  /* host-based decrypt */
    84 #define IEEE80211_KEY_SWENMIC   0x0040  /* host-based enmic */
    85 #define IEEE80211_KEY_SWDEMIC   0x0080  /* host-based demic */
    86 #define IEEE80211_KEY_DEVKEY    0x0100  /* device key request completed */
    87 #define IEEE80211_KEY_CIPHER0   0x1000  /* cipher-specific action 0 */
    88 #define IEEE80211_KEY_CIPHER1   0x2000  /* cipher-specific action 1 */
     76        uint8_t         wk_pad;         /* .. some drivers use this. Fix that. */
     77        uint8_t         wk_pad1[2];
     78        uint32_t        wk_flags;
     79#define IEEE80211_KEY_XMIT      0x00000001      /* key used for xmit */
     80#define IEEE80211_KEY_RECV      0x00000002      /* key used for recv */
     81#define IEEE80211_KEY_GROUP     0x00000004      /* key used for WPA group operation */
     82#define IEEE80211_KEY_NOREPLAY  0x00000008      /* ignore replay failures */
     83#define IEEE80211_KEY_SWENCRYPT 0x00000010      /* host-based encrypt */
     84#define IEEE80211_KEY_SWDECRYPT 0x00000020      /* host-based decrypt */
     85#define IEEE80211_KEY_SWENMIC   0x00000040      /* host-based enmic */
     86#define IEEE80211_KEY_SWDEMIC   0x00000080      /* host-based demic */
     87#define IEEE80211_KEY_DEVKEY    0x00000100      /* device key request completed */
     88#define IEEE80211_KEY_CIPHER0   0x00001000      /* cipher-specific action 0 */
     89#define IEEE80211_KEY_CIPHER1   0x00002000      /* cipher-specific action 1 */
     90#define IEEE80211_KEY_NOIV      0x00004000      /* don't insert IV/MIC for !mgmt */
     91#define IEEE80211_KEY_NOIVMGT   0x00008000      /* don't insert IV/MIC for mgmt */
     92#define IEEE80211_KEY_NOMIC     0x00010000      /* don't insert MIC for !mgmt */
     93#define IEEE80211_KEY_NOMICMGT  0x00020000      /* don't insert MIC for mgmt */
     94
    8995        ieee80211_keyix wk_keyix;       /* h/w key index */
    9096        ieee80211_keyix wk_rxkeyix;     /* optional h/w rx key index */
     
    102108        (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP | \
    103109         IEEE80211_KEY_NOREPLAY)
    104 #define IEEE80211_KEY_DEVICE            /* flags owned by device driver */\
    105         (IEEE80211_KEY_DEVKEY|IEEE80211_KEY_CIPHER0|IEEE80211_KEY_CIPHER1)
    106110
    107111#define IEEE80211_KEY_SWCRYPT \
    108112        (IEEE80211_KEY_SWENCRYPT | IEEE80211_KEY_SWDECRYPT)
    109113#define IEEE80211_KEY_SWMIC     (IEEE80211_KEY_SWENMIC | IEEE80211_KEY_SWDEMIC)
     114
     115#define IEEE80211_KEY_DEVICE            /* flags owned by device driver */\
     116        (IEEE80211_KEY_DEVKEY|IEEE80211_KEY_CIPHER0|IEEE80211_KEY_CIPHER1| \
     117         IEEE80211_KEY_SWCRYPT|IEEE80211_KEY_SWMIC|IEEE80211_KEY_NOIV | \
     118         IEEE80211_KEY_NOIVMGT|IEEE80211_KEY_NOMIC|IEEE80211_KEY_NOMICMGT)
    110119
    111120#define IEEE80211_KEY_BITS \
     
    163172void    ieee80211_crypto_delglobalkeys(struct ieee80211vap *);
    164173void    ieee80211_crypto_reload_keys(struct ieee80211com *);
     174void    ieee80211_crypto_set_deftxkey(struct ieee80211vap *,
     175            ieee80211_keyix kid);
    165176
    166177/*
     
    179190        void    (*ic_detach)(struct ieee80211_key *);
    180191        int     (*ic_setkey)(struct ieee80211_key *);
    181         int     (*ic_encap)(struct ieee80211_key *, struct mbuf *,
    182                         uint8_t keyid);
     192        void    (*ic_setiv)(struct ieee80211_key *, uint8_t *);
     193        int     (*ic_encap)(struct ieee80211_key *, struct mbuf *);
    183194        int     (*ic_decap)(struct ieee80211_key *, struct mbuf *, int);
    184195        int     (*ic_enmic)(struct ieee80211_key *, struct mbuf *, int);
     
    194205int     ieee80211_crypto_available(u_int cipher);
    195206
     207int     ieee80211_crypto_get_key_wepidx(const struct ieee80211vap *,
     208            const struct ieee80211_key *k);
     209uint8_t ieee80211_crypto_get_keyid(struct ieee80211vap *vap,
     210                struct ieee80211_key *k);
     211struct ieee80211_key *ieee80211_crypto_get_txkey(struct ieee80211_node *,
     212                struct mbuf *);
    196213struct ieee80211_key *ieee80211_crypto_encap(struct ieee80211_node *,
    197214                struct mbuf *);
    198 struct ieee80211_key *ieee80211_crypto_decap(struct ieee80211_node *,
     215int     ieee80211_crypto_decap(struct ieee80211_node *,
     216                struct mbuf *, int, struct ieee80211_key **);
     217int ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k,
    199218                struct mbuf *, int);
    200 
    201 /*
    202  * Check and remove any MIC.
    203  */
    204 static __inline int
    205 ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k,
    206         struct mbuf *m, int force)
    207 {
    208         const struct ieee80211_cipher *cip = k->wk_cipher;
    209         return (cip->ic_miclen > 0 ? cip->ic_demic(k, m, force) : 1);
    210 }
    211 
    212219/*
    213220 * Add any MIC.
  • freebsd/sys/net80211/ieee80211_crypto_ccmp.c

    r172f2ac ra241ea8  
    6666static  void ccmp_detach(struct ieee80211_key *);
    6767static  int ccmp_setkey(struct ieee80211_key *);
    68 static  int ccmp_encap(struct ieee80211_key *k, struct mbuf *, uint8_t keyid);
     68static  void ccmp_setiv(struct ieee80211_key *, uint8_t *);
     69static  int ccmp_encap(struct ieee80211_key *, struct mbuf *);
    6970static  int ccmp_decap(struct ieee80211_key *, struct mbuf *, int);
    7071static  int ccmp_enmic(struct ieee80211_key *, struct mbuf *, int);
     
    8182        .ic_detach      = ccmp_detach,
    8283        .ic_setkey      = ccmp_setkey,
     84        .ic_setiv       = ccmp_setiv,
    8385        .ic_encap       = ccmp_encap,
    8486        .ic_decap       = ccmp_decap,
     
    99101        struct ccmp_ctx *ctx;
    100102
    101         ctx = (struct ccmp_ctx *) malloc(sizeof(struct ccmp_ctx),
    102                 M_80211_CRYPTO, M_NOWAIT | M_ZERO);
     103        ctx = (struct ccmp_ctx *) IEEE80211_MALLOC(sizeof(struct ccmp_ctx),
     104                M_80211_CRYPTO, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
    103105        if (ctx == NULL) {
    104106                vap->iv_stats.is_crypto_nomem++;
     
    116118        struct ccmp_ctx *ctx = k->wk_private;
    117119
    118         free(ctx, M_80211_CRYPTO);
     120        IEEE80211_FREE(ctx, M_80211_CRYPTO);
    119121        KASSERT(nrefs > 0, ("imbalanced attach/detach"));
    120122        nrefs--;                        /* NB: we assume caller locking */
     
    137139}
    138140
    139 /*
    140  * Add privacy headers appropriate for the specified key.
    141  */
    142 static int
    143 ccmp_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid)
     141static void
     142ccmp_setiv(struct ieee80211_key *k, uint8_t *ivp)
    144143{
    145144        struct ccmp_ctx *ctx = k->wk_private;
    146         struct ieee80211com *ic = ctx->cc_ic;
    147         uint8_t *ivp;
    148         int hdrlen;
    149 
    150         hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
    151 
    152         /*
    153          * Copy down 802.11 header and add the IV, KeyID, and ExtIV.
    154          */
    155         M_PREPEND(m, ccmp.ic_header, M_NOWAIT);
    156         if (m == NULL)
    157                 return 0;
    158         ivp = mtod(m, uint8_t *);
    159         ovbcopy(ivp + ccmp.ic_header, ivp, hdrlen);
    160         ivp += hdrlen;
    161 
    162         k->wk_keytsc++;         /* XXX wrap at 48 bits */
     145        struct ieee80211vap *vap = ctx->cc_vap;
     146        uint8_t keyid;
     147
     148        keyid = ieee80211_crypto_get_keyid(vap, k) << 6;
     149
     150        k->wk_keytsc++;
    163151        ivp[0] = k->wk_keytsc >> 0;             /* PN0 */
    164152        ivp[1] = k->wk_keytsc >> 8;             /* PN1 */
     
    169157        ivp[6] = k->wk_keytsc >> 32;            /* PN4 */
    170158        ivp[7] = k->wk_keytsc >> 40;            /* PN5 */
    171 
    172         /*
    173          * Finally, do software encrypt if neeed.
     159}
     160
     161/*
     162 * Add privacy headers appropriate for the specified key.
     163 */
     164static int
     165ccmp_encap(struct ieee80211_key *k, struct mbuf *m)
     166{
     167        const struct ieee80211_frame *wh;
     168        struct ccmp_ctx *ctx = k->wk_private;
     169        struct ieee80211com *ic = ctx->cc_ic;
     170        uint8_t *ivp;
     171        int hdrlen;
     172        int is_mgmt;
     173
     174        hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
     175        wh = mtod(m, const struct ieee80211_frame *);
     176        is_mgmt = IEEE80211_IS_MGMT(wh);
     177
     178        /*
     179         * Check to see if we need to insert IV/MIC.
     180         *
     181         * Some offload devices don't require the IV to be inserted
     182         * as part of the hardware encryption.
     183         */
     184        if (is_mgmt && (k->wk_flags & IEEE80211_KEY_NOIVMGT))
     185                return 1;
     186        if ((! is_mgmt) && (k->wk_flags & IEEE80211_KEY_NOIV))
     187                return 1;
     188
     189        /*
     190         * Copy down 802.11 header and add the IV, KeyID, and ExtIV.
     191         */
     192        M_PREPEND(m, ccmp.ic_header, M_NOWAIT);
     193        if (m == NULL)
     194                return 0;
     195        ivp = mtod(m, uint8_t *);
     196        ovbcopy(ivp + ccmp.ic_header, ivp, hdrlen);
     197        ivp += hdrlen;
     198
     199        ccmp_setiv(k, ivp);
     200
     201        /*
     202         * Finally, do software encrypt if needed.
    174203         */
    175204        if ((k->wk_flags & IEEE80211_KEY_SWENCRYPT) &&
     
    206235ccmp_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
    207236{
     237        const struct ieee80211_rx_stats *rxs;
    208238        struct ccmp_ctx *ctx = k->wk_private;
    209239        struct ieee80211vap *vap = ctx->cc_vap;
     
    211241        uint8_t *ivp, tid;
    212242        uint64_t pn;
     243
     244        rxs = ieee80211_get_rx_params_ptr(m);
     245
     246        if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_IV_STRIP))
     247                goto finish;
    213248
    214249        /*
     
    250285                return 0;
    251286
     287finish:
    252288        /*
    253289         * Copy up 802.11 header and strip crypto bits.
    254290         */
    255         ovbcopy(mtod(m, void *), mtod(m, uint8_t *) + ccmp.ic_header, hdrlen);
    256         m_adj(m, ccmp.ic_header);
    257         m_adj(m, -ccmp.ic_trailer);
     291        if (! ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_IV_STRIP))) {
     292                ovbcopy(mtod(m, void *), mtod(m, uint8_t *) + ccmp.ic_header,
     293                    hdrlen);
     294                m_adj(m, ccmp.ic_header);
     295        }
     296
     297        /*
     298         * XXX TODO: see if MMIC_STRIP also covers CCMP MIC trailer.
     299         */
     300        if (! ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_MMIC_STRIP)))
     301                m_adj(m, -ccmp.ic_trailer);
    258302
    259303        /*
    260304         * Ok to update rsc now.
    261305         */
    262         k->wk_keyrsc[tid] = pn;
     306        if (! ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_IV_STRIP))) {
     307                k->wk_keyrsc[tid] = pn;
     308        }
    263309
    264310        return 1;
  • freebsd/sys/net80211/ieee80211_crypto_none.c

    r172f2ac ra241ea8  
    3636#include <rtems/bsd/sys/param.h>
    3737#include <sys/kernel.h>
     38#include <sys/malloc.h>
    3839#include <sys/systm.h>
    3940#include <sys/mbuf.h>   
     
    5152static  void none_detach(struct ieee80211_key *);
    5253static  int none_setkey(struct ieee80211_key *);
    53 static  int none_encap(struct ieee80211_key *, struct mbuf *, uint8_t);
     54static  void none_setiv(struct ieee80211_key *, uint8_t *);
     55static  int none_encap(struct ieee80211_key *, struct mbuf *);
    5456static  int none_decap(struct ieee80211_key *, struct mbuf *, int);
    5557static  int none_enmic(struct ieee80211_key *, struct mbuf *, int);
     
    6567        .ic_detach      = none_detach,
    6668        .ic_setkey      = none_setkey,
     69        .ic_setiv       = none_setiv,
    6770        .ic_encap       = none_encap,
    6871        .ic_decap       = none_decap,
     
    9093}
    9194
     95static void
     96none_setiv(struct ieee80211_key *k, uint8_t *ivp)
     97{
     98}
     99
    92100static int
    93 none_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid)
     101none_encap(struct ieee80211_key *k, struct mbuf *m)
    94102{
    95103        struct ieee80211vap *vap = k->wk_private;
    96104#ifdef IEEE80211_DEBUG
    97105        struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
    98 #endif
     106        uint8_t keyid;
     107
     108        keyid = ieee80211_crypto_get_keyid(vap, k);
    99109
    100110        /*
     
    103113         */
    104114        IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr1,
    105             "key id %u is not set (encap)", keyid>>6);
     115            "key id %u is not set (encap)", keyid);
     116#endif
    106117        vap->iv_stats.is_tx_badcipher++;
    107118        return 0;
  • freebsd/sys/net80211/ieee80211_crypto_tkip.c

    r172f2ac ra241ea8  
    5757static  void tkip_detach(struct ieee80211_key *);
    5858static  int tkip_setkey(struct ieee80211_key *);
    59 static  int tkip_encap(struct ieee80211_key *, struct mbuf *m, uint8_t keyid);
     59static  void tkip_setiv(struct ieee80211_key *, uint8_t *);
     60static  int tkip_encap(struct ieee80211_key *, struct mbuf *);
    6061static  int tkip_enmic(struct ieee80211_key *, struct mbuf *, int);
    6162static  int tkip_decap(struct ieee80211_key *, struct mbuf *, int);
     
    7273        .ic_detach      = tkip_detach,
    7374        .ic_setkey      = tkip_setkey,
     75        .ic_setiv       = tkip_setiv,
    7476        .ic_encap       = tkip_encap,
    7577        .ic_decap       = tkip_decap,
     
    8789
    8890        u16     tx_ttak[5];
    89         int     tx_phase1_done;
    9091        u8      tx_rc4key[16];          /* XXX for test module; make locals? */
    9192
     
    112113        struct tkip_ctx *ctx;
    113114
    114         ctx = (struct tkip_ctx *) malloc(sizeof(struct tkip_ctx),
    115                 M_80211_CRYPTO, M_NOWAIT | M_ZERO);
     115        ctx = (struct tkip_ctx *) IEEE80211_MALLOC(sizeof(struct tkip_ctx),
     116                M_80211_CRYPTO, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
    116117        if (ctx == NULL) {
    117118                vap->iv_stats.is_crypto_nomem++;
     
    129130        struct tkip_ctx *ctx = k->wk_private;
    130131
    131         free(ctx, M_80211_CRYPTO);
     132        IEEE80211_FREE(ctx, M_80211_CRYPTO);
    132133        KASSERT(nrefs > 0, ("imbalanced attach/detach"));
    133134        nrefs--;                        /* NB: we assume caller locking */
     
    146147                return 0;
    147148        }
    148         k->wk_keytsc = 1;               /* TSC starts at 1 */
    149149        ctx->rx_phase1_done = 0;
    150150        return 1;
    151151}
    152152
    153 /*
    154  * Add privacy headers and do any s/w encryption required.
    155  */
    156 static int
    157 tkip_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid)
     153static void
     154tkip_setiv(struct ieee80211_key *k, uint8_t *ivp)
    158155{
    159156        struct tkip_ctx *ctx = k->wk_private;
    160157        struct ieee80211vap *vap = ctx->tc_vap;
    161         struct ieee80211com *ic = vap->iv_ic;
    162         uint8_t *ivp;
    163         int hdrlen;
    164 
    165         /*
    166          * Handle TKIP counter measures requirement.
    167          */
    168         if (vap->iv_flags & IEEE80211_F_COUNTERM) {
    169 #ifdef IEEE80211_DEBUG
    170                 struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
    171 #endif
    172 
    173                 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2,
    174                     "discard frame due to countermeasures (%s)", __func__);
    175                 vap->iv_stats.is_crypto_tkipcm++;
    176                 return 0;
    177         }
    178         hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
    179 
    180         /*
    181          * Copy down 802.11 header and add the IV, KeyID, and ExtIV.
    182          */
    183         M_PREPEND(m, tkip.ic_header, M_NOWAIT);
    184         if (m == NULL)
    185                 return 0;
    186         ivp = mtod(m, uint8_t *);
    187         memmove(ivp, ivp + tkip.ic_header, hdrlen);
    188         ivp += hdrlen;
    189 
     158        uint8_t keyid;
     159
     160        keyid = ieee80211_crypto_get_keyid(vap, k) << 6;
     161
     162        k->wk_keytsc++;
    190163        ivp[0] = k->wk_keytsc >> 8;             /* TSC1 */
    191164        ivp[1] = (ivp[0] | 0x20) & 0x7f;        /* WEP seed */
     
    196169        ivp[6] = k->wk_keytsc >> 32;            /* TSC4 */
    197170        ivp[7] = k->wk_keytsc >> 40;            /* TSC5 */
    198 
    199         /*
    200          * Finally, do software encrypt if neeed.
    201          */
    202         if (k->wk_flags & IEEE80211_KEY_SWENCRYPT) {
    203                 if (!tkip_encrypt(ctx, k, m, hdrlen))
    204                         return 0;
    205                 /* NB: tkip_encrypt handles wk_keytsc */
    206         } else
    207                 k->wk_keytsc++;
     171}
     172
     173/*
     174 * Add privacy headers and do any s/w encryption required.
     175 */
     176static int
     177tkip_encap(struct ieee80211_key *k, struct mbuf *m)
     178{
     179        struct tkip_ctx *ctx = k->wk_private;
     180        struct ieee80211vap *vap = ctx->tc_vap;
     181        struct ieee80211com *ic = vap->iv_ic;
     182        struct ieee80211_frame *wh;
     183        uint8_t *ivp;
     184        int hdrlen;
     185        int is_mgmt;
     186
     187        wh = mtod(m, struct ieee80211_frame *);
     188        is_mgmt = IEEE80211_IS_MGMT(wh);
     189
     190        /*
     191         * Handle TKIP counter measures requirement.
     192         */
     193        if (vap->iv_flags & IEEE80211_F_COUNTERM) {
     194#ifdef IEEE80211_DEBUG
     195                struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
     196#endif
     197
     198                IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2,
     199                    "discard frame due to countermeasures (%s)", __func__);
     200                vap->iv_stats.is_crypto_tkipcm++;
     201                return 0;
     202        }
     203
     204        /*
     205         * Check to see whether IV needs to be included.
     206         */
     207        if (is_mgmt && (k->wk_flags & IEEE80211_KEY_NOIVMGT))
     208                return 1;
     209        if ((! is_mgmt) && (k->wk_flags & IEEE80211_KEY_NOIV))
     210                return 1;
     211
     212
     213        hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
     214
     215        /*
     216         * Copy down 802.11 header and add the IV, KeyID, and ExtIV.
     217         */
     218        M_PREPEND(m, tkip.ic_header, M_NOWAIT);
     219        if (m == NULL)
     220                return 0;
     221        ivp = mtod(m, uint8_t *);
     222        memmove(ivp, ivp + tkip.ic_header, hdrlen);
     223        ivp += hdrlen;
     224
     225        tkip_setiv(k, ivp);
     226
     227        /*
     228         * Finally, do software encrypt if needed.
     229         */
     230        if ((k->wk_flags & IEEE80211_KEY_SWENCRYPT) &&
     231            !tkip_encrypt(ctx, k, m, hdrlen))
     232                return 0;
    208233
    209234        return 1;
     
    217242{
    218243        struct tkip_ctx *ctx = k->wk_private;
     244        struct ieee80211_frame *wh;
     245        int is_mgmt;
     246
     247        wh = mtod(m, struct ieee80211_frame *);
     248        is_mgmt = IEEE80211_IS_MGMT(wh);
     249
     250        /*
     251         * Check to see whether MIC needs to be included.
     252         */
     253        if (is_mgmt && (k->wk_flags & IEEE80211_KEY_NOMICMGT))
     254                return 1;
     255        if ((! is_mgmt) && (k->wk_flags & IEEE80211_KEY_NOMIC))
     256                return 1;
    219257
    220258        if (force || (k->wk_flags & IEEE80211_KEY_SWENMIC)) {
     
    252290tkip_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
    253291{
     292        const struct ieee80211_rx_stats *rxs;
    254293        struct tkip_ctx *ctx = k->wk_private;
    255294        struct ieee80211vap *vap = ctx->tc_vap;
    256295        struct ieee80211_frame *wh;
    257296        uint8_t *ivp, tid;
     297
     298        rxs = ieee80211_get_rx_params_ptr(m);
     299
     300        /*
     301         * If IV has been stripped, we skip most of the below.
     302         */
     303        if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_IV_STRIP))
     304                goto finish;
    258305
    259306        /*
     
    311358                return 0;
    312359
    313         /*
    314          * Copy up 802.11 header and strip crypto bits.
    315          */
    316         memmove(mtod(m, uint8_t *) + tkip.ic_header, mtod(m, void *), hdrlen);
    317         m_adj(m, tkip.ic_header);
     360finish:
     361
     362        /*
     363         * Copy up 802.11 header and strip crypto bits - but only if we
     364         * are required to.
     365         */
     366        if (! ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_IV_STRIP))) {
     367                memmove(mtod(m, uint8_t *) + tkip.ic_header, mtod(m, void *),
     368                    hdrlen);
     369                m_adj(m, tkip.ic_header);
     370        }
     371
     372        /*
     373         * XXX TODO: do we need an option to potentially not strip the
     374         * WEP trailer?  Does "MMIC_STRIP" also mean this? Or?
     375         */
    318376        m_adj(m, -tkip.ic_trailer);
    319377
     
    327385tkip_demic(struct ieee80211_key *k, struct mbuf *m, int force)
    328386{
     387        const struct ieee80211_rx_stats *rxs;
    329388        struct tkip_ctx *ctx = k->wk_private;
    330389        struct ieee80211_frame *wh;
     
    332391
    333392        wh = mtod(m, struct ieee80211_frame *);
     393        rxs = ieee80211_get_rx_params_ptr(m);
     394
     395        /*
     396         * If we are told about a MIC failure from the driver,
     397         * directly notify as a michael failure to the upper
     398         * layers.
     399         */
     400        if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_FAIL_MIC)) {
     401                struct ieee80211vap *vap = ctx->tc_vap;
     402                ieee80211_notify_michael_failure(vap, wh,
     403                    k->wk_rxkeyix != IEEE80211_KEYIX_NONE ?
     404                    k->wk_rxkeyix : k->wk_keyix);
     405                return 0;
     406        }
     407
     408        /*
     409         * If IV has been stripped, we skip most of the below.
     410         */
     411        if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_MMIC_STRIP))
     412                goto finish;
     413
    334414        if ((k->wk_flags & IEEE80211_KEY_SWDEMIC) || force) {
    335415                struct ieee80211vap *vap = ctx->tc_vap;
     
    364444        k->wk_keyrsc[tid] = ctx->rx_rsc;
    365445
     446finish:
    366447        return 1;
    367448}
     
    9341015
    9351016        wh = mtod(m, struct ieee80211_frame *);
    936         if (!ctx->tx_phase1_done) {
     1017        if ((u16)(key->wk_keytsc) == 0 || key->wk_keytsc == 1) {
    9371018                tkip_mixing_phase1(ctx->tx_ttak, key->wk_key, wh->i_addr2,
    9381019                                   (u32)(key->wk_keytsc >> 16));
    939                 ctx->tx_phase1_done = 1;
    9401020        }
    9411021        tkip_mixing_phase2(ctx->tx_rc4key, key->wk_key, ctx->tx_ttak,
     
    9481028        (void) m_append(m, IEEE80211_WEP_CRCLEN, icv);  /* XXX check return */
    9491029
    950         key->wk_keytsc++;
    951         if ((u16)(key->wk_keytsc) == 0)
    952                 ctx->tx_phase1_done = 0;
    9531030        return 1;
    9541031}
  • freebsd/sys/net80211/ieee80211_crypto_wep.c

    r172f2ac ra241ea8  
    5353static  void wep_detach(struct ieee80211_key *);
    5454static  int wep_setkey(struct ieee80211_key *);
    55 static  int wep_encap(struct ieee80211_key *, struct mbuf *, uint8_t keyid);
    56 static  int wep_decap(struct ieee80211_key *, struct mbuf *, int hdrlen);
     55static  void wep_setiv(struct ieee80211_key *, uint8_t *);
     56static  int wep_encap(struct ieee80211_key *, struct mbuf *);
     57static  int wep_decap(struct ieee80211_key *, struct mbuf *, int);
    5758static  int wep_enmic(struct ieee80211_key *, struct mbuf *, int);
    5859static  int wep_demic(struct ieee80211_key *, struct mbuf *, int);
     
    6768        .ic_detach      = wep_detach,
    6869        .ic_setkey      = wep_setkey,
     70        .ic_setiv       = wep_setiv,
    6971        .ic_encap       = wep_encap,
    7072        .ic_decap       = wep_decap,
     
    9092        struct wep_ctx *ctx;
    9193
    92         ctx = (struct wep_ctx *) malloc(sizeof(struct wep_ctx),
    93                 M_80211_CRYPTO, M_NOWAIT | M_ZERO);
     94        ctx = (struct wep_ctx *) IEEE80211_MALLOC(sizeof(struct wep_ctx),
     95                M_80211_CRYPTO, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
    9496        if (ctx == NULL) {
    9597                vap->iv_stats.is_crypto_nomem++;
     
    109111        struct wep_ctx *ctx = k->wk_private;
    110112
    111         free(ctx, M_80211_CRYPTO);
     113        IEEE80211_FREE(ctx, M_80211_CRYPTO);
    112114        KASSERT(nrefs > 0, ("imbalanced attach/detach"));
    113115        nrefs--;                        /* NB: we assume caller locking */
     
    120122}
    121123
    122 /*
    123  * Add privacy headers appropriate for the specified key.
    124  */
    125 static int
    126 wep_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid)
     124static void
     125wep_setiv(struct ieee80211_key *k, uint8_t *ivp)
    127126{
    128127        struct wep_ctx *ctx = k->wk_private;
    129         struct ieee80211com *ic = ctx->wc_ic;
     128        struct ieee80211vap *vap = ctx->wc_vap;
    130129        uint32_t iv;
    131         uint8_t *ivp;
    132         int hdrlen;
    133 
    134         hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
    135 
    136         /*
    137          * Copy down 802.11 header and add the IV + KeyID.
    138          */
    139         M_PREPEND(m, wep.ic_header, M_NOWAIT);
    140         if (m == NULL)
    141                 return 0;
    142         ivp = mtod(m, uint8_t *);
    143         ovbcopy(ivp + wep.ic_header, ivp, hdrlen);
    144         ivp += hdrlen;
     130        uint8_t keyid;
     131
     132        keyid = ieee80211_crypto_get_keyid(vap, k) << 6;
    145133
    146134        /*
     
    185173#endif
    186174        ivp[3] = keyid;
    187 
    188         /*
    189          * Finally, do software encrypt if neeed.
     175}
     176
     177/*
     178 * Add privacy headers appropriate for the specified key.
     179 */
     180static int
     181wep_encap(struct ieee80211_key *k, struct mbuf *m)
     182{
     183        struct wep_ctx *ctx = k->wk_private;
     184        struct ieee80211com *ic = ctx->wc_ic;
     185        struct ieee80211_frame *wh;
     186        uint8_t *ivp;
     187        int hdrlen;
     188        int is_mgmt;
     189
     190        hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
     191        wh = mtod(m, struct ieee80211_frame *);
     192        is_mgmt = IEEE80211_IS_MGMT(wh);
     193
     194        /*
     195         * Check to see if IV is required.
     196         */
     197        if (is_mgmt && (k->wk_flags & IEEE80211_KEY_NOIVMGT))
     198                return 1;
     199        if ((! is_mgmt) && (k->wk_flags & IEEE80211_KEY_NOIV))
     200                return 1;
     201
     202        /*
     203         * Copy down 802.11 header and add the IV + KeyID.
     204         */
     205        M_PREPEND(m, wep.ic_header, M_NOWAIT);
     206        if (m == NULL)
     207                return 0;
     208        ivp = mtod(m, uint8_t *);
     209        ovbcopy(ivp + wep.ic_header, ivp, hdrlen);
     210        ivp += hdrlen;
     211
     212        wep_setiv(k, ivp);
     213
     214        /*
     215         * Finally, do software encrypt if needed.
    190216         */
    191217        if ((k->wk_flags & IEEE80211_KEY_SWENCRYPT) &&
     
    217243        struct ieee80211vap *vap = ctx->wc_vap;
    218244        struct ieee80211_frame *wh;
     245        const struct ieee80211_rx_stats *rxs;
    219246
    220247        wh = mtod(m, struct ieee80211_frame *);
     248
     249        rxs = ieee80211_get_rx_params_ptr(m);
     250
     251        if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_IV_STRIP))
     252                goto finish;
    221253
    222254        /*
     
    238270        ovbcopy(mtod(m, void *), mtod(m, uint8_t *) + wep.ic_header, hdrlen);
    239271        m_adj(m, wep.ic_header);
     272
     273finish:
     274        /* XXX TODO: do we have to strip this for offload devices? */
    240275        m_adj(m, -wep.ic_trailer);
    241276
     
    422457
    423458        off = hdrlen + wep.ic_header;
    424         data_len = m->m_pkthdr.len - (off + wep.ic_trailer),
     459        data_len = m->m_pkthdr.len - (off + wep.ic_trailer);
    425460
    426461        /* Compute CRC32 over unencrypted data and apply RC4 to data */
  • freebsd/sys/net80211/ieee80211_ddb.c

    r172f2ac ra241ea8  
    3939#include <sys/systm.h>
    4040#include <sys/kernel.h>
     41#include <sys/malloc.h>
    4142#include <sys/socket.h>
    4243
    4344#include <net/if.h>
     45#include <net/if_var.h>
    4446#include <net/if_dl.h>
    4547#include <net/if_media.h>
     
    6668
    6769static void _db_show_sta(const struct ieee80211_node *);
    68 static void _db_show_vap(const struct ieee80211vap *, int);
     70static void _db_show_vap(const struct ieee80211vap *, int, int);
    6971static void _db_show_com(const struct ieee80211com *,
    70         int showvaps, int showsta, int showprocs);
     72        int showvaps, int showsta, int showmesh, int showprocs);
     73
     74static void _db_show_all_vaps(void *, struct ieee80211com *);
    7175
    7276static void _db_show_node_table(const char *tag,
     
    106110DB_SHOW_COMMAND(vap, db_show_vap)
    107111{
    108         int i, showprocs = 0;
     112        int i, showmesh = 0, showprocs = 0;
    109113
    110114        if (!have_addr) {
     
    116120                case 'a':
    117121                        showprocs = 1;
     122                        showmesh = 1;
     123                        break;
     124                case 'm':
     125                        showmesh = 1;
    118126                        break;
    119127                case 'p':
     
    121129                        break;
    122130                }
    123         _db_show_vap((const struct ieee80211vap *) addr, showprocs);
     131        _db_show_vap((const struct ieee80211vap *) addr, showmesh, showprocs);
    124132}
    125133
     
    127135{
    128136        const struct ieee80211com *ic;
    129         int i, showprocs = 0, showvaps = 0, showsta = 0;
     137        int i, showprocs = 0, showvaps = 0, showsta = 0, showmesh = 0;
    130138
    131139        if (!have_addr) {
     
    136144                switch (modif[i]) {
    137145                case 'a':
    138                         showsta = showvaps = showprocs = 1;
     146                        showsta = showmesh = showvaps = showprocs = 1;
    139147                        break;
    140148                case 's':
    141149                        showsta = 1;
    142150                        break;
     151                case 'm':
     152                        showmesh = 1;
     153                        break;
    143154                case 'v':
    144155                        showvaps = 1;
     
    150161
    151162        ic = (const struct ieee80211com *) addr;
    152         _db_show_com(ic, showvaps, showsta, showprocs);
     163        _db_show_com(ic, showvaps, showsta, showmesh, showprocs);
    153164}
    154165
    155166DB_SHOW_ALL_COMMAND(vaps, db_show_all_vaps)
    156167{
    157         VNET_ITERATOR_DECL(vnet_iter);
    158         const struct ifnet *ifp;
    159168        int i, showall = 0;
    160169
     
    166175                }
    167176
    168         VNET_FOREACH(vnet_iter) {
    169                 TAILQ_FOREACH(ifp, &V_ifnet, if_list)
    170                         if (ifp->if_type == IFT_IEEE80211) {
    171                                 const struct ieee80211com *ic = ifp->if_l2com;
    172 
    173                                 if (!showall) {
    174                                         const struct ieee80211vap *vap;
    175                                         db_printf("%s: com %p vaps:",
    176                                             ifp->if_xname, ic);
    177                                         TAILQ_FOREACH(vap, &ic->ic_vaps,
    178                                             iv_next)
    179                                                 db_printf(" %s(%p)",
    180                                                     vap->iv_ifp->if_xname, vap);
    181                                         db_printf("\n");
    182                                 } else
    183                                         _db_show_com(ic, 1, 1, 1);
    184                         }
    185         }
     177        ieee80211_iterate_coms(_db_show_all_vaps, &showall);
    186178}
    187179
     
    205197        db_printf("%stxampdu[%d]: %p flags %b %s\n",
    206198                sep, ix, tap, tap->txa_flags, IEEE80211_AGGR_BITS,
    207                 ieee80211_wme_acnames[tap->txa_ac]);
     199                ieee80211_wme_acnames[TID_TO_WME_AC(tap->txa_tid)]);
    208200        db_printf("%s  token %u lastsample %d pkts %d avgpps %d qbytes %d qframes %d\n",
    209201                sep, tap->txa_token, tap->txa_lastsample, tap->txa_pkts,
     
    244236                ni->ni_vap, ni->ni_wdsvap, ni->ni_ic, ni->ni_table);
    245237        db_printf("\tflags=%b\n", ni->ni_flags, IEEE80211_NODE_BITS);
    246         db_printf("\tscangen %u authmode %u ath_flags 0x%x ath_defkeyix %u\n",
    247                 ni->ni_scangen, ni->ni_authmode,
    248                 ni->ni_ath_flags, ni->ni_ath_defkeyix);
     238        db_printf("\tauthmode %u ath_flags 0x%x ath_defkeyix %u\n",
     239                ni->ni_authmode, ni->ni_ath_flags, ni->ni_ath_defkeyix);
    249240        db_printf("\tassocid 0x%x txpower %u vlan %u\n",
    250241                ni->ni_associd, ni->ni_txpower, ni->ni_vlan);
     
    296287
    297288        /* XXX ampdu state */
    298         for (i = 0; i < WME_NUM_AC; i++)
     289        for (i = 0; i < WME_NUM_TID; i++)
    299290                if (ni->ni_tx_ampdu[i].txa_flags & IEEE80211_AGGR_SETUP)
    300291                        _db_show_txampdu("\t", i, &ni->ni_tx_ampdu[i]);
     
    333324
    334325static void
    335 _db_show_vap(const struct ieee80211vap *vap, int showprocs)
     326_db_show_vap(const struct ieee80211vap *vap, int showmesh, int showprocs)
    336327{
    337328        const struct ieee80211com *ic = vap->iv_ic;
     
    344335
    345336        db_printf("\topmode %s", ieee80211_opmode_name[vap->iv_opmode]);
     337#ifdef IEEE80211_SUPPORT_MESH
     338        if (vap->iv_opmode == IEEE80211_M_MBSS)
     339                db_printf("(%p)", vap->iv_mesh);
     340#endif
    346341        db_printf(" state %s", ieee80211_state_name[vap->iv_state]);
    347342        db_printf(" ifp %p(%s)", vap->iv_ifp, vap->iv_ifp->if_xname);
     
    475470        db_printf(" as %p", vap->iv_as);
    476471        db_printf("\n");
     472#ifdef IEEE80211_SUPPORT_MESH
     473        if (showmesh && vap->iv_mesh != NULL)
     474                _db_show_mesh(vap->iv_mesh);
     475#endif
    477476#ifdef IEEE80211_SUPPORT_TDMA
    478477        if (vap->iv_tdma != NULL)
     
    498497
    499498static void
    500 _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta, int showprocs)
     499_db_show_com(const struct ieee80211com *ic, int showvaps, int showsta,
     500    int showmesh, int showprocs)
    501501{
    502502        struct ieee80211vap *vap;
     
    506506                db_printf(" %s(%p)", vap->iv_ifp->if_xname, vap);
    507507        db_printf("\n");
    508         db_printf("\tifp %p(%s)", ic->ic_ifp, ic->ic_ifp->if_xname);
     508        db_printf("\tsoftc %p", ic->ic_softc);
     509        db_printf("\tname %s", ic->ic_name);
    509510        db_printf(" comlock %p", &ic->ic_comlock);
     511        db_printf(" txlock %p", &ic->ic_txlock);
     512        db_printf(" fflock %p", &ic->ic_fflock);
    510513        db_printf("\n");
    511514        db_printf("\theadroom %d", ic->ic_headroom);
     
    513516        db_printf(" opmode %s", ieee80211_opmode_name[ic->ic_opmode]);
    514517        db_printf("\n");
    515         db_printf("\tmedia %p", &ic->ic_media);
    516518        db_printf(" inact %p", &ic->ic_inact);
    517519        db_printf("\n");
     
    654656                db_printf("\n");
    655657                TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
    656                         _db_show_vap(vap, showprocs);
     658                        _db_show_vap(vap, showmesh, showprocs);
    657659        }
    658660        if (showsta && !TAILQ_EMPTY(&ic->ic_sta.nt_node)) {
     
    668670
    669671static void
     672_db_show_all_vaps(void *arg, struct ieee80211com *ic)
     673{
     674        int showall = *(int *)arg;
     675
     676        if (!showall) {
     677                const struct ieee80211vap *vap;
     678                db_printf("%s: com %p vaps:", ic->ic_name, ic);
     679                TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
     680                        db_printf(" %s(%p)", vap->iv_ifp->if_xname, vap);
     681                db_printf("\n");
     682        } else
     683                _db_show_com(ic, 1, 1, 1, 1);
     684}
     685
     686static void
    670687_db_show_node_table(const char *tag, const struct ieee80211_node_table *nt)
    671688{
     
    675692        db_printf("%s nodelock %p", tag, &nt->nt_nodelock);
    676693        db_printf(" inact_init %d", nt->nt_inact_init);
    677         db_printf(" scanlock %p", &nt->nt_scanlock);
    678         db_printf(" scangen %u\n", nt->nt_scangen);
    679694        db_printf("%s keyixmax %d keyixmap %p\n",
    680695            tag, nt->nt_keyixmax, nt->nt_keyixmap);
     
    873888                db_printf("entry %d:\tdest: %6D nexthop: %6D metric: %u", i,
    874889                    rt->rt_dest, ":", rt->rt_nexthop, ":", rt->rt_metric);
     890
    875891                db_printf("\tlifetime: %u lastseq: %u priv: %p\n",
    876                     rt->rt_lifetime, rt->rt_lastmseq, rt->rt_priv);
     892                    ieee80211_mesh_rt_update(rt, 0),
     893                    rt->rt_lastmseq, rt->rt_priv);
    877894                i++;
    878895        }
  • freebsd/sys/net80211/ieee80211_dfs.c

    r172f2ac ra241ea8  
    5151
    5252#include <net/if.h>
     53#include <net/if_var.h>
    5354#include <net/if_media.h>
     55#include <net/ethernet.h>
    5456
    5557#include <net80211/ieee80211_var.h>
     
    6769#define CAC_TIMEOUT     msecs_to_ticks(ieee80211_cac_timeout*1000)
    6870
     71/*
     72 DFS* In order to facilitate  debugging, a couple of operating
     73 * modes aside from the default are needed.
     74 *
     75 * 0 - default CAC/NOL behaviour - ie, start CAC, place
     76 *     channel on NOL list.
     77 * 1 - send CAC, but don't change channel or add the channel
     78 *     to the NOL list.
     79 * 2 - just match on radar, don't send CAC or place channel in
     80 *     the NOL list.
     81 */
     82static  int ieee80211_dfs_debug = DFS_DBG_NONE;
     83
     84/*
     85 * This option must not be included in the default kernel
     86 * as it allows users to plainly disable CAC/NOL handling.
     87 */
     88#ifdef  IEEE80211_DFS_DEBUG
     89SYSCTL_INT(_net_wlan, OID_AUTO, dfs_debug, CTLFLAG_RW,
     90        &ieee80211_dfs_debug, 0, "DFS debug behaviour");
     91#endif
     92
     93static int
     94null_set_quiet(struct ieee80211_node *ni, u_int8_t *quiet_elm)
     95{
     96        return ENOSYS;
     97}
     98
    6999void
    70100ieee80211_dfs_attach(struct ieee80211com *ic)
     
    74104        callout_init_mtx(&dfs->nol_timer, IEEE80211_LOCK_OBJ(ic), 0);
    75105        callout_init_mtx(&dfs->cac_timer, IEEE80211_LOCK_OBJ(ic), 0);
     106
     107        ic->ic_set_quiet = null_set_quiet;
    76108}
    77109
     
    216248                c = &ic->ic_channels[i];
    217249                if (IEEE80211_IS_CHAN_RADAR(c)) {
    218                         if (time_after_eq(now, dfs->nol_event[i]+NOL_TIMEOUT)) {
     250                        if (ieee80211_time_after_eq(now, dfs->nol_event[i]+NOL_TIMEOUT)) {
    219251                                c->ic_state &= ~IEEE80211_CHANSTATE_RADAR;
    220252                                if (c->ic_state & IEEE80211_CHANSTATE_NORADAR) {
     
    224256                                         * table entry.
    225257                                         */
    226                                         if_printf(ic->ic_ifp, "radar on channel"
    227                                             " %u (%u MHz) cleared after timeout\n",
     258                                        ic_printf(ic, "radar on channel %u "
     259                                            "(%u MHz) cleared after timeout\n",
    228260                                            c->ic_ieee, c->ic_freq);
    229261                                        /* notify user space */
     
    243275
    244276static void
    245 announce_radar(struct ifnet *ifp, const struct ieee80211_channel *curchan,
     277announce_radar(struct ieee80211com *ic, const struct ieee80211_channel *curchan,
    246278        const struct ieee80211_channel *newchan)
    247279{
    248280        if (newchan == NULL)
    249                 if_printf(ifp, "radar detected on channel %u (%u MHz)\n",
     281                ic_printf(ic, "radar detected on channel %u (%u MHz)\n",
    250282                    curchan->ic_ieee, curchan->ic_freq);
    251283        else
    252                 if_printf(ifp, "radar detected on channel %u (%u MHz), "
     284                ic_printf(ic, "radar detected on channel %u (%u MHz), "
    253285                    "moving to channel %u (%u MHz)\n",
    254286                    curchan->ic_ieee, curchan->ic_freq,
     
    273305
    274306        /*
    275          * Mark all entries with this frequency.  Notify user
    276          * space and arrange for notification when the radar
    277          * indication is cleared.  Then kick the NOL processing
    278          * thread if not already running.
    279          */
    280         now = ticks;
    281         for (i = 0; i < ic->ic_nchans; i++) {
    282                 struct ieee80211_channel *c = &ic->ic_channels[i];
    283                 if (c->ic_freq == chan->ic_freq) {
    284                         c->ic_state &= ~IEEE80211_CHANSTATE_CACDONE;
    285                         c->ic_state |= IEEE80211_CHANSTATE_RADAR;
    286                         dfs->nol_event[i] = now;
     307         * If doing DFS debugging (mode 2), don't bother
     308         * running the rest of this function.
     309         *
     310         * Simply announce the presence of the radar and continue
     311         * along merrily.
     312         */
     313        if (ieee80211_dfs_debug == DFS_DBG_NOCSANOL) {
     314                announce_radar(ic, chan, chan);
     315                ieee80211_notify_radar(ic, chan);
     316                return;
     317        }
     318
     319        /*
     320         * Don't mark the channel and don't put it into NOL
     321         * if we're doing DFS debugging.
     322         */
     323        if (ieee80211_dfs_debug == DFS_DBG_NONE) {
     324                /*
     325                 * Mark all entries with this frequency.  Notify user
     326                 * space and arrange for notification when the radar
     327                 * indication is cleared.  Then kick the NOL processing
     328                 * thread if not already running.
     329                 */
     330                now = ticks;
     331                for (i = 0; i < ic->ic_nchans; i++) {
     332                        struct ieee80211_channel *c = &ic->ic_channels[i];
     333                        if (c->ic_freq == chan->ic_freq) {
     334                                c->ic_state &= ~IEEE80211_CHANSTATE_CACDONE;
     335                                c->ic_state |= IEEE80211_CHANSTATE_RADAR;
     336                                dfs->nol_event[i] = now;
     337                        }
    287338                }
    288         }
    289         ieee80211_notify_radar(ic, chan);
    290         chan->ic_state |= IEEE80211_CHANSTATE_NORADAR;
    291         if (!callout_pending(&dfs->nol_timer))
    292                 callout_reset(&dfs->nol_timer, NOL_TIMEOUT, dfs_timeout, ic);
     339                ieee80211_notify_radar(ic, chan);
     340                chan->ic_state |= IEEE80211_CHANSTATE_NORADAR;
     341                if (!callout_pending(&dfs->nol_timer))
     342                        callout_reset(&dfs->nol_timer, NOL_TIMEOUT,
     343                            dfs_timeout, ic);
     344        }
    293345
    294346        /*
     
    305357        if (chan == ic->ic_bsschan) {
    306358                /* XXX need a way to defer to user app */
    307                 dfs->newchan = ieee80211_dfs_pickchannel(ic);
    308 
    309                 announce_radar(ic->ic_ifp, chan, dfs->newchan);
     359
     360                /*
     361                 * Don't flip over to a new channel if
     362                 * we are currently doing DFS debugging.
     363                 */
     364                if (ieee80211_dfs_debug == DFS_DBG_NONE)
     365                        dfs->newchan = ieee80211_dfs_pickchannel(ic);
     366                else
     367                        dfs->newchan = chan;
     368
     369                announce_radar(ic, chan, dfs->newchan);
    310370
    311371                if (callout_pending(&dfs->cac_timer))
     
    323383                         */
    324384                        /*XXX*/
    325                         if_printf(ic->ic_ifp, "%s: No free channels; waiting for entry "
     385                        ic_printf(ic, "%s: No free channels; waiting for entry "
    326386                            "on NOL to expire\n", __func__);
    327387                }
     
    333393                        dfs->lastchan = chan;
    334394                        dfs->cureps = 0;
    335                         announce_radar(ic->ic_ifp, chan, NULL);
     395                        announce_radar(ic, chan, NULL);
    336396                } else if (ppsratecheck(&dfs->lastevent, &dfs->cureps, 1)) {
    337                         announce_radar(ic->ic_ifp, chan, NULL);
     397                        announce_radar(ic, chan, NULL);
    338398                }
    339399        }
     
    377437                        return c;
    378438        }
    379         if_printf(ic->ic_ifp, "HELP, no channel located to switch to!\n");
     439        ic_printf(ic, "HELP, no channel located to switch to!\n");
    380440        return NULL;
    381441}
  • freebsd/sys/net80211/ieee80211_dfs.h

    r172f2ac ra241ea8  
    3232 */
    3333
     34typedef enum {
     35        DFS_DBG_NONE            = 0,
     36        DFS_DBG_NONOL           = 1,
     37        DFS_DBG_NOCSANOL        = 2
     38} dfs_debug_t;
     39
    3440struct ieee80211_dfs_state {
    3541        int             nol_event[IEEE80211_CHAN_MAX];
  • freebsd/sys/net80211/ieee80211_freebsd.c

    r172f2ac ra241ea8  
    3535
    3636#include <rtems/bsd/sys/param.h>
     37#include <sys/systm.h>
     38#include <sys/eventhandler.h>
    3739#include <sys/kernel.h>
    38 #include <sys/systm.h>
    3940#include <sys/linker.h>
     41#include <sys/malloc.h>
    4042#include <sys/mbuf.h>   
    4143#include <sys/module.h>
     
    4749#include <net/bpf.h>
    4850#include <net/if.h>
     51#include <net/if_var.h>
    4952#include <net/if_dl.h>
    5053#include <net/if_clone.h>
     
    6164
    6265#ifdef IEEE80211_DEBUG
    63 int     ieee80211_debug = 0;
     66static int      ieee80211_debug = 0;
    6467SYSCTL_INT(_net_wlan, OID_AUTO, debug, CTLFLAG_RW, &ieee80211_debug,
    6568            0, "debugging printfs");
     
    6871static MALLOC_DEFINE(M_80211_COM, "80211com", "802.11 com state");
    6972
    70 /*
    71  * Allocate/free com structure in conjunction with ifnet;
    72  * these routines are registered with if_register_com_alloc
    73  * below and are called automatically by the ifnet code
    74  * when the ifnet of the parent device is created.
    75  */
    76 static void *
    77 wlan_alloc(u_char type, struct ifnet *ifp)
    78 {
    79         struct ieee80211com *ic;
    80 
    81         ic = malloc(sizeof(struct ieee80211com), M_80211_COM, M_WAITOK|M_ZERO);
    82         ic->ic_ifp = ifp;
    83 
    84         return (ic);
    85 }
    86 
    87 static void
    88 wlan_free(void *ic, u_char type)
    89 {
    90         free(ic, M_80211_COM);
    91 }
     73static const char wlanname[] = "wlan";
     74static struct if_clone *wlan_cloner;
    9275
    9376static int
     
    9780        struct ieee80211vap *vap;
    9881        struct ieee80211com *ic;
    99         struct ifnet *ifp;
    10082        int error;
    10183
     
    10385        if (error)
    10486                return error;
    105         ifp = ifunit(cp.icp_parent);
    106         if (ifp == NULL)
     87        ic = ieee80211_find_com(cp.icp_parent);
     88        if (ic == NULL)
    10789                return ENXIO;
    108         /* XXX move printfs to DIAGNOSTIC before release */
    109         if (ifp->if_type != IFT_IEEE80211) {
    110                 if_printf(ifp, "%s: reject, not an 802.11 device\n", __func__);
    111                 return ENXIO;
    112         }
    11390        if (cp.icp_opmode >= IEEE80211_OPMODE_MAX) {
    114                 if_printf(ifp, "%s: invalid opmode %d\n",
    115                     __func__, cp.icp_opmode);
     91                ic_printf(ic, "%s: invalid opmode %d\n", __func__,
     92                    cp.icp_opmode);
    11693                return EINVAL;
    11794        }
    118         ic = ifp->if_l2com;
    11995        if ((ic->ic_caps & ieee80211_opcap[cp.icp_opmode]) == 0) {
    120                 if_printf(ifp, "%s mode not supported\n",
     96                ic_printf(ic, "%s mode not supported\n",
    12197                    ieee80211_opmode_name[cp.icp_opmode]);
    12298                return EOPNOTSUPP;
     
    129105#endif
    130106        ) {
    131                 if_printf(ifp, "TDMA not supported\n");
     107                ic_printf(ic, "TDMA not supported\n");
    132108                return EOPNOTSUPP;
    133109        }
    134         vap = ic->ic_vap_create(ic, ifc->ifc_name, unit,
     110        vap = ic->ic_vap_create(ic, wlanname, unit,
    135111                        cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
    136112                        cp.icp_flags & IEEE80211_CLONE_MACADDR ?
    137                             cp.icp_macaddr : (const uint8_t *)IF_LLADDR(ifp));
     113                            cp.icp_macaddr : ic->ic_macaddr);
     114
    138115        return (vap == NULL ? EIO : 0);
    139116}
     
    147124        ic->ic_vap_delete(vap);
    148125}
    149 IFC_SIMPLE_DECLARE(wlan, 0);
    150126
    151127void
    152128ieee80211_vap_destroy(struct ieee80211vap *vap)
    153129{
    154         if_clone_destroyif(&wlan_cloner, vap->iv_ifp);
     130        CURVNET_SET(vap->iv_ifp->if_vnet);
     131        if_clone_destroyif(wlan_cloner, vap->iv_ifp);
     132        CURVNET_RESTORE();
    155133}
    156134
     
    186164{
    187165        struct ieee80211com *ic = arg1;
    188         const char *name = ic->ic_ifp->if_xname;
    189 
    190         return SYSCTL_OUT(req, name, strlen(name));
     166
     167        return SYSCTL_OUT_STR(req, ic->ic_name);
    191168}
    192169
     
    224201        char num[14];                   /* sufficient for 32 bits */
    225202
    226         ctx = (struct sysctl_ctx_list *) malloc(sizeof(struct sysctl_ctx_list),
    227                 M_DEVBUF, M_NOWAIT | M_ZERO);
     203        ctx = (struct sysctl_ctx_list *) IEEE80211_MALLOC(sizeof(struct sysctl_ctx_list),
     204                M_DEVBUF, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
    228205        if (ctx == NULL) {
    229206                if_printf(ifp, "%s: cannot allocate sysctl context!\n",
     
    300277        if (vap->iv_sysctl != NULL) {
    301278                sysctl_ctx_free(vap->iv_sysctl);
    302                 free(vap->iv_sysctl, M_DEVBUF);
     279                IEEE80211_FREE(vap->iv_sysctl, M_DEVBUF);
    303280                vap->iv_sysctl = NULL;
    304281        }
     
    366343#define MC_ALIGN(m, len)                                                \
    367344do {                                                                    \
    368         (m)->m_data += (MCLBYTES - (len)) &~ (sizeof(long) - 1);        \
     345        (m)->m_data += rounddown2(MCLBYTES - (len), sizeof(long));      \
    369346} while (/* CONSTCOND */ 0)
    370347
     
    399376                 */
    400377                if (m != NULL)
    401                         MH_ALIGN(m, len);
     378                        M_ALIGN(m, len);
    402379        } else {
    403380                m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
     
    412389}
    413390
     391#ifndef __NO_STRICT_ALIGNMENT
    414392/*
    415393 * Re-align the payload in the mbuf.  This is mainly used (right now)
     
    425403        space = pktlen + align;
    426404        if (space < MINCLSIZE)
    427                 n = m_gethdr(M_DONTWAIT, MT_DATA);
     405                n = m_gethdr(M_NOWAIT, MT_DATA);
    428406        else {
    429                 n = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR,
     407                n = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR,
    430408                    space <= MCLBYTES ?     MCLBYTES :
    431409#if MJUMPAGESIZE != MCLBYTES
     
    448426        return n;
    449427}
     428#endif /* !__NO_STRICT_ALIGNMENT */
    450429
    451430int
     
    469448}
    470449
     450int
     451ieee80211_add_xmit_params(struct mbuf *m,
     452    const struct ieee80211_bpf_params *params)
     453{
     454        struct m_tag *mtag;
     455        struct ieee80211_tx_params *tx;
     456
     457        mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_XMIT_PARAMS,
     458            sizeof(struct ieee80211_tx_params), M_NOWAIT);
     459        if (mtag == NULL)
     460                return (0);
     461
     462        tx = (struct ieee80211_tx_params *)(mtag+1);
     463        memcpy(&tx->params, params, sizeof(struct ieee80211_bpf_params));
     464        m_tag_prepend(m, mtag);
     465        return (1);
     466}
     467
     468int
     469ieee80211_get_xmit_params(struct mbuf *m,
     470    struct ieee80211_bpf_params *params)
     471{
     472        struct m_tag *mtag;
     473        struct ieee80211_tx_params *tx;
     474
     475        mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_XMIT_PARAMS,
     476            NULL);
     477        if (mtag == NULL)
     478                return (-1);
     479        tx = (struct ieee80211_tx_params *)(mtag + 1);
     480        memcpy(params, &tx->params, sizeof(struct ieee80211_bpf_params));
     481        return (0);
     482}
     483
    471484void
    472485ieee80211_process_callback(struct ieee80211_node *ni,
     
    480493                cb->func(ni, cb->arg, status);
    481494        }
     495}
     496
     497/*
     498 * Add RX parameters to the given mbuf.
     499 *
     500 * Returns 1 if OK, 0 on error.
     501 */
     502int
     503ieee80211_add_rx_params(struct mbuf *m, const struct ieee80211_rx_stats *rxs)
     504{
     505        struct m_tag *mtag;
     506        struct ieee80211_rx_params *rx;
     507
     508        mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS,
     509            sizeof(struct ieee80211_rx_stats), M_NOWAIT);
     510        if (mtag == NULL)
     511                return (0);
     512
     513        rx = (struct ieee80211_rx_params *)(mtag + 1);
     514        memcpy(&rx->params, rxs, sizeof(*rxs));
     515        m_tag_prepend(m, mtag);
     516        return (1);
     517}
     518
     519int
     520ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs)
     521{
     522        struct m_tag *mtag;
     523        struct ieee80211_rx_params *rx;
     524
     525        mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS,
     526            NULL);
     527        if (mtag == NULL)
     528                return (-1);
     529        rx = (struct ieee80211_rx_params *)(mtag + 1);
     530        memcpy(rxs, &rx->params, sizeof(*rxs));
     531        return (0);
     532}
     533
     534const struct ieee80211_rx_stats *
     535ieee80211_get_rx_params_ptr(struct mbuf *m)
     536{
     537        struct m_tag *mtag;
     538        struct ieee80211_rx_params *rx;
     539
     540        mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS,
     541            NULL);
     542        if (mtag == NULL)
     543                return (NULL);
     544        rx = (struct ieee80211_rx_params *)(mtag + 1);
     545        return (&rx->params);
     546}
     547
     548
     549/*
     550 * Add TOA parameters to the given mbuf.
     551 */
     552int
     553ieee80211_add_toa_params(struct mbuf *m, const struct ieee80211_toa_params *p)
     554{
     555        struct m_tag *mtag;
     556        struct ieee80211_toa_params *rp;
     557
     558        mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_TOA_PARAMS,
     559            sizeof(struct ieee80211_toa_params), M_NOWAIT);
     560        if (mtag == NULL)
     561                return (0);
     562
     563        rp = (struct ieee80211_toa_params *)(mtag + 1);
     564        memcpy(rp, p, sizeof(*rp));
     565        m_tag_prepend(m, mtag);
     566        return (1);
     567}
     568
     569int
     570ieee80211_get_toa_params(struct mbuf *m, struct ieee80211_toa_params *p)
     571{
     572        struct m_tag *mtag;
     573        struct ieee80211_toa_params *rp;
     574
     575        mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_TOA_PARAMS,
     576            NULL);
     577        if (mtag == NULL)
     578                return (0);
     579        rp = (struct ieee80211_toa_params *)(mtag + 1);
     580        if (p != NULL)
     581                memcpy(p, rp, sizeof(*p));
     582        return (1);
     583}
     584
     585/*
     586 * Transmit a frame to the parent interface.
     587 */
     588int
     589ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
     590{
     591        int error;
     592
     593        /*
     594         * Assert the IC TX lock is held - this enforces the
     595         * processing -> queuing order is maintained
     596         */
     597        IEEE80211_TX_LOCK_ASSERT(ic);
     598        error = ic->ic_transmit(ic, m);
     599        if (error) {
     600                struct ieee80211_node *ni;
     601
     602                ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
     603
     604                /* XXX number of fragments */
     605                if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
     606                ieee80211_free_node(ni);
     607                ieee80211_free_mbuf(m);
     608        }
     609        return (error);
     610}
     611
     612/*
     613 * Transmit a frame to the VAP interface.
     614 */
     615int
     616ieee80211_vap_xmitpkt(struct ieee80211vap *vap, struct mbuf *m)
     617{
     618        struct ifnet *ifp = vap->iv_ifp;
     619
     620        /*
     621         * When transmitting via the VAP, we shouldn't hold
     622         * any IC TX lock as the VAP TX path will acquire it.
     623         */
     624        IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
     625
     626        return (ifp->if_transmit(ifp, m));
     627
    482628}
    483629
     
    574720
    575721        IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2,
    576             "%s replay detected <rsc %ju, csc %ju, keyix %u rxkeyix %u>",
    577             k->wk_cipher->ic_name, (intmax_t) rsc,
     722            "%s replay detected tid %d <rsc %ju, csc %ju, keyix %u rxkeyix %u>",
     723            k->wk_cipher->ic_name, tid, (intmax_t) rsc,
    578724            (intmax_t) k->wk_keyrsc[tid],
    579725            k->wk_keyix, k->wk_rxkeyix);
     
    633779        const struct ieee80211_channel *c, int mode, int count)
    634780{
    635         struct ifnet *ifp = ic->ic_ifp;
    636781        struct ieee80211_csa_event iev;
     782        struct ieee80211vap *vap;
     783        struct ifnet *ifp;
    637784
    638785        memset(&iev, 0, sizeof(iev));
     
    642789        iev.iev_mode = mode;
    643790        iev.iev_count = count;
    644         rt_ieee80211msg(ifp, RTM_IEEE80211_CSA, &iev, sizeof(iev));
     791        TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
     792                ifp = vap->iv_ifp;
     793                CURVNET_SET(ifp->if_vnet);
     794                rt_ieee80211msg(ifp, RTM_IEEE80211_CSA, &iev, sizeof(iev));
     795                CURVNET_RESTORE();
     796        }
    645797}
    646798
     
    649801        const struct ieee80211_channel *c)
    650802{
    651         struct ifnet *ifp = ic->ic_ifp;
    652803        struct ieee80211_radar_event iev;
     804        struct ieee80211vap *vap;
     805        struct ifnet *ifp;
    653806
    654807        memset(&iev, 0, sizeof(iev));
     
    656809        iev.iev_freq = c->ic_freq;
    657810        iev.iev_ieee = c->ic_ieee;
    658         rt_ieee80211msg(ifp, RTM_IEEE80211_RADAR, &iev, sizeof(iev));
     811        TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
     812                ifp = vap->iv_ifp;
     813                CURVNET_SET(ifp->if_vnet);
     814                rt_ieee80211msg(ifp, RTM_IEEE80211_RADAR, &iev, sizeof(iev));
     815                CURVNET_RESTORE();
     816        }
    659817}
    660818
     
    663821        const struct ieee80211_channel *c, enum ieee80211_notify_cac_event type)
    664822{
    665         struct ifnet *ifp = ic->ic_ifp;
    666823        struct ieee80211_cac_event iev;
     824        struct ieee80211vap *vap;
     825        struct ifnet *ifp;
    667826
    668827        memset(&iev, 0, sizeof(iev));
     
    671830        iev.iev_ieee = c->ic_ieee;
    672831        iev.iev_type = type;
    673         rt_ieee80211msg(ifp, RTM_IEEE80211_CAC, &iev, sizeof(iev));
     832        TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
     833                ifp = vap->iv_ifp;
     834                CURVNET_SET(ifp->if_vnet);
     835                rt_ieee80211msg(ifp, RTM_IEEE80211_CAC, &iev, sizeof(iev));
     836                CURVNET_RESTORE();
     837        }
    674838}
    675839
     
    707871        iev.iev_cc[0] = cc[0];
    708872        iev.iev_cc[1] = cc[1];
     873        CURVNET_SET(ifp->if_vnet);
    709874        rt_ieee80211msg(ifp, RTM_IEEE80211_COUNTRY, &iev, sizeof(iev));
     875        CURVNET_RESTORE();
    710876}
    711877
     
    713879ieee80211_notify_radio(struct ieee80211com *ic, int state)
    714880{
    715         struct ifnet *ifp = ic->ic_ifp;
    716881        struct ieee80211_radio_event iev;
     882        struct ieee80211vap *vap;
     883        struct ifnet *ifp;
    717884
    718885        memset(&iev, 0, sizeof(iev));
    719886        iev.iev_state = state;
    720         rt_ieee80211msg(ifp, RTM_IEEE80211_RADIO, &iev, sizeof(iev));
     887        TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
     888                ifp = vap->iv_ifp;
     889                CURVNET_SET(ifp->if_vnet);
     890                rt_ieee80211msg(ifp, RTM_IEEE80211_RADIO, &iev, sizeof(iev));
     891                CURVNET_RESTORE();
     892        }
    721893}
    722894
     
    738910bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
    739911{
    740         /* NB: identify vap's by if_start */
    741         if (dlt == DLT_IEEE802_11_RADIO && ifp->if_start == ieee80211_start) {
     912        /* NB: identify vap's by if_init */
     913        if (dlt == DLT_IEEE802_11_RADIO &&
     914            ifp->if_init == ieee80211_init) {
    742915                struct ieee80211vap *vap = ifp->if_softc;
    743916                /*
     
    760933}
    761934
     935/*
     936 * Change MAC address on the vap (if was not started).
     937 */
    762938static void
    763939wlan_iflladdr(void *arg __unused, struct ifnet *ifp)
    764940{
    765         struct ieee80211com *ic = ifp->if_l2com;
    766         struct ieee80211vap *vap, *next;
    767 
    768         if (ifp->if_type != IFT_IEEE80211 || ic == NULL)
    769                 return;
    770 
    771         IEEE80211_LOCK(ic);
    772         TAILQ_FOREACH_SAFE(vap, &ic->ic_vaps, iv_next, next) {
    773                 /*
    774                  * If the MAC address has changed on the parent and it was
    775                  * copied to the vap on creation then re-sync.
    776                  */
    777                 if (vap->iv_ic == ic &&
    778                     (vap->iv_flags_ext & IEEE80211_FEXT_UNIQMAC) == 0) {
    779                         IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp));
    780                         IEEE80211_UNLOCK(ic);
    781                         if_setlladdr(vap->iv_ifp, IF_LLADDR(ifp),
    782                             IEEE80211_ADDR_LEN);
    783                         IEEE80211_LOCK(ic);
    784                 }
    785         }
    786         IEEE80211_UNLOCK(ic);
     941        /* NB: identify vap's by if_init */
     942        if (ifp->if_init == ieee80211_init &&
     943            (ifp->if_flags & IFF_UP) == 0) {
     944                struct ieee80211vap *vap = ifp->if_softc;
     945
     946                IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp));
     947        }
    787948}
    788949
     
    801962                wlan_bpfevent = EVENTHANDLER_REGISTER(bpf_track,
    802963                    bpf_track, 0, EVENTHANDLER_PRI_ANY);
    803                 if (wlan_bpfevent == NULL)
    804                         return ENOMEM;
    805964                wlan_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event,
    806965                    wlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
    807                 if (wlan_ifllevent == NULL) {
    808                         EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
    809                         return ENOMEM;
    810                 }
    811                 if_clone_attach(&wlan_cloner);
    812                 if_register_com_alloc(IFT_IEEE80211, wlan_alloc, wlan_free);
     966                wlan_cloner = if_clone_simple(wlanname, wlan_clone_create,
     967                    wlan_clone_destroy, 0);
    813968                return 0;
    814969        case MOD_UNLOAD:
    815                 if_deregister_com_alloc(IFT_IEEE80211);
    816                 if_clone_detach(&wlan_cloner);
     970                if_clone_detach(wlan_cloner);
    817971                EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
    818972                EVENTHANDLER_DEREGISTER(iflladdr_event, wlan_ifllevent);
     
    823977
    824978static moduledata_t wlan_mod = {
    825         "wlan",
     979        wlanname,
    826980        wlan_modevent,
    827981        0
     
    830984MODULE_VERSION(wlan, 1);
    831985MODULE_DEPEND(wlan, ether, 1, 1, 1);
     986#ifdef  IEEE80211_ALQ
     987MODULE_DEPEND(wlan, alq, 1, 1, 1);
     988#endif  /* IEEE80211_ALQ */
     989
  • freebsd/sys/net80211/ieee80211_freebsd.h

    r172f2ac ra241ea8  
    3030#ifdef _KERNEL
    3131#include <rtems/bsd/sys/param.h>
     32#include <sys/systm.h>
     33#include <sys/counter.h>
    3234#include <rtems/bsd/sys/lock.h>
    3335#include <sys/mutex.h>
     
    5456#define IEEE80211_LOCK_ASSERT(_ic) \
    5557        mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_OWNED)
     58#define IEEE80211_UNLOCK_ASSERT(_ic) \
     59        mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_NOTOWNED)
     60
     61/*
     62 * Transmit lock.
     63 *
     64 * This is a (mostly) temporary lock designed to serialise all of the
     65 * transmission operations throughout the stack.
     66 */
     67typedef struct {
     68        char            name[16];               /* e.g. "ath0_tx_lock" */
     69        struct mtx      mtx;
     70} ieee80211_tx_lock_t;
     71#define IEEE80211_TX_LOCK_INIT(_ic, _name) do {                         \
     72        ieee80211_tx_lock_t *cl = &(_ic)->ic_txlock;                    \
     73        snprintf(cl->name, sizeof(cl->name), "%s_tx_lock", _name);      \
     74        mtx_init(&cl->mtx, cl->name, NULL, MTX_DEF);    \
     75} while (0)
     76#define IEEE80211_TX_LOCK_OBJ(_ic)      (&(_ic)->ic_txlock.mtx)
     77#define IEEE80211_TX_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_TX_LOCK_OBJ(_ic))
     78#define IEEE80211_TX_LOCK(_ic)     mtx_lock(IEEE80211_TX_LOCK_OBJ(_ic))
     79#define IEEE80211_TX_UNLOCK(_ic)           mtx_unlock(IEEE80211_TX_LOCK_OBJ(_ic))
     80#define IEEE80211_TX_LOCK_ASSERT(_ic) \
     81        mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_OWNED)
     82#define IEEE80211_TX_UNLOCK_ASSERT(_ic) \
     83        mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_NOTOWNED)<