0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc/*
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Use is subject to license terms.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
034536e9c476303015b9836aca06e46531705f2aHans Rosenfeld/*
034536e9c476303015b9836aca06e46531705f2aHans Rosenfeld * Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
034536e9c476303015b9836aca06e46531705f2aHans Rosenfeld */
034536e9c476303015b9836aca06e46531705f2aHans Rosenfeld
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc/*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Copyright (c) 2001 Atsushi Onoe
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * All rights reserved.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc *
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Redistribution and use in source and binary forms, with or without
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * modification, are permitted provided that the following conditions
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * are met:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * 1. Redistributions of source code must retain the above copyright
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * notice, this list of conditions and the following disclaimer.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * 2. Redistributions in binary form must reproduce the above copyright
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * notice, this list of conditions and the following disclaimer in the
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * documentation and/or other materials provided with the distribution.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * 3. The name of the author may not be used to endorse or promote products
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * derived from this software without specific prior written permission.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc *
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Alternatively, this software may be distributed under the terms of the
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * GNU General Public License ("GPL") version 2 as published by the Free
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Software Foundation.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc *
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc/*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * IEEE 802.11 protocol support
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc#include "net80211_impl.h"
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang/* tunables */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang#define AGGRESSIVE_MODE_SWITCH_HYSTERESIS 3 /* pkts / 100ms */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang#define HIGH_PRI_SWITCH_THRESH 10 /* pkts / 100ms */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang#define IEEE80211_RATE2MBS(r) (((r) & IEEE80211_RATE_VAL) / 2)
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcconst char *ieee80211_mgt_subtype_name[] = {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc "assoc_req", "assoc_resp", "reassoc_req", "reassoc_resp",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc "probe_req", "probe_resp", "reserved#6", "reserved#7",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc "beacon", "atim", "disassoc", "auth",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc "deauth", "reserved#13", "reserved#14", "reserved#15"
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc};
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcconst char *ieee80211_ctl_subtype_name[] = {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc "reserved#0", "reserved#1", "reserved#2", "reserved#3",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc "reserved#3", "reserved#5", "reserved#6", "reserved#7",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc "reserved#8", "reserved#9", "ps_poll", "rts",
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc "cts", "ack", "cf_end", "cf_end_ack"
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc};
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcconst char *ieee80211_state_name[IEEE80211_S_MAX] = {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc "INIT", /* IEEE80211_S_INIT */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc "SCAN", /* IEEE80211_S_SCAN */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc "AUTH", /* IEEE80211_S_AUTH */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc "ASSOC", /* IEEE80211_S_ASSOC */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc "RUN" /* IEEE80211_S_RUN */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc};
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangconst char *ieee80211_wme_acnames[] = {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang "WME_AC_BE",
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang "WME_AC_BK",
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang "WME_AC_VI",
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang "WME_AC_VO",
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang "WME_UPSD",
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang};
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcstatic int ieee80211_newstate(ieee80211com_t *, enum ieee80211_state, int);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc/*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Initialize the interface softc, ic, with protocol management
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * related data structures and functions.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcvoid
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_proto_attach(ieee80211com_t *ic)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc{
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc struct ieee80211_impl *im = ic->ic_private;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_rtsthreshold = IEEE80211_RTS_DEFAULT;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_fragthreshold = IEEE80211_FRAG_DEFAULT;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_fixed_rate = IEEE80211_FIXED_RATE_NONE;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_protmode = IEEE80211_PROT_CTSONLY;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc im->im_bmiss_max = IEEE80211_BMISS_MAX;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ic->ic_wme.wme_hipri_switch_hysteresis =
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang AGGRESSIVE_MODE_SWITCH_HYSTERESIS;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* protocol state change handler */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_newstate = ieee80211_newstate;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* initialize management frame handlers */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_recv_mgmt = ieee80211_recv_mgmt;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_send_mgmt = ieee80211_send_mgmt;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc}
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc/*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Print a 802.11 frame header
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcvoid
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_dump_pkt(const uint8_t *buf, int32_t len, int32_t rate, int32_t rssi)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc{
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc struct ieee80211_frame *wh;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc int8_t buf1[100];
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc int8_t buf2[25];
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc int i;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc bzero(buf1, sizeof (buf1));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc bzero(buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc wh = (struct ieee80211_frame *)buf;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_FC1_DIR_NODS:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "NODS %s",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_macaddr_sprintf(wh->i_addr2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "->%s",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_macaddr_sprintf(wh->i_addr1));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "(%s)",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_macaddr_sprintf(wh->i_addr3));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_FC1_DIR_TODS:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "TODS %s",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_macaddr_sprintf(wh->i_addr2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "->%s",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_macaddr_sprintf(wh->i_addr3));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "(%s)",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_macaddr_sprintf(wh->i_addr1));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_FC1_DIR_FROMDS:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "FRDS %s",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_macaddr_sprintf(wh->i_addr3));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "->%s",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_macaddr_sprintf(wh->i_addr1));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "(%s)",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_macaddr_sprintf(wh->i_addr2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_FC1_DIR_DSTODS:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "DSDS %s",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_macaddr_sprintf((uint8_t *)&wh[1]));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "->%s ",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_macaddr_sprintf(wh->i_addr3));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "%s",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_macaddr_sprintf(wh->i_addr2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "->%s",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_macaddr_sprintf(wh->i_addr1));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_dbg(IEEE80211_MSG_ANY, "ieee80211_dump_pkt(): %s", buf1);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc bzero(buf1, sizeof (buf1));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_FC0_TYPE_DATA:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) sprintf(buf2, "data");
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_FC0_TYPE_MGT:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "%s",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_mgt_subtype_name[
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK)
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China >> IEEE80211_FC0_SUBTYPE_SHIFT]);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc default:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), "type#%d",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) sprintf(buf2, " WEP");
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strcat(buf1, buf2);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (rate >= 0) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), " %dM", rate / 2);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (rssi >= 0) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, sizeof (buf2), " +%d", rssi);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, sizeof (buf2));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_dbg(IEEE80211_MSG_ANY, "ieee80211_dump_pkt(): %s", buf1);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc bzero(buf1, sizeof (buf1));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (len > 0) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc for (i = 0; i < (len > 40 ? 40 : len); i++) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if ((i & 0x03) == 0)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strcat(buf1, " ");
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) snprintf(buf2, 3, "%02x", buf[i]);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) strncat(buf1, buf2, 3);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_dbg(IEEE80211_MSG_ANY, "ieee80211_dump_pkt(): %s",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China buf1);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc}
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc/*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Adjust/Fix the specified node's rate table
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc *
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * in node
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * flag IEEE80211_F_DOSORT : sort the node's rate table
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * IEEE80211_F_DONEGO : mark a rate as basic rate if it is
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * a device's basic rate
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * IEEE80211_F_DODEL : delete rates not supported by the device
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * IEEE80211_F_DOFRATE: check if the fixed rate is supported by
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * the device
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc *
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * The highest bit of returned rate value is set to 1 on failure.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcint
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangieee80211_fix_rate(ieee80211_node_t *in,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang struct ieee80211_rateset *nrs, int flags)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc{
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211com_t *ic = in->in_ic;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc struct ieee80211_rateset *srs;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc boolean_t ignore;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc int i;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc int okrate;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc int badrate;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc int fixedrate;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc uint8_t r;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * If the fixed rate check was requested but no
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * fixed has been defined then just remove it.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if ((flags & IEEE80211_F_DOFRATE) &&
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE)) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc flags &= ~IEEE80211_F_DOFRATE;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
40db2e2b777b79f3dd0d6d9629593a07f86b9c0azf if (in->in_chan == IEEE80211_CHAN_ANYC) {
40db2e2b777b79f3dd0d6d9629593a07f86b9c0azf return (IEEE80211_RATE_BASIC);
40db2e2b777b79f3dd0d6d9629593a07f86b9c0azf }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc okrate = badrate = fixedrate = 0;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc srs = &ic->ic_sup_rates[ieee80211_chan2mode(ic, in->in_chan)];
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc for (i = 0; i < nrs->ir_nrates; ) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc int j;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ignore = B_FALSE;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (flags & IEEE80211_F_DOSORT) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Sort rates.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc for (j = i + 1; j < nrs->ir_nrates; j++) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (IEEE80211_RV(nrs->ir_rates[i]) >
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_RV(nrs->ir_rates[j])) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc r = nrs->ir_rates[i];
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc nrs->ir_rates[i] = nrs->ir_rates[j];
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc nrs->ir_rates[j] = r;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc r = IEEE80211_RV(nrs->ir_rates[i]);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc badrate = r;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Check against supported rates.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc for (j = 0; j < srs->ir_nrates; j++) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (r == IEEE80211_RV(srs->ir_rates[j])) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Overwrite with the supported rate
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * value so any basic rate bit is set.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * This insures that response we send
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * to stations have the necessary basic
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * rate bit set.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (flags & IEEE80211_F_DONEGO)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc nrs->ir_rates[i] = srs->ir_rates[j];
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (j == srs->ir_nrates) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * A rate in the node's rate set is not
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * supported. We just discard/ignore the rate.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Note that this is important for 11b stations
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * when they want to associate with an 11g AP.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ignore = B_TRUE;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (flags & IEEE80211_F_DODEL) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Delete unacceptable rates.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (ignore) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc nrs->ir_nrates--;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc for (j = i; j < nrs->ir_nrates; j++)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc nrs->ir_rates[j] = nrs->ir_rates[j + 1];
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc nrs->ir_rates[j] = 0;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc continue;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (flags & IEEE80211_F_DOFRATE) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Check any fixed rate is included.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (r == ic->ic_fixed_rate)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc fixedrate = r;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (!ignore)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc okrate = nrs->ir_rates[i];
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc i++;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (okrate == 0 || ((flags & IEEE80211_F_DOFRATE) && fixedrate == 0))
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return (badrate | IEEE80211_RATE_BASIC);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc else
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return (IEEE80211_RV(okrate));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc}
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc/*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Reset 11g-related state.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcvoid
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_reset_erp(ieee80211com_t *ic)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc{
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_flags &= ~IEEE80211_F_USEPROT;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Short slot time is enabled only when operating in 11g
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * and not in an IBSS. We must also honor whether or not
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * the driver is capable of doing it.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_set_shortslottime(ic,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ic->ic_curmode == IEEE80211_MODE_11A);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Set short preamble and ERP barker-preamble flags.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (ic->ic_curmode == IEEE80211_MODE_11A ||
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (ic->ic_caps & IEEE80211_C_SHPREAMBLE)) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_flags &= ~IEEE80211_F_USEBARKER;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc } else {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_flags |= IEEE80211_F_USEBARKER;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc}
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc/*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Change current channel to be the next available channel
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcvoid
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_reset_chan(ieee80211com_t *ic)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc{
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc struct ieee80211_channel *ch = ic->ic_curchan;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_LOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc do {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (++ch > &ic->ic_sup_channels[IEEE80211_CHAN_MAX])
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ch = &ic->ic_sup_channels[0];
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (ieee80211_isset(ic->ic_chan_active,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_chan2ieee(ic, ch))) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc } while (ch != ic->ic_curchan);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_curchan = ch;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_UNLOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc}
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc/*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Set the short slot time state and notify the driver.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcvoid
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_set_shortslottime(ieee80211com_t *ic, boolean_t on)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc{
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (on)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_flags |= IEEE80211_F_SHSLOT;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc else
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_flags &= ~IEEE80211_F_SHSLOT;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* notify driver */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (ic->ic_set_shortslot != NULL)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_set_shortslot(ic, on);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc}
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc/*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Mark the basic rates for the 11g rate table based on the
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * operating mode. For real 11g we mark all the 11b rates
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * and 6, 12, and 24 OFDM. For 11b compatibility we mark only
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * 11b rates. There's also a pseudo 11a-mode used to mark only
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * the basic OFDM rates.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcvoid
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_setbasicrates(struct ieee80211_rateset *rs,
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc enum ieee80211_phymode mode)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc{
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc static const struct ieee80211_rateset basic[] = {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc { 0 }, /* IEEE80211_MODE_AUTO */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc { 3, { 12, 24, 48 } }, /* IEEE80211_MODE_11A */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc { 2, { 2, 4} }, /* IEEE80211_MODE_11B */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_11G mixed b/g */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc { 0 }, /* IEEE80211_MODE_FH */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc { 3, { 12, 24, 48 } }, /* IEEE80211_MODE_TURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 4, { 2, 4, 11, 22 } },
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang /* IEEE80211_MODE_TURBO_G (mixed b/g) */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 0 }, /* IEEE80211_MODE_STURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, { 12, 24, 48 } }, /* IEEE80211_MODE_11NA */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang /* IEEE80211_MODE_11NG (mixed b/g) */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 7, { 2, 4, 11, 22, 12, 24, 48 } }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc };
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc int i, j;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ASSERT(mode < IEEE80211_MODE_MAX);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc for (i = 0; i < rs->ir_nrates; i++) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc rs->ir_rates[i] &= IEEE80211_RATE_VAL;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc for (j = 0; j < basic[mode].ir_nrates; j++) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (basic[mode].ir_rates[j] == rs->ir_rates[i]) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc rs->ir_rates[i] |= IEEE80211_RATE_BASIC;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc}
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang/*
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * WME protocol support. The following parameters come from the spec.
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangtypedef struct phyParamType {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang uint8_t aifsn;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang uint8_t logcwmin;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang uint8_t logcwmax;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang uint16_t txopLimit;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang uint8_t acm;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang} paramType;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangstatic const paramType phyParamForAC_BE[IEEE80211_MODE_MAX] = {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, 4, 6, 0, 0 }, /* IEEE80211_MODE_AUTO */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, 4, 6, 0, 0 }, /* IEEE80211_MODE_11A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, 4, 6, 0, 0 }, /* IEEE80211_MODE_11B */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, 4, 6, 0, 0 }, /* IEEE80211_MODE_11G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, 4, 6, 0, 0 }, /* IEEE80211_MODE_FH */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 3, 5, 0, 0 }, /* IEEE80211_MODE_TURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 3, 5, 0, 0 }, /* IEEE80211_MODE_TURBO_G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 3, 5, 0, 0 }, /* IEEE80211_MODE_STURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, 4, 6, 0, 0 }, /* IEEE80211_MODE_11NA */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, 4, 6, 0, 0 } /* IEEE80211_MODE_11NG */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang};
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangstatic const struct phyParamType phyParamForAC_BK[IEEE80211_MODE_MAX] = {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 7, 4, 10, 0, 0 }, /* IEEE80211_MODE_AUTO */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 7, 4, 10, 0, 0 }, /* IEEE80211_MODE_11A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 7, 4, 10, 0, 0 }, /* IEEE80211_MODE_11B */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 7, 4, 10, 0, 0 }, /* IEEE80211_MODE_11G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 7, 4, 10, 0, 0 }, /* IEEE80211_MODE_FH */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 7, 3, 10, 0, 0 }, /* IEEE80211_MODE_TURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 7, 3, 10, 0, 0 }, /* IEEE80211_MODE_TURBO_G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 7, 3, 10, 0, 0 }, /* IEEE80211_MODE_STURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 7, 4, 10, 0, 0 }, /* IEEE80211_MODE_11NA */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 7, 4, 10, 0, 0 }, /* IEEE80211_MODE_11NG */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang};
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangstatic const struct phyParamType phyParamForAC_VI[IEEE80211_MODE_MAX] = {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 3, 4, 94, 0 }, /* IEEE80211_MODE_AUTO */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 3, 4, 94, 0 }, /* IEEE80211_MODE_11A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 3, 4, 188, 0 }, /* IEEE80211_MODE_11B */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 3, 4, 94, 0 }, /* IEEE80211_MODE_11G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 3, 4, 188, 0 }, /* IEEE80211_MODE_FH */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 3, 94, 0 }, /* IEEE80211_MODE_TURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 3, 94, 0 }, /* IEEE80211_MODE_TURBO_G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 3, 94, 0 }, /* IEEE80211_MODE_STURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 3, 4, 94, 0 }, /* IEEE80211_MODE_11NA */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 3, 4, 94, 0 }, /* IEEE80211_MODE_11NG */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang};
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangstatic const struct phyParamType phyParamForAC_VO[IEEE80211_MODE_MAX] = {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 3, 47, 0 }, /* IEEE80211_MODE_AUTO */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 3, 47, 0 }, /* IEEE80211_MODE_11A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 3, 102, 0 }, /* IEEE80211_MODE_11B */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 3, 47, 0 }, /* IEEE80211_MODE_11G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 3, 102, 0 }, /* IEEE80211_MODE_FH */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 2, 47, 0 }, /* IEEE80211_MODE_TURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 2, 47, 0 }, /* IEEE80211_MODE_TURBO_G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 2, 47, 0 }, /* IEEE80211_MODE_STURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 3, 47, 0 }, /* IEEE80211_MODE_11NA */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 3, 47, 0 }, /* IEEE80211_MODE_11NG */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang};
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangstatic const struct phyParamType bssPhyParamForAC_BE[IEEE80211_MODE_MAX] = {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, 4, 10, 0, 0 }, /* IEEE80211_MODE_AUTO */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, 4, 10, 0, 0 }, /* IEEE80211_MODE_11A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, 4, 10, 0, 0 }, /* IEEE80211_MODE_11B */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, 4, 10, 0, 0 }, /* IEEE80211_MODE_11G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, 4, 10, 0, 0 }, /* IEEE80211_MODE_FH */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 3, 10, 0, 0 }, /* IEEE80211_MODE_TURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 3, 10, 0, 0 }, /* IEEE80211_MODE_TURBO_G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 3, 10, 0, 0 }, /* IEEE80211_MODE_STURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, 4, 10, 0, 0 }, /* IEEE80211_MODE_11NA */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 3, 4, 10, 0, 0 }, /* IEEE80211_MODE_11NG */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang};
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangstatic const struct phyParamType bssPhyParamForAC_VI[IEEE80211_MODE_MAX] = {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 3, 4, 94, 0 }, /* IEEE80211_MODE_AUTO */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 3, 4, 94, 0 }, /* IEEE80211_MODE_11A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 3, 4, 188, 0 }, /* IEEE80211_MODE_11B */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 3, 4, 94, 0 }, /* IEEE80211_MODE_11G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 3, 4, 188, 0 }, /* IEEE80211_MODE_FH */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 2, 3, 94, 0 }, /* IEEE80211_MODE_TURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 2, 3, 94, 0 }, /* IEEE80211_MODE_TURBO_G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 2, 3, 94, 0 }, /* IEEE80211_MODE_STURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 3, 4, 94, 0 }, /* IEEE80211_MODE_11NA */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 3, 4, 94, 0 }, /* IEEE80211_MODE_11NG */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang};
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangstatic const struct phyParamType bssPhyParamForAC_VO[IEEE80211_MODE_MAX] = {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 2, 3, 47, 0 }, /* IEEE80211_MODE_AUTO */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 2, 3, 47, 0 }, /* IEEE80211_MODE_11A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 2, 3, 102, 0 }, /* IEEE80211_MODE_11B */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 2, 3, 47, 0 }, /* IEEE80211_MODE_11G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 2, 3, 102, 0 }, /* IEEE80211_MODE_FH */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 2, 47, 0 }, /* IEEE80211_MODE_TURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 2, 47, 0 }, /* IEEE80211_MODE_TURBO_G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 2, 2, 47, 0 }, /* IEEE80211_MODE_STURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 2, 3, 47, 0 }, /* IEEE80211_MODE_11NA */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 2, 3, 47, 0 }, /* IEEE80211_MODE_11NG */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang};
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangvoid
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangieee80211_wme_initparams(struct ieee80211com *ic)
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang{
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang struct ieee80211_wme_state *wme = &ic->ic_wme;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang const paramType *pPhyParam, *pBssPhyParam;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang struct wmeParams *wmep;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang enum ieee80211_phymode mode;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang int i;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang if ((ic->ic_caps & IEEE80211_C_WME) == 0)
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang return;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang /*
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * Select mode; we can be called early in which case we
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * always use auto mode. We know we'll be called when
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * entering the RUN state with bsschan setup properly
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * so state will eventually get set correctly
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang if (ic->ic_curchan != IEEE80211_CHAN_ANYC)
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang mode = ieee80211_chan2mode(ic, ic->ic_curchan);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang else
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang mode = IEEE80211_MODE_AUTO;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang for (i = 0; i < WME_NUM_AC; i++) {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang switch (i) {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang case WME_AC_BK:
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang pPhyParam = &phyParamForAC_BK[mode];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang pBssPhyParam = &phyParamForAC_BK[mode];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang break;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang case WME_AC_VI:
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang pPhyParam = &phyParamForAC_VI[mode];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang pBssPhyParam = &bssPhyParamForAC_VI[mode];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang break;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang case WME_AC_VO:
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang pPhyParam = &phyParamForAC_VO[mode];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang pBssPhyParam = &bssPhyParamForAC_VO[mode];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang break;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang case WME_AC_BE:
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang default:
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang pPhyParam = &phyParamForAC_BE[mode];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang pBssPhyParam = &bssPhyParamForAC_BE[mode];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang break;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang }
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep = &wme->wme_wmeChanParams.cap_wmeParams[i];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_acm = pPhyParam->acm;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_aifsn = pPhyParam->aifsn;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_logcwmin = pPhyParam->logcwmin;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_logcwmax = pPhyParam->logcwmax;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_txopLimit = pPhyParam->txopLimit;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang } else {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_acm = pBssPhyParam->acm;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_aifsn = pBssPhyParam->aifsn;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_logcwmin = pBssPhyParam->logcwmin;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_logcwmax = pBssPhyParam->logcwmax;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_txopLimit = pBssPhyParam->txopLimit;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang }
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ieee80211_dbg(IEEE80211_MSG_WME, "ieee80211_wme_initparams: "
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang "%s chan [acm %u aifsn %u log2(cwmin) %u "
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang "log2(cwmax) %u txpoLimit %u]\n",
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ieee80211_wme_acnames[i],
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_acm,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_aifsn,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_logcwmin,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_logcwmax,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_txopLimit);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[i];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_acm = pBssPhyParam->acm;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_aifsn = pBssPhyParam->aifsn;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_logcwmin = pBssPhyParam->logcwmin;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_logcwmax = pBssPhyParam->logcwmax;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_txopLimit = pBssPhyParam->txopLimit;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ieee80211_dbg(IEEE80211_MSG_WME, "ieee80211_wme_initparams: "
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang "%s bss [acm %u aifsn %u log2(cwmin) %u "
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang "log2(cwmax) %u txpoLimit %u]\n",
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ieee80211_wme_acnames[i],
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_acm,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_aifsn,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_logcwmin,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_logcwmax,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep->wmep_txopLimit);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang }
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang /* NB: check ic_bss to avoid NULL deref on initial attach */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang if (ic->ic_bss != NULL) {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang /*
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * Calculate agressive mode switching threshold based
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * on beacon interval. This doesn't need locking since
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * we're only called before entering the RUN state at
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * which point we start sending beacon frames.
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wme->wme_hipri_switch_thresh =
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang (HIGH_PRI_SWITCH_THRESH * ic->ic_bss->in_intval) / 100;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ieee80211_wme_updateparams(ic);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang }
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang}
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang/*
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * Update WME parameters for ourself and the BSS.
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangvoid
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fangieee80211_wme_updateparams(struct ieee80211com *ic)
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang{
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang static const paramType phyParam[IEEE80211_MODE_MAX] = {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 4, 10, 64, 0 }, /* IEEE80211_MODE_AUTO */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 4, 10, 64, 0 }, /* IEEE80211_MODE_11A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 5, 10, 64, 0 }, /* IEEE80211_MODE_11B */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 4, 10, 64, 0 }, /* IEEE80211_MODE_11G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 5, 10, 64, 0 }, /* IEEE80211_MODE_FH */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 3, 10, 64, 0 }, /* IEEE80211_MODE_TURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 3, 10, 64, 0 }, /* IEEE80211_MODE_TURBO_G */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 1, 3, 10, 64, 0 }, /* IEEE80211_MODE_STURBO_A */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 4, 10, 64, 0 }, /* IEEE80211_MODE_11NA */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang { 2, 4, 10, 64, 0 }, /* IEEE80211_MODE_11NG */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang };
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang struct ieee80211_wme_state *wme = &ic->ic_wme;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang const struct wmeParams *wmep;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang struct wmeParams *chanp, *bssp;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang enum ieee80211_phymode mode;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang int i;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang if ((ic->ic_caps & IEEE80211_C_WME) == 0)
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang return;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang /* set up the channel access parameters for the physical device */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang for (i = 0; i < WME_NUM_AC; i++) {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp = &wme->wme_chanParams.cap_wmeParams[i];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep = &wme->wme_wmeChanParams.cap_wmeParams[i];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_aifsn = wmep->wmep_aifsn;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_logcwmin = wmep->wmep_logcwmin;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_logcwmax = wmep->wmep_logcwmax;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_txopLimit = wmep->wmep_txopLimit;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp = &wme->wme_bssChanParams.cap_wmeParams[i];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[i];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_aifsn = wmep->wmep_aifsn;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_logcwmin = wmep->wmep_logcwmin;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_logcwmax = wmep->wmep_logcwmax;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_txopLimit = wmep->wmep_txopLimit;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang }
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang /*
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * Select mode; we can be called early in which case we
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * always use auto mode. We know we'll be called when
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * entering the RUN state with bsschan setup properly
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * so state will eventually get set correctly
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang if (ic->ic_curchan != IEEE80211_CHAN_ANYC)
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang mode = ieee80211_chan2mode(ic, ic->ic_curchan);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang else
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang mode = IEEE80211_MODE_AUTO;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang /*
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * This implements agressive mode as found in certain
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * vendors' AP's. When there is significant high
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * priority (VI/VO) traffic in the BSS throttle back BE
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * traffic by using conservative parameters. Otherwise
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * BE uses agressive params to optimize performance of
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang * legacy/non-QoS traffic.
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang */
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang if ((ic->ic_opmode == IEEE80211_M_HOSTAP &&
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang (wme->wme_flags & WME_F_AGGRMODE) != 0) ||
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang (ic->ic_opmode == IEEE80211_M_STA &&
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang (ic->ic_bss->in_flags & IEEE80211_NODE_QOS) == 0) ||
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang (ic->ic_flags & IEEE80211_F_WME) == 0) {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp = &wme->wme_chanParams.cap_wmeParams[WME_AC_BE];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang bssp = &wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE];
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_aifsn = bssp->wmep_aifsn = phyParam[mode].aifsn;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_logcwmin = bssp->wmep_logcwmin =
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang phyParam[mode].logcwmin;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_logcwmax = bssp->wmep_logcwmax =
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang phyParam[mode].logcwmax;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_txopLimit = bssp->wmep_txopLimit =
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang (ic->ic_flags & IEEE80211_F_BURST) ?
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang phyParam[mode].txopLimit : 0;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ieee80211_dbg(IEEE80211_MSG_WME,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang "ieee80211_wme_updateparams_locked: "
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang "%s [acm %u aifsn %u log2(cwmin) %u "
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang "log2(cwmax) %u txpoLimit %u]\n",
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ieee80211_wme_acnames[WME_AC_BE],
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_acm,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_aifsn,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_logcwmin,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_logcwmax,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang chanp->wmep_txopLimit);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang }
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wme->wme_update(ic);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ieee80211_dbg(IEEE80211_MSG_WME, "ieee80211_wme_updateparams(): "
034536e9c476303015b9836aca06e46531705f2aHans Rosenfeld "WME params updated, cap_info 0x%x\n",
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang ic->ic_opmode == IEEE80211_M_STA ?
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wme->wme_wmeChanParams.cap_info :
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wme->wme_bssChanParams.cap_info);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang}
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc/*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Process STA mode beacon miss events. Send a direct probe request
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * frame to the current ap bmiss_max times (w/o answer) before
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * scanning for a new ap.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcvoid
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_beacon_miss(ieee80211com_t *ic)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc{
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_impl_t *im = ic->ic_private;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (ic->ic_flags & IEEE80211_F_SCAN)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_dbg(IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China "%s\n", "beacon miss");
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Our handling is only meaningful for stations that are
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * associated; any other conditions else will be handled
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * through different means (e.g. the tx timeout on mgt frames).
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (ic->ic_opmode != IEEE80211_M_STA ||
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_state != IEEE80211_S_RUN) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_LOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (++im->im_bmiss_count < im->im_bmiss_max) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Send a directed probe req before falling back to a scan;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * if we receive a response ic_bmiss_count will be reset.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Some cards mistakenly report beacon miss so this avoids
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * the expensive scan if the ap is still there.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_UNLOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) ieee80211_send_probereq(ic->ic_bss, ic->ic_macaddr,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ic->ic_bss->in_bssid, ic->ic_bss->in_bssid,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ic->ic_bss->in_essid, ic->ic_bss->in_esslen,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ic->ic_opt_ie, ic->ic_opt_ie_len);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc im->im_bmiss_count = 0;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_UNLOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc}
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc/*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Manage state transition between INIT | AUTH | ASSOC | RUN.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcstatic int
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxcieee80211_newstate(ieee80211com_t *ic, enum ieee80211_state nstate, int arg)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc{
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc struct ieee80211_impl *im = ic->ic_private;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_node_t *in;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc enum ieee80211_state ostate;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc wifi_data_t wd = { 0 };
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_LOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ostate = ic->ic_state;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_dbg(IEEE80211_MSG_STATE, "ieee80211_newstate(): "
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China "%s -> %s\n",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_state_name[ostate], ieee80211_state_name[nstate]);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_state = nstate;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc in = ic->ic_bss;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc im->im_swbmiss_period = 0; /* Reset software beacon miss period */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (nstate) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_INIT:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_UNLOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (ostate) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_INIT:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return (0);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_SCAN:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_cancel_scan(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_AUTH:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_ASSOC:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (ic->ic_opmode == IEEE80211_M_STA) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_SEND_MGMT(ic, in,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China IEEE80211_FC0_SUBTYPE_DEAUTH,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China IEEE80211_REASON_AUTH_LEAVE);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_RUN:
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China switch (ic->ic_opmode) {
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China case IEEE80211_M_STA:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_SEND_MGMT(ic, in,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang IEEE80211_FC0_SUBTYPE_DEAUTH,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang IEEE80211_REASON_AUTH_LEAVE);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_sta_leave(ic, in);
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China break;
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China case IEEE80211_M_IBSS:
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_notify_node_leave(ic, in);
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China break;
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China default:
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_LOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc im->im_mgt_timer = 0;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_reset_bss(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_SCAN:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (ostate) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_INIT:
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China IEEE80211_UNLOCK(ic);
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_begin_scan(ic, (arg == 0) ? B_FALSE : B_TRUE);
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China return (0);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_SCAN:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Scan next. If doing an active scan and the
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * channel is not marked passive-only then send
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * a probe request. Otherwise just listen for
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * beacons on the channel.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if ((ic->ic_flags & IEEE80211_F_ASCAN) &&
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc !IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan)) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_UNLOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) ieee80211_send_probereq(in,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ic->ic_macaddr, wifi_bcastaddr,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China wifi_bcastaddr,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ic->ic_des_essid, ic->ic_des_esslen,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ic->ic_opt_ie, ic->ic_opt_ie_len);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return (0);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_RUN:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* beacon miss */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_dbg(IEEE80211_MSG_STATE,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China "no recent beacons from %s, rescanning\n",
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_macaddr_sprintf(in->in_macaddr));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_UNLOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_sta_leave(ic, in);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_LOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_flags &= ~IEEE80211_F_SIBSS;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* FALLTHRU */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_AUTH:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_ASSOC:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* timeout restart scan */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc in = ieee80211_find_node(&ic->ic_scan,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ic->ic_bss->in_macaddr);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (in != NULL) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc in->in_fails++;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_unref_node(&in);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_AUTH:
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ASSERT(ic->ic_opmode == IEEE80211_M_STA);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (ostate) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_INIT:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_SCAN:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_UNLOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_SEND_MGMT(ic, in, IEEE80211_FC0_SUBTYPE_AUTH,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China 1);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return (0);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_AUTH:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_ASSOC:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (arg) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_FC0_SUBTYPE_AUTH:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_UNLOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_SEND_MGMT(ic, in,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China IEEE80211_FC0_SUBTYPE_AUTH, 2);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return (0);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_FC0_SUBTYPE_DEAUTH:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* ignore and retry scan on timeout */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_RUN:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (arg) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_FC0_SUBTYPE_AUTH:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_state = ostate; /* stay RUN */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_UNLOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_SEND_MGMT(ic, in,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China IEEE80211_FC0_SUBTYPE_AUTH, 2);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return (0);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_FC0_SUBTYPE_DEAUTH:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_UNLOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_sta_leave(ic, in);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /* try to re-auth */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_SEND_MGMT(ic, in,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China IEEE80211_FC0_SUBTYPE_AUTH, 1);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return (0);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_ASSOC:
034536e9c476303015b9836aca06e46531705f2aHans Rosenfeld ASSERT(ic->ic_opmode == IEEE80211_M_STA ||
034536e9c476303015b9836aca06e46531705f2aHans Rosenfeld ic->ic_opmode == IEEE80211_M_IBSS);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (ostate) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_INIT:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_SCAN:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_ASSOC:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_dbg(IEEE80211_MSG_ANY, "ieee80211_newstate: "
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China "invalid transition\n");
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_AUTH:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_UNLOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_SEND_MGMT(ic, in,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return (0);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_RUN:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_UNLOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_sta_leave(ic, in);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_SEND_MGMT(ic, in,
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 1);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return (0);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_RUN:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc switch (ostate) {
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_INIT:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_err("ieee80211_newstate: "
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China "invalid transition\n");
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_AUTH:
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_err("ieee80211_newstate: "
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China "invalid transition\n");
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_SCAN: /* adhoc/hostap mode */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc case IEEE80211_S_ASSOC: /* infra mode */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ASSERT(in->in_txrate < in->in_rates.ir_nrates);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc im->im_mgt_timer = 0;
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China ieee80211_notify_node_join(ic, in);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * We can send data now; update the fastpath with our
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * current associated BSSID and other relevant settings.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc wd.wd_secalloc = ieee80211_crypto_getciphertype(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc wd.wd_opmode = ic->ic_opmode;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_ADDR_COPY(wd.wd_bssid, in->in_bssid);
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wd.wd_qospad = 0;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang if (in->in_flags &
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang (IEEE80211_NODE_QOS|IEEE80211_NODE_HT)) {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wd.wd_qospad = 2;
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang if (ic->ic_flags & IEEE80211_F_DATAPAD) {
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang wd.wd_qospad = roundup(wd.wd_qospad,
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang sizeof (uint32_t));
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang }
e2cf88ac9d753a00c17aa235f6afdc76574fe3a6Quaker Fang }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc (void) mac_pdata_update(ic->ic_mach, &wd, sizeof (wd));
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc }
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * When 802.1x is not in use mark the port authorized
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * at this point so traffic can flow.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc if (in->in_authmode != IEEE80211_AUTH_8021X)
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ieee80211_node_authorize(in);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc /*
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc * Enable inactivity processing.
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_scan.nt_inact_timer = IEEE80211_INACT_WAIT;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc ic->ic_sta.nt_inact_timer = IEEE80211_INACT_WAIT;
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc break; /* IEEE80211_S_RUN */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc } /* switch nstate */
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc IEEE80211_UNLOCK(ic);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc return (0);
0ba2cbe97e0678a691742f98d2532caed0a2c4aaxc}