From owner-p4-projects@FreeBSD.ORG Wed Apr 25 04:20:03 2007 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 C3CA816A403; Wed, 25 Apr 2007 04:20:02 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 7A40F16A401 for ; Wed, 25 Apr 2007 04:20:02 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 5924013C45E for ; Wed, 25 Apr 2007 04:20:02 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l3P4K20L009502 for ; Wed, 25 Apr 2007 04:20:02 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l3P4K2Vr009498 for perforce@freebsd.org; Wed, 25 Apr 2007 04:20:02 GMT (envelope-from sam@freebsd.org) Date: Wed, 25 Apr 2007 04:20:02 GMT Message-Id: <200704250420.l3P4K2Vr009498@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 118768 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: Wed, 25 Apr 2007 04:20:03 -0000 http://perforce.freebsd.org/chv.cgi?CH=118768 Change 118768 by sam@sam_ebb on 2007/04/25 04:19:04 import bits of 11n work: o implement ht channel promotion o fix misc bugs in ht channel attribute parsing o identify associated stations using HT o add a "precise" parameter to get_chaninfo that causes it to identify a channel as one of "ht/20", "ht/40+", or "ht/40-"; if not given HT channels are lumped together as "ht" o always display the verbose+precise channel in status o display the imprecise channel for list chan o update man page to talk about specifying channels w/ attributes Affected files ... .. //depot/projects/wifi/sbin/ifconfig/ifconfig.8#23 edit .. //depot/projects/wifi/sbin/ifconfig/ifieee80211.c#65 edit Differences ... ==== //depot/projects/wifi/sbin/ifconfig/ifconfig.8#23 (text+ko) ==== @@ -663,6 +663,48 @@ adaptors ignore this setting unless you are in ad-hoc mode. Alternatively the frequency, in megahertz, may be specified instead of the channel number. +.Pp +When there are several ways to use a channel the channel +number/frequency may be appended with attributes to clarify. +For example, if a device is capable of operating on channel 6 +with 802.11n and 802.11g then one can specify that g-only use +should be used by specifying ``6:g''. +Similarly the channel width can be specified by appending it +with ``/''; e.g. ``6/40'' specifies a 40MHz wide channel, +These attributes can be combined as in: ``6:ht/40''. +The full set of flags specified following a `:'' are: +.Cm a +(802.11a), +.Cm b +(802.11b), +.Cm d +(Atheros Dynamic Turbo mode), +.Cm g +(802.11g), +.Cm h +or +.Cm n +(802.11n aka HT), +.Cm s +(Atheros Static Turbo mode), +and +.Cm t +(Atheros Dynamic Turbo mode, or appendeded to ``st'' and ``dt''). +The full set of channel widths following a '/' are: +.Cm 5 +(5MHz aka quarter-rate channel), +.Cm 10 +(10MHz aka half-rate channel), +.Cm 20 +(20MHz mostly for use in specifying ht20), +and +.Cm 40 +(40MHz mostly for use in specifying ht40), +In addition, +a 40MHz HT channel specification may include the location +of the extension channel by appending ``+'' or ``-'' for above and below, +respectively; e.g. ``2437:ht/40+'' specifies 40MHz wide HT operation +with the center channel at frequency 2437 and the extension channel above. .It Cm deftxkey Ar index Set the default key to use for transmission. Typically this is only set when using WEP encryption. ==== //depot/projects/wifi/sbin/ifconfig/ifieee80211.c#65 (text+ko) ==== @@ -103,13 +103,16 @@ #define IEEE80211_CHAN_HT40 (IEEE80211_CHAN_HT40U | IEEE80211_CHAN_HT40D) #define IEEE80211_CHAN_HT (IEEE80211_CHAN_HT20 | IEEE80211_CHAN_HT40) -#define IEEE80211_CHAN_HTA \ - (IEEE80211_CHAN_A | IEEE80211_CHAN_HT) -#define IEEE80211_CHAN_HTG \ - (IEEE80211_CHAN_G | IEEE80211_CHAN_HT) - #define IEEE80211_IS_CHAN_HT(_c) \ (((_c)->ic_flags & IEEE80211_CHAN_HT) != 0) +#define IEEE80211_IS_CHAN_HT20(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HT20) != 0) +#define IEEE80211_IS_CHAN_HT40(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HT40) != 0) +#define IEEE80211_IS_CHAN_HT40U(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HT40U) != 0) +#define IEEE80211_IS_CHAN_HT40D(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_HT40D) != 0) #endif static void set80211(int s, int type, int val, int len, void *data); @@ -156,20 +159,20 @@ int j; if ((fc->ic_flags & from) != from) - return 0; + return i; /* NB: quick check exploiting ordering of chans w/ same frequency */ if (i+1 < chaninfo.ic_nchans && chaninfo.ic_chans[i+1].ic_freq == fc->ic_freq && (chaninfo.ic_chans[i+1].ic_flags & to) == to) - return 1; + return i+1; /* brute force search in case channel list is not ordered */ for (j = 0; j < chaninfo.ic_nchans; j++) { const struct ieee80211_channel *tc = &chaninfo.ic_chans[j]; if (j != i && tc->ic_freq == fc->ic_freq && (tc->ic_flags & to) == to) - return 1; + return j; } - return 0; + return i; } /* @@ -203,15 +206,25 @@ int chanmode = ifmr != NULL ? IFM_MODE(ifmr->ifm_current) : IFM_AUTO; /* when ambiguous promote to ``best'' */ - if (chanmode != IFM_IEEE80211_11B && - canpromote(i, IEEE80211_CHAN_B, IEEE80211_CHAN_G)) - i++; - if (chanmode != IFM_IEEE80211_11G && - canpromote(i, IEEE80211_CHAN_G, IEEE80211_CHAN_HTG)) - i++; - if (chanmode != IFM_IEEE80211_11A && - canpromote(i, IEEE80211_CHAN_A, IEEE80211_CHAN_HTA)) - i++; + /* NB: we abitrarily pick HT40+ over HT40- */ + if (chanmode != IFM_IEEE80211_11B) + i = canpromote(i, IEEE80211_CHAN_B, IEEE80211_CHAN_G); + if (chanmode != IFM_IEEE80211_11G) { + i = canpromote(i, IEEE80211_CHAN_G, + IEEE80211_CHAN_G | IEEE80211_CHAN_HT20); + i = canpromote(i, IEEE80211_CHAN_G, + IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D); + i = canpromote(i, IEEE80211_CHAN_G, + IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U); + } + if (chanmode != IFM_IEEE80211_11A) { + i = canpromote(i, IEEE80211_CHAN_A, + IEEE80211_CHAN_A | IEEE80211_CHAN_HT20); + i = canpromote(i, IEEE80211_CHAN_A, + IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D); + i = canpromote(i, IEEE80211_CHAN_A, + IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U); + } return i; } @@ -320,6 +333,7 @@ static int getchannelflags(const char *val) { +#define CHAN_HT_DEFAULT IEEE80211_CHAN_HT40U #define _CHAN_HT 0x80000000 const char *cp; int flags; @@ -385,8 +399,8 @@ flags |= IEEE80211_CHAN_HT40U; else if (ep != NULL && *ep == '-') flags |= IEEE80211_CHAN_HT40D; - else - flags |= IEEE80211_CHAN_HT40; + else /* NB: pick something */ + flags |= CHAN_HT_DEFAULT; break; default: errx(-1, "%s: Invalid channel width\n", val); @@ -412,9 +426,10 @@ */ flags &= ~_CHAN_HT; if ((flags & IEEE80211_CHAN_HT) == 0) - flags |= IEEE80211_CHAN_HT; + flags |= CHAN_HT_DEFAULT; } return flags; +#undef CHAN_HT_DEFAULT #undef _CHAN_HT } @@ -1076,6 +1091,7 @@ #define IEEE80211_NODE_QOS 0x0002 /* QoS enabled */ #define IEEE80211_NODE_ERP 0x0004 /* ERP enabled */ #define IEEE80211_NODE_PWR_MGT 0x0010 /* power save mode enabled */ +#define IEEE80211_NODE_HT 0x0040 /* HT enabled */ static char flagstring[32]; char *cp = flagstring; @@ -1087,8 +1103,11 @@ *cp++ = 'E'; if (flags & IEEE80211_NODE_PWR_MGT) *cp++ = 'P'; + if (flags & IEEE80211_NODE_HT) + *cp++ = 'H'; *cp = '\0'; return flagstring; +#undef IEEE80211_NODE_HT #undef IEEE80211_NODE_AUTH #undef IEEE80211_NODE_QOS #undef IEEE80211_NODE_ERP @@ -1634,7 +1653,8 @@ } static const char * -get_chaninfo(const struct ieee80211_channel *c, char buf[], size_t bsize) +get_chaninfo(const struct ieee80211_channel *c, int precise, + char buf[], size_t bsize) { buf[0] = '\0'; if (IEEE80211_IS_CHAN_FHSS(c)) @@ -1658,8 +1678,17 @@ strlcat(buf, " 11b", bsize); if (IEEE80211_IS_CHAN_TURBO(c)) strlcat(buf, " Turbo", bsize); - if (IEEE80211_IS_CHAN_HT(c)) - strlcat(buf, " HT", bsize); + if (precise) { + if (IEEE80211_IS_CHAN_HT20(c)) + strlcat(buf, " ht/20", bsize); + else if (IEEE80211_IS_CHAN_HT40D(c)) + strlcat(buf, " ht/40-", bsize); + else if (IEEE80211_IS_CHAN_HT40U(c)) + strlcat(buf, " ht/40+", bsize); + } else { + if (IEEE80211_IS_CHAN_HT(c)) + strlcat(buf, " ht", bsize); + } return buf; } @@ -1671,7 +1700,7 @@ printf("Channel %3u : %u%c Mhz%-14.14s", ieee80211_mhz2ieee(c->ic_freq, c->ic_flags), c->ic_freq, IEEE80211_IS_CHAN_PASSIVE(c) ? '*' : ' ', - get_chaninfo(c, buf, sizeof(buf))); + get_chaninfo(c, verbose, buf, sizeof(buf))); } static void @@ -2189,12 +2218,9 @@ } c = &chan; if (c->ic_freq != IEEE80211_CHAN_ANY) { - printf(" channel %d", c->ic_ieee); - if (verbose) { - char buf[14]; - printf(" (%u Mhz%s)", c->ic_freq, - get_chaninfo(c, buf, sizeof(buf))); - } + char buf[14]; + printf(" channel %d (%u Mhz%s)", c->ic_ieee, c->ic_freq, + get_chaninfo(c, 1, buf, sizeof(buf))); } else if (verbose) printf(" channel UNDEF");