From patchwork Wed Mar 28 10:24:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Coelho X-Patchwork-Id: 10312733 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6A7A360212 for ; Wed, 28 Mar 2018 10:24:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6238529A36 for ; Wed, 28 Mar 2018 10:24:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 55ADE29EB6; Wed, 28 Mar 2018 10:24:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0D3D129A36 for ; Wed, 28 Mar 2018 10:24:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752082AbeC1KYY (ORCPT ); Wed, 28 Mar 2018 06:24:24 -0400 Received: from paleale.coelho.fi ([176.9.41.70]:36882 "EHLO farmhouse.coelho.fi" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751241AbeC1KYX (ORCPT ); Wed, 28 Mar 2018 06:24:23 -0400 Received: from 91-156-4-241.elisa-laajakaista.fi ([91.156.4.241] helo=redipa.ger.corp.intel.com) by farmhouse.coelho.fi with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.89) (envelope-from ) id 1f18Fh-0005uw-Jq; Wed, 28 Mar 2018 13:24:22 +0300 From: Luca Coelho To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Haim Dreyfuss , Luca Coelho Date: Wed, 28 Mar 2018 13:24:11 +0300 Message-Id: <20180328102411.25677-4-luca@coelho.fi> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180328102411.25677-1-luca@coelho.fi> References: <20180328102411.25677-1-luca@coelho.fi> X-SA-Exim-Connect-IP: 91.156.4.241 X-SA-Exim-Mail-From: luca@coelho.fi Subject: [PATCH v3 3/3] cfg80211: Add API to allow querying regdb for wmm_rule X-SA-Exim-Version: 4.2.1 (built Tue, 02 Aug 2016 21:08:31 +0000) X-SA-Exim-Scanned: Yes (on farmhouse.coelho.fi) Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Haim Dreyfuss In general regulatory self managed devices maintain their own regulatory profiles thus it doesn't have to query the regulatory database on country change. ETSI has recently introduced a new channel access mechanism for 5GHz that all wlan devices need to comply with. These values are stored in the regulatory database. There are self managed devices which can't maintain these values on their own. Add API to allow self managed regulatory devices to query the regulatory database for high band wmm rule. Signed-off-by: Haim Dreyfuss Signed-off-by: Luca Coelho --- include/net/cfg80211.h | 28 ++++++++++++++++++++++++++ net/wireless/reg.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index fc40843baed3..18f57ae25171 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -6,6 +6,7 @@ * Copyright 2006-2010 Johannes Berg * Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2015-2017 Intel Deutschland GmbH + * Copyright (C) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -4657,6 +4658,33 @@ const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy, */ const char *reg_initiator_name(enum nl80211_reg_initiator initiator); +/** + * DOC: Internal regulatory db functions + * + */ + +/** + * reg_query_regdb_wmm - Query internal regulatory db for wmm rule + * Regulatory self-managed driver can use it to proactively + * + * @alpha2: the ISO/IEC 3166 alpha2 wmm rule to be queried. + * @freq: the freqency(in MHz) to be queried. + * @dbptr: pointer where the regdb wmm data is to be stored (or %NULL if + * irrelevant). This can be used later for deduplication. + * @rule: pointer to store the wmm rule from the regulatory db. + * + * Self-managed wireless drivers can use this function to query + * the internal regulatory database to check whether the given + * ISO/IEC 3166 alpha2 country and freq have wmm rule limitations. + * + * Drivers should check the return value, its possible you can get + * an -ENODATA. + * + * Return: 0 on success. -ENODATA. + */ +int reg_query_regdb_wmm(char *alpha2, int freq, u32 *ptr, + struct ieee80211_wmm_rule *rule); + /* * callbacks for asynchronous cfg80211 methods, notification * functions and BSS handling helpers diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 2520734bd1db..4f5e7d6c9f62 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -878,6 +878,60 @@ static void set_wmm_rule(struct ieee80211_wmm_rule *rule, } } +static int __regdb_query_wmm(const struct fwdb_header *db, + const struct fwdb_country *country, int freq, + u32 *dbptr, struct ieee80211_wmm_rule *rule) +{ + unsigned int ptr = be16_to_cpu(country->coll_ptr) << 2; + struct fwdb_collection *coll = (void *)((u8 *)db + ptr); + int i; + + for (i = 0; i < coll->n_rules; i++) { + __be16 *rules_ptr = (void *)((u8 *)coll + ALIGN(coll->len, 2)); + unsigned int rule_ptr = be16_to_cpu(rules_ptr[i]) << 2; + struct fwdb_rule *rrule = (void *)((u8 *)db + rule_ptr); + struct fwdb_wmm_rule *wmm; + unsigned int wmm_ptr; + + if (rrule->len < offsetofend(struct fwdb_rule, wmm_ptr)) + continue; + + if (freq >= KHZ_TO_MHZ(be32_to_cpu(rrule->start)) && + freq <= KHZ_TO_MHZ(be32_to_cpu(rrule->end))) { + wmm_ptr = be16_to_cpu(rrule->wmm_ptr) << 2; + wmm = (void *)((u8 *)db + wmm_ptr); + set_wmm_rule(rule, wmm); + if (dbptr) + *dbptr = wmm_ptr; + return 0; + } + } + + return -ENODATA; +} + +int reg_query_regdb_wmm(char *alpha2, int freq, u32 *dbptr, + struct ieee80211_wmm_rule *rule) +{ + const struct fwdb_header *hdr = regdb; + const struct fwdb_country *country; + + if (IS_ERR(regdb)) + return PTR_ERR(regdb); + + country = &hdr->country[0]; + while (country->coll_ptr) { + if (alpha2_equal(alpha2, country->alpha2)) + return __regdb_query_wmm(regdb, country, freq, dbptr, + rule); + + country++; + } + + return -ENODATA; +} +EXPORT_SYMBOL(reg_query_regdb_wmm); + struct wmm_ptrs { struct ieee80211_wmm_rule *rule; u32 ptr;