Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Sep 2011 10:15:28 +0530
From:      Himali <himali.patel@sibridgetech.com>
To:        freebsd-wireless@freebsd.org
Subject:   11n DFS Channel selection Implementation
Message-ID:  <4E8154E8.5070807@sibridgetech.com>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------010507010909070700040401
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi,

      We have implemented the 11n DFS Channel selection ( making channel 
scan list according to HT mode) in FreeBSD. Please find the attached 
patch for the same.

        In this, we are making scan list for 11NA/NG mode also. So, 
channel marked with HT flags will also be included in scan list.
        Another things that we have done is putting Extension channel 
also in NOL list after radar detected on channel (required when we 
configured 11n mode).

       Test Procedure:
       (1) Creation and configuration of interface for 11n mode
            ifconfig -v wlan0 create wlandev ath0 wlanmode ap
            ifconfig -v wlan0 regdomain FCC3
            ifconfig -v wlan0 country US
            ifconfig wlan0 ht
            ifconfig wlan0 htcompat
            ifconfig wlan0 mode 11na
            ifconfig wlan0 up

       (2) By using command "sysctl net.wlan.0.radar=1" , we can 
generate radar interrupt and put the channel in NOL list. For 11n mode, 
this will put extension channel also in NOL list.
            For example, if radar detected on channel 153 (5765 MHz) 
then its extension channel 149 (5745 MHz) will also goes in NOL list and 
AP will not consider these two channel for next channel selection criteria.

Let us know in case of any queries regarding this.

Thanks and Regards,
Himali



--------------010507010909070700040401
Content-Type: text/x-patch;
 name="net80211_11nDFS.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="net80211_11nDFS.patch"

diff -Naur ../net80211/ieee80211.c net80211/ieee80211.c
--- ../net80211/ieee80211.c	2011-09-23 11:25:53.271558983 +0530
+++ net80211/ieee80211.c	2011-09-26 11:00:45.668417920 +0530
@@ -926,8 +926,8 @@
 	/* brute force search */
 	for (i = 0; i < ic->ic_nchans; i++) {
 		c = &ic->ic_channels[i];
-		if (c->ic_freq == freq &&
-		    (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags)
+		if(c->ic_freq == freq &&
+			((c->ic_flags & IEEE80211_CHAN_ALLTURBO)& flags) == flags)
 			return c;
 	}
 	return NULL;
diff -Naur ../net80211/ieee80211_dfs.c net80211/ieee80211_dfs.c
--- ../net80211/ieee80211_dfs.c	2011-09-23 11:25:53.584545819 +0530
+++ net80211/ieee80211_dfs.c	2011-09-26 11:00:45.662418172 +0530
@@ -275,6 +275,12 @@
 	 * indication is cleared.  Then kick the NOL processing
 	 * thread if not already running.
 	 */
+	if (IEEE80211_IS_CHAN_HT40(chan) && chan->ic_extieee == 0) {
+		chan->ic_extieee = ieee80211_mhz2ieee(chan->ic_freq +
+				(IEEE80211_IS_CHAN_HT40U(chan) ? 20 : -20),
+				chan->ic_flags);
+	}
+
 	now = ticks;
 	for (i = 0; i < ic->ic_nchans; i++) {
 		struct ieee80211_channel *c = &ic->ic_channels[i];
@@ -283,6 +289,12 @@
 			c->ic_state |= IEEE80211_CHANSTATE_RADAR;
 			dfs->nol_event[i] = now;
 		}
+		if(chan->ic_extieee && (c->ic_ieee == chan->ic_extieee)) {
+			c->ic_state &= ~IEEE80211_CHANSTATE_CACDONE;
+			c->ic_state |= IEEE80211_CHANSTATE_RADAR;
+			dfs->nol_event[i] = now;
+		}
+
 	}
 	ieee80211_notify_radar(ic, chan);
 	chan->ic_state |= IEEE80211_CHANSTATE_NORADAR;
@@ -343,11 +355,14 @@
 	struct ieee80211_channel *c;
 	int i, flags;
 	uint16_t v;
+	uint32_t ht40mask;
+
 
 	/*
 	 * Consult the scan cache first.
 	 */
 	flags = ic->ic_curchan->ic_flags & IEEE80211_CHAN_ALL;
+	ht40mask = (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_HT40);
 	/*
 	 * XXX if curchan is HT this will never find a channel
 	 * XXX 'cuz we scan only legacy channels
@@ -356,6 +371,15 @@
 	if (c != NULL)
 		return c;
 	/*
+		Try to get legacy 11a channel if failed to get 11a ht40 channel.
+	*/
+	if((c == NULL ) && ((flags & ht40mask) == ht40mask)) {
+		c = ieee80211_scan_pickchannel(ic, flags & (~IEEE80211_CHAN_HT40) );
+		if (c != NULL)
+			return c;
+	}
+
+	/*
 	 * No channel found in scan cache; select a compatible
 	 * one at random (skipping channels where radar has
 	 * been detected).
diff -Naur ../net80211/_ieee80211.h net80211/_ieee80211.h
--- ../net80211/_ieee80211.h	2011-09-23 11:25:53.881533329 +0530
+++ net80211/_ieee80211.h	2011-09-26 11:00:45.668417920 +0530
@@ -71,6 +71,13 @@
 };
 #define	IEEE80211_MODE_MAX	(IEEE80211_MODE_QUARTER+1)
 
+enum ieee80211_htmode {
+	IEEE80211_MODE_11NA_HT20 = IEEE80211_MODE_MAX,
+	IEEE80211_MODE_11NA_HT40,
+	IEEE80211_MODE_11NG_HT20,
+	IEEE80211_MODE_11NG_HT40,
+};
+
 /*
  * Operating mode.  Devices do not necessarily support
  * all modes; they indicate which are supported in their
diff -Naur ../net80211/ieee80211_scan_sta.c net80211/ieee80211_scan_sta.c
--- ../net80211/ieee80211_scan_sta.c	2011-09-23 11:25:54.190520334 +0530
+++ net80211/ieee80211_scan_sta.c	2011-09-26 11:00:45.657418382 +0530
@@ -440,8 +440,8 @@
 	[IEEE80211_MODE_HALF]	  = IEEE80211_CHAN_HALF,
 	[IEEE80211_MODE_QUARTER]  = IEEE80211_CHAN_QUARTER,
 	/* check legacy */
-	[IEEE80211_MODE_11NA]	  = IEEE80211_CHAN_A,
-	[IEEE80211_MODE_11NG]	  = IEEE80211_CHAN_G,
+	[IEEE80211_MODE_11NA]	  = IEEE80211_CHAN_A | IEEE80211_CHAN_HT,
+	[IEEE80211_MODE_11NG]	  = IEEE80211_CHAN_G | IEEE80211_CHAN_HT,
 };
 
 static void
@@ -454,9 +454,33 @@
 	struct ieee80211_channel *c, *cg;
 	u_int modeflags;
 	int i;
+	u_int htmask;
+
+	switch(mode) {
+		case IEEE80211_MODE_11NG_HT20:
+			mode = IEEE80211_MODE_11NG;
+			htmask = ~IEEE80211_CHAN_HT40;
+			break;
+		case IEEE80211_MODE_11NG_HT40:
+			mode = IEEE80211_MODE_11NG;
+			htmask = ~IEEE80211_CHAN_HT20;
+			break;
+		case IEEE80211_MODE_11NA_HT20:
+			mode = IEEE80211_MODE_11NA;
+			htmask = ~IEEE80211_CHAN_HT40;
+			break;
+		case IEEE80211_MODE_11NA_HT40:
+			mode = IEEE80211_MODE_11NA;
+			htmask = ~IEEE80211_CHAN_HT20;
+			break;
+		default:
+			htmask = IEEE80211_CHAN_ALLTURBO;
+			break;
+	}
 
 	KASSERT(mode < N(chanflags), ("Unexpected mode %u", mode));
 	modeflags = chanflags[mode];
+	modeflags &= htmask;
 	for (i = 0; i < nfreq; i++) {
 		if (ss->ss_last >= IEEE80211_SCAN_MAX)
 			break;
@@ -528,7 +552,7 @@
 		 * for HT channels, they get scanned using
 		 * legacy rates.
 		 */
-		if (IEEE80211_IS_CHAN_DTURBO(c) || IEEE80211_IS_CHAN_HT(c))
+		if (IEEE80211_IS_CHAN_DTURBO(c))
 			continue;
 
 		/*
@@ -600,10 +624,27 @@
 				 * so if the desired mode is 11g, then use
 				 * the 11b channel list but upgrade the mode.
 				 */
-				if (vap->iv_des_mode != IEEE80211_MODE_11G ||
-				    mode != IEEE80211_MODE_11B)
+				switch(vap->iv_des_mode)
+				{
+					case IEEE80211_MODE_11G:
+						if (mode == IEEE80211_MODE_11B)
+							mode = IEEE80211_MODE_11G;
+						break;
+					case IEEE80211_MODE_11NA:
+						if (mode == IEEE80211_MODE_11A)
+							mode = IEEE80211_MODE_11NA;
+						break;
+					case IEEE80211_MODE_11NG:
+						if ((mode == IEEE80211_MODE_11G) ||
+								(mode == IEEE80211_MODE_11B))
+							mode = IEEE80211_MODE_11NG;
+						break;
+					default:
+						break;
+				}
+
+				if (vap->iv_des_mode != mode)
 					continue;
-				mode = IEEE80211_MODE_11G;	/* upgrade */
 			}
 		} else {
 			/*
@@ -625,7 +666,16 @@
 		 * Add the list of the channels; any that are not
 		 * in the master channel list will be discarded.
 		 */
-		add_channels(vap, ss, mode, scan->list, scan->count);
+		if(vap->iv_des_mode == IEEE80211_MODE_11NG) {
+			add_channels(vap, ss, IEEE80211_MODE_11NG_HT20, scan->list, scan->count);
+			add_channels(vap, ss, IEEE80211_MODE_11NG_HT40, scan->list, scan->count);
+		}
+		else if(vap->iv_des_mode == IEEE80211_MODE_11NA) {
+			add_channels(vap, ss, IEEE80211_MODE_11NA_HT20, scan->list, scan->count);
+			add_channels(vap, ss, IEEE80211_MODE_11NA_HT40, scan->list, scan->count);
+		}
+		else	
+			add_channels(vap, ss, mode, scan->list, scan->count);
 	}
 
 	/*

--------------010507010909070700040401--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4E8154E8.5070807>