From patchwork Thu Jun 11 15:12:33 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthias May X-Patchwork-Id: 6589151 X-Patchwork-Delegate: johannes@sipsolutions.net 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 27D9EC0020 for ; Thu, 11 Jun 2015 15:13:02 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id F15C02025A for ; Thu, 11 Jun 2015 15:13:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8CF9D20652 for ; Thu, 11 Jun 2015 15:12:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932630AbbFKPMx (ORCPT ); Thu, 11 Jun 2015 11:12:53 -0400 Received: from mail.neratec.com ([46.140.151.2]:34359 "EHLO mail.neratec.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752868AbbFKPMu (ORCPT ); Thu, 11 Jun 2015 11:12:50 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.neratec.com (Postfix) with ESMTP id 7EAC3A06CBB for ; Thu, 11 Jun 2015 17:12:47 +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 67vwJIGfh7k6; Thu, 11 Jun 2015 17:12:46 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail.neratec.com (Postfix) with ESMTP id C0431A06CBA; Thu, 11 Jun 2015 17:12:46 +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 AWUIk5dBHGC4; Thu, 11 Jun 2015 17:12:46 +0200 (CEST) Received: from CHD500279.neratec.local (CHD500279.neratec.local [192.168.11.50]) by mail.neratec.com (Postfix) with ESMTPSA id AC228A06CB7; Thu, 11 Jun 2015 17:12:46 +0200 (CEST) From: Matthias May To: linux-wireless@vger.kernel.org Cc: matthias.may@neratec.com Subject: [PATCH v3] cfg80211: Handle minimum bandwidth for quarter and half rates Date: Thu, 11 Jun 2015 17:12:33 +0200 Message-Id: <1434035553-6621-1-git-send-email-matthias.may@neratec.com> X-Mailer: git-send-email 2.1.4 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 The goal of this patch is to improve regd handling of quarter and half rates. The original assumption of 20MHz wide channels is with the introduction of quarter and half rates no longer true. With this patch we no longer disable all channels that don't fit into the 20MHz grid, but instead set the appropriate flags to disable operation on specific bandwidths. v2: Changes based on feedback by Johannes Berg. v3: Changes based on feedback by Johannes Berg and Zefir Kurtisi. Signed-off-by: Matthias May --- net/wireless/reg.c | 51 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index d359e06..4ab1b67 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1004,7 +1004,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, - const struct ieee80211_regdomain *regd) + const struct ieee80211_regdomain *regd, u32 bw) { int i; bool band_rule_found = false; @@ -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; @@ -1040,14 +1040,26 @@ freq_reg_info_regd(struct wiphy *wiphy, u32 center_freq, return ERR_PTR(-EINVAL); } -const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy, - u32 center_freq) +const struct ieee80211_reg_rule *__freq_reg_info(struct wiphy *wiphy, + u32 center_freq, u32 min_bw) { - const struct ieee80211_regdomain *regd; + const struct ieee80211_regdomain *regd = reg_get_regdomain(wiphy); + const struct ieee80211_reg_rule *reg_rule = NULL; + u32 bw; - regd = reg_get_regdomain(wiphy); + for (bw = MHZ_TO_KHZ(20); bw >= min_bw; bw = bw / 2) { + reg_rule = freq_reg_info_regd(wiphy, center_freq, regd, bw); + if (!IS_ERR(reg_rule)) + return reg_rule; + } - return freq_reg_info_regd(wiphy, center_freq, regd); + return reg_rule; +} + +const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy, + u32 center_freq) +{ + return __freq_reg_info(wiphy, center_freq, MHZ_TO_KHZ(20)); } EXPORT_SYMBOL(freq_reg_info); @@ -1176,8 +1188,14 @@ 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 we get a reg_rule we can assume that at least 5Mhz fitted */ + if (!reg_does_bw_fit(freq_range, chan->center_freq, 10)) + bw_flags |= IEEE80211_CHAN_NO_10MHZ; + if (!reg_does_bw_fit(freq_range, chan->center_freq, 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)) @@ -1695,9 +1713,14 @@ static void handle_channel_custom(struct wiphy *wiphy, 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); + for (bw = MHZ_TO_KHZ(20); bw >= MHZ_TO_KHZ(5); bw = bw / 2) { + reg_rule = freq_reg_info_regd(wiphy, chan->center_freq, + regd, bw); + if (!IS_ERR(reg_rule)) + break; + } if (IS_ERR(reg_rule)) { REG_DBG_PRINT("Disabling freq %d MHz as custom regd has no rule that fits it\n", @@ -1721,8 +1744,14 @@ 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 we get a reg_rule we can assume that at least 5Mhz fitted */ + if (!reg_does_bw_fit(freq_range, chan->center_freq, 10)) + bw_flags |= IEEE80211_CHAN_NO_10MHZ; + if (!reg_does_bw_fit(freq_range, chan->center_freq, 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))