From patchwork Tue Feb 25 12:39:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Coelho X-Patchwork-Id: 3716361 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 EF9119F38B for ; Tue, 25 Feb 2014 12:39:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D153D201DD for ; Tue, 25 Feb 2014 12:39:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B54BF201D3 for ; Tue, 25 Feb 2014 12:39:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753424AbaBYMjy (ORCPT ); Tue, 25 Feb 2014 07:39:54 -0500 Received: from emh04.mail.saunalahti.fi ([62.142.5.110]:50199 "EHLO emh04.mail.saunalahti.fi" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751948AbaBYMjx (ORCPT ); Tue, 25 Feb 2014 07:39:53 -0500 Received: from porter.coelho.fi (a88-113-225-236.elisa-laajakaista.fi [88.113.225.236]) by emh04.mail.saunalahti.fi (Postfix) with ESMTP id B2AAB1A277D; Tue, 25 Feb 2014 14:39:48 +0200 (EET) From: Luciano Coelho To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, michal.kazior@tieto.com, sw@simonwunderlich.de, bzhao@marvell.com, arend@broadcom.com Subject: [PATCH v5 1/4] cfg80211: refactor cfg80211_can_use_iftype_chan() Date: Tue, 25 Feb 2014 14:39:41 +0200 Message-Id: <1393331984-21692-2-git-send-email-luca@coelho.fi> X-Mailer: git-send-email 1.8.5.3 In-Reply-To: <1393331984-21692-1-git-send-email-luca@coelho.fi> References: <1393331984-21692-1-git-send-email-luca@coelho.fi> 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, 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 From: Luciano Coelho Separate the code that counts the interface types and channels from the code that check the interface combinations. The new function that checks for combinations is exported so it can be called by the drivers. This is done in preparation for moving the interface combinations checks out of cfg80211. Signed-off-by: Luciano Coelho --- In v4: * rebased on top of slightly modified applied patches * removed the parenthesis from the comment (not needed for docbook) * use num[NUM_NL80211_IFTYPES] in cfg80211_check_combinations() --- Documentation/DocBook/80211.tmpl | 1 + include/net/cfg80211.h | 29 ++++++++++ net/wireless/util.c | 121 ++++++++++++++++++++++----------------- 3 files changed, 97 insertions(+), 54 deletions(-) diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index 044b764..d9b9416 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -100,6 +100,7 @@ !Finclude/net/cfg80211.h wdev_priv !Finclude/net/cfg80211.h ieee80211_iface_limit !Finclude/net/cfg80211.h ieee80211_iface_combination +!Finclude/net/cfg80211.h cfg80211_check_combinations Actions and configuration diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 8c9ba44..5f5a598 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -4677,6 +4677,35 @@ void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp); */ unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy); +/** + * cfg80211_check_combinations - check interface combinations + * + * @wiphy: the wiphy + * @num_different_channels: the number of different channels we want + * to use for verification + * @num_interfaces: the number of different interfaces we want to use + * for verification + * @used_iftypes: a bitmap where each bit corresponds to an interface + * type, as in the definition of &struct + * ieee80211_iface_limit.@types. + * @radar_detect: a bitmap where each bit corresponds to a channel + * width where radar detection is needed, as in the definition of + * &struct ieee80211_iface_combination.@radar_detect_widths + * @iftype_num: array with the numbers of interfaces of each interface + * type. The index is the interface type as specified in &enum + * nl80211_iftype. + * + * This function can be called by the driver to check whether a + * combination of interfaces and their types are allowed according to + * the interface combinations. + */ +int cfg80211_check_combinations(struct wiphy *wiphy, + const int num_different_channels, + const int num_interfaces, + const u32 used_iftypes, + const u8 radar_detect, + const int iftype_num[NUM_NL80211_IFTYPES]); + /* Logging, debugging and troubleshooting/diagnostic helpers. */ /* wiphy_printk helpers, similar to dev_printk */ diff --git a/net/wireless/util.c b/net/wireless/util.c index 57b3ce7..d562dd6 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1253,6 +1253,69 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, return res; } +int cfg80211_check_combinations(struct wiphy *wiphy, + const int num_different_channels, + const int num_interfaces, + const u32 used_iftypes, + const u8 radar_detect, + const int iftype_num[NUM_NL80211_IFTYPES]) +{ + int i, j, iftype; + + for (i = 0; i < wiphy->n_iface_combinations; i++) { + const struct ieee80211_iface_combination *c; + struct ieee80211_iface_limit *limits; + u32 all_iftypes = 0; + + c = &wiphy->iface_combinations[i]; + + if (num_interfaces > c->max_interfaces) + continue; + if (num_different_channels > c->num_different_channels) + continue; + + limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits, + GFP_KERNEL); + if (!limits) + return -ENOMEM; + + for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { + if (wiphy->software_iftypes & BIT(iftype)) + continue; + for (j = 0; j < c->n_limits; j++) { + all_iftypes |= limits[j].types; + if (!(limits[j].types & BIT(iftype))) + continue; + if (limits[j].max < iftype_num[iftype]) + goto cont; + limits[j].max -= iftype_num[iftype]; + } + } + + if (radar_detect && !(c->radar_detect_widths & radar_detect)) + goto cont; + + /* Finally check that all iftypes that we're currently + * using are actually part of this combination. If they + * aren't then we can't use this combination and have + * to continue to the next. + */ + if ((all_iftypes & used_iftypes) != used_iftypes) + goto cont; + + /* This combination covered all interface types and + * supported the requested numbers, so we're good. + */ + kfree(limits); + return 0; + cont: + kfree(limits); + } + + return -EBUSY; +} +EXPORT_SYMBOL(cfg80211_check_combinations); + int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, enum nl80211_iftype iftype, @@ -1269,7 +1332,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, enum cfg80211_chan_mode chmode; int num_different_channels = 0; int total = 1; - int i, j; + int i; ASSERT_RTNL(); @@ -1360,59 +1423,9 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, if (total == 1 && !radar_detect) return 0; - for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) { - const struct ieee80211_iface_combination *c; - struct ieee80211_iface_limit *limits; - u32 all_iftypes = 0; - - c = &rdev->wiphy.iface_combinations[i]; - - if (total > c->max_interfaces) - continue; - if (num_different_channels > c->num_different_channels) - continue; - - limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits, - GFP_KERNEL); - if (!limits) - return -ENOMEM; - - for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { - if (rdev->wiphy.software_iftypes & BIT(iftype)) - continue; - for (j = 0; j < c->n_limits; j++) { - all_iftypes |= limits[j].types; - if (!(limits[j].types & BIT(iftype))) - continue; - if (limits[j].max < num[iftype]) - goto cont; - limits[j].max -= num[iftype]; - } - } - - if (radar_detect && !(c->radar_detect_widths & radar_detect)) - goto cont; - - /* - * Finally check that all iftypes that we're currently - * using are actually part of this combination. If they - * aren't then we can't use this combination and have - * to continue to the next. - */ - if ((all_iftypes & used_iftypes) != used_iftypes) - goto cont; - - /* - * This combination covered all interface types and - * supported the requested numbers, so we're good. - */ - kfree(limits); - return 0; - cont: - kfree(limits); - } - - return -EBUSY; + return cfg80211_check_combinations(&rdev->wiphy, num_different_channels, + total, used_iftypes, + radar_detect, num); } int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,