From owner-p4-projects@FreeBSD.ORG Thu Aug 4 16:15:54 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 58BBA16A421; Thu, 4 Aug 2005 16:15:54 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 31C9216A41F for ; Thu, 4 Aug 2005 16:15:54 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id E1CD743D48 for ; Thu, 4 Aug 2005 16:15:53 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j74GFrhh096165 for ; Thu, 4 Aug 2005 16:15:53 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j74GFrGw096162 for perforce@freebsd.org; Thu, 4 Aug 2005 16:15:53 GMT (envelope-from sam@freebsd.org) Date: Thu, 4 Aug 2005 16:15:53 GMT Message-Id: <200508041615.j74GFrGw096162@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 81452 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Aug 2005 16:15:55 -0000 http://perforce.freebsd.org/chv.cgi?CH=81452 Change 81452 by sam@sam_ebb on 2005/08/04 16:15:47 revamp ath protocol handling to be like madwifi Affected files ... .. //depot/projects/wifi/sys/net80211/ieee80211.h#12 edit .. //depot/projects/wifi/sys/net80211/ieee80211_input.c#59 edit .. //depot/projects/wifi/sys/net80211/ieee80211_node.c#61 edit .. //depot/projects/wifi/sys/net80211/ieee80211_node.h#30 edit .. //depot/projects/wifi/sys/net80211/ieee80211_output.c#53 edit .. //depot/projects/wifi/sys/net80211/ieee80211_proto.c#34 edit .. //depot/projects/wifi/sys/net80211/ieee80211_proto.h#21 edit .. //depot/projects/wifi/sys/net80211/ieee80211_var.h#33 edit Differences ... ==== //depot/projects/wifi/sys/net80211/ieee80211.h#12 (text+ko) ==== @@ -445,7 +445,10 @@ #define ATHEROS_CAP_TURBO_PRIME 0x01 /* dynamic turbo--aka Turbo' */ #define ATHEROS_CAP_COMPRESSION 0x02 /* data compression */ #define ATHEROS_CAP_FAST_FRAME 0x04 /* fast (jumbo) frames */ -/* bits 3-6 reserved */ +#define ATHEROS_CAP_XR 0x08 /* Xtended Range support */ +#define ATHEROS_CAP_AR 0x10 /* Advanded Radar support */ +#define ATHEROS_CAP_BURST 0x20 /* Bursting - not negotiated */ +#define ATHEROS_CAP_WME 0x40 /* CWMin tuning */ #define ATHEROS_CAP_BOOST 0x80 /* use turbo/!turbo mode */ u_int8_t ath_defkeyix[2]; } __packed; ==== //depot/projects/wifi/sys/net80211/ieee80211_input.c#59 (text+ko) ==== @@ -479,7 +479,7 @@ IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len); #define FF_LLC_SIZE (sizeof(struct ether_header) + sizeof(struct llc)) - if ((ni->ni_flags & IEEE80211_NODE_FF) && + if ((ni->ni_ath_flags & IEEE80211_NODE_FF) && m->m_pkthdr.len >= 3*FF_LLC_SIZE) { struct llc *llc; @@ -1824,7 +1824,8 @@ struct ieee80211com *ic = ni->ni_ic; const struct ieee80211_ath_ie *ath; u_int len = frm[1]; - int caps; + int capschanged; + u_int16_t defkeyix; if (len < sizeof(struct ieee80211_ath_ie)-2) { IEEE80211_DISCARD_IE(ic, @@ -1833,22 +1834,44 @@ return -1; } ath = (const struct ieee80211_ath_ie *)frm; - caps = 0; - if ((ath->ath_capability & ATHEROS_CAP_TURBO_PRIME) && - (ic->ic_flags & IEEE80211_F_TURBOP)) - caps |= IEEE80211_NODE_TURBOP; - if ((ath->ath_capability & ATHEROS_CAP_FAST_FRAME) && - (ic->ic_flags & IEEE80211_F_FF)) - caps |= IEEE80211_NODE_FF; - if ((ni->ni_flags ^ caps) & IEEE80211_NODE_ATH) { + capschanged = (ni->ni_ath_flags != ath->ath_capability); + defkeyix = LE_READ_2(ath->ath_defkeyix); + if (capschanged || defkeyix != ni->ni_ath_defkeyix) { + ni->ni_ath_flags = ath->ath_capability; + ni->ni_ath_defkeyix = defkeyix; IEEE80211_DPRINTF(ic, IEEE80211_MSG_SUPERG, - "[%s] ath ie: caps 0x%x defkeyix 0x%x, use 0x%x\n", + "[%s] ath ie change: new caps 0x%x defkeyix 0x%x\n", ether_sprintf(ni->ni_macaddr), - ath->ath_capability, LE_READ_2(ath->ath_defkeyix), caps); - ni->ni_flags = (ni->ni_flags &~ IEEE80211_NODE_ATH) | caps; - return 1; - } else - return 0; /* NB: no change */ + ni->ni_ath_flags, ni->ni_ath_defkeyix); + } + if (IEEE80211_ATH_CAP(ic, ni, ATHEROS_CAP_TURBO_PRIME)) { + u_int16_t curflags, newflags; + + /* + * Check for turbo mode switch. Calculate flags + * for the new mode and effect the switch. + */ + newflags = curflags = ic->ic_bsschan->ic_flags; + /* NB: BOOST is not in ic_flags, so get it from the ie */ + if (ath->ath_capability & ATHEROS_CAP_BOOST) + newflags |= IEEE80211_CHAN_TURBO; + else + newflags &= ~IEEE80211_CHAN_TURBO; + if (newflags != curflags) + ieee80211_dturbo_switch(ic, newflags); + } + return capschanged; +} + +void +ieee80211_saveath(struct ieee80211_node *ni, u_int8_t *ie) +{ + const struct ieee80211_ath_ie *ath = + (const struct ieee80211_ath_ie *) ie; + + ni->ni_ath_flags = ath->ath_capability; + ni->ni_ath_defkeyix = LE_READ_2(&ath->ath_defkeyix); + ieee80211_saveie(&ni->ni_ath_ie, ie); } void @@ -1868,18 +1891,6 @@ /* XXX note failure */ } -void -ieee80211_saveath(struct ieee80211_node *ni, u_int8_t *ie) -{ -#if 0 - const struct ieee80211_ath_ie *ath = - (const struct ieee80211_ath_ie *) ie; - - ni->ni_ath_flags = ath->ath_capability; -#endif - ieee80211_saveie(&ni->ni_ath_ie, ie); -} - static __inline int contbgscan(struct ieee80211com *ic) { @@ -2245,10 +2256,6 @@ "[%s] recv probe req\n", ether_sprintf(wh->i_addr2)); ni->ni_rssi = rssi; ni->ni_rstamp = rstamp; - if (ath != NULL) { - ieee80211_saveie(&ni->ni_ath_ie, ath); - (void) ieee80211_parse_athparams(ni, ath, wh); - } rate = ieee80211_setup_rates(ni, rates, xrates, IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); @@ -2264,7 +2271,8 @@ if (allocbs && ic->ic_opmode != IEEE80211_M_IBSS) { /* reclaim immediately */ ieee80211_free_node(ni); - } + } else if (ath != NULL) + ieee80211_saveath(ni, ath); break; case IEEE80211_FC0_SUBTYPE_AUTH: { @@ -2543,15 +2551,14 @@ * record the information element for * applications that require it. */ - ieee80211_saveie(&ni->ni_ath_ie, ath); - (void) ieee80211_parse_athparams(ni, ath, wh); + ieee80211_saveath(ni, ath); } else if (ni->ni_ath_ie != NULL) { /* * Flush any state from a previous association. */ FREE(ni->ni_ath_ie, M_DEVBUF); ni->ni_ath_ie = NULL; - ni->ni_flags &= ~IEEE80211_NODE_ATH; + ni->ni_ath_flags = 0; } ieee80211_node_join(ic, ni, resp); break; @@ -2672,8 +2679,10 @@ ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long", ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "", ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "", - ni->ni_flags & IEEE80211_NODE_FF ? ", fast-frames" : "", - ni->ni_flags & IEEE80211_NODE_TURBOP ? ", turbo'" : "" + IEEE80211_ATH_CAP(ic, ni, IEEE80211_NODE_FF) ? + ", fast-frames" : "", + IEEE80211_ATH_CAP(ic, ni, IEEE80211_NODE_TURBOP) ? + ", turbo" : "" ); ieee80211_new_state(ic, IEEE80211_S_RUN, subtype); break; ==== //depot/projects/wifi/sys/net80211/ieee80211_node.c#61 (text+ko) ==== @@ -727,6 +727,7 @@ ieee80211_crypto_resetkey(ic, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE); ni->ni_inact_reload = nt->nt_inact_init; ni->ni_inact = ni->ni_inact_reload; + ni->ni_ath_defkeyix = 0x7fff; IEEE80211_NODE_SAVEQ_INIT(ni, "unknown"); IEEE80211_NODE_LOCK(nt); @@ -1552,8 +1553,10 @@ ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long", ic->ic_flags & IEEE80211_F_USEPROT ? ", protection" : "", ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "", - ni->ni_flags & IEEE80211_NODE_FF ? ", fast-frames" : "", - ni->ni_flags & IEEE80211_NODE_TURBOP ? ", turbo'" : "" + IEEE80211_ATH_CAP(ic, ni, IEEE80211_NODE_FF) ? + ", fast-frames" : "", + IEEE80211_ATH_CAP(ic, ni, IEEE80211_NODE_TURBOP) ? + ", turbo" : "" ); /* give driver a chance to setup state like ni_txrate */ ==== //depot/projects/wifi/sys/net80211/ieee80211_node.h#30 (text+ko) ==== @@ -94,6 +94,15 @@ u_int ni_refcnt; u_int ni_scangen; /* gen# for timeout scan */ u_int8_t ni_authmode; /* authentication algorithm */ + u_int8_t ni_ath_flags; /* Atheros feature flags */ + /* NB: These must have the same values as IEEE80211_ATHC_* */ +#define IEEE80211_NODE_TURBOP 0x0001 /* Turbo prime enable */ +#define IEEE80211_NODE_COMP 0x0002 /* Compresssion enable */ +#define IEEE80211_NODE_FF 0x0004 /* Fast Frame capable */ +#define IEEE80211_NODE_XR 0x0008 /* Atheros WME enable */ +#define IEEE80211_NODE_AR 0x0010 /* AR capable */ +#define IEEE80211_NODE_BOOST 0x0080 +#define IEEE80211_NODE_PS_CHANGED 0x0200 /* PS state change */ u_int16_t ni_flags; /* special-purpose state */ #define IEEE80211_NODE_AUTH 0x0001 /* authorized for data */ #define IEEE80211_NODE_QOS 0x0002 /* QoS enabled */ @@ -101,8 +110,7 @@ /* NB: this must have the same value as IEEE80211_FC1_PWR_MGT */ #define IEEE80211_NODE_PWR_MGT 0x0010 /* power save mode enabled */ #define IEEE80211_NODE_AREF 0x0020 /* authentication ref held */ -#define IEEE80211_NODE_FF 0x0040 /* Atheros fast-frames enabled*/ -#define IEEE80211_NODE_TURBOP 0x0080 /* Atheros Turbo' enabled */ + u_int16_t ni_ath_defkeyix;/* Atheros def key index */ u_int16_t ni_associd; /* assoc response */ u_int16_t ni_txpower; /* current transmit power */ u_int16_t ni_vlan; /* vlan tag */ ==== //depot/projects/wifi/sys/net80211/ieee80211_output.c#53 (text+ko) ==== @@ -1252,7 +1252,7 @@ * Add a WME information element to a frame. */ static u_int8_t * -ieee80211_add_ath(u_int8_t *frm, struct ieee80211_node *ni) +ieee80211_add_ath(u_int8_t *frm, u_int8_t caps, u_int16_t defkeyix) { static const struct ieee80211_ath_ie info = { .ath_id = IEEE80211_ELEMID_VENDOR, @@ -1261,15 +1261,13 @@ .ath_oui_type = ATH_OUI_TYPE, .ath_oui_subtype= ATH_OUI_SUBTYPE, .ath_version = ATH_OUI_VERSION, - .ath_defkeyix = { 0x7f, 0xff, }, }; struct ieee80211_ath_ie *ath = (struct ieee80211_ath_ie *) frm; memcpy(frm, &info, sizeof(info)); - if (ni->ni_flags & IEEE80211_NODE_FF) - ath->ath_capability |= ATHEROS_CAP_FAST_FRAME; - if (ni->ni_flags & IEEE80211_NODE_TURBOP) - ath->ath_capability |= ATHEROS_CAP_TURBO_PRIME; + ath->ath_capability = caps; + ath->ath_defkeyix[0] = (defkeyix & 0xff); + ath->ath_defkeyix[1] = ((defkeyix >> 8) & 0xff); return frm + sizeof(info); } #undef ATH_OUI_BYTES @@ -1476,7 +1474,8 @@ if (ic->ic_flags & IEEE80211_F_WME) frm = ieee80211_add_wme_param(frm, &ic->ic_wme); if (ni->ni_ath_ie != NULL) - frm = ieee80211_add_ath(frm, ni); + frm = ieee80211_add_ath(frm, ni->ni_ath_flags, + ni->ni_ath_defkeyix); m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *); break; @@ -1567,7 +1566,7 @@ * [tlv] supported rates * [tlv] extended supported rates * [tlv] WME - * [tlv] Atheros capabilities + * [tlv] Atheros capabilities (if negotiated) * [tlv] user-specified ie's */ m = ieee80211_getmgtframe(&frm, @@ -1617,8 +1616,13 @@ frm = ieee80211_add_xrates(frm, &ni->ni_rates); if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL) frm = ieee80211_add_wme_info(frm, &ic->ic_wme); - if (ni->ni_ath_ie != NULL) - frm = ieee80211_add_ath(frm, ni); + if (IEEE80211_ATH_CAP(ic, ni, IEEE80211_F_ATHEROS)) + frm = ieee80211_add_ath(frm, + IEEE80211_ATH_CAP(ic, ni, IEEE80211_F_ATHEROS), + (ic->ic_flags & IEEE80211_F_WPA) == 0 && + ni->ni_authmode != IEEE80211_AUTH_8021X && + ic->ic_def_txkey != IEEE80211_KEYIX_NONE ? + ic->ic_def_txkey : 0x7fff); if (ic->ic_opt_ie != NULL) { memcpy(frm, ic->ic_opt_ie, ic->ic_opt_ie_len); frm += ic->ic_opt_ie_len; @@ -1638,6 +1642,7 @@ * [tlv] supported rates * [tlv] extended supported rates * [tlv] WME (if enabled and STA enabled) + * [tlv] Atheros capabilities (if enabled and STA enabled) */ m = ieee80211_getmgtframe(&frm, sizeof(u_int16_t) @@ -1646,6 +1651,7 @@ + 2 + IEEE80211_RATE_SIZE + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) + sizeof(struct ieee80211_wme_param) + + sizeof(struct ieee80211_ath_ie) ); if (m == NULL) senderr(ENOMEM, is_tx_nobuf); @@ -1675,6 +1681,10 @@ frm = ieee80211_add_xrates(frm, &ni->ni_rates); if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL) frm = ieee80211_add_wme_param(frm, &ic->ic_wme); + if (IEEE80211_ATH_CAP(ic, ni, IEEE80211_F_ATHEROS)) + frm = ieee80211_add_ath(frm, + IEEE80211_ATH_CAP(ic, ni, IEEE80211_F_ATHEROS), + ni->ni_ath_defkeyix); m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *); break; ==== //depot/projects/wifi/sys/net80211/ieee80211_proto.c#34 (text+ko) ==== @@ -842,7 +842,39 @@ } } +/* + * Switch between turbo and non-turbo operating modes. + * Use the specified channel flags to locate the new + * channel, update 802.11 state, and then call back into + * the driver to effect the change. + */ void +ieee80211_dturbo_switch(struct ieee80211com *ic, int newflags) +{ + struct ieee80211_channel *chan; + + chan = ieee80211_find_channel(ic, ic->ic_bsschan->ic_freq, newflags); + if (chan == NULL) { /* XXX should not happen */ + IEEE80211_DPRINTF(ic, IEEE80211_MSG_SUPERG, + "%s: no channel with freq %u flags 0x%x\n", + __func__, ic->ic_bsschan->ic_freq, newflags); + return; + } + + IEEE80211_DPRINTF(ic, IEEE80211_MSG_SUPERG, + "%s: %s -> %s (freq %u flags 0x%x)\n", __func__, + ieee80211_phymode_name[ieee80211_chan2mode(ic->ic_bsschan)], + ieee80211_phymode_name[ieee80211_chan2mode(chan)], + chan->ic_freq, chan->ic_flags); + + ic->ic_bsschan = chan; + ic->ic_prevchan = ic->ic_curchan; + ic->ic_curchan = chan; + ic->ic_set_channel(ic); + /* NB: do not need to reset ERP state 'cuz we're in sta mode */ +} + +void ieee80211_beacon_miss(struct ieee80211com *ic) { @@ -850,8 +882,7 @@ /* XXX check ic_curchan != ic_bsschan? */ return; } - IEEE80211_DPRINTF(ic, - IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, + IEEE80211_DPRINTF(ic, IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, "%s\n", "beacon miss"); /* @@ -863,16 +894,14 @@ ic->ic_state != IEEE80211_S_RUN) return; if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) { -#ifdef ATH_SUPERG_DYNTURBO /* * If we receive a beacon miss interrupt when using * dynamic turbo, attempt to switch modes before * reassociating. */ - if (IEEE80211_ATH_CAP(ic, ic->ic_bss, IEEE80211_ATHC_TURBOP)) + if (IEEE80211_ATH_CAP(ic, ic->ic_bss, IEEE80211_NODE_TURBOP)) ieee80211_dturbo_switch(ic, ic->ic_bsschan->ic_flags ^ IEEE80211_CHAN_TURBO); -#endif /* ATH_SUPERG_DYNTURBO */ /* * Try to reassociate before scanning for a new ap. */ ==== //depot/projects/wifi/sys/net80211/ieee80211_proto.h#21 (text+ko) ==== @@ -214,6 +214,7 @@ #define ieee80211_new_state(_ic, _nstate, _arg) \ (((_ic)->ic_newstate)((_ic), (_nstate), (_arg))) +void ieee80211_dturbo_switch(struct ieee80211com *, int newflags); void ieee80211_beacon_miss(struct ieee80211com *); void ieee80211_print_essid(const u_int8_t *, int); void ieee80211_dump_pkt(struct ieee80211com *, ==== //depot/projects/wifi/sys/net80211/ieee80211_var.h#33 (text+ko) ==== @@ -248,8 +248,9 @@ /* ic_flags */ /* NB: bits 0x4c available */ -#define IEEE80211_F_FF 0x00000001 /* CONF: ATH FF enabled */ -#define IEEE80211_F_TURBOP 0x00000002 /* CONF: ATH Turbo enabled*/ +#define IEEE80211_F_TURBOP 0x00000001 /* CONF: ATH Turbo enabled*/ +#define IEEE80211_F_COMP 0x00000002 /* CONF: ATH comp enabled */ +#define IEEE80211_F_FF 0x00000004 /* CONF: ATH FF enabled */ /* NB: this is intentionally setup to be IEEE80211_CAPINFO_PRIVACY */ #define IEEE80211_F_PRIVACY 0x00000010 /* CONF: privacy enabled */ #define IEEE80211_F_PUREG 0x00000020 /* CONF: 11g w/o 11b sta's */ @@ -279,6 +280,13 @@ #define IEEE80211_F_NOBRIDGE 0x10000000 /* CONF: dis. internal bridge */ #define IEEE80211_F_WMEUPDATE 0x20000000 /* STATUS: update beacon wme */ +/* Atheros protocol-specific flags */ +#define IEEE80211_F_ATHEROS \ + (IEEE80211_F_FF | IEEE80211_F_COMP | IEEE80211_F_TURBOP) +/* Check if an Atheros capability was negotiated for use */ +#define IEEE80211_ATH_CAP(ic, ni, bit) \ + ((ic)->ic_flags & (ni)->ni_ath_flags & (bit)) + /* ic_flags_ext */ #define IEEE80211_FEXT_WDS 0x00000001 /* CONF: 4 addr allowed */ /* 0x00000006 reserved */