From patchwork Tue Dec 31 15:32:26 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Peer, Ilan" X-Patchwork-Id: 3421871 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4C6049F374 for ; Tue, 31 Dec 2013 15:31:02 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 67012200E0 for ; Tue, 31 Dec 2013 15:31:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 52A162011D for ; Tue, 31 Dec 2013 15:31:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753639Ab3LaPa5 (ORCPT ); Tue, 31 Dec 2013 10:30:57 -0500 Received: from mga02.intel.com ([134.134.136.20]:43410 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753547Ab3LaPa4 (ORCPT ); Tue, 31 Dec 2013 10:30:56 -0500 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 31 Dec 2013 07:30:55 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.95,581,1384329600"; d="scan'208";a="432235413" Received: from ipeer-e6430-1.jer.intel.com ([10.12.217.171]) by orsmga001.jf.intel.com with ESMTP; 31 Dec 2013 07:30:54 -0800 From: Ilan Peer To: linux-wireless@vger.kernel.org Cc: Ilan Peer Subject: [PATCH 2/2] [RFC] mac80211: Add all enabled channels to the supported channels element Date: Tue, 31 Dec 2013 17:32:26 +0200 Message-Id: <1388503946-25862-3-git-send-email-ilan.peer@intel.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1388503946-25862-1-git-send-email-ilan.peer@intel.com> References: <1388503946-25862-1-git-send-email-ilan.peer@intel.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In the current implementation, in case that the AP supports spectrum management, the supported channels information element added to the association and re-association frames includes only the channels that where in the same band as that of the operating channel of the AP. However, the 80211-2012 specification defines in 8.4.2.20 that the supported channels information element should contain a list of the channel subbands in which the station is capable to operate. Fix this gap by including all the channels enabled by the device (excluding channels that are marked as disabled). Signed-off-by: Ilan Peer --- net/mac80211/mlme.c | 80 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 10 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 9c2c7ee..04da17d 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -540,6 +540,70 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata, ieee80211_ie_build_vht_cap(pos, &vht_cap, cap); } +static void ieee80211_add_supported_channels(struct ieee80211_local *local, + struct sk_buff *skb, + unsigned int n_channels) +{ + struct ieee80211_supported_band *sband; + unsigned int i, j; + u8 *pos, *len_pos; + + if (!n_channels) + return; + + pos = skb_put(skb, 2); + *pos++ = WLAN_EID_SUPPORTED_CHANNELS; + len_pos = pos; + *len_pos = 0; + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) { + u8 chan, first_chan = 0, count = 0; + + sband = local->hw.wiphy->bands[i]; + if (!sband) + continue; + + for (j = 0; j < sband->n_channels; j++) { + u16 center_freq; + + if (sband->channels[j].flags & IEEE80211_CHAN_DISABLED) + continue; + + center_freq = sband->channels[j].center_freq; + chan = ieee80211_frequency_to_channel(center_freq); + + if (first_chan == 0) { + /* first subband */ + first_chan = chan; + count = 1; + } else if (first_chan + count == chan) { + /* continue the subband. + * TODO: this is really only useful for 2.4, + * need to add spacing considerations for other + * bands as well (the definition of a subband + * in the 802.11 spec. is a bit vague). + */ + count++; + } else { + /* store the subband and start a new one */ + pos = skb_put(skb, 2); + *pos++ = first_chan; + *pos = count; + *len_pos += 2; + first_chan = chan; + count = 1; + } + } + + if (first_chan) { + pos = skb_put(skb, 2); + *pos++ = first_chan; + *pos = count; + *len_pos += 2; + } + } +} + static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; @@ -555,6 +619,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) struct ieee80211_chanctx_conf *chanctx_conf; struct ieee80211_channel *chan; u32 rate_flags, rates = 0; + unsigned int n_channels; sdata_assert_lock(sdata); @@ -597,12 +662,15 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) } } + /* Get the number of enabled channels for spectrum management */ + n_channels = ieee80211_get_num_enabled_channels(local->hw.wiphy); + skb = alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + /* bit too much but doesn't matter */ 2 + assoc_data->ssid_len + /* SSID */ 4 + rates_len + /* (extended) rates */ 4 + /* power capability */ - 2 + 2 * sband->n_channels + /* supported channels */ + 2 + 2 * n_channels + /* supported channels */ 2 + sizeof(struct ieee80211_ht_cap) + /* HT */ 2 + sizeof(struct ieee80211_vht_cap) + /* VHT */ assoc_data->ie_len + /* extra IEs */ @@ -704,15 +772,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) *pos++ = ieee80211_chandef_max_power(&chanctx_conf->def); /* 2. supported channels */ - /* TODO: get this in reg domain format */ - pos = skb_put(skb, 2 * sband->n_channels + 2); - *pos++ = WLAN_EID_SUPPORTED_CHANNELS; - *pos++ = 2 * sband->n_channels; - for (i = 0; i < sband->n_channels; i++) { - *pos++ = ieee80211_frequency_to_channel( - sband->channels[i].center_freq); - *pos++ = 1; /* one channel in the subband*/ - } + ieee80211_add_supported_channels(local, skb, n_channels); } /* if present, add any custom IEs that go before HT */