From owner-p4-projects@FreeBSD.ORG Fri Jan 30 22:07:00 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 800A516A4D0; Fri, 30 Jan 2004 22:07:00 -0800 (PST) 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 5969116A4CE for ; Fri, 30 Jan 2004 22:07:00 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4801B43D3F for ; Fri, 30 Jan 2004 22:06:57 -0800 (PST) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.10/8.12.10) with ESMTP id i0V66v0B006817 for ; Fri, 30 Jan 2004 22:06:57 -0800 (PST) (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.10/8.12.10/Submit) id i0V66ujq006814 for perforce@freebsd.org; Fri, 30 Jan 2004 22:06:56 -0800 (PST) (envelope-from sam@freebsd.org) Date: Fri, 30 Jan 2004 22:06:56 -0800 (PST) Message-Id: <200401310606.i0V66ujq006814@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 Subject: PERFORCE change 46243 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 31 Jan 2004 06:07:01 -0000 http://perforce.freebsd.org/chv.cgi?CH=46243 Change 46243 by sam@sam_ebb on 2004/01/30 22:06:28 Add 11g support based on ViVATO contribution: o correct basic rate set munging o handle short/long preamble more correctly o handle short/long slot time o implement 11g protection for AP (track long slot stations) o implement ERP for AP (track non-ERP stations) o honor ERP for station/IBSS operation o add ioctl to control 11g protection mode o revise beacon interface to support dynamic updates o add dynamic beacon update interface that handles capabilities changes (but not yet TIM) o shuffle some function decls from public ieee80211_var.h to private files Affected files ... .. //depot/projects/netperf+sockets/sys/net80211/ieee80211.c#8 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_input.c#11 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_ioctl.c#13 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_ioctl.h#6 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_node.c#6 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_node.h#6 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_output.c#10 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_proto.c#6 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_proto.h#5 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_var.h#8 edit Differences ... ==== //depot/projects/netperf+sockets/sys/net80211/ieee80211.c#8 (text+ko) ==== @@ -646,11 +646,13 @@ ieee80211_set11gbasicrates(struct ieee80211_rateset *rs, enum ieee80211_phymode mode) { static const struct ieee80211_rateset basic[] = { - { 3, { 12, 24, 48 } }, /* IEEE80211_MODE_11A */ - { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_11B */ - { 7, { 2, 4, 11, 22, 12, 24, 48 } },/* IEEE80211_MODE_11G */ - { 0 }, /* IEEE80211_MODE_FH */ - { 0 }, /* IEEE80211_MODE_TURBO */ + { 0 }, /* IEEE80211_MODE_AUTO */ + { 3, { 12, 24, 48 } }, /* IEEE80211_MODE_11A */ + { 2, { 2, 4 } }, /* IEEE80211_MODE_11B */ + { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_11G (mixed b/g) */ + { 0 }, /* IEEE80211_MODE_FH */ + /* IEEE80211_MODE_PUREG (not yet) */ + { 7, { 2, 4, 11, 22, 12, 24, 48 } }, }; int i, j; @@ -753,21 +755,21 @@ } /* - * Set/reset state flags that influence beacon contents, etc. - * - * XXX what if we have stations already associated??? - * XXX probably not right for autoselect? + * Do 11b/11g mixed-mode state setup. */ - if (ic->ic_caps & IEEE80211_C_SHPREAMBLE) - ic->ic_flags |= IEEE80211_F_SHPREAMBLE; if (mode == IEEE80211_MODE_11G) { - if (ic->ic_caps & IEEE80211_C_SHSLOT) - ic->ic_flags |= IEEE80211_F_SHSLOT; + /* use mixed 11b/11g rate set */ ieee80211_set11gbasicrates(&ic->ic_sup_rates[mode], IEEE80211_MODE_11G); + } else if (mode == IEEE80211_MODE_11B) { + /* force pure 11b rate set */ + ieee80211_set11gbasicrates(&ic->ic_sup_rates[mode], + IEEE80211_MODE_11B); + ic->ic_flags &= ~IEEE80211_F_SHSLOT; } else { ic->ic_flags &= ~IEEE80211_F_SHSLOT; } + ieee80211_reset_erp(ic, mode); /* reset ERP state */ /* * Setup an initial rate set according to the @@ -784,6 +786,29 @@ } /* + * Reset 11g-related state. + */ +void +ieee80211_reset_erp(struct ieee80211com *ic, enum ieee80211_phymode mode) +{ + ic->ic_flags &= ~IEEE80211_F_USEPROT; + ic->ic_nonerpsta = 0; + ic->ic_longslotsta = 0; + if (mode == IEEE80211_MODE_11G && (ic->ic_caps & IEEE80211_C_SHSLOT)) + ic->ic_flags &= ~IEEE80211_F_SHSLOT; + /* + * Set short preamble and ERP barker-preamble flags. + */ + if (ic->ic_caps & IEEE80211_C_SHPREAMBLE) { + ic->ic_flags |= IEEE80211_F_SHPREAMBLE; + ic->ic_flags &= ~IEEE80211_F_USEBARKER; + } else { + ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE; + ic->ic_flags |= IEEE80211_F_USEBARKER; + } +} + +/* * Return the phy mode for with the specified channel so the * caller can select a rate set. This is problematic and the * work here assumes how things work elsewhere in this code. ==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_input.c#11 (text+ko) ==== @@ -1220,7 +1220,15 @@ ni->ni_chan = &ic->ic_channels[chan]; ni->ni_fhdwell = fhdwell; ni->ni_fhindex = fhindex; - ni->ni_erp = erp; + /* + * Honor ERP: enable protection and/or disable + * the use of short slot time. + * XXX where do we reset this state? + */ + if (erp & IEEE80211_ERP_USE_PROTECTION) + ic->ic_flags |= IEEE80211_F_USEPROT; + if (erp & IEEE80211_ERP_LONG_PREAMBLE) + ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE; /* NB: must be after ni_chan is setup */ ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT); ieee80211_unref_node(&ni); @@ -1493,8 +1501,39 @@ } } else newassoc = 0; - /* XXX for 11g must turn off short slot time if long - slot time sta associates */ + /* + * Station isn't capable of short slot time. Bump + * the count of long slot time stations and disable + * use of short slot time. Note that the actual switch + * over to long slot time use will not occur until the + * next beacon transmission (per sec. 7.3.1.4 of 11g). + */ + if ((capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) { + ic->ic_longslotsta++; + ic->ic_flags &= ~IEEE80211_F_SHSLOT; + } + /* + * If the new station is not an ERP station + * then bump the counter and enable protection + * if configured. + */ + if (!ieee80211_iserp_rateset(ic, &ni->ni_rates)) { + ic->ic_nonerpsta++; + /* + * If protection is configured, enable it. + */ + if (ic->ic_protmode != IEEE80211_PROT_NONE) + ic->ic_flags |= IEEE80211_F_USEPROT; + /* + * If station does not support long preamble then + * we must enable use of Barker preamble. + */ + if ((capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) == 0) { + ic->ic_flags |= IEEE80211_F_USEBARKER; + ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE; + } + } else + ni->ni_flags |= IEEE80211_NODE_ERP; IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS); IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG, ("station %s %s associated at aid %d\n", @@ -1585,6 +1624,7 @@ ("station %s deauthenticated by " "peer (reason %d)\n", ether_sprintf(ni->ni_macaddr), reason)); + ieee80211_node_leave(ic, ni); /* node will be free'd on return */ ieee80211_unref_node(&ni); } @@ -1618,7 +1658,8 @@ IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap); ni->ni_associd = 0; - /* XXX node reclaimed how? */ + ieee80211_node_leave(ic, ni); + ieee80211_unref_node(&ni); /* XXX??? */ } break; default: ==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_ioctl.c#13 (text+ko) ==== @@ -897,6 +897,9 @@ case IEEE80211_IOC_RTSTHRESHOLD: ireq->i_val = ic->ic_rtsthreshold; break; + case IEEE80211_IOC_PROTECTION: + ireq->i_val = ic->ic_protmode; + break; default: error = EINVAL; } @@ -1048,6 +1051,15 @@ ic->ic_rtsthreshold = ireq->i_val; error = ieee80211_reset(ic); break; + case IEEE80211_IOC_PROTECTION: + if (!(IEEE80211_PROTECTION_OFF <= ireq->i_val && + ireq->i_val <= IEEE80211_PROTECTION_RTSCTS)) { + error = EINVAL; + break; + } + ic->ic_protmode = ireq->i_val; + error = ieee80211_reset(ic); /* ???XXX */ + break; default: error = EINVAL; break; ==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_ioctl.h#6 (text+ko) ==== @@ -161,6 +161,11 @@ #define IEEE80211_POWERSAVE_ON IEEE80211_POWERSAVE_CAM #define IEEE80211_IOC_POWERSAVESLEEP 11 #define IEEE80211_IOC_RTSTHRESHOLD 12 +#define IEEE80211_IOC_PROTECTION 13 +#define IEEE80211_PROTECTION_NOSUP -1 +#define IEEE80211_PROTECTION_OFF 0 +#define IEEE80211_PROTECTION_CTS 1 +#define IEEE80211_PROTECTION_RTSCTS 2 #ifndef IEEE80211_CHAN_ANY #define IEEE80211_CHAN_ANY 0xffff /* token for ``any channel'' */ ==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_node.c#6 (text+ko) ==== @@ -613,6 +613,7 @@ ("station %s timed out due to inactivity (%u secs)\n", ether_sprintf(ni->ni_macaddr), ni->ni_inact)); + ieee80211_node_leave(ic, ni); /* * Send a deauthenticate frame. * ==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_node.h#6 (text+ko) ==== @@ -72,6 +72,7 @@ #define IEEE80211_NODE_AUTH 0x0001 /* 802.1x auth complete */ #define IEEE80211_NODE_WPA 0x0002 /* WPA enabled */ #define IEEE80211_NODE_QOS 0x0004 /* QoS enabled */ +#define IEEE80211_NODE_ERP 0x0008 /* ERP enabled */ /* NB: this must have the same value as IEEE80211_FC1_PWR_MGT */ #define IEEE80211_NODE_PWR_MGT 0x0010 /* power save mode enabled */ u_int16_t ni_associd; /* assoc response */ @@ -102,7 +103,6 @@ struct ieee80211_channel *ni_chan; u_int16_t ni_fhdwell; /* FH only */ u_int8_t ni_fhindex; /* FH only */ - u_int8_t ni_erp; /* 11g only */ #ifdef notyet /* DTIM and contention free period (CFP) */ ==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_output.c#10 (text+ko) ==== @@ -304,6 +304,27 @@ } /* + * Add an erp element to a frame. + */ +static u_int8_t * +ieee80211_add_erp(u_int8_t *frm, struct ieee80211com *ic) +{ + u_int8_t erp; + + *frm++ = IEEE80211_ELEMID_ERP; + *frm++ = 1; + erp = 0; + if (ic->ic_nonerpsta != 0) + erp |= IEEE80211_ERP_NON_ERP_PRESENT; + if (ic->ic_flags & IEEE80211_F_USEPROT) + erp |= IEEE80211_ERP_USE_PROTECTION; + if (ic->ic_flags & IEEE80211_F_USEBARKER) + erp |= IEEE80211_ERP_LONG_PREAMBLE; + *frm++ = erp; + return frm; +} + +/* * Send a management frame. The node is for the destination (or ic_bss * when in station mode). Nodes other than ic_bss have their reference * count bumped to reflect our use for an indeterminant time. @@ -362,6 +383,7 @@ * [tlv] supported rates * [tlv] parameter set (FH/DS) * [tlv] parameter set (IBSS) + * [tlv] extended rate phy (ERP) * [tlv] extended supported rates */ m = ieee80211_getmgtframe(&frm, @@ -370,6 +392,7 @@ + 2 + IEEE80211_RATE_SIZE + (ic->ic_phytype == IEEE80211_T_FH ? 7 : 3) + 6 + + (ic->ic_curmode == IEEE80211_MODE_11G ? 3 : 0) + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)); if (m == NULL) senderr(ENOMEM, is_tx_nobuf); @@ -387,6 +410,8 @@ if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE; + if (ic->ic_flags & IEEE80211_F_SHSLOT) + capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME; *(u_int16_t *)frm = htole16(capinfo); frm += 2; @@ -414,15 +439,9 @@ *frm++ = IEEE80211_ELEMID_IBSSPARMS; *frm++ = 2; *frm++ = 0; *frm++ = 0; /* TODO: ATIM window */ - } else { /* IEEE80211_M_HOSTAP */ - /* TODO: TIM */ - *frm++ = IEEE80211_ELEMID_TIM; - *frm++ = 4; /* length */ - *frm++ = 0; /* DTIM count */ - *frm++ = 1; /* DTIM period */ - *frm++ = 0; /* bitmap control */ - *frm++ = 0; /* Partial Virtual Bitmap (variable length) */ } + if (ic->ic_curmode == IEEE80211_MODE_11G) + ieee80211_add_erp(frm, ic); frm = ieee80211_add_xrates(frm, &ic->ic_bss->ni_rates); m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *); break; @@ -613,13 +632,14 @@ * Allocate a beacon frame and fillin the appropriate bits. */ struct mbuf * -ieee80211_beacon_alloc(struct ieee80211com *ic, struct ieee80211_node *ni) +ieee80211_beacon_alloc(struct ieee80211com *ic, struct ieee80211_node *ni, + struct ieee80211_beacon_offsets *bo) { struct ifnet *ifp = ic->ic_ifp; struct ieee80211_frame *wh; struct mbuf *m; int pktlen; - u_int8_t *frm; + u_int8_t *frm, *efrm; u_int16_t capinfo; struct ieee80211_rateset *rs; @@ -632,6 +652,7 @@ * [tlv] supported rates * [3] parameter set (DS) * [tlv] parameter set (IBSS/TIM) + * [tlv] extended rate phy (ERP) * [tlv] extended supported rates * XXX WME, WPA, etc. * XXX Vendor-specific OIDs (e.g. Atheros) @@ -645,6 +666,8 @@ + 6; if (ic->ic_curmode != IEEE80211_MODE_FH) pktlen += 3; /* DS parameter set */ + if (ic->ic_curmode == IEEE80211_MODE_11G) + pktlen += 3; /* ERP information element */ if (rs->rs_nrates > IEEE80211_RATE_SIZE) pktlen += 2; /* extended rate set */ m = ieee80211_getmgtframe(&frm, pktlen); @@ -680,6 +703,7 @@ capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE; if (ic->ic_flags & IEEE80211_F_SHSLOT) capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME; + bo->bo_caps = (u_int16_t *)frm; *(u_int16_t *)frm = htole16(capinfo); frm += 2; *frm++ = IEEE80211_ELEMID_SSID; @@ -696,7 +720,10 @@ *frm++ = IEEE80211_ELEMID_IBSSPARMS; *frm++ = 2; *frm++ = 0; *frm++ = 0; /* TODO: ATIM window */ + bo->bo_dtim = NULL; + bo->bo_dtim_len = 0; } else { + bo->bo_dtim = frm; /* TODO: TIM */ *frm++ = IEEE80211_ELEMID_TIM; *frm++ = 4; /* length */ @@ -704,9 +731,14 @@ *frm++ = 1; /* DTIM period */ *frm++ = 0; /* bitmap control */ *frm++ = 0; /* Partial Virtual Bitmap (variable length) */ + bo->bo_dtim_len = 6; } - frm = ieee80211_add_xrates(frm, rs); - m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *); + if (ic->ic_curmode == IEEE80211_MODE_11G) + ieee80211_add_erp(frm, ic); + bo->bo_xrates = frm; + efrm = ieee80211_add_xrates(frm, rs); + bo->bo_xrates_len = efrm - frm; + m->m_pkthdr.len = m->m_len = efrm - mtod(m, u_int8_t *); KASSERT(m->m_pkthdr.len <= pktlen + sizeof(struct ieee80211_frame), ("beacon bigger than expected, len %u calculated %u", m->m_pkthdr.len, pktlen + sizeof(struct ieee80211_frame))); @@ -714,6 +746,45 @@ } /* + * Update the dynamic parts of a beacon frame based on the current state. + */ +int +ieee80211_beacon_update(struct ieee80211com *ic, struct ieee80211_node *ni, + struct ieee80211_beacon_offsets *bo, struct mbuf **m0) +{ + u_int16_t capinfo; + + /* XXX lock out changes */ + /* XXX only update as needed */ + /* XXX faster to recalculate entirely or just changes? */ + if (ic->ic_opmode == IEEE80211_M_IBSS) + capinfo = IEEE80211_CAPINFO_IBSS; + else + capinfo = IEEE80211_CAPINFO_ESS; + if (ic->ic_flags & IEEE80211_F_WEPON) + capinfo |= IEEE80211_CAPINFO_PRIVACY; + if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && + IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) + capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE; + if (ic->ic_flags & IEEE80211_F_SHSLOT) + capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME; + *bo->bo_caps = htole16(capinfo); + + if (ic->ic_flags & IEEE80211_F_DTIMUPDATE) { + /* + * DTIM needs updating. If it fits in the current + * space allocated then just copy in the new bits. + * Otherwise we need to move any extended rate set + * the follows and, possibly, allocate a new mbuf + * if the this current mbuf isn't large enough. + */ + /* XXX fillin */ + ic->ic_flags &= ~IEEE80211_F_DTIMUPDATE; + } + return 0; +} + +/* * Save an outbound packet for a node in power-save sleep state. * The new packet is placed on the node's saved queue, and the TIM * is changed, if necessary. ==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_proto.c#6 (text+ko) ==== @@ -305,6 +305,70 @@ #undef RV } +/* + * Check if the specified rate set supports ERP. + * NB: the rate set is assumed to be sorted. + */ +int +ieee80211_iserp_rateset(struct ieee80211com *ic, struct ieee80211_rateset *rs) +{ +#define N(a) (sizeof(a) / sizeof(a[0])) + static const int rates[] = { 2, 4, 11, 22, 12, 24, 48 }; + int i, j; + + if (rs->rs_nrates < N(rates)) + return 0; + for (i = 0; i < N(rates); i++) { + for (j = 0; j < rs->rs_nrates && rates[i] < rs->rs_rates[j]; j++) + ; + if (j == rs->rs_nrates || rates[i] > rs->rs_rates[j]) + return 0; + } + return 1; +#undef N +} + +/* + * Handle bookkeeping for station deauthentication/disassociation + * when operating as an ap. + */ +void +ieee80211_node_leave(struct ieee80211com *ic, struct ieee80211_node *ni) +{ + KASSERT(ic->ic_opmode == IEEE80211_M_HOSTAP, + ("not in ap mode, mode %u", ic->ic_opmode)); + + /* + * If a long slot station do the slot time bookkeeping. + */ + if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) { + KASSERT(ic->ic_longslotsta > 0, + ("bogus long slot station count %d", ic->ic_longslotsta)); + ic->ic_longslotsta--; + if (ic->ic_longslotsta == 0 && + ic->ic_curmode == IEEE80211_MODE_11G) { + /* XXX check capability */ + ic->ic_flags |= IEEE80211_F_SHSLOT; + } + } + /* + * If a non-ERP station do the protection-related bookkeeping. + */ + if ((ni->ni_flags & IEEE80211_NODE_ERP) == 0) { + KASSERT(ic->ic_nonerpsta > 0, + ("bogus non-ERP station count %d", ic->ic_nonerpsta)); + ic->ic_nonerpsta--; + if (ic->ic_nonerpsta == 0) { + ic->ic_flags &= ~IEEE80211_F_USEPROT; + /* XXX verify mode? */ + if (ic->ic_caps & IEEE80211_C_SHPREAMBLE) { + ic->ic_flags |= IEEE80211_F_SHPREAMBLE; + ic->ic_flags &= ~IEEE80211_F_USEBARKER; + } + } + } +} + static int ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int mgt) { @@ -359,6 +423,8 @@ IEEE80211_REASON_AUTH_LEAVE); } IEEE80211_NODE_UNLOCK(ic); + /* XXX??? */ + ieee80211_reset_erp(ic, ic->ic_curmode); break; default: break; ==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_proto.h#5 (text+ko) ==== @@ -63,16 +63,38 @@ struct ieee80211_node *, int, int, u_int32_t); extern int ieee80211_send_mgmt(struct ieee80211com *, struct ieee80211_node *, int, int); -extern struct mbuf * ieee80211_beacon_alloc(struct ieee80211com *, - struct ieee80211_node *); extern void ieee80211_pwrsave(struct ieee80211com *, struct ieee80211_node *, struct mbuf *); extern struct mbuf *ieee80211_encap(struct ieee80211com *, struct mbuf *, struct ieee80211_node **); +extern int ieee80211_fix_rate(struct ieee80211com *, + struct ieee80211_node *, int); +extern int ieee80211_iserp_rateset(struct ieee80211com *, + struct ieee80211_rateset *); +extern void ieee80211_node_leave(struct ieee80211com *, + struct ieee80211_node *); #define ieee80211_new_state(_ic, _nstate, _arg) \ (((_ic)->ic_newstate)((_ic), (_nstate), (_arg))) extern void ieee80211_print_essid(u_int8_t *, int); extern void ieee80211_dump_pkt(u_int8_t *, int, int, int); extern const char *ieee80211_state_name[IEEE80211_S_MAX]; + +/* + * Beacon frames constructed by ieee80211_beacon_alloc + * have the following structure filled in so drivers + * can update the frame later w/ minimal overhead. + */ +struct ieee80211_beacon_offsets { + u_int16_t *bo_caps; /* capabilities */ + u_int8_t *bo_dtim; /* start of dtim */ + u_int8_t *bo_xrates; /* start of extended rates */ + u_int16_t bo_dtim_len; /* dtim length in bytes */ + u_int16_t bo_xrates_len; /* xrates length in bytes */ +}; +extern struct mbuf * ieee80211_beacon_alloc(struct ieee80211com *, + struct ieee80211_node *, struct ieee80211_beacon_offsets *); +extern int ieee80211_beacon_update(struct ieee80211com *, + struct ieee80211_node *, struct ieee80211_beacon_offsets *, + struct mbuf **); #endif /* _NET80211_IEEE80211_PROTO_H_ */ ==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_var.h#8 (text+ko) ==== @@ -89,6 +89,15 @@ }; /* + * 802.11g protection mode. + */ +enum ieee80211_protmode { + IEEE80211_PROT_NONE = 0, /* no protection */ + IEEE80211_PROT_CTSONLY = 1, /* CTS to self */ + IEEE80211_PROT_RTSCTS = 2, /* RTS-CTS */ +}; + +/* * Channels are specified by frequency and attributes. */ struct ieee80211_channel { @@ -188,6 +197,7 @@ enum ieee80211_phytype ic_phytype; /* XXX wrong for multi-mode */ enum ieee80211_opmode ic_opmode; /* operation mode */ enum ieee80211_state ic_state; /* 802.11 state */ + enum ieee80211_protmode ic_protmode; /* 802.11g protection mode */ u_int32_t ic_aid_bitmap[IEEE80211_MAX_AID / 32 + 1]; u_int16_t ic_max_aid; struct ifmedia ic_media; /* interface media config */ @@ -217,6 +227,8 @@ u_int16_t ic_txpower; /* tx power setting (dbM) */ u_int16_t ic_bmisstimeout;/* beacon miss threshold (ms) */ u_int16_t ic_authmode; /* authentication mode */ + u_int16_t ic_nonerpsta; /* # non-ERP stations */ + u_int16_t ic_longslotsta; /* # long slot time stations */ int ic_mgt_timer; /* mgmt timeout */ int ic_inact_timer; /* inactivity timer wait */ int ic_des_esslen; @@ -249,6 +261,9 @@ #define IEEE80211_F_SHSLOT 0x00020000 /* CONF: short slot time */ #define IEEE80211_F_SHPREAMBLE 0x00040000 /* CONF: short preamble */ #define IEEE80211_F_DATAPAD 0x00080000 /* CONF: do alignment pad */ +#define IEEE80211_F_USEPROT 0x00100000 /* STATUS: protection enabled */ +#define IEEE80211_F_USEBARKER 0x00200000 /* STATUS: use barker preamble*/ +#define IEEE80211_F_DTIMUPDATE 0x00400000 /* STATUS: update beacon dtim */ /* ic_caps */ #define IEEE80211_C_WEP 0x00000001 /* CAPABILITY: WEP available */ @@ -262,6 +277,7 @@ #define IEEE80211_C_SHPREAMBLE 0x00000100 /* CAPABILITY: short preamble */ #define IEEE80211_C_MONITOR 0x00000200 /* CAPABILITY: monitor mode */ #define IEEE80211_C_RCVMGT 0x00000400 /* CAPABILITY: rcv mgt frames */ +/* XXX protection/barker? */ /* flags for ieee80211_fix_rate() */ #define IEEE80211_F_DOSORT 0x00000001 /* sort rate list */ @@ -279,7 +295,6 @@ int ieee80211_cfgget(struct ieee80211com *, u_long, caddr_t); int ieee80211_cfgset(struct ieee80211com *, u_long, caddr_t); void ieee80211_watchdog(struct ieee80211com *); -int ieee80211_fix_rate(struct ieee80211com *, struct ieee80211_node *, int); int ieee80211_rate2media(struct ieee80211com *, int, enum ieee80211_phymode); int ieee80211_media2rate(int); @@ -287,6 +302,7 @@ u_int ieee80211_chan2ieee(struct ieee80211com *, struct ieee80211_channel *); u_int ieee80211_ieee2mhz(u_int, u_int); int ieee80211_setmode(struct ieee80211com *, enum ieee80211_phymode); +void ieee80211_reset_erp(struct ieee80211com *, enum ieee80211_phymode); enum ieee80211_phymode ieee80211_chan2mode(struct ieee80211com *, struct ieee80211_channel *);