Home | History | Annotate | Download | only in net80211
      1 /*
      2  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
      3  * Use is subject to license terms.
      4  */
      5 
      6 /*
      7  * Copyright (c) 2001 Atsushi Onoe
      8  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  * 3. The name of the author may not be used to endorse or promote products
     20  *    derived from this software without specific prior written permission.
     21  *
     22  * Alternatively, this software may be distributed under the terms of the
     23  * GNU General Public License ("GPL") version 2 as published by the Free
     24  * Software Foundation.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     27  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     28  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     29  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     30  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     31  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     35  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     36  */
     37 
     38 /*
     39  * IEEE 802.11 generic handler
     40  */
     41 
     42 #include <sys/param.h>
     43 #include <sys/types.h>
     44 #include <sys/cmn_err.h>
     45 #include <sys/modctl.h>
     46 #include <sys/stropts.h>
     47 #include <sys/door.h>
     48 #include <sys/mac_provider.h>
     49 #include "net80211_impl.h"
     50 
     51 uint32_t ieee80211_debug = 0x0;	/* debug msg flags */
     52 
     53 const char *ieee80211_phymode_name[] = {
     54 	"auto",		/* IEEE80211_MODE_AUTO */
     55 	"11a",		/* IEEE80211_MODE_11A */
     56 	"11b",		/* IEEE80211_MODE_11B */
     57 	"11g",		/* IEEE80211_MODE_11G */
     58 	"FH",		/* IEEE80211_MODE_FH */
     59 	"turboA",	/* IEEE80211_MODE_TURBO_A */
     60 	"turboG",	/* IEEE80211_MODE_TURBO_G */
     61 	"sturboA",	/* IEEE80211_MODE_STURBO_A */
     62 	"11na",		/* IEEE80211_MODE_11NA */
     63 	"11ng",		/* IEEE80211_MODE_11NG */
     64 };
     65 
     66 #define	IEEE80211_DPRINT(_level, _fmt)	do {	\
     67 		_NOTE(CONSTCOND)		\
     68 		va_list ap;			\
     69 		va_start(ap, (_fmt));		\
     70 		vcmn_err((_level), (_fmt), ap);	\
     71 		va_end(ap);			\
     72 		_NOTE(CONSTCOND)		\
     73 	} while (0)
     74 
     75 /*
     76  * Print error messages
     77  */
     78 void
     79 ieee80211_err(const int8_t *fmt, ...)
     80 {
     81 	IEEE80211_DPRINT(CE_WARN, fmt);
     82 }
     83 
     84 /*
     85  * Print debug messages
     86  */
     87 void
     88 ieee80211_dbg(uint32_t flag, const int8_t *fmt, ...)
     89 {
     90 	if (flag & ieee80211_debug)
     91 		IEEE80211_DPRINT(CE_CONT, fmt);
     92 }
     93 
     94 /*
     95  * Alloc memory, and save the size
     96  */
     97 void *
     98 ieee80211_malloc(size_t size)
     99 {
    100 	void *p = kmem_zalloc((size + 4), KM_SLEEP);
    101 	*(int *)p = size;
    102 	p = (char *)p + 4;
    103 
    104 	return (p);
    105 }
    106 
    107 void
    108 ieee80211_free(void *p)
    109 {
    110 	void *tp = (char *)p - 4;
    111 	kmem_free((char *)p - 4, *(int *)tp + 4);
    112 }
    113 
    114 void
    115 ieee80211_mac_update(ieee80211com_t *ic)
    116 {
    117 	wifi_data_t wd = { 0 };
    118 	ieee80211_node_t *in;
    119 
    120 	/*
    121 	 * We can send data now; update the fastpath with our
    122 	 * current associated BSSID and other relevant settings.
    123 	 */
    124 	in = ic->ic_bss;
    125 	wd.wd_secalloc = ieee80211_crypto_getciphertype(ic);
    126 	wd.wd_opmode = ic->ic_opmode;
    127 	IEEE80211_ADDR_COPY(wd.wd_bssid, in->in_bssid);
    128 	wd.wd_qospad = 0;
    129 	if (in->in_flags & (IEEE80211_NODE_QOS|IEEE80211_NODE_HT)) {
    130 		wd.wd_qospad = 2;
    131 		if (ic->ic_flags & IEEE80211_F_DATAPAD)
    132 			wd.wd_qospad = roundup(wd.wd_qospad, sizeof (uint32_t));
    133 	}
    134 	(void) mac_pdata_update(ic->ic_mach, &wd, sizeof (wd));
    135 	mac_tx_update(ic->ic_mach);
    136 	ieee80211_dbg(IEEE80211_MSG_ANY, "ieee80211_mac_update"
    137 	    "(cipher = %d)\n", wd.wd_secalloc);
    138 }
    139 
    140 /*
    141  * ieee80211_event_thread
    142  * open door of wpa, send event to wpad service
    143  */
    144 static void
    145 ieee80211_event_thread(void *arg)
    146 {
    147 	ieee80211com_t *ic = arg;
    148 	door_handle_t event_door = NULL;	/* Door for upcalls */
    149 	wl_events_t ev;
    150 	door_arg_t darg;
    151 
    152 	mutex_enter(&ic->ic_doorlock);
    153 
    154 	ev.event = ic->ic_eventq[ic->ic_evq_head];
    155 	ic->ic_evq_head ++;
    156 	if (ic->ic_evq_head >= MAX_EVENT)
    157 		ic->ic_evq_head = 0;
    158 
    159 	ieee80211_dbg(IEEE80211_MSG_DEBUG, "ieee80211_event(%d)\n", ev.event);
    160 	/*
    161 	 * Locate the door used for upcalls
    162 	 */
    163 	if (door_ki_open(ic->ic_wpadoor, &event_door) != 0) {
    164 		ieee80211_err("ieee80211_event: door_ki_open(%s) failed\n",
    165 		    ic->ic_wpadoor);
    166 		goto out;
    167 	}
    168 
    169 	darg.data_ptr = (char *)&ev;
    170 	darg.data_size = sizeof (wl_events_t);
    171 	darg.desc_ptr = NULL;
    172 	darg.desc_num = 0;
    173 	darg.rbuf = NULL;
    174 	darg.rsize = 0;
    175 
    176 	if (door_ki_upcall_limited(event_door, &darg, NULL, SIZE_MAX, 0) != 0) {
    177 		ieee80211_err("ieee80211_event: door_ki_upcall() failed\n");
    178 	}
    179 
    180 	if (event_door) {	/* release our hold (if any) */
    181 		door_ki_rele(event_door);
    182 	}
    183 
    184 out:
    185 	mutex_exit(&ic->ic_doorlock);
    186 }
    187 
    188 /*
    189  * Notify state transition event message to WPA daemon
    190  */
    191 void
    192 ieee80211_notify(ieee80211com_t *ic, wpa_event_type event)
    193 {
    194 	if ((ic->ic_flags & IEEE80211_F_WPA) == 0)
    195 		return;		/* Not running on WPA mode */
    196 
    197 	ic->ic_eventq[ic->ic_evq_tail] = event;
    198 	ic->ic_evq_tail ++;
    199 	if (ic->ic_evq_tail >= MAX_EVENT) ic->ic_evq_tail = 0;
    200 
    201 	/* async */
    202 	(void) timeout(ieee80211_event_thread, (void *)ic, 0);
    203 }
    204 
    205 /*
    206  * Register WPA door
    207  */
    208 void
    209 ieee80211_register_door(ieee80211com_t *ic, const char *drvname, int inst)
    210 {
    211 	(void) snprintf(ic->ic_wpadoor, MAX_IEEE80211STR, "%s_%s%d",
    212 	    WPA_DOOR, drvname, inst);
    213 }
    214 
    215 /*
    216  * Default reset method for use with the ioctl support.  This
    217  * method is invoked after any state change in the 802.11
    218  * layer that should be propagated to the hardware but not
    219  * require re-initialization of the 802.11 state machine (e.g
    220  * rescanning for an ap).  We always return ENETRESET which
    221  * should cause the driver to re-initialize the device. Drivers
    222  * can override this method to implement more optimized support.
    223  */
    224 /* ARGSUSED */
    225 static int
    226 ieee80211_default_reset(ieee80211com_t *ic)
    227 {
    228 	return (ENETRESET);
    229 }
    230 
    231 /*
    232  * Convert channel to IEEE channel number.
    233  */
    234 uint32_t
    235 ieee80211_chan2ieee(ieee80211com_t *ic, struct ieee80211_channel *ch)
    236 {
    237 	if ((ic->ic_sup_channels <= ch) &&
    238 	    (ch <= &ic->ic_sup_channels[IEEE80211_CHAN_MAX])) {
    239 		return (ch - ic->ic_sup_channels);
    240 	} else if (ch == IEEE80211_CHAN_ANYC) {
    241 		return (IEEE80211_CHAN_ANY);
    242 	} else if (ch != NULL) {
    243 		ieee80211_err("invalid channel freq %u flags %x\n",
    244 		    ch->ich_freq, ch->ich_flags);
    245 		return (0);
    246 	}
    247 	ieee80211_err("invalid channel (NULL)\n");	/* ch == NULL */
    248 	return (0);
    249 }
    250 
    251 /*
    252  * Convert IEEE channel number to MHz frequency.
    253  *    chan    IEEE channel number
    254  *    flags   specify whether the frequency is in the 2GHz ISM
    255  *            band or the 5GHz band
    256  *
    257  * 802.11b 2GHz: 14 channels, each 5 MHz wide. Channel 1 is placed
    258  * at 2.412 GHz, channel 2 at 2.417 GHz, and so on up to channel 13
    259  * at 2.472 GHz. Channel 14 was defined especially for operation in
    260  * Japan, and has a center frequency 2.484 GHz.
    261  * 802.11g 2GHz: adopts the frequency plan of 802.11b. Japan only
    262  * allows 802.11g operation in channels 1-13
    263  * 802.11a 5GHz: starting every 5 MHz
    264  * 802.11b/g channels 15-24 (2512-2692) are used by some implementation
    265  * (Atheros etc.)
    266  */
    267 uint32_t
    268 ieee80211_ieee2mhz(uint32_t chan, uint32_t flags)
    269 {
    270 	if (flags & IEEE80211_CHAN_2GHZ) {	/* 2GHz band */
    271 		if (chan == 14)
    272 			return (2484);
    273 		if (chan < 14)
    274 			return (2412 + (chan - 1) * 5);
    275 		else
    276 			return (2512 + ((chan - 15) * 20));
    277 	} else if (flags & IEEE80211_CHAN_5GHZ) {	/* 5Ghz band */
    278 		return (5000 + (chan * 5));	/* OFDM */
    279 	} else {				/* either, guess */
    280 		if (chan == 14)
    281 			return (2484);
    282 		if (chan < 14)			/* 0-13 */
    283 			return (2412 + (chan - 1) * 5);
    284 		if (chan < 27)			/* 15-26 */
    285 			return (2512 + ((chan - 15) * 20));
    286 		return (5000 + (chan * 5));
    287 	}
    288 }
    289 
    290 /*
    291  * Do late attach work. It must be called by the driver after
    292  * calling ieee80211_attach() and before calling most ieee80211
    293  * functions.
    294  */
    295 void
    296 ieee80211_media_init(ieee80211com_t *ic)
    297 {
    298 	/*
    299 	 * Do late attach work that must wait for any subclass
    300 	 * (i.e. driver) work such as overriding methods.
    301 	 */
    302 	ieee80211_node_lateattach(ic);
    303 }
    304 
    305 /*
    306  * Start Watchdog timer. After count down timer(s), ic_watchdog
    307  * will be called
    308  */
    309 void
    310 ieee80211_start_watchdog(ieee80211com_t *ic, uint32_t timer)
    311 {
    312 	if (ic->ic_watchdog_timer == 0 && ic->ic_watchdog != NULL) {
    313 		ic->ic_watchdog_timer = timeout(ic->ic_watchdog, ic,
    314 		    drv_usectohz(1000000 * timer));
    315 	}
    316 }
    317 
    318 /*
    319  * Stop watchdog timer.
    320  */
    321 void
    322 ieee80211_stop_watchdog(ieee80211com_t *ic)
    323 {
    324 	if (ic->ic_watchdog_timer != 0) {
    325 		if (ic->ic_watchdog != NULL)
    326 			(void) untimeout(ic->ic_watchdog_timer);
    327 		ic->ic_watchdog_timer = 0;
    328 	}
    329 }
    330 
    331 /*
    332  * Called from a driver's xxx_watchdog routine. It is used to
    333  * perform periodic cleanup of state for net80211, as well as
    334  * timeout scans.
    335  */
    336 void
    337 ieee80211_watchdog(void *arg)
    338 {
    339 	ieee80211com_t *ic = arg;
    340 	struct ieee80211_impl *im = ic->ic_private;
    341 	ieee80211_node_table_t *nt;
    342 	int inact_timer = 0;
    343 
    344 	if (ic->ic_state == IEEE80211_S_INIT)
    345 		return;
    346 
    347 	IEEE80211_LOCK(ic);
    348 	if ((im->im_mgt_timer != 0) && (--im->im_mgt_timer == 0)) {
    349 		IEEE80211_UNLOCK(ic);
    350 		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
    351 		IEEE80211_LOCK(ic);
    352 	}
    353 
    354 	nt = &ic->ic_scan;
    355 	if (nt->nt_inact_timer != 0) {
    356 		if (--nt->nt_inact_timer == 0)
    357 			nt->nt_timeout(nt);
    358 		inact_timer += nt->nt_inact_timer;
    359 	}
    360 	nt = &ic->ic_sta;
    361 	if (nt->nt_inact_timer != 0) {
    362 		if (--nt->nt_inact_timer == 0)
    363 			nt->nt_timeout(nt);
    364 		inact_timer += nt->nt_inact_timer;
    365 	}
    366 
    367 	IEEE80211_UNLOCK(ic);
    368 
    369 	if (im->im_mgt_timer != 0 || inact_timer > 0)
    370 		ieee80211_start_watchdog(ic, 1);
    371 }
    372 
    373 /*
    374  * Set the current phy mode and recalculate the active channel
    375  * set and supported rates based on the available channels for
    376  * this mode. Also select a new BSS channel if the current one
    377  * is inappropriate for this mode.
    378  * This function is called by net80211, and not intended to be
    379  * called directly.
    380  */
    381 static int
    382 ieee80211_setmode(ieee80211com_t *ic, enum ieee80211_phymode mode)
    383 {
    384 	static const uint32_t chanflags[] = {
    385 		0,			/* IEEE80211_MODE_AUTO */
    386 		IEEE80211_CHAN_A,	/* IEEE80211_MODE_11A */
    387 		IEEE80211_CHAN_B,	/* IEEE80211_MODE_11B */
    388 		IEEE80211_CHAN_PUREG,	/* IEEE80211_MODE_11G */
    389 		IEEE80211_CHAN_FHSS,	/* IEEE80211_MODE_FH */
    390 		IEEE80211_CHAN_T,	/* IEEE80211_MODE_TURBO_A */
    391 		IEEE80211_CHAN_108G,	/* IEEE80211_MODE_TURBO_G */
    392 		IEEE80211_CHAN_ST,	/* IEEE80211_MODE_STURBO_A */
    393 		IEEE80211_CHAN_A,	/* IEEE80211_MODE_11NA (check legacy) */
    394 		IEEE80211_CHAN_G,	/* IEEE80211_MODE_11NG (check legacy) */
    395 	};
    396 	struct ieee80211_channel *ch;
    397 	uint32_t modeflags;
    398 	int i;
    399 	int achannels = 0;
    400 
    401 	/* validate new mode */
    402 	if ((ic->ic_modecaps & (1 << mode)) == 0) {
    403 		ieee80211_err("ieee80211_setmode(): mode %u not supported"
    404 		    " (caps 0x%x)\n", mode, ic->ic_modecaps);
    405 		return (EINVAL);
    406 	}
    407 
    408 	/*
    409 	 * Verify at least one channel is present in the available
    410 	 * channel list before committing to the new mode.
    411 	 * Calculate the active channel set.
    412 	 */
    413 	ASSERT(mode < IEEE80211_N(chanflags));
    414 	modeflags = chanflags[mode];
    415 	bzero(ic->ic_chan_active, sizeof (ic->ic_chan_active));
    416 	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
    417 		ch = &ic->ic_sup_channels[i];
    418 		if (ch->ich_flags == 0)
    419 			continue;
    420 		if (mode == IEEE80211_MODE_AUTO) {
    421 			/* take anything but pure turbo channels */
    422 			if ((ch->ich_flags & ~IEEE80211_CHAN_TURBO) != 0) {
    423 				ieee80211_setbit(ic->ic_chan_active, i);
    424 				achannels++;
    425 			}
    426 		} else {
    427 			if ((ch->ich_flags & modeflags) == modeflags) {
    428 				ieee80211_setbit(ic->ic_chan_active, i);
    429 				achannels++;
    430 			}
    431 		}
    432 	}
    433 	if (achannels == 0) {
    434 		ieee80211_err("ieee80211_setmode(): "
    435 		    "no channel found for mode %u\n", mode);
    436 		return (EINVAL);
    437 	}
    438 
    439 	/*
    440 	 * If no current/default channel is setup or the current
    441 	 * channel is wrong for the mode then pick the first
    442 	 * available channel from the active list.  This is likely
    443 	 * not the right one.
    444 	 */
    445 	if (ic->ic_ibss_chan == NULL ||
    446 	    ieee80211_isclr(ic->ic_chan_active,
    447 	    ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) {
    448 		for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
    449 			if (ieee80211_isset(ic->ic_chan_active, i)) {
    450 				ic->ic_ibss_chan = &ic->ic_sup_channels[i];
    451 				break;
    452 			}
    453 		}
    454 	}
    455 	/*
    456 	 * If the desired channel is set but no longer valid then reset it.
    457 	 */
    458 	if (ic->ic_des_chan != IEEE80211_CHAN_ANYC &&
    459 	    ieee80211_isclr(ic->ic_chan_active,
    460 	    ieee80211_chan2ieee(ic, ic->ic_des_chan))) {
    461 		ic->ic_des_chan = IEEE80211_CHAN_ANYC;
    462 	}
    463 
    464 	/*
    465 	 * Do mode-specific rate setup.
    466 	 */
    467 	if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11B)
    468 		ieee80211_setbasicrates(&ic->ic_sup_rates[mode], mode);
    469 
    470 	/*
    471 	 * Setup an initial rate set according to the
    472 	 * current/default channel.  This will be changed
    473 	 * when scanning but must exist now so drivers have
    474 	 * consistent state of ic_bsschan.
    475 	 */
    476 	if (ic->ic_bss != NULL)
    477 		ic->ic_bss->in_rates = ic->ic_sup_rates[mode];
    478 	ic->ic_curmode = mode;
    479 	ieee80211_reset_erp(ic);	/* reset ERP state */
    480 	ieee80211_wme_initparams(ic);	/* reset WME stat */
    481 
    482 	return (0);
    483 }
    484 
    485 /*
    486  * Return the phy mode for with the specified channel so the
    487  * caller can select a rate set.  This is problematic for channels
    488  * where multiple operating modes are possible (e.g. 11g+11b).
    489  * In those cases we defer to the current operating mode when set.
    490  */
    491 /* ARGSUSED */
    492 enum ieee80211_phymode
    493 ieee80211_chan2mode(ieee80211com_t *ic, struct ieee80211_channel *chan)
    494 {
    495 	if (IEEE80211_IS_CHAN_HTA(chan))
    496 		return (IEEE80211_MODE_11NA);
    497 	else if (IEEE80211_IS_CHAN_HTG(chan))
    498 		return (IEEE80211_MODE_11NG);
    499 	else if (IEEE80211_IS_CHAN_108G(chan))
    500 		return (IEEE80211_MODE_TURBO_G);
    501 	else if (IEEE80211_IS_CHAN_ST(chan))
    502 		return (IEEE80211_MODE_STURBO_A);
    503 	else if (IEEE80211_IS_CHAN_T(chan))
    504 		return (IEEE80211_MODE_TURBO_A);
    505 	else if (IEEE80211_IS_CHAN_A(chan))
    506 		return (IEEE80211_MODE_11A);
    507 	else if (IEEE80211_IS_CHAN_ANYG(chan))
    508 		return (IEEE80211_MODE_11G);
    509 	else if (IEEE80211_IS_CHAN_B(chan))
    510 		return (IEEE80211_MODE_11B);
    511 	else if (IEEE80211_IS_CHAN_FHSS(chan))
    512 		return (IEEE80211_MODE_FH);
    513 
    514 	/* NB: should not get here */
    515 	ieee80211_err("cannot map channel to mode; freq %u flags 0x%x\n",
    516 	    chan->ich_freq, chan->ich_flags);
    517 
    518 	return (IEEE80211_MODE_11B);
    519 }
    520 
    521 const struct ieee80211_rateset *
    522 ieee80211_get_suprates(ieee80211com_t *ic, struct ieee80211_channel *c)
    523 {
    524 	if (IEEE80211_IS_CHAN_HTA(c))
    525 		return (&ic->ic_sup_rates[IEEE80211_MODE_11A]);
    526 	if (IEEE80211_IS_CHAN_HTG(c)) {
    527 		return (&ic->ic_sup_rates[IEEE80211_MODE_11G]);
    528 	}
    529 	return (&ic->ic_sup_rates[ieee80211_chan2mode(ic, c)]);
    530 }
    531 
    532 /*
    533  * Locate a channel given a frequency+flags.  We cache
    534  * the previous lookup to optimize swithing between two
    535  * channels--as happens with dynamic turbo.
    536  */
    537 struct ieee80211_channel *
    538 ieee80211_find_channel(ieee80211com_t *ic, int freq, int flags)
    539 {
    540 	struct ieee80211_channel *c;
    541 	int i;
    542 
    543 	flags &= IEEE80211_CHAN_ALLTURBO;
    544 	/* brute force search */
    545 	for (i = 0; i < IEEE80211_CHAN_MAX; i++) {
    546 		c = &ic->ic_sup_channels[i];
    547 		if (c->ich_freq == freq &&
    548 		    (c->ich_flags & IEEE80211_CHAN_ALLTURBO) == flags)
    549 			return (c);
    550 	}
    551 	return (NULL);
    552 }
    553 
    554 /*
    555  * Return the size of the 802.11 header for a management or data frame.
    556  */
    557 int
    558 ieee80211_hdrsize(const void *data)
    559 {
    560 	const struct ieee80211_frame *wh = data;
    561 	int size = sizeof (struct ieee80211_frame);
    562 
    563 	/* NB: we don't handle control frames */
    564 	ASSERT((wh->i_fc[0]&IEEE80211_FC0_TYPE_MASK) !=
    565 	    IEEE80211_FC0_TYPE_CTL);
    566 	if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
    567 		size += IEEE80211_ADDR_LEN;
    568 	if (IEEE80211_QOS_HAS_SEQ(wh))
    569 		size += sizeof (uint16_t);
    570 
    571 	return (size);
    572 }
    573 
    574 /*
    575  * Return the space occupied by the 802.11 header and any
    576  * padding required by the driver.  This works for a
    577  * management or data frame.
    578  */
    579 int
    580 ieee80211_hdrspace(ieee80211com_t *ic, const void *data)
    581 {
    582 	int size = ieee80211_hdrsize(data);
    583 	if (ic->ic_flags & IEEE80211_F_DATAPAD)
    584 		size = roundup(size, sizeof (uint32_t));
    585 	return (size);
    586 }
    587 
    588 /*
    589  * Like ieee80211_hdrsize, but handles any type of frame.
    590  */
    591 int
    592 ieee80211_anyhdrsize(const void *data)
    593 {
    594 	const struct ieee80211_frame *wh = data;
    595 
    596 	if ((wh->i_fc[0]&IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) {
    597 		switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
    598 		case IEEE80211_FC0_SUBTYPE_CTS:
    599 		case IEEE80211_FC0_SUBTYPE_ACK:
    600 			return (sizeof (struct ieee80211_frame_ack));
    601 		case IEEE80211_FC0_SUBTYPE_BAR:
    602 			return (sizeof (struct ieee80211_frame_bar));
    603 		}
    604 		return (sizeof (struct ieee80211_frame_min));
    605 	} else
    606 		return (ieee80211_hdrsize(data));
    607 }
    608 
    609 /*
    610  * Like ieee80211_hdrspace, but handles any type of frame.
    611  */
    612 int
    613 ieee80211_anyhdrspace(ieee80211com_t *ic, const void *data)
    614 {
    615 	int size = ieee80211_anyhdrsize(data);
    616 	if (ic->ic_flags & IEEE80211_F_DATAPAD)
    617 		size = roundup(size, sizeof (uint32_t));
    618 	return (size);
    619 }
    620 
    621 /*
    622  * Allocate and setup a management frame of the specified
    623  * size.  We return the mblk and a pointer to the start
    624  * of the contiguous data area that's been reserved based
    625  * on the packet length.
    626  */
    627 mblk_t *
    628 ieee80211_getmgtframe(uint8_t **frm, int pktlen)
    629 {
    630 	mblk_t *mp;
    631 	int len;
    632 
    633 	len = sizeof (struct ieee80211_frame) + pktlen;
    634 	mp = allocb(len, BPRI_MED);
    635 	if (mp != NULL) {
    636 		*frm = mp->b_rptr + sizeof (struct ieee80211_frame);
    637 		mp->b_wptr = mp->b_rptr + len;
    638 	} else {
    639 		ieee80211_err("ieee80211_getmgtframe: "
    640 		    "alloc frame failed, %d\n", len);
    641 	}
    642 	return (mp);
    643 }
    644 
    645 /*
    646  * Send system messages to notify the device has joined a WLAN.
    647  * This is an OS specific function. Solaris marks link status
    648  * as up.
    649  */
    650 void
    651 ieee80211_notify_node_join(ieee80211com_t *ic, ieee80211_node_t *in)
    652 {
    653 	if (in == ic->ic_bss)
    654 		mac_link_update(ic->ic_mach, LINK_STATE_UP);
    655 	ieee80211_notify(ic, EVENT_ASSOC);	/* notify WPA service */
    656 }
    657 
    658 /*
    659  * Send system messages to notify the device has left a WLAN.
    660  * This is an OS specific function. Solaris marks link status
    661  * as down.
    662  */
    663 void
    664 ieee80211_notify_node_leave(ieee80211com_t *ic, ieee80211_node_t *in)
    665 {
    666 	if (in == ic->ic_bss)
    667 		mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
    668 	ieee80211_notify(ic, EVENT_DISASSOC);	/* notify WPA service */
    669 }
    670 
    671 
    672 /*
    673  * Get 802.11 kstats defined in ieee802.11(5)
    674  *
    675  * Return 0 on success
    676  */
    677 int
    678 ieee80211_stat(ieee80211com_t *ic, uint_t stat, uint64_t *val)
    679 {
    680 	ASSERT(val != NULL);
    681 	IEEE80211_LOCK(ic);
    682 	switch (stat) {
    683 	case WIFI_STAT_TX_FRAGS:
    684 		*val = ic->ic_stats.is_tx_frags;
    685 		break;
    686 	case WIFI_STAT_MCAST_TX:
    687 		*val = ic->ic_stats.is_tx_mcast;
    688 		break;
    689 	case WIFI_STAT_TX_FAILED:
    690 		*val = ic->ic_stats.is_tx_failed;
    691 		break;
    692 	case WIFI_STAT_TX_RETRANS:
    693 		*val = ic->ic_stats.is_tx_retries;
    694 		break;
    695 	case WIFI_STAT_RTS_SUCCESS:
    696 		*val = ic->ic_stats.is_rts_success;
    697 		break;
    698 	case WIFI_STAT_RTS_FAILURE:
    699 		*val = ic->ic_stats.is_rts_failure;
    700 		break;
    701 	case WIFI_STAT_ACK_FAILURE:
    702 		*val = ic->ic_stats.is_ack_failure;
    703 		break;
    704 	case WIFI_STAT_RX_FRAGS:
    705 		*val = ic->ic_stats.is_rx_frags;
    706 		break;
    707 	case WIFI_STAT_MCAST_RX:
    708 		*val = ic->ic_stats.is_rx_mcast;
    709 		break;
    710 	case WIFI_STAT_RX_DUPS:
    711 		*val = ic->ic_stats.is_rx_dups;
    712 		break;
    713 	case WIFI_STAT_FCS_ERRORS:
    714 		*val = ic->ic_stats.is_fcs_errors;
    715 		break;
    716 	case WIFI_STAT_WEP_ERRORS:
    717 		*val = ic->ic_stats.is_wep_errors;
    718 		break;
    719 	}
    720 	IEEE80211_UNLOCK(ic);
    721 	return (0);
    722 }
    723 
    724 /*
    725  * Attach network interface to the 802.11 support module. This
    726  * function must be called before using any of the ieee80211
    727  * functionss. The parameter "ic" MUST be initialized to tell
    728  * net80211 about interface's capabilities.
    729  */
    730 void
    731 ieee80211_attach(ieee80211com_t *ic)
    732 {
    733 	struct ieee80211_impl		*im;
    734 	struct ieee80211_channel	*ch;
    735 	int				i;
    736 
    737 	/* Check mandatory callback functions not NULL */
    738 	ASSERT(ic->ic_xmit != NULL);
    739 
    740 	mutex_init(&ic->ic_genlock, NULL, MUTEX_DRIVER, NULL);
    741 	mutex_init(&ic->ic_doorlock, NULL, MUTEX_DRIVER, NULL);
    742 
    743 	im = kmem_alloc(sizeof (ieee80211_impl_t), KM_SLEEP);
    744 	ic->ic_private = im;
    745 	cv_init(&im->im_scan_cv, NULL, CV_DRIVER, NULL);
    746 
    747 	/*
    748 	 * Fill in 802.11 available channel set, mark
    749 	 * all available channels as active, and pick
    750 	 * a default channel if not already specified.
    751 	 */
    752 	bzero(im->im_chan_avail, sizeof (im->im_chan_avail));
    753 	ic->ic_modecaps |= 1 << IEEE80211_MODE_AUTO;
    754 	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
    755 		ch = &ic->ic_sup_channels[i];
    756 		if (ch->ich_flags) {
    757 			/* Verify driver passed us valid data */
    758 			if (i != ieee80211_chan2ieee(ic, ch)) {
    759 				ieee80211_err("bad channel ignored: "
    760 				    "freq %u flags%x number %u\n",
    761 				    ch->ich_freq, ch->ich_flags, i);
    762 				ch->ich_flags = 0;
    763 				continue;
    764 			}
    765 			ieee80211_setbit(im->im_chan_avail, i);
    766 			/* Identify mode capabilities */
    767 			if (IEEE80211_IS_CHAN_A(ch))
    768 				ic->ic_modecaps |= 1 << IEEE80211_MODE_11A;
    769 			if (IEEE80211_IS_CHAN_B(ch))
    770 				ic->ic_modecaps |= 1 << IEEE80211_MODE_11B;
    771 			if (IEEE80211_IS_CHAN_PUREG(ch))
    772 				ic->ic_modecaps |= 1 << IEEE80211_MODE_11G;
    773 			if (IEEE80211_IS_CHAN_FHSS(ch))
    774 				ic->ic_modecaps |= 1 << IEEE80211_MODE_FH;
    775 			if (IEEE80211_IS_CHAN_T(ch))
    776 				ic->ic_modecaps |= 1 << IEEE80211_MODE_TURBO_A;
    777 			if (IEEE80211_IS_CHAN_108G(ch))
    778 				ic->ic_modecaps |= 1 << IEEE80211_MODE_TURBO_G;
    779 			if (IEEE80211_IS_CHAN_ST(ch))
    780 				ic->ic_modecaps |= 1 << IEEE80211_MODE_STURBO_A;
    781 			if (IEEE80211_IS_CHAN_HTA(ch))
    782 				ic->ic_modecaps |= 1 << IEEE80211_MODE_11NA;
    783 			if (IEEE80211_IS_CHAN_HTG(ch))
    784 				ic->ic_modecaps |= 1 << IEEE80211_MODE_11NG;
    785 			if (ic->ic_curchan == NULL) {
    786 				/* arbitrarily pick the first channel */
    787 				ic->ic_curchan = &ic->ic_sup_channels[i];
    788 			}
    789 		}
    790 	}
    791 	/* validate ic->ic_curmode */
    792 	if ((ic->ic_modecaps & (1 << ic->ic_curmode)) == 0)
    793 		ic->ic_curmode = IEEE80211_MODE_AUTO;
    794 	ic->ic_des_chan = IEEE80211_CHAN_ANYC;	/* any channel is ok */
    795 	(void) ieee80211_setmode(ic, ic->ic_curmode);
    796 
    797 	if (ic->ic_caps & IEEE80211_C_WME)	/* enable if capable */
    798 		ic->ic_flags |= IEEE80211_F_WME;
    799 	if (ic->ic_caps & IEEE80211_C_BURST)
    800 		ic->ic_flags |= IEEE80211_F_BURST;
    801 	ic->ic_bintval = IEEE80211_BINTVAL_DEFAULT;
    802 	ic->ic_lintval = ic->ic_bintval;
    803 	ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;
    804 	ic->ic_bmissthreshold = IEEE80211_HWBMISS_DEFAULT;
    805 
    806 	ic->ic_reset = ieee80211_default_reset;
    807 
    808 	ieee80211_node_attach(ic);
    809 	ieee80211_proto_attach(ic);
    810 	ieee80211_crypto_attach(ic);
    811 	ieee80211_ht_attach(ic);
    812 
    813 	ic->ic_watchdog_timer = 0;
    814 }
    815 
    816 /*
    817  * Free any ieee80211 structures associated with the driver.
    818  */
    819 void
    820 ieee80211_detach(ieee80211com_t *ic)
    821 {
    822 	struct ieee80211_impl *im = ic->ic_private;
    823 
    824 	ieee80211_stop_watchdog(ic);
    825 	cv_destroy(&im->im_scan_cv);
    826 	kmem_free(im, sizeof (ieee80211_impl_t));
    827 
    828 	if (ic->ic_opt_ie != NULL)
    829 		ieee80211_free(ic->ic_opt_ie);
    830 
    831 	ieee80211_ht_detach(ic);
    832 	ieee80211_node_detach(ic);
    833 	ieee80211_crypto_detach(ic);
    834 
    835 	mutex_destroy(&ic->ic_genlock);
    836 	mutex_destroy(&ic->ic_doorlock);
    837 }
    838 
    839 static struct modlmisc	i_wifi_modlmisc = {
    840 	&mod_miscops,
    841 	"IEEE80211 Kernel Module v2.0"
    842 };
    843 
    844 static struct modlinkage	i_wifi_modlinkage = {
    845 	MODREV_1,
    846 	&i_wifi_modlmisc,
    847 	NULL
    848 };
    849 
    850 /*
    851  * modlinkage functions
    852  */
    853 int
    854 _init(void)
    855 {
    856 	return (mod_install(&i_wifi_modlinkage));
    857 }
    858 
    859 int
    860 _fini(void)
    861 {
    862 	return (mod_remove(&i_wifi_modlinkage));
    863 }
    864 
    865 int
    866 _info(struct modinfo *modinfop)
    867 {
    868 	return (mod_info(&i_wifi_modlinkage, modinfop));
    869 }
    870