From patchwork Mon Jul 4 10:23:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aditya Kumar Singh X-Patchwork-Id: 12905011 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B4CAC433EF for ; Mon, 4 Jul 2022 10:25:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233792AbiGDKZn (ORCPT ); Mon, 4 Jul 2022 06:25:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50662 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233875AbiGDKZW (ORCPT ); Mon, 4 Jul 2022 06:25:22 -0400 Received: from alexa-out.qualcomm.com (alexa-out.qualcomm.com [129.46.98.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 30E591B7 for ; Mon, 4 Jul 2022 03:24:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1656930243; x=1688466243; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=l26yKAdHAT0aHgydRvuzdgRPmcJU/SbFfguiNZFjGoY=; b=VWbRp2aPVxKA+dND9v8Uiwd/4/xuoxAtGpleMmfFe7sK7Efw1FXf2kIi 41uYwTQ/aanyFc491h8/ixneJomWHGshE7KTbN/0r6zvQO+s63QcWjiJY 3W2tqcy2Rnrc9U/VTFsqi9XIKbcSv5B2OgzCb4YzKkbH1/OflCXpY/PjQ E=; Received: from ironmsg09-lv.qualcomm.com ([10.47.202.153]) by alexa-out.qualcomm.com with ESMTP; 04 Jul 2022 03:24:02 -0700 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg09-lv.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jul 2022 03:24:02 -0700 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Mon, 4 Jul 2022 03:24:02 -0700 Received: from adisi-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Mon, 4 Jul 2022 03:24:00 -0700 From: Aditya Kumar Singh To: CC: , Wen Gong , "Aditya Kumar Singh" Subject: [PATCH 1/7] cfg80211: save Power Spectral Density (PSD) of the regulatory rule Date: Mon, 4 Jul 2022 15:53:35 +0530 Message-ID: <20220704102341.5692-2-quic_adisi@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220704102341.5692-1-quic_adisi@quicinc.com> References: <20220704102341.5692-1-quic_adisi@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Wen Gong 6 GHz regulatory domain introduces Power Spectral Density (PSD). The PSD value of the regulatory rule should be taken into effect for the ieee80211_channels falling into that particular regulatory rule. Save the values in the channel which has PSD value and add nl80211 attributes accordingly to handle it. Signed-off-by: Wen Gong Co-developed-by: Aditya Kumar Singh Signed-off-by: Aditya Kumar Singh --- include/net/cfg80211.h | 5 +++++ include/net/regulatory.h | 1 + include/uapi/linux/nl80211.h | 9 +++++++++ net/wireless/nl80211.c | 18 ++++++++++++++++++ net/wireless/reg.c | 17 +++++++++++++++++ 5 files changed, 50 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 140354f5f15b..600c080a280b 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -115,6 +115,8 @@ struct wiphy; * This may be due to the driver or due to regulatory bandwidth * restrictions. * @IEEE80211_CHAN_NO_EHT: EHT operation is not permitted on this channel. + * @IEEE80211_CHAN_PSD: power spectral density (in dBm) + * on this channel */ enum ieee80211_channel_flags { IEEE80211_CHAN_DISABLED = 1<<0, @@ -138,6 +140,7 @@ enum ieee80211_channel_flags { IEEE80211_CHAN_16MHZ = 1<<18, IEEE80211_CHAN_NO_320MHZ = 1<<19, IEEE80211_CHAN_NO_EHT = 1<<20, + IEEE80211_CHAN_PSD = 1<<21, }; #define IEEE80211_CHAN_NO_HT40 \ @@ -171,6 +174,7 @@ enum ieee80211_channel_flags { * on this channel. * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered. * @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels. + * @psd: power spectral density (in dBm) */ struct ieee80211_channel { enum nl80211_band band; @@ -187,6 +191,7 @@ struct ieee80211_channel { enum nl80211_dfs_state dfs_state; unsigned long dfs_state_entered; unsigned int dfs_cac_ms; + s8 psd; }; /** diff --git a/include/net/regulatory.h b/include/net/regulatory.h index 47f06f6f5a67..ed20004fb6a9 100644 --- a/include/net/regulatory.h +++ b/include/net/regulatory.h @@ -221,6 +221,7 @@ struct ieee80211_reg_rule { u32 flags; u32 dfs_cac_ms; bool has_wmm; + s8 psd; }; struct ieee80211_regdomain { diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 279f9715919e..8c21136ac18c 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -4062,6 +4062,8 @@ enum nl80211_wmm_rule { * as the primary or any of the secondary channels isn't possible * @NL80211_FREQUENCY_ATTR_NO_EHT: EHT operation is not allowed on this channel * in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_PSD: power spectral density (in dBm) + * is allowed on this channel in current regulatory domain. * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number * currently defined * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use @@ -4100,6 +4102,7 @@ enum nl80211_frequency_attr { NL80211_FREQUENCY_ATTR_16MHZ, NL80211_FREQUENCY_ATTR_NO_320MHZ, NL80211_FREQUENCY_ATTR_NO_EHT, + NL80211_FREQUENCY_ATTR_PSD, /* keep last */ __NL80211_FREQUENCY_ATTR_AFTER_LAST, @@ -4200,6 +4203,8 @@ enum nl80211_reg_type { * a given frequency range. The value is in mBm (100 * dBm). * @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds. * If not present or 0 default CAC time will be used. + * @NL80211_ATTR_POWER_RULE_PSD: power spectral density (in dBm). + * This could be negative. * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number * currently defined * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use @@ -4217,6 +4222,8 @@ enum nl80211_reg_rule_attr { NL80211_ATTR_DFS_CAC_TIME, + NL80211_ATTR_POWER_RULE_PSD, + /* keep last */ __NL80211_REG_RULE_ATTR_AFTER_LAST, NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1 @@ -4299,6 +4306,7 @@ enum nl80211_sched_scan_match_attr { * @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed * @NL80211_RRF_NO_HE: HE operation not allowed * @NL80211_RRF_NO_320MHZ: 320MHz operation not allowed + * @NL80211_RRF_PSD: channel has power spectral density value */ enum nl80211_reg_rule_flags { NL80211_RRF_NO_OFDM = 1<<0, @@ -4318,6 +4326,7 @@ enum nl80211_reg_rule_flags { NL80211_RRF_NO_160MHZ = 1<<16, NL80211_RRF_NO_HE = 1<<17, NL80211_RRF_NO_320MHZ = 1<<18, + NL80211_RRF_PSD = 1<<19, }; #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index eda2ad029c90..afa8cd686e0e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1096,6 +1096,10 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy, if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_OFFSET, chan->freq_offset)) goto nla_put_failure; + if ((chan->flags & IEEE80211_CHAN_PSD) && + nla_put_s8(msg, NL80211_FREQUENCY_ATTR_PSD, chan->psd)) + goto nla_put_failure; + if ((chan->flags & IEEE80211_CHAN_DISABLED) && nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED)) goto nla_put_failure; @@ -8168,6 +8172,11 @@ static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom, reg_rule->dfs_cac_ms)) goto nla_put_failure; + if ((reg_rule->flags & NL80211_RRF_PSD) && + nla_put_s8(msg, NL80211_ATTR_POWER_RULE_PSD, + reg_rule->psd)) + goto nla_put_failure; + nla_nest_end(msg, nl_reg_rule); } @@ -8341,6 +8350,7 @@ static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 }, [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 }, [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 }, + [NL80211_ATTR_POWER_RULE_PSD] = { .type = NLA_S8 }, }; static int parse_reg_rule(struct nlattr *tb[], @@ -8362,6 +8372,14 @@ static int parse_reg_rule(struct nlattr *tb[], reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]); + if (reg_rule->flags & NL80211_RRF_PSD) { + if (!tb[NL80211_ATTR_POWER_RULE_PSD]) + return -EINVAL; + + reg_rule->psd = + nla_get_s8(tb[NL80211_ATTR_POWER_RULE_PSD]); + } + freq_range->start_freq_khz = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]); freq_range->end_freq_khz = diff --git a/net/wireless/reg.c b/net/wireless/reg.c index c7383ede794f..9a06aadba0d7 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1619,6 +1619,8 @@ static u32 map_regdom_flags(u32 rd_flags) channel_flags |= IEEE80211_CHAN_NO_HE; if (rd_flags & NL80211_RRF_NO_320MHZ) channel_flags |= IEEE80211_CHAN_NO_320MHZ; + if (rd_flags & NL80211_RRF_PSD) + channel_flags |= IEEE80211_CHAN_PSD; return channel_flags; } @@ -1825,6 +1827,9 @@ static void handle_channel_single_rule(struct wiphy *wiphy, chan->dfs_cac_ms = reg_rule->dfs_cac_ms; } + if (chan->flags & IEEE80211_CHAN_PSD) + chan->psd = reg_rule->psd; + return; } @@ -1845,6 +1850,9 @@ static void handle_channel_single_rule(struct wiphy *wiphy, chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; } + if (chan->flags & IEEE80211_CHAN_PSD) + chan->psd = reg_rule->psd; + if (chan->orig_mpwr) { /* * Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER @@ -1914,6 +1922,12 @@ static void handle_channel_adjacent_rules(struct wiphy *wiphy, rrule2->dfs_cac_ms); } + if ((rrule1->flags & NL80211_RRF_PSD) && + (rrule2->flags & NL80211_RRF_PSD)) + chan->psd = min_t(s8, rrule1->psd, rrule2->psd); + else + chan->flags &= ~NL80211_RRF_PSD; + return; } @@ -2600,6 +2614,9 @@ static void handle_channel_custom(struct wiphy *wiphy, chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; } + if (chan->flags & IEEE80211_CHAN_PSD) + chan->psd = reg_rule->psd; + chan->max_power = chan->max_reg_power; } From patchwork Mon Jul 4 10:23:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aditya Kumar Singh X-Patchwork-Id: 12905012 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF509C433EF for ; Mon, 4 Jul 2022 10:25:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234483AbiGDKZs (ORCPT ); Mon, 4 Jul 2022 06:25:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49942 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234501AbiGDKZZ (ORCPT ); Mon, 4 Jul 2022 06:25:25 -0400 Received: from alexa-out-sd-02.qualcomm.com (alexa-out-sd-02.qualcomm.com [199.106.114.39]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A332010FEC for ; Mon, 4 Jul 2022 03:24:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1656930246; x=1688466246; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=EvUYaTqGrY7Ds94cNF7HnBqnA+zaPRn8jhmHdgqloj0=; b=n0EpQBtl0gxk1u72qKEA3NTW/RsMP+3nMkJ64FkCNnoV3Dfs2xebZpMK /i3k2DVRtwtTUORc+SAYNqLHruD2K7tmgrmRXc9D5p13f0HtI2kMMo9rQ USOm3xCpyM8a94xs8bSISDFaBNy/7rH/k3OQFhqGwa3kqWwi6OvBF+3wB s=; Received: from unknown (HELO ironmsg05-sd.qualcomm.com) ([10.53.140.145]) by alexa-out-sd-02.qualcomm.com with ESMTP; 04 Jul 2022 03:24:05 -0700 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg05-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jul 2022 03:24:05 -0700 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Mon, 4 Jul 2022 03:24:05 -0700 Received: from adisi-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Mon, 4 Jul 2022 03:24:03 -0700 From: Aditya Kumar Singh To: CC: , Aditya Kumar Singh Subject: [PATCH 2/7] mac80211: rework on 6 GHz power type definition Date: Mon, 4 Jul 2022 15:53:36 +0530 Message-ID: <20220704102341.5692-3-quic_adisi@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220704102341.5692-1-quic_adisi@quicinc.com> References: <20220704102341.5692-1-quic_adisi@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org 6 GHz regulatory domains introduces different modes for 6 GHz AP operation - Low Power Indoor(LPI), Standard Power(SP) and Very Low Power(VLP). 6 GHz STAs could be operated as either Regular or Subordinate clients. We have separate definitions of AP and client. However, IEEE80211_REG_UNSET_* is not a defined power type. Hence, remove IEEE80211_REG_UNSET_* from both AP and client power mode enums. To demonstrate unset or invalid type, (IEEE80211_REG_*_POWER_MAX + 1) value can be used instead. Signed-off-by: Aditya Kumar Singh --- include/linux/ieee80211.h | 10 ++++------ net/mac80211/util.c | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index f386f9ed41f3..606b5ba8b161 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -2132,18 +2132,17 @@ int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap, /** * enum ieee80211_ap_reg_power - regulatory power for a Access Point * - * @IEEE80211_REG_UNSET_AP: Access Point has no regulatory power mode * @IEEE80211_REG_LPI: Indoor Access Point * @IEEE80211_REG_SP: Standard power Access Point * @IEEE80211_REG_VLP: Very low power Access Point - * @IEEE80211_REG_AP_POWER_AFTER_LAST: internal + * @IEEE80211_REG_AP_POWER_AFTER_LAST: internal use * @IEEE80211_REG_AP_POWER_MAX: maximum value */ enum ieee80211_ap_reg_power { - IEEE80211_REG_UNSET_AP, IEEE80211_REG_LPI_AP, IEEE80211_REG_SP_AP, IEEE80211_REG_VLP_AP, + /* keep last */ IEEE80211_REG_AP_POWER_AFTER_LAST, IEEE80211_REG_AP_POWER_MAX = IEEE80211_REG_AP_POWER_AFTER_LAST - 1, @@ -2152,16 +2151,15 @@ enum ieee80211_ap_reg_power { /** * enum ieee80211_client_reg_power - regulatory power for a client * - * @IEEE80211_REG_UNSET_CLIENT: Client has no regulatory power mode * @IEEE80211_REG_DEFAULT_CLIENT: Default Client * @IEEE80211_REG_SUBORDINATE_CLIENT: Subordinate Client - * @IEEE80211_REG_CLIENT_POWER_AFTER_LAST: internal + * @IEEE80211_REG_CLIENT_POWER_AFTER_LAST: internal use * @IEEE80211_REG_CLIENT_POWER_MAX: maximum value */ enum ieee80211_client_reg_power { - IEEE80211_REG_UNSET_CLIENT, IEEE80211_REG_DEFAULT_CLIENT, IEEE80211_REG_SUBORDINATE_CLIENT, + /* keep last */ IEEE80211_REG_CLIENT_POWER_AFTER_LAST, IEEE80211_REG_CLIENT_POWER_MAX = IEEE80211_REG_CLIENT_POWER_AFTER_LAST - 1, diff --git a/net/mac80211/util.c b/net/mac80211/util.c index bccc3a309ed0..efdea5c2f2db 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -3524,7 +3524,7 @@ bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata, bss_conf->power_type = IEEE80211_REG_SP_AP; break; default: - bss_conf->power_type = IEEE80211_REG_UNSET_AP; + bss_conf->power_type = IEEE80211_REG_AP_POWER_MAX + 1; break; } From patchwork Mon Jul 4 10:23:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aditya Kumar Singh X-Patchwork-Id: 12905013 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90C6DC433EF for ; Mon, 4 Jul 2022 10:25:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234502AbiGDKZw (ORCPT ); Mon, 4 Jul 2022 06:25:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45812 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234507AbiGDKZ3 (ORCPT ); Mon, 4 Jul 2022 06:25:29 -0400 Received: from alexa-out.qualcomm.com (alexa-out.qualcomm.com [129.46.98.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7ED8610FFD for ; Mon, 4 Jul 2022 03:24:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1656930248; x=1688466248; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=JLjUcfEAoZGdc0LpXM0fzRBNZSHUKbX665cALsYwCoo=; b=keOjFQ4TSAcijuoytFihVG2NPWiz9J1uNHGOiJwjxIYNa7ArzHVqTM+J DmW+sdbZHTFPwszc+hgUO0RyOa7P3m2CzqObsJT/GmbGWW95EtWq916Tx 1D6+5Z6i9Ch8ynYzVOk5ZX374phmEz9Amgj163zorUHw5IyL6MfgOK4b+ Y=; Received: from ironmsg-lv-alpha.qualcomm.com ([10.47.202.13]) by alexa-out.qualcomm.com with ESMTP; 04 Jul 2022 03:24:08 -0700 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg-lv-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jul 2022 03:24:08 -0700 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Mon, 4 Jul 2022 03:24:07 -0700 Received: from adisi-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Mon, 4 Jul 2022 03:24:06 -0700 From: Aditya Kumar Singh To: CC: , Aditya Kumar Singh Subject: [PATCH 3/7] mac80211: add combined power type definition for 6 GHz Date: Mon, 4 Jul 2022 15:53:37 +0530 Message-ID: <20220704102341.5692-4-quic_adisi@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220704102341.5692-1-quic_adisi@quicinc.com> References: <20220704102341.5692-1-quic_adisi@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org 6 GHz regulatory domain introduces different power modes for 6 GHz AP operation - Low Power Indoor(LPI), Standard Power(SP) and Very Low Power(VLP). 6 GHz STAs could be operated as either Regular or Subordinate clients. We have separate definitions of AP and client. However, during concurrency (multi-interfaces), it would be difficult to keep different enum containers for different interface types in order to track its power mode. Add new combined power type definition for 6 GHz interfaces. Also add support to convert existing AP/Client Power type to this new combined power type enum. Signed-off-by: Aditya Kumar Singh --- include/net/cfg80211.h | 19 ++++++++++++ include/uapi/linux/nl80211.h | 38 +++++++++++++++++++++++ net/wireless/util.c | 60 ++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 600c080a280b..ed482b23fb9c 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -5902,6 +5902,25 @@ ieee80211_frequency_to_channel(int freq) struct ieee80211_channel * ieee80211_get_channel_khz(struct wiphy *wiphy, u32 freq); +/** + * ieee80211_ap_reg_power_to_reg_power_mode - convert AP specific 6 GHz power + * type into combined 6 GHz power type + * @ap_type: AP's power mode + * Return: Power mode as referenced in &enum nl80211_regulatory_power_modes + */ +enum nl80211_regulatory_power_modes +ieee80211_ap_reg_power_to_reg_power_mode(enum ieee80211_ap_reg_power ap_type); + +/** + * ieee80211_client_reg_power_to_reg_power_mode - convert Client specific 6 GHz + * power type into combined 6 GHz power type + * @client_type: Client's power mode + * @ap_type: AP's power mode to which this client is associating + * Return: Power mode as referenced in &enum nl80211_regulatory_power_modes + */ +enum nl80211_regulatory_power_modes +ieee80211_client_reg_power_to_reg_power_mode(enum ieee80211_client_reg_power client_type, + enum ieee80211_ap_reg_power ap_type); /** * ieee80211_get_channel - get channel struct from wiphy for specified frequency * diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 8c21136ac18c..789f73878f50 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -3970,6 +3970,44 @@ enum nl80211_band_attr { #define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA +/** + * enum nl80211_regulatory_power_modes - 6 GHz regulatory power + * modes + * @NL80211_REG_AP_LPI: Low Power Indoor (Access Point) + * @NL80211_REG_AP_SP: Standard Power (Access Point) + * @NL80211_REG_AP_VLP: Very Low Power (Access Point) + * @NL80211_REG_REGULAR_CLIENT_LPI: Low Power Indoor (Regular + * or Default Client) + * @NL80211_REG_REGULAR_CLIENT_SP: Standard Power (Regular + * or Default Client) + * @NL80211_REG_REGULAR_CLIENT_VLP: Very Low Power (Regular + * or Default Client) + * @NL80211_REG_SUBORDINATE_CLIENT_LPI: Low Power Indoor + * (Subordinate Client) + * @NL80211_REG_SUBORDINATE_CLIENT_SP: Standard Power + * (Subordinate Client) + * @NL80211_REG_SUBORDINATE_CLIENT_VLP: Very Low Power + * (Subordinate Client) + * @NL80211_REG_MAX_POWER_MODES: Max supported number of power + * modes + * @__NL80211_REG_LAST: Internal use + */ +enum nl80211_regulatory_power_modes { + NL80211_REG_AP_LPI, + NL80211_REG_AP_SP, + NL80211_REG_AP_VLP, + NL80211_REG_REGULAR_CLIENT_LPI, + NL80211_REG_REGULAR_CLIENT_SP, + NL80211_REG_REGULAR_CLIENT_VLP, + NL80211_REG_SUBORDINATE_CLIENT_LPI, + NL80211_REG_SUBORDINATE_CLIENT_SP, + NL80211_REG_SUBORDINATE_CLIENT_VLP, + + /* keep last */ + __NL80211_REG_LAST, + NL80211_REG_MAX_POWER_MODES = __NL80211_REG_LAST - 1, +}; + /** * enum nl80211_wmm_rule - regulatory wmm rule * diff --git a/net/wireless/util.c b/net/wireless/util.c index b7257862e0fe..cca0ee321a03 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -190,6 +190,66 @@ struct ieee80211_channel *ieee80211_get_channel_khz(struct wiphy *wiphy, } EXPORT_SYMBOL(ieee80211_get_channel_khz); +enum nl80211_regulatory_power_modes +ieee80211_ap_reg_power_to_reg_power_mode(enum ieee80211_ap_reg_power ap_type) +{ + switch (ap_type) { + case IEEE80211_REG_LPI_AP: + return NL80211_REG_AP_LPI; + case IEEE80211_REG_SP_AP: + return NL80211_REG_AP_SP; + case IEEE80211_REG_VLP_AP: + return NL80211_REG_AP_VLP; + default: + return NL80211_REG_MAX_POWER_MODES + 1; + } +} +EXPORT_SYMBOL(ieee80211_ap_reg_power_to_reg_power_mode); + +/* ieee80211_client_reg_power_to_reg_power_mode: Accepts the individual power type of + * a 6 GHz client and power type of AP to which the client is associating and returns + * the final combined power mode as enumerated in &enum nl80211_regulatory_power_modes. + * + * Unlike AP, for client there is no direct mapping because final power mode of + * operation of client is dependent upon the power type of AP. + * For example - + * If client is a Regular client and AP is Low Power Indoor then combined power mode + * will be Regular Low Power Indoor where as if AP is Standard Power, then it will be + * Regular Standard Power Mode. + */ +enum nl80211_regulatory_power_modes +ieee80211_client_reg_power_to_reg_power_mode(enum ieee80211_client_reg_power client_type, + enum ieee80211_ap_reg_power ap_type) +{ + switch (client_type) { + case IEEE80211_REG_DEFAULT_CLIENT: + switch (ap_type) { + case IEEE80211_REG_LPI_AP: + return NL80211_REG_REGULAR_CLIENT_LPI; + case IEEE80211_REG_SP_AP: + return NL80211_REG_REGULAR_CLIENT_SP; + case IEEE80211_REG_VLP_AP: + return NL80211_REG_REGULAR_CLIENT_VLP; + default: + return NL80211_REG_MAX_POWER_MODES + 1; + } + case IEEE80211_REG_SUBORDINATE_CLIENT: + switch (ap_type) { + case IEEE80211_REG_LPI_AP: + return NL80211_REG_SUBORDINATE_CLIENT_LPI; + case IEEE80211_REG_SP_AP: + return NL80211_REG_SUBORDINATE_CLIENT_SP; + case IEEE80211_REG_VLP_AP: + return NL80211_REG_SUBORDINATE_CLIENT_SP; + default: + return NL80211_REG_MAX_POWER_MODES; + } + default: + return NL80211_REG_MAX_POWER_MODES + 1; + } +} +EXPORT_SYMBOL(ieee80211_client_reg_power_to_reg_power_mode); + static void set_mandatory_flags_band(struct ieee80211_supported_band *sband) { int i, want; From patchwork Mon Jul 4 10:23:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aditya Kumar Singh X-Patchwork-Id: 12905014 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4DF80C433EF for ; Mon, 4 Jul 2022 10:25:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234286AbiGDKZz (ORCPT ); Mon, 4 Jul 2022 06:25:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45872 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234262AbiGDKZd (ORCPT ); Mon, 4 Jul 2022 06:25:33 -0400 Received: from alexa-out-sd-02.qualcomm.com (alexa-out-sd-02.qualcomm.com [199.106.114.39]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E5DED1114C for ; Mon, 4 Jul 2022 03:24:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1656930250; x=1688466250; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=fjJINO81/YrRYiiogSNa+48rhNRYhIS+of2WeOkh6AQ=; b=BsDR/UWo+vBkWFq7ut7FFMjm97pAQ9yFNlk2UmgFXqvI7vTcCvUdTbaj p/wNtWZzsPF6TdbI7fUeT+pXjAEqXqE4b/TN+e23v6ioOylZA/7qVOdNT t+Gu8hr9FB7PQsl6TuD3/6APaTfwyTW4Bl63KVpi2Q0rEKsffF8ldMptx w=; Received: from unknown (HELO ironmsg02-sd.qualcomm.com) ([10.53.140.142]) by alexa-out-sd-02.qualcomm.com with ESMTP; 04 Jul 2022 03:24:10 -0700 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg02-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jul 2022 03:24:10 -0700 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Mon, 4 Jul 2022 03:24:10 -0700 Received: from adisi-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Mon, 4 Jul 2022 03:24:08 -0700 From: Aditya Kumar Singh To: CC: , Aditya Kumar Singh Subject: [PATCH 4/7] cfg80211: add NL command to set 6 GHz power mode Date: Mon, 4 Jul 2022 15:53:38 +0530 Message-ID: <20220704102341.5692-5-quic_adisi@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220704102341.5692-1-quic_adisi@quicinc.com> References: <20220704102341.5692-1-quic_adisi@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org 6 GHz introduces various power modes for access points and for clients. When user configures these power modes, currently cfg80211 does not have support to store the configured power mode. Add support to store the 6 GHz configured power mode in the structure wireless_dev via a new NL command - NL80211_CMD_SET_6GHZ_POWER_MODE. The above command uses two new NL attributes to set power mode for AP and clients - NL80211_ATTR_6GHZ_REG_AP_POWER_MODE and NL80211_ATTR_6GHZ_REG_CLIENT_POWER_MODE respectively. Signed-off-by: Aditya Kumar Singh --- include/net/cfg80211.h | 9 ++++++ include/uapi/linux/nl80211.h | 15 +++++++++ net/wireless/ap.c | 4 +++ net/wireless/nl80211.c | 62 ++++++++++++++++++++++++++++++++++++ net/wireless/sme.c | 3 ++ 5 files changed, 93 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ed482b23fb9c..1e8852c6149f 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -5644,6 +5644,9 @@ static inline void wiphy_unlock(struct wiphy *wiphy) * @links: array of %IEEE80211_MLD_MAX_NUM_LINKS elements containing @addr * @ap and @client for each link * @valid_links: bitmap describing what elements of @links are valid + * @ap_6ghz_power: 6 GHz regulatory power mode for Access Points + * @client_6ghz_power: 6 GHz regulatory power mode for Clients + * @reg_6ghz_pwr_configured: true if 6 GHz power mode is configured */ struct wireless_dev { struct wiphy *wiphy; @@ -5758,6 +5761,12 @@ struct wireless_dev { }; } links[IEEE80211_MLD_MAX_NUM_LINKS]; u16 valid_links; + + union { + enum ieee80211_ap_reg_power ap_6ghz_power; + enum ieee80211_client_reg_power client_6ghz_power; + }; + bool reg_6ghz_pwr_configured; }; static inline const u8 *wdev_address(struct wireless_dev *wdev) diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 789f73878f50..e62838887802 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -1254,6 +1254,11 @@ * without %NL80211_ATTR_MLO_LINK_ID as an easy way to remove all links * in preparation for e.g. roaming to a regular (non-MLO) AP. * + * @NL80211_CMD_SET_6GHZ_POWER_MODE: Set 6 GHz power mode for the interface + * using - + * &NL80211_ATTR_6GHZ_REG_AP_POWER_MODE - for access points + * &NL80211_ATTR_6GHZ_REG_CLIENT_POWER_MODE - for clients + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -1501,6 +1506,8 @@ enum nl80211_commands { NL80211_CMD_ADD_LINK, NL80211_CMD_REMOVE_LINK, + NL80211_CMD_SET_6GHZ_POWER_MODE, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -2701,6 +2708,12 @@ enum nl80211_commands { * suites allowed as %NL80211_MAX_NR_AKM_SUITES which is the legacy maximum * number prior to the introduction of this attribute. * + * @NL80211_ATTR_6GHZ_REG_AP_POWER_MODE: Configure 6 GHz regulatory power mode + * for access points. Referenced from &enum ieee80211_ap_reg_power. + * + * @NL80211_ATTR_6GHZ_REG_CLIENT_POWER_MODE: Configure 6 GHz regulatory power + * mode for clients. Referenced from &enum ieee80211_client_reg_power. + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -3223,6 +3236,8 @@ enum nl80211_attrs { NL80211_ATTR_MAX_NUM_AKM_SUITES, + NL80211_ATTR_6GHZ_REG_AP_POWER_MODE, + NL80211_ATTR_6GHZ_REG_CLIENT_POWER_MODE, /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/net/wireless/ap.c b/net/wireless/ap.c index e68923200018..be4e6177d72a 100644 --- a/net/wireless/ap.c +++ b/net/wireless/ap.c @@ -82,6 +82,10 @@ int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, wdev_lock(wdev); err = __cfg80211_stop_ap(rdev, dev, link_id, notify); + + if (wdev->reg_6ghz_pwr_configured) + wdev->reg_6ghz_pwr_configured = false; + wdev_unlock(wdev); return err; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index afa8cd686e0e..4d5c45f303ec 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -799,6 +799,12 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN), [NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG }, [NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT }, + [NL80211_ATTR_6GHZ_REG_AP_POWER_MODE] = + NLA_POLICY_RANGE(NLA_U8, IEEE80211_REG_LPI_AP, + IEEE80211_REG_AP_POWER_MAX), + [NL80211_ATTR_6GHZ_REG_CLIENT_POWER_MODE] = + NLA_POLICY_RANGE(NLA_U8, IEEE80211_REG_DEFAULT_CLIENT, + IEEE80211_REG_CLIENT_POWER_MAX), }; /* policy for the key attributes */ @@ -15699,6 +15705,55 @@ static int nl80211_remove_link(struct sk_buff *skb, struct genl_info *info) return 0; } +static int nl80211_set_6ghz_power_mode(struct sk_buff *skb, + struct genl_info *info) +{ + struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = NULL; + enum nl80211_iftype iftype = NL80211_IFTYPE_UNSPECIFIED; + int ret = -EINVAL; + + if (dev) + wdev = dev->ieee80211_ptr; + + if (wdev) + iftype = wdev->iftype; + + if (iftype != NL80211_IFTYPE_AP && + iftype != NL80211_IFTYPE_STATION) + return -EOPNOTSUPP; + + if (!info->attrs[NL80211_ATTR_6GHZ_REG_AP_POWER_MODE] && + !info->attrs[NL80211_ATTR_6GHZ_REG_CLIENT_POWER_MODE]) + return -EINVAL; + + wdev_lock(wdev); + if (wdev->reg_6ghz_pwr_configured) { + wdev_unlock(wdev); + return -EALREADY; + } + + if (iftype == NL80211_IFTYPE_AP && + info->attrs[NL80211_ATTR_6GHZ_REG_AP_POWER_MODE]) { + wdev->ap_6ghz_power = + nla_get_u8(info->attrs[NL80211_ATTR_6GHZ_REG_AP_POWER_MODE]); + ret = 0; + } + + if (iftype == NL80211_IFTYPE_STATION && + info->attrs[NL80211_ATTR_6GHZ_REG_CLIENT_POWER_MODE]) { + wdev->client_6ghz_power = + nla_get_u8(info->attrs[NL80211_ATTR_6GHZ_REG_CLIENT_POWER_MODE]); + ret = 0; + } + + if (!ret) + wdev->reg_6ghz_pwr_configured = true; + + wdev_unlock(wdev); + return ret; +} + #define NL80211_FLAG_NEED_WIPHY 0x01 #define NL80211_FLAG_NEED_NETDEV 0x02 #define NL80211_FLAG_NEED_RTNL 0x04 @@ -16849,6 +16904,13 @@ static const struct genl_small_ops nl80211_small_ops[] = { .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_MLO_VALID_LINK_ID), }, + { + .cmd = NL80211_CMD_SET_6GHZ_POWER_MODE, + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, + .doit = nl80211_set_6ghz_power_mode, + .flags = GENL_UNS_ADMIN_PERM, + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV), + } }; static struct genl_family nl80211_fam __ro_after_init = { diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 00be498aab2e..8858d396e4f8 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -1500,6 +1500,9 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev, if (!wdev->connected) wdev->u.client.ssid_len = 0; + if (wdev->reg_6ghz_pwr_configured) + wdev->reg_6ghz_pwr_configured = false; + return err; } From patchwork Mon Jul 4 10:23:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aditya Kumar Singh X-Patchwork-Id: 12905015 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 768D6CCA47F for ; Mon, 4 Jul 2022 10:25:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234524AbiGDKZ5 (ORCPT ); Mon, 4 Jul 2022 06:25:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45924 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234299AbiGDKZf (ORCPT ); Mon, 4 Jul 2022 06:25:35 -0400 Received: from alexa-out.qualcomm.com (alexa-out.qualcomm.com [129.46.98.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 94AD51115C for ; Mon, 4 Jul 2022 03:24:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1656930253; x=1688466253; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=1rcXM5diwjF9xWa5nm07uvLm6hFCJu0vRsRlo5z046w=; b=QOHUNZZ7Ggc9M6rhKwrlAlzZkDrY6HRj3pK0aZ4fV2Bo2kcEv4i6WTG4 GTeI0Fz8Y5Tv9IBYtrzNFBReAAbxU9eqqiXzr/BysFuvBpIZxA7ffKu4q 2YqAN9tp8BsXWm4kFI3MulkFrjChaK3gYRIJuY+PcKsgQKo/fkZZJezLo 0=; Received: from ironmsg09-lv.qualcomm.com ([10.47.202.153]) by alexa-out.qualcomm.com with ESMTP; 04 Jul 2022 03:24:13 -0700 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg09-lv.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jul 2022 03:24:13 -0700 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Mon, 4 Jul 2022 03:24:12 -0700 Received: from adisi-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Mon, 4 Jul 2022 03:24:11 -0700 From: Aditya Kumar Singh To: CC: , Aditya Kumar Singh Subject: [PATCH 5/7] mac80211: add support for 6 GHz channels and regulatory Date: Mon, 4 Jul 2022 15:53:39 +0530 Message-ID: <20220704102341.5692-6-quic_adisi@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220704102341.5692-1-quic_adisi@quicinc.com> References: <20220704102341.5692-1-quic_adisi@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org 6 GHz introduces various power modes of operation. Currently, based on the power mode, channel's Power Spectral Density (PSD) value as well as channel disabled flag can change. For single interface, current implementation works just fine. But for multi-interfaces, for example AP-STA concurrency, two different channel context needs to be maintained. This is because, STA power mode also depends on the AP's power mode it is going to associate with. Hence, PSD value and channel disabled flag might vary. In this case, same channel context cannot be used for both AP and STA. Therefore, to support multiple channel space for each power mode, the 6 GHz channels needs a separate storage space in struct ieee80211_supported_band. Because of this, the existing APIs to get the channel/freq from freq/channel will not work for 6 GHz band. Add support to store all possible 6 GHz channel pools according to the power mode as well as add API support for getting chan/freq info from the new struct ieee80211_channel_6ghz. Signed-off-by: Aditya Kumar Singh --- include/net/cfg80211.h | 31 ++++++++++++++++++++++++++++ include/net/regulatory.h | 1 + net/mac80211/util.c | 40 +++++++++++++++++++++++++++++++++++- net/wireless/reg.c | 44 +++++++++++++++++++++++++++++++++------- net/wireless/util.c | 27 ++++++++++++++++++++++++ 5 files changed, 135 insertions(+), 8 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 1e8852c6149f..21c058bec5fe 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -512,6 +512,21 @@ struct ieee80211_sta_s1g_cap { u8 nss_mcs[5]; }; +/** + * struct ieee80211_channel_6ghz - 6 GHz channel definitions + * + * This structure defines all the channels supported by the + * 6 GHz band. + * + * @channels: Array of channels the hardware can operate with + * in 6 GHz band. + * @n_channels: Number of channels in @channels + */ +struct ieee80211_channel_6ghz { + struct ieee80211_channel *channels; + int n_channels; +}; + /** * struct ieee80211_supported_band - frequency band definition * @@ -520,6 +535,7 @@ struct ieee80211_sta_s1g_cap { * * @channels: Array of channels the hardware can operate with * in this band. + * @channels_6ghz: Array of 6 GHz channels the hardware can operate with * @band: the band this structure represents * @n_channels: Number of channels in @channels * @bitrates: Array of bitrates the hardware can operate with @@ -539,6 +555,8 @@ struct ieee80211_sta_s1g_cap { */ struct ieee80211_supported_band { struct ieee80211_channel *channels; + struct ieee80211_channel_6ghz + *channels_6ghz[NL80211_REG_MAX_POWER_MODES + 1]; struct ieee80211_rate *bitrates; enum nl80211_band band; int n_channels; @@ -5943,6 +5961,19 @@ ieee80211_get_channel(struct wiphy *wiphy, int freq) return ieee80211_get_channel_khz(wiphy, MHZ_TO_KHZ(freq)); } +/** + * ieee80211_get_6ghz_channel_khz - get channel struct from wiphy for specified + * frequency in 6 GHz band + * + * @wiphy: the struct wiphy to get the channel for + * @freq: the center frequency (in KHz) of the channel + * @power_mode: the power mode in which freq is to be operated + * Return: The channel struct from @wiphy at @freq. + */ +struct ieee80211_channel * +ieee80211_get_6ghz_channel_khz(struct wiphy *wiphy, u32 freq, + enum nl80211_regulatory_power_modes power_mode); + /** * cfg80211_channel_is_psc - Check if the channel is a 6 GHz PSC * @chan: control channel to check diff --git a/include/net/regulatory.h b/include/net/regulatory.h index ed20004fb6a9..5589c3eb8316 100644 --- a/include/net/regulatory.h +++ b/include/net/regulatory.h @@ -218,6 +218,7 @@ struct ieee80211_reg_rule { struct ieee80211_freq_range freq_range; struct ieee80211_power_rule power_rule; struct ieee80211_wmm_rule wmm_rule; + enum nl80211_regulatory_power_modes power_mode; u32 flags; u32 dfs_cac_ms; bool has_wmm; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index efdea5c2f2db..6a955ef5712c 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -3464,6 +3464,9 @@ bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata, bool support_80_80, support_160, support_320; u8 he_phy_cap, eht_phy_cap; u32 freq; + enum ieee80211_ap_reg_power reg_6ghz_power_beacon, reg_6ghz_ap_power; + enum ieee80211_client_reg_power reg_6ghz_client_power; + enum nl80211_regulatory_power_modes reg_6ghz_power_final; if (chandef->chan->band != NL80211_BAND_6GHZ) return true; @@ -3506,6 +3509,39 @@ bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata, return false; } + /* 6 GHz Power mode present in the beacon */ + reg_6ghz_power_beacon = u8_get_bits(he_6ghz_oper->control, + IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO); + switch (reg_6ghz_power_beacon) { + case IEEE80211_REG_LPI_AP: + case IEEE80211_REG_SP_AP: + case IEEE80211_REG_VLP_AP: + break; + default: + sdata_info(sdata, + "Invalid Regulatory Info subfield in HE 6 GHz operation, expect issues\n"); + return false; + } + + /* For AP/AP_VLAN/MESH_POINT interfaces, the 6 GHz power mode depends on the + * mode configured by user (LPI/SP/VLP). For other interfaces (for ex STA) + * mode depends on the power mode present in beacon as well as power mode + * configured by the user for that interface + */ + if (iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_AP_VLAN || + iftype == NL80211_IFTYPE_MESH_POINT) { + /* 6 GHz Power mode configured by the user in the config */ + reg_6ghz_ap_power = sdata->wdev.ap_6ghz_power; + reg_6ghz_power_final = + ieee80211_ap_reg_power_to_reg_power_mode(reg_6ghz_ap_power); + } else { + /* 6 GHz Power mode configured by the user in the config */ + reg_6ghz_client_power = sdata->wdev.client_6ghz_power; + reg_6ghz_power_final = + ieee80211_client_reg_power_to_reg_power_mode(reg_6ghz_client_power, + reg_6ghz_power_beacon); + } + /* * The EHT operation IE does not contain the primary channel so the * primary channel frequency should be taken from the 6 GHz operation @@ -3513,7 +3549,9 @@ bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata, */ freq = ieee80211_channel_to_frequency(he_6ghz_oper->primary, NL80211_BAND_6GHZ); - he_chandef.chan = ieee80211_get_channel(sdata->local->hw.wiphy, freq); + he_chandef.chan = ieee80211_get_6ghz_channel_khz(sdata->local->hw.wiphy, + MHZ_TO_KHZ(freq), + reg_6ghz_power_final); switch (u8_get_bits(he_6ghz_oper->control, IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO)) { diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 9a06aadba0d7..fae360afbd65 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1626,7 +1626,8 @@ static u32 map_regdom_flags(u32 rd_flags) static const struct ieee80211_reg_rule * freq_reg_info_regd(u32 center_freq, - const struct ieee80211_regdomain *regd, u32 bw) + const struct ieee80211_regdomain *regd, u32 bw, + enum nl80211_regulatory_power_modes power_mode) { int i; bool band_rule_found = false; @@ -1640,7 +1641,12 @@ freq_reg_info_regd(u32 center_freq, const struct ieee80211_freq_range *fr = NULL; rr = ®d->reg_rules[i]; - fr = &rr->freq_range; + + if (rr->power_mode == power_mode) + fr = &rr->freq_range; + + if (!fr) + continue; /* * We only need to know if one frequency rule was @@ -1672,7 +1678,8 @@ __freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 min_bw) u32 bw; for (bw = MHZ_TO_KHZ(bws[i]); bw >= min_bw; bw = MHZ_TO_KHZ(bws[i--])) { - reg_rule = freq_reg_info_regd(center_freq, regd, bw); + reg_rule = freq_reg_info_regd(center_freq, regd, bw, + NL80211_REG_AP_LPI); if (!IS_ERR(reg_rule)) return reg_rule; } @@ -2324,7 +2331,8 @@ static void reg_process_ht_flags_channel(struct wiphy *wiphy, if (regd) { const struct ieee80211_reg_rule *reg_rule = freq_reg_info_regd(MHZ_TO_KHZ(channel->center_freq), - regd, MHZ_TO_KHZ(20)); + regd, MHZ_TO_KHZ(20), + NL80211_REG_AP_LPI); if (!IS_ERR(reg_rule)) flags = reg_rule->flags; @@ -2563,7 +2571,8 @@ static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator) static void handle_channel_custom(struct wiphy *wiphy, struct ieee80211_channel *chan, const struct ieee80211_regdomain *regd, - u32 min_bw) + u32 min_bw, + enum nl80211_regulatory_power_modes power_mode) { u32 bw_flags = 0; const struct ieee80211_reg_rule *reg_rule = NULL; @@ -2572,7 +2581,7 @@ static void handle_channel_custom(struct wiphy *wiphy, center_freq_khz = ieee80211_channel_to_khz(chan); for (bw = MHZ_TO_KHZ(20); bw >= min_bw; bw = bw / 2) { - reg_rule = freq_reg_info_regd(center_freq_khz, regd, bw); + reg_rule = freq_reg_info_regd(center_freq_khz, regd, bw, power_mode); if (!IS_ERR(reg_rule)) break; } @@ -2625,10 +2634,30 @@ static void handle_band_custom(struct wiphy *wiphy, const struct ieee80211_regdomain *regd) { unsigned int i; + unsigned int j; + bool _6ghz_new_support = false; if (!sband) return; + if (sband->band == NL80211_BAND_6GHZ) { + for (i = 0; i < NL80211_REG_MAX_POWER_MODES + 1; i++) { + if (!sband->channels_6ghz[i]) + continue; + + if (!_6ghz_new_support) + _6ghz_new_support = true; + + for (j = 0; j < sband->channels_6ghz[i]->n_channels; j++) + handle_channel_custom(wiphy, + &sband->channels_6ghz[i]->channels[j], + regd, MHZ_TO_KHZ(20), i); + } + + if (_6ghz_new_support) + return; + } + /* * We currently assume that you always want at least 20 MHz, * otherwise channel 12 might get enabled if this rule is @@ -2636,7 +2665,8 @@ static void handle_band_custom(struct wiphy *wiphy, */ for (i = 0; i < sband->n_channels; i++) handle_channel_custom(wiphy, &sband->channels[i], regd, - MHZ_TO_KHZ(20)); + MHZ_TO_KHZ(20), + NL80211_REG_AP_LPI); } /* Used by drivers prior to wiphy registration */ diff --git a/net/wireless/util.c b/net/wireless/util.c index cca0ee321a03..38e807e30874 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -165,6 +165,33 @@ int ieee80211_freq_khz_to_channel(u32 freq) } EXPORT_SYMBOL(ieee80211_freq_khz_to_channel); +struct ieee80211_channel +*ieee80211_get_6ghz_channel_khz(struct wiphy *wiphy, u32 freq, + enum nl80211_regulatory_power_modes power_mode) +{ + struct ieee80211_supported_band *sband; + int i; + struct ieee80211_channel *chan; + + sband = wiphy->bands[NL80211_BAND_6GHZ]; + + if (!sband || power_mode >= NL80211_REG_MAX_POWER_MODES + 1) + return NULL; + + if (!sband->channels_6ghz[power_mode]) + return ieee80211_get_channel_khz(wiphy, freq); + + for (i = 0; i < sband->channels_6ghz[power_mode]->n_channels; i++) { + chan = &sband->channels_6ghz[power_mode]->channels[i]; + + if (ieee80211_channel_to_khz(chan) == freq) + return chan; + } + + return NULL; +} +EXPORT_SYMBOL(ieee80211_get_6ghz_channel_khz); + struct ieee80211_channel *ieee80211_get_channel_khz(struct wiphy *wiphy, u32 freq) { From patchwork Mon Jul 4 10:23:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aditya Kumar Singh X-Patchwork-Id: 12905016 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72E87C43334 for ; Mon, 4 Jul 2022 10:26:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233904AbiGDK0B (ORCPT ); Mon, 4 Jul 2022 06:26:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45734 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234416AbiGDKZk (ORCPT ); Mon, 4 Jul 2022 06:25:40 -0400 Received: from alexa-out-sd-02.qualcomm.com (alexa-out-sd-02.qualcomm.com [199.106.114.39]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9644711173 for ; Mon, 4 Jul 2022 03:24:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1656930256; x=1688466256; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=iXM8+wzxpHBX7tWTfApBS8Lo/t8rOP/V6VAcMB5qOQo=; b=S+Vmb98zFu9z2d3NJ+r6MFfcN3pu75Jpm6CR3OtdI8v584mg0HJSGTtB qNw1mVh7r8K3jsmReGMO8yx2ZyafpCdf+18ZlOkEyJzGDRvzG+akuIAw9 CVCJVLcWCps8b0agWDvLLi8Pm1YEKpylOa2OpQt1VPlz8N8/p9gZOW1nC Y=; Received: from unknown (HELO ironmsg-SD-alpha.qualcomm.com) ([10.53.140.30]) by alexa-out-sd-02.qualcomm.com with ESMTP; 04 Jul 2022 03:24:15 -0700 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg-SD-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jul 2022 03:24:15 -0700 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Mon, 4 Jul 2022 03:24:15 -0700 Received: from adisi-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Mon, 4 Jul 2022 03:24:13 -0700 From: Aditya Kumar Singh To: CC: , Aditya Kumar Singh Subject: [PATCH 6/7] cfg80211: rework nl80211_parse_chandef for 6 GHz Date: Mon, 4 Jul 2022 15:53:40 +0530 Message-ID: <20220704102341.5692-7-quic_adisi@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220704102341.5692-1-quic_adisi@quicinc.com> References: <20220704102341.5692-1-quic_adisi@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Currently, nl80211_parse_chandef function just selects a channel based on the control frequency provided. However, for 6 GHz, power mode also needs to be considered since 6 GHz has got multiple channel pools based on the power mode. Modify logic to consider power mode as well for 6 GHz interface and accordingly select the channel for the given control frequency. Signed-off-by: Aditya Kumar Singh --- include/net/cfg80211.h | 4 +++ net/mac80211/cfg.c | 35 ++++++++++++++++++++++++ net/wireless/nl80211.c | 59 +++++++++++++++++++++++++++++------------ net/wireless/nl80211.h | 3 ++- net/wireless/pmsr.c | 8 +++--- net/wireless/rdev-ops.h | 19 +++++++++++++ net/wireless/trace.h | 21 +++++++++++++++ 7 files changed, 128 insertions(+), 21 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 21c058bec5fe..df493feb6d89 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -4238,6 +4238,8 @@ struct mgmt_frame_regs { * radar channel. * The caller is expected to set chandef pointer to NULL in order to * disable background CAC/radar detection. + * + * @get_6ghz_power_mode: Get the 6 GHz power mode for the given interface. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -4583,6 +4585,8 @@ struct cfg80211_ops { struct cfg80211_fils_aad *fils_aad); int (*set_radar_background)(struct wiphy *wiphy, struct cfg80211_chan_def *chandef); + int (*get_6ghz_power_mode)(struct wireless_dev *wdev, + enum nl80211_regulatory_power_modes *power_mode_6ghz); }; /* diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index fd6c4291c971..4962f9b5917f 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -4549,6 +4549,40 @@ static void ieee80211_del_intf_link(struct wiphy *wiphy, ieee80211_vif_set_links(sdata, wdev->valid_links); } +static int +ieee80211_get_6ghz_power_mode(struct wireless_dev *wdev, + enum nl80211_regulatory_power_modes *power_mode_6ghz) +{ + enum nl80211_iftype iftype; + struct ieee80211_sub_if_data *sdata; + struct ieee80211_vif vif; + + if (!wdev) + return 1; + + iftype = wdev->iftype; + + /* For APs, 6 GHz power mode is taken from the user configured + * value. However, for clients, power mode is also dependent + * upon the APs power mode to which this client has associated. + * Hence for client, need to take power mode of asscoiated AP, + * which is present in beacon data. + */ + if (iftype == NL80211_IFTYPE_AP) { + *power_mode_6ghz = + ieee80211_ap_reg_power_to_reg_power_mode(wdev->ap_6ghz_power); + } else if (iftype == NL80211_IFTYPE_STATION) { + sdata = container_of(wdev, struct ieee80211_sub_if_data, wdev); + vif = sdata->vif; + + *power_mode_6ghz = + ieee80211_client_reg_power_to_reg_power_mode(wdev->client_6ghz_power, + vif.bss_conf.power_type); + } + + return 0; +} + const struct cfg80211_ops mac80211_config_ops = { .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface, @@ -4656,4 +4690,5 @@ const struct cfg80211_ops mac80211_config_ops = { .set_radar_background = ieee80211_set_radar_background, .add_intf_link = ieee80211_add_intf_link, .del_intf_link = ieee80211_del_intf_link, + .get_6ghz_power_mode = ieee80211_get_6ghz_power_mode, }; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4d5c45f303ec..915516bd4d93 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3163,10 +3163,12 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, struct genl_info *info, - struct cfg80211_chan_def *chandef) + struct cfg80211_chan_def *chandef, + struct wireless_dev *wdev) { struct netlink_ext_ack *extack = info->extack; struct nlattr **attrs = info->attrs; + enum nl80211_regulatory_power_modes power_mode_6ghz = NL80211_REG_AP_LPI; u32 control_freq; if (!attrs[NL80211_ATTR_WIPHY_FREQ]) @@ -3179,7 +3181,26 @@ int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]); memset(chandef, 0, sizeof(*chandef)); - chandef->chan = ieee80211_get_channel_khz(&rdev->wiphy, control_freq); + + if (control_freq >= MHZ_TO_KHZ(5945) && control_freq <= MHZ_TO_KHZ(7125)) { + if (!wdev) + return -EINVAL; + + if (!rdev->ops->get_6ghz_power_mode) + return -EINVAL; + + power_mode_6ghz = rdev_get_6ghz_power_mode(rdev, wdev); + + if (power_mode_6ghz >= NL80211_REG_MAX_POWER_MODES + 1) + return -EINVAL; + + chandef->chan = ieee80211_get_6ghz_channel_khz(&rdev->wiphy, + control_freq, + power_mode_6ghz); + } else { + chandef->chan = ieee80211_get_channel_khz(&rdev->wiphy, control_freq); + } + chandef->width = NL80211_CHAN_WIDTH_20_NOHT; chandef->center_freq1 = KHZ_TO_MHZ(control_freq); chandef->freq1_offset = control_freq % 1000; @@ -3310,7 +3331,7 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, link_id = 0; } - result = nl80211_parse_chandef(rdev, info, &chandef); + result = nl80211_parse_chandef(rdev, info, &chandef, wdev); if (result) return result; @@ -5786,7 +5807,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) } if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { - err = nl80211_parse_chandef(rdev, info, ¶ms->chandef); + err = nl80211_parse_chandef(rdev, info, ¶ms->chandef, + wdev); if (err) goto out; } else if (wdev->valid_links) { @@ -9580,7 +9602,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb, if (dfs_region == NL80211_DFS_UNSET) goto unlock; - err = nl80211_parse_chandef(rdev, info, &chandef); + err = nl80211_parse_chandef(rdev, info, &chandef, wdev); if (err) goto unlock; @@ -9660,7 +9682,7 @@ static int nl80211_notify_radar_detection(struct sk_buff *skb, return -EINVAL; } - err = nl80211_parse_chandef(rdev, info, &chandef); + err = nl80211_parse_chandef(rdev, info, &chandef, wdev); if (err) { GENL_SET_ERR_MSG(info, "Unable to extract chandef info"); return err; @@ -9858,7 +9880,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) } skip_beacons: - err = nl80211_parse_chandef(rdev, info, ¶ms.chandef); + err = nl80211_parse_chandef(rdev, info, ¶ms.chandef, wdev); if (err) goto free; @@ -10903,6 +10925,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) struct cfg80211_ibss_params ibss; struct wiphy *wiphy; struct cfg80211_cached_keys *connkeys = NULL; + struct wireless_dev *wdev = dev->ieee80211_ptr; int err; memset(&ibss, 0, sizeof(ibss)); @@ -10925,7 +10948,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->join_ibss) return -EOPNOTSUPP; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) + if (wdev->iftype != NL80211_IFTYPE_ADHOC) return -EOPNOTSUPP; wiphy = &rdev->wiphy; @@ -10944,7 +10967,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); } - err = nl80211_parse_chandef(rdev, info, &ibss.chandef); + err = nl80211_parse_chandef(rdev, info, &ibss.chandef, wdev); if (err) return err; @@ -11043,13 +11066,13 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) ibss.userspace_handles_dfs = nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]); - wdev_lock(dev->ieee80211_ptr); + wdev_lock(wdev); err = __cfg80211_join_ibss(rdev, dev, &ibss, connkeys); if (err) kfree_sensitive(connkeys); else if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) - dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid; - wdev_unlock(dev->ieee80211_ptr); + wdev->conn_owner_nlportid = info->snd_portid; + wdev_unlock(wdev); return err; } @@ -11918,7 +11941,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, duration > rdev->wiphy.max_remain_on_channel_duration) return -EINVAL; - err = nl80211_parse_chandef(rdev, info, &chandef); + err = nl80211_parse_chandef(rdev, info, &chandef, wdev); if (err) return err; @@ -12132,7 +12155,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) */ chandef.chan = NULL; if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { - err = nl80211_parse_chandef(rdev, info, &chandef); + err = nl80211_parse_chandef(rdev, info, &chandef, wdev); if (err) return err; } @@ -12525,7 +12548,8 @@ static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info) struct ocb_setup setup = {}; int err; - err = nl80211_parse_chandef(rdev, info, &setup.chandef); + err = nl80211_parse_chandef(rdev, info, &setup.chandef, + dev->ieee80211_ptr); if (err) return err; @@ -12600,7 +12624,8 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) cfg.auto_open_plinks = false; if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { - err = nl80211_parse_chandef(rdev, info, &setup.chandef); + err = nl80211_parse_chandef(rdev, info, &setup.chandef, + dev->ieee80211_ptr); if (err) return err; } else { @@ -14933,7 +14958,7 @@ static int nl80211_tdls_channel_switch(struct sk_buff *skb, !info->attrs[NL80211_ATTR_OPER_CLASS]) return -EINVAL; - err = nl80211_parse_chandef(rdev, info, &chandef); + err = nl80211_parse_chandef(rdev, info, &chandef, wdev); if (err) return err; diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index d642e3be4ee7..76e95e6b4c11 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -24,7 +24,8 @@ static inline u64 wdev_id(struct wireless_dev *wdev) int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, struct genl_info *info, - struct cfg80211_chan_def *chandef); + struct cfg80211_chan_def *chandef, + struct wireless_dev *wdev); int nl80211_parse_random_mac(struct nlattr **attrs, u8 *mac_addr, u8 *mac_addr_mask); diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c index 2bc647720cda..501b8af547e1 100644 --- a/net/wireless/pmsr.c +++ b/net/wireless/pmsr.c @@ -184,7 +184,8 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, static int pmsr_parse_peer(struct cfg80211_registered_device *rdev, struct nlattr *peer, struct cfg80211_pmsr_request_peer *out, - struct genl_info *info) + struct genl_info *info, + struct wireless_dev *wdev) { struct nlattr *tb[NL80211_PMSR_PEER_ATTR_MAX + 1]; struct nlattr *req[NL80211_PMSR_REQ_ATTR_MAX + 1]; @@ -213,7 +214,7 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev, if (err) return err; - err = nl80211_parse_chandef(rdev, info, &out->chandef); + err = nl80211_parse_chandef(rdev, info, &out->chandef, wdev); if (err) return err; @@ -316,7 +317,8 @@ int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info) idx = 0; nla_for_each_nested(peer, peers, rem) { /* NB: this reuses info->attrs, but we no longer need it */ - err = pmsr_parse_peer(rdev, peer, &req->peers[idx], info); + err = pmsr_parse_peer(rdev, peer, &req->peers[idx], info, + wdev); if (err) goto out_err; idx++; diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index a329ba036989..4dac065c55ed 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -1448,4 +1448,23 @@ rdev_del_intf_link(struct cfg80211_registered_device *rdev, trace_rdev_return_void(&rdev->wiphy); } +static inline enum nl80211_regulatory_power_modes +rdev_get_6ghz_power_mode(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev) +{ + enum nl80211_regulatory_power_modes power_mode_6ghz = NL80211_REG_AP_LPI; + int ret; + + if (!rdev->ops->get_6ghz_power_mode) + return NL80211_REG_MAX_POWER_MODES + 1; + + trace_rdev_get_6ghz_power_mode(&rdev->wiphy, wdev); + ret = rdev->ops->get_6ghz_power_mode(wdev, &power_mode_6ghz); + trace_rdev_return_6ghz_power_mode(wdev, ret, power_mode_6ghz); + + if (ret) + return NL80211_REG_MAX_POWER_MODES + 1; + + return power_mode_6ghz; +} #endif /* __CFG80211_RDEV_OPS */ diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 65f8b814ecd0..9308efde3cb2 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -3775,6 +3775,27 @@ TRACE_EVENT(cfg80211_assoc_comeback, WDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->timeout) ); +DEFINE_EVENT(wiphy_wdev_evt, rdev_get_6ghz_power_mode, + TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), + TP_ARGS(wiphy, wdev) +); + +TRACE_EVENT(rdev_return_6ghz_power_mode, + TP_PROTO(struct wireless_dev *wdev, int ret, u8 power_mode), + TP_ARGS(wdev, ret, power_mode), + TP_STRUCT__entry( + WDEV_ENTRY + __field(u8, ret) + __field(u8, power_mode) + ), + TP_fast_assign( + WDEV_ASSIGN; + __entry->ret = ret; + __entry->power_mode = power_mode; + ), + TP_printk(WDEV_PR_FMT ", function returns: %d, function filled: %d", + WDEV_PR_ARG, __entry->ret, __entry->power_mode) +); #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ #undef TRACE_INCLUDE_PATH From patchwork Mon Jul 4 10:23:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aditya Kumar Singh X-Patchwork-Id: 12905017 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C607BC43334 for ; Mon, 4 Jul 2022 10:26:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233456AbiGDK0D (ORCPT ); Mon, 4 Jul 2022 06:26:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234450AbiGDKZm (ORCPT ); Mon, 4 Jul 2022 06:25:42 -0400 Received: from alexa-out-sd-02.qualcomm.com (alexa-out-sd-02.qualcomm.com [199.106.114.39]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7926211440 for ; Mon, 4 Jul 2022 03:24:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1656930258; x=1688466258; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=MvdYv+YJGN2ILOx1k1ef7ciZKV3uX6IdJ7SV9yLTtkA=; b=v0YoVWrtPt36Vf/T61YlHK3YAxye67906+eBDIQDlVn2wJA3Xwvc7YXc f7XWKhgydVoygIzmKbpKYmggaOucqg+eXoaxvgYgCmSQqd0qHA4UbJ3yw Um44OdTwrtpojnF6ZzrkJgmE+lXqKIXZUoUHer7fHPcU22+jyCP/m8Gsn o=; Received: from unknown (HELO ironmsg-SD-alpha.qualcomm.com) ([10.53.140.30]) by alexa-out-sd-02.qualcomm.com with ESMTP; 04 Jul 2022 03:24:18 -0700 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg-SD-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jul 2022 03:24:18 -0700 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Mon, 4 Jul 2022 03:24:17 -0700 Received: from adisi-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.22; Mon, 4 Jul 2022 03:24:16 -0700 From: Aditya Kumar Singh To: CC: , Aditya Kumar Singh Subject: [PATCH 7/7] cfg80211: save 6 GHz power mode of the regulatory rules Date: Mon, 4 Jul 2022 15:53:41 +0530 Message-ID: <20220704102341.5692-8-quic_adisi@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220704102341.5692-1-quic_adisi@quicinc.com> References: <20220704102341.5692-1-quic_adisi@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Currently when user space demands the reg rules via NL80211_CMD_GET_REG command, along with Power Spectral Denity (PSD) values, power mode needs to be advertised since in 6 GHz AP beacon, Tx power envelope should have PSD info as well which can be opted based on the power mode. Similarly, via NL80211_CMD_SET_REG command, user space can try to set regulatory rules and cfg80211 needs to store the incoming power mode for the rule. Add support for 6 GHz power mode advertisement in NL80211_CMD_GET_REG command and saving 6 GHz power mode for reg rules via NL80211_CMD_SET_REG command. Signed-off-by: Aditya Kumar Singh --- include/uapi/linux/nl80211.h | 4 ++++ net/wireless/nl80211.c | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index e62838887802..f2a32023a3f4 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -4258,6 +4258,8 @@ enum nl80211_reg_type { * If not present or 0 default CAC time will be used. * @NL80211_ATTR_POWER_RULE_PSD: power spectral density (in dBm). * This could be negative. + * @NL80211_ATTR_REG_POWER_MODE: the regulatory power mode for 6 GHz rules. + * Referenced from &enum nl80211_regulatory_power_modes * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number * currently defined * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use @@ -4277,6 +4279,8 @@ enum nl80211_reg_rule_attr { NL80211_ATTR_POWER_RULE_PSD, + NL80211_ATTR_REG_POWER_MODE, + /* keep last */ __NL80211_REG_RULE_ATTR_AFTER_LAST, NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 915516bd4d93..5c0ac12c26b7 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -8200,6 +8200,13 @@ static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom, reg_rule->dfs_cac_ms)) goto nla_put_failure; + /* Put power mode as well if its a 6 GHz reg rule */ + if (freq_range->start_freq_khz >= MHZ_TO_KHZ(5925) && + freq_range->end_freq_khz <= MHZ_TO_KHZ(7125) && + nla_put_u8(msg, NL80211_ATTR_REG_POWER_MODE, + reg_rule->power_mode)) + goto nla_put_failure; + if ((reg_rule->flags & NL80211_RRF_PSD) && nla_put_s8(msg, NL80211_ATTR_POWER_RULE_PSD, reg_rule->psd)) @@ -8379,6 +8386,10 @@ static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 }, [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 }, [NL80211_ATTR_POWER_RULE_PSD] = { .type = NLA_S8 }, + [NL80211_ATTR_REG_POWER_MODE] = + NLA_POLICY_RANGE(NLA_U8, + NL80211_REG_AP_LPI, + NL80211_REG_MAX_POWER_MODES), }; static int parse_reg_rule(struct nlattr *tb[], @@ -8426,6 +8437,15 @@ static int parse_reg_rule(struct nlattr *tb[], reg_rule->dfs_cac_ms = nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]); + if (freq_range->start_freq_khz >= MHZ_TO_KHZ(5925) && + freq_range->end_freq_khz <= MHZ_TO_KHZ(7125)) { + if (!tb[NL80211_ATTR_REG_POWER_MODE]) + return -EINVAL; + + reg_rule->power_mode = + nla_get_u8(tb[NL80211_ATTR_REG_POWER_MODE]); + } + return 0; }