From patchwork Thu Jun 11 11:06:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthias May X-Patchwork-Id: 6587571 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 09CB5C0020 for ; Thu, 11 Jun 2015 11:06:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 08A1E205E8 for ; Thu, 11 Jun 2015 11:06:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DED692061B for ; Thu, 11 Jun 2015 11:06:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753213AbbFKLGt (ORCPT ); Thu, 11 Jun 2015 07:06:49 -0400 Received: from mail.neratec.com ([46.140.151.2]:24482 "EHLO mail.neratec.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752754AbbFKLGj (ORCPT ); Thu, 11 Jun 2015 07:06:39 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.neratec.com (Postfix) with ESMTP id 06BD28E4A7A for ; Thu, 11 Jun 2015 13:06:37 +0200 (CEST) Received: from mail.neratec.com ([127.0.0.1]) by localhost (mail.neratec.com [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id us266j1L8uO4; Thu, 11 Jun 2015 13:06:36 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail.neratec.com (Postfix) with ESMTP id 619178E4A81; Thu, 11 Jun 2015 13:06:36 +0200 (CEST) X-Virus-Scanned: amavisd-new at neratec.com Received: from mail.neratec.com ([127.0.0.1]) by localhost (mail.neratec.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id Axazcj9P4FlJ; Thu, 11 Jun 2015 13:06:36 +0200 (CEST) Received: from CHD500279.neratec.local (CHD500279.neratec.local [192.168.11.50]) by mail.neratec.com (Postfix) with ESMTPSA id 40B108E4A73; Thu, 11 Jun 2015 13:06:36 +0200 (CEST) From: Matthias May To: linux-wireless@vger.kernel.org Cc: matthias.may@neratec.com Subject: [PATCHv2 1/4] cfg80211: handle minimum bandwidth for quarter and half rates Date: Thu, 11 Jun 2015 13:06:28 +0200 Message-Id: <1434020791-16291-2-git-send-email-matthias.may@neratec.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1434020791-16291-1-git-send-email-matthias.may@neratec.com> References: <1434020791-16291-1-git-send-email-matthias.may@neratec.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=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham 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 This patch changes the API of freq_freq_info() to take as additional argument the minimum bandwidth the caller can handle. If multiple rules match, the match with the widest bandwidth is returned. Signed-off-by: Matthias May --- include/net/cfg80211.h | 3 ++- net/wireless/reg.c | 46 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index a741678..ac5d8e8 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3876,6 +3876,7 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy, * freq_reg_info - get regulatory information for the given frequency * @wiphy: the wiphy for which we want to process this rule for * @center_freq: Frequency in KHz for which we want regulatory information for + * @min_bw: The minimum bandwidth in KHz the caller can handle * * Use this function to get the regulatory rule for a specific frequency on * a given wireless device. If the device has a specific regulatory domain @@ -3891,7 +3892,7 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy, * purely subjective and right now it's 802.11 specific. */ const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy, - u32 center_freq); + u32 center_freq, u32 min_bw); /** * reg_initiator_name - map regulatory request initiator enum to name diff --git a/net/wireless/reg.c b/net/wireless/reg.c index d359e06..c4f85bb 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1003,7 +1003,7 @@ static u32 map_regdom_flags(u32 rd_flags) } static const struct ieee80211_reg_rule * -freq_reg_info_regd(struct wiphy *wiphy, u32 center_freq, +freq_reg_info_regd(struct wiphy *wiphy, u32 center_freq, u32 bw, const struct ieee80211_regdomain *regd) { int i; @@ -1028,7 +1028,7 @@ freq_reg_info_regd(struct wiphy *wiphy, u32 center_freq, if (!band_rule_found) band_rule_found = freq_in_rule_band(fr, center_freq); - bw_fits = reg_does_bw_fit(fr, center_freq, MHZ_TO_KHZ(20)); + bw_fits = reg_does_bw_fit(fr, center_freq, bw); if (band_rule_found && bw_fits) return rr; @@ -1041,13 +1041,22 @@ freq_reg_info_regd(struct wiphy *wiphy, u32 center_freq, } const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy, - u32 center_freq) + u32 center_freq, u32 min_bw) { const struct ieee80211_regdomain *regd; + const struct ieee80211_reg_rule *rr_tmp = NULL; + const struct ieee80211_reg_rule *reg_rule = NULL; + u32 bw; regd = reg_get_regdomain(wiphy); - return freq_reg_info_regd(wiphy, center_freq, regd); + for(bw=min_bw; bw <= MHZ_TO_KHZ(20); bw=bw*2) { + rr_tmp = freq_reg_info_regd(wiphy, center_freq, bw, regd); + if(!reg_rule || !IS_ERR(rr_tmp)) + reg_rule = rr_tmp; + } + + return reg_rule; } EXPORT_SYMBOL(freq_reg_info); @@ -1134,7 +1143,8 @@ static void handle_channel(struct wiphy *wiphy, flags = chan->orig_flags; - reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq)); + reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq), + MHZ_TO_KHZ(20)); if (IS_ERR(reg_rule)) { /* * We will disable all channels that do not match our @@ -1176,8 +1186,12 @@ static void handle_channel(struct wiphy *wiphy, if (reg_rule->flags & NL80211_RRF_AUTO_BW) max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); + if (max_bandwidth_khz < MHZ_TO_KHZ(10)) + bw_flags = IEEE80211_CHAN_NO_10MHZ; + if (max_bandwidth_khz < MHZ_TO_KHZ(20)) + bw_flags |= IEEE80211_CHAN_NO_20MHZ; if (max_bandwidth_khz < MHZ_TO_KHZ(40)) - bw_flags = IEEE80211_CHAN_NO_HT40; + bw_flags |= IEEE80211_CHAN_NO_HT40; if (max_bandwidth_khz < MHZ_TO_KHZ(80)) bw_flags |= IEEE80211_CHAN_NO_80MHZ; if (max_bandwidth_khz < MHZ_TO_KHZ(160)) @@ -1692,12 +1706,22 @@ static void handle_channel_custom(struct wiphy *wiphy, { u32 bw_flags = 0; const struct ieee80211_reg_rule *reg_rule = NULL; + const struct ieee80211_reg_rule *rr_tmp = NULL; const struct ieee80211_power_rule *power_rule = NULL; const struct ieee80211_freq_range *freq_range = NULL; u32 max_bandwidth_khz; + u32 bw; - reg_rule = freq_reg_info_regd(wiphy, MHZ_TO_KHZ(chan->center_freq), - regd); + /* Check if a frequency fits a rule for 5, 10 and 20MHz in that order. + * Use the rule with the widest bandwidth that fits. + */ + for(bw=MHZ_TO_KHZ(5); bw <= MHZ_TO_KHZ(20); bw=bw*2) { + rr_tmp = freq_reg_info_regd(wiphy, + MHZ_TO_KHZ(chan->center_freq), bw, + regd); + if(!reg_rule || !IS_ERR(rr_tmp)) + reg_rule = rr_tmp; + } if (IS_ERR(reg_rule)) { REG_DBG_PRINT("Disabling freq %d MHz as custom regd has no rule that fits it\n", @@ -1721,8 +1745,12 @@ static void handle_channel_custom(struct wiphy *wiphy, if (reg_rule->flags & NL80211_RRF_AUTO_BW) max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); + if (max_bandwidth_khz < MHZ_TO_KHZ(10)) + bw_flags = IEEE80211_CHAN_NO_10MHZ; + if (max_bandwidth_khz < MHZ_TO_KHZ(20)) + bw_flags |= IEEE80211_CHAN_NO_20MHZ; if (max_bandwidth_khz < MHZ_TO_KHZ(40)) - bw_flags = IEEE80211_CHAN_NO_HT40; + bw_flags |= IEEE80211_CHAN_NO_HT40; if (max_bandwidth_khz < MHZ_TO_KHZ(80)) bw_flags |= IEEE80211_CHAN_NO_80MHZ; if (max_bandwidth_khz < MHZ_TO_KHZ(160))