From owner-freebsd-wireless@FreeBSD.ORG Tue Sep 27 04:43:24 2011 Return-Path: Delivered-To: freebsd-wireless@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8434D106566B for ; Tue, 27 Sep 2011 04:43:24 +0000 (UTC) (envelope-from himali.patel@sibridgetech.com) Received: from mail-pz0-f44.google.com (mail-pz0-f44.google.com [209.85.210.44]) by mx1.freebsd.org (Postfix) with ESMTP id 5F8318FC16 for ; Tue, 27 Sep 2011 04:43:24 +0000 (UTC) Received: by pzk32 with SMTP id 32so29825233pzk.3 for ; Mon, 26 Sep 2011 21:43:24 -0700 (PDT) Received: by 10.68.30.97 with SMTP id r1mr34403140pbh.67.1317098604095; Mon, 26 Sep 2011 21:43:24 -0700 (PDT) Received: from himali.sibshivalik.com ([110.172.28.16]) by mx.google.com with ESMTPS id h5sm801738pbf.4.2011.09.26.21.43.22 (version=SSLv3 cipher=OTHER); Mon, 26 Sep 2011 21:43:23 -0700 (PDT) Message-ID: <4E8154E8.5070807@sibridgetech.com> Date: Tue, 27 Sep 2011 10:15:28 +0530 From: Himali User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc14 Thunderbird/3.1.10 MIME-Version: 1.0 To: freebsd-wireless@freebsd.org Content-Type: multipart/mixed; boundary="------------010507010909070700040401" Subject: 11n DFS Channel selection Implementation X-BeenThere: freebsd-wireless@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: himali.patel@sibridgetech.com List-Id: "Discussions of 802.11 stack, tools device driver development." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Sep 2011 04:43:24 -0000 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--