PERFORCE change 118768 for review

Sam Leffler sam at FreeBSD.org
Wed Apr 25 04:20:03 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=118768

Change 118768 by sam at 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");
 


More information about the p4-projects mailing list