From patchwork Mon Aug 31 20:55:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 259410 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8873BC433E2 for ; Mon, 31 Aug 2020 20:56:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 688FA206E3 for ; Mon, 31 Aug 2020 20:56:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729493AbgHaU4L (ORCPT ); Mon, 31 Aug 2020 16:56:11 -0400 Received: from mail.adapt-ip.com ([173.164.178.19]:52174 "EHLO web.adapt-ip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729325AbgHaU4L (ORCPT ); Mon, 31 Aug 2020 16:56:11 -0400 Received: from localhost (localhost [127.0.0.1]) by web.adapt-ip.com (Postfix) with ESMTP id 828764F8E7E; Mon, 31 Aug 2020 20:56:10 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at web.adapt-ip.com Received: from web.adapt-ip.com ([127.0.0.1]) by localhost (web.adapt-ip.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id d07uZxoOyeAC; Mon, 31 Aug 2020 20:56:07 +0000 (UTC) Received: from atlas.campbell.adapt-ip.com (gateway.adapt-ip.com [173.164.178.20]) (Authenticated sender: thomas@adapt-ip.com) by web.adapt-ip.com (Postfix) with ESMTPSA id B84AC4F865E; Mon, 31 Aug 2020 20:56:04 +0000 (UTC) From: Thomas Pedersen To: Johannes Berg Cc: linux-wireless , Thomas Pedersen Subject: [PATCH v2 02/22] nl80211: advertise supported channel width in S1G Date: Mon, 31 Aug 2020 13:55:40 -0700 Message-Id: <20200831205600.21058-3-thomas@adapt-ip.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200831205600.21058-1-thomas@adapt-ip.com> References: <20200831205600.21058-1-thomas@adapt-ip.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org S1G supports 5 channel widths: 1, 2, 4, 8, and 16. One channel width is allowed per frequency in each operating class, so it makes more sense to advertise the specific channel width allowed. Signed-off-by: Thomas Pedersen --- include/net/cfg80211.h | 15 +++++++++++++++ include/uapi/linux/nl80211.h | 15 +++++++++++++++ net/wireless/nl80211.c | 15 +++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index c9bce9bba511..e4d4fbcb2edc 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -96,6 +96,16 @@ struct wiphy; * @IEEE80211_CHAN_NO_10MHZ: 10 MHz bandwidth is not permitted * on this channel. * @IEEE80211_CHAN_NO_HE: HE operation is not permitted on this channel. + * @IEEE80211_CHAN_1MHZ: 1 MHz bandwidth is permitted + * on this channel. + * @IEEE80211_CHAN_2MHZ: 2 MHz bandwidth is permitted + * on this channel. + * @IEEE80211_CHAN_4MHZ: 4 MHz bandwidth is permitted + * on this channel. + * @IEEE80211_CHAN_8MHZ: 8 MHz bandwidth is permitted + * on this channel. + * @IEEE80211_CHAN_16MHZ: 16 MHz bandwidth is permitted + * on this channel. * */ enum ieee80211_channel_flags { @@ -113,6 +123,11 @@ enum ieee80211_channel_flags { IEEE80211_CHAN_NO_20MHZ = 1<<11, IEEE80211_CHAN_NO_10MHZ = 1<<12, IEEE80211_CHAN_NO_HE = 1<<13, + IEEE80211_CHAN_1MHZ = 1<<14, + IEEE80211_CHAN_2MHZ = 1<<15, + IEEE80211_CHAN_4MHZ = 1<<16, + IEEE80211_CHAN_8MHZ = 1<<17, + IEEE80211_CHAN_16MHZ = 1<<18, }; #define IEEE80211_CHAN_NO_HT40 \ diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 0584e0d349f0..4e119c6afa31 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -3737,6 +3737,16 @@ enum nl80211_wmm_rule { * @NL80211_FREQUENCY_ATTR_NO_HE: HE operation is not allowed on this channel * in current regulatory domain. * @NL80211_FREQUENCY_ATTR_OFFSET: frequency offset in KHz + * @NL80211_FREQUENCY_ATTR_1MHZ: 1 MHz operation is allowed + * on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_2MHZ: 2 MHz operation is allowed + * on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_4MHZ: 4 MHz operation is allowed + * on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_8MHZ: 8 MHz operation is allowed + * on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_16MHZ: 16 MHz operation 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 @@ -3768,6 +3778,11 @@ enum nl80211_frequency_attr { NL80211_FREQUENCY_ATTR_WMM, NL80211_FREQUENCY_ATTR_NO_HE, NL80211_FREQUENCY_ATTR_OFFSET, + NL80211_FREQUENCY_ATTR_1MHZ, + NL80211_FREQUENCY_ATTR_2MHZ, + NL80211_FREQUENCY_ATTR_4MHZ, + NL80211_FREQUENCY_ATTR_8MHZ, + NL80211_FREQUENCY_ATTR_16MHZ, /* keep last */ __NL80211_FREQUENCY_ATTR_AFTER_LAST, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 52a35e788547..7da4d84bcc1a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1010,6 +1010,21 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy, if ((chan->flags & IEEE80211_CHAN_NO_HE) && nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HE)) goto nla_put_failure; + if ((chan->flags & IEEE80211_CHAN_1MHZ) && + nla_put_flag(msg, NL80211_FREQUENCY_ATTR_1MHZ)) + goto nla_put_failure; + if ((chan->flags & IEEE80211_CHAN_2MHZ) && + nla_put_flag(msg, NL80211_FREQUENCY_ATTR_2MHZ)) + goto nla_put_failure; + if ((chan->flags & IEEE80211_CHAN_4MHZ) && + nla_put_flag(msg, NL80211_FREQUENCY_ATTR_4MHZ)) + goto nla_put_failure; + if ((chan->flags & IEEE80211_CHAN_8MHZ) && + nla_put_flag(msg, NL80211_FREQUENCY_ATTR_8MHZ)) + goto nla_put_failure; + if ((chan->flags & IEEE80211_CHAN_16MHZ) && + nla_put_flag(msg, NL80211_FREQUENCY_ATTR_16MHZ)) + goto nla_put_failure; } if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, From patchwork Mon Aug 31 20:55:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 259409 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD3D6C433E6 for ; Mon, 31 Aug 2020 20:56:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7B9F2206E3 for ; Mon, 31 Aug 2020 20:56:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729552AbgHaU4O (ORCPT ); Mon, 31 Aug 2020 16:56:14 -0400 Received: from mail.adapt-ip.com ([173.164.178.19]:52210 "EHLO web.adapt-ip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729485AbgHaU4N (ORCPT ); Mon, 31 Aug 2020 16:56:13 -0400 Received: from localhost (localhost [127.0.0.1]) by web.adapt-ip.com (Postfix) with ESMTP id 51DAC4F8F09; Mon, 31 Aug 2020 20:56:13 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at web.adapt-ip.com Received: from web.adapt-ip.com ([127.0.0.1]) by localhost (web.adapt-ip.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id kxkuQSDrrqZr; Mon, 31 Aug 2020 20:56:10 +0000 (UTC) Received: from atlas.campbell.adapt-ip.com (gateway.adapt-ip.com [173.164.178.20]) (Authenticated sender: thomas@adapt-ip.com) by web.adapt-ip.com (Postfix) with ESMTPSA id 94E744F8D69; Mon, 31 Aug 2020 20:56:06 +0000 (UTC) From: Thomas Pedersen To: Johannes Berg Cc: linux-wireless , Thomas Pedersen Subject: [PATCH v2 04/22] nl80211: correctly validate S1G beacon head Date: Mon, 31 Aug 2020 13:55:42 -0700 Message-Id: <20200831205600.21058-5-thomas@adapt-ip.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200831205600.21058-1-thomas@adapt-ip.com> References: <20200831205600.21058-1-thomas@adapt-ip.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org The S1G beacon has a different header size than regular beacons, so adjust the beacon head validator. Signed-off-by: Thomas Pedersen --- net/wireless/nl80211.c | 16 +++++++++++++--- net/wireless/util.c | 5 +++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 7da4d84bcc1a..3bf595c828db 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -209,14 +209,24 @@ static int validate_beacon_head(const struct nlattr *attr, unsigned int len = nla_len(attr); const struct element *elem; const struct ieee80211_mgmt *mgmt = (void *)data; - unsigned int fixedlen = offsetof(struct ieee80211_mgmt, - u.beacon.variable); + bool s1g_bcn = ieee80211_is_s1g_beacon(mgmt->frame_control); + unsigned int fixedlen, hdrlen; + + if (s1g_bcn) { + fixedlen = offsetof(struct ieee80211_ext, + u.s1g_beacon.variable); + hdrlen = offsetof(struct ieee80211_ext, u.s1g_beacon); + } else { + fixedlen = offsetof(struct ieee80211_mgmt, + u.beacon.variable); + hdrlen = offsetof(struct ieee80211_mgmt, u.beacon); + } if (len < fixedlen) goto err; if (ieee80211_hdrlen(mgmt->frame_control) != - offsetof(struct ieee80211_mgmt, u.beacon)) + hdrlen) goto err; data += fixedlen; diff --git a/net/wireless/util.c b/net/wireless/util.c index 4a9ff9ef513f..49e7c0cbbf62 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -399,6 +399,11 @@ unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc) { unsigned int hdrlen = 24; + if (ieee80211_is_ext(fc)) { + hdrlen = 4; + goto out; + } + if (ieee80211_is_data(fc)) { if (ieee80211_has_a4(fc)) hdrlen = 30; From patchwork Mon Aug 31 20:55:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 259408 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1271AC433E6 for ; Mon, 31 Aug 2020 20:56:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DA1B4206E3 for ; Mon, 31 Aug 2020 20:56:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729591AbgHaU4S (ORCPT ); Mon, 31 Aug 2020 16:56:18 -0400 Received: from mail.adapt-ip.com ([173.164.178.19]:52242 "EHLO web.adapt-ip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729462AbgHaU4Q (ORCPT ); Mon, 31 Aug 2020 16:56:16 -0400 Received: from localhost (localhost [127.0.0.1]) by web.adapt-ip.com (Postfix) with ESMTP id 399634F8F92; Mon, 31 Aug 2020 20:56:16 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at web.adapt-ip.com Received: from web.adapt-ip.com ([127.0.0.1]) by localhost (web.adapt-ip.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id lTTqmStC6uTE; Mon, 31 Aug 2020 20:56:13 +0000 (UTC) Received: from atlas.campbell.adapt-ip.com (gateway.adapt-ip.com [173.164.178.20]) (Authenticated sender: thomas@adapt-ip.com) by web.adapt-ip.com (Postfix) with ESMTPSA id 58D904EE3BF; Mon, 31 Aug 2020 20:56:08 +0000 (UTC) From: Thomas Pedersen To: Johannes Berg Cc: linux-wireless , Thomas Pedersen Subject: [PATCH v2 06/22] {cfg, mac}80211: get correct default channel width for S1G Date: Mon, 31 Aug 2020 13:55:44 -0700 Message-Id: <20200831205600.21058-7-thomas@adapt-ip.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200831205600.21058-1-thomas@adapt-ip.com> References: <20200831205600.21058-1-thomas@adapt-ip.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Until now, the wifi default channels were assumed to be NL80211_CHAN_NO_HT, or NL80211_CHAN_WIDTH_20_NOHT. S1G devices however do not support these channel types/width. When a default channel width is requested (during default chandef init, or chanctx removal when not using channel context), for S1G calculate the correct width. Fixes eg. configuring strange (20Mhz) width during a scan on the S1G band. Signed-off-by: Thomas Pedersen --- net/mac80211/chan.c | 9 ++++++++- net/wireless/chan.c | 10 ++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index bdc0f29dc6cd..8f48aff74c7b 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -536,7 +536,14 @@ static void ieee80211_del_chanctx(struct ieee80211_local *local, if (!local->use_chanctx) { struct cfg80211_chan_def *chandef = &local->_oper_chandef; - chandef->width = NL80211_CHAN_WIDTH_20_NOHT; + /* S1G doesn't have 20MHz, so get the correct width for the + * current channel. + */ + if (chandef->chan->band == NL80211_BAND_S1GHZ) + chandef->width = + ieee80211_s1g_channel_width(chandef->chan); + else + chandef->width = NL80211_CHAN_WIDTH_20_NOHT; chandef->center_freq1 = chandef->chan->center_freq; chandef->freq1_offset = chandef->chan->freq_offset; chandef->center_freq2 = 0; diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 96e24ee4c7e8..a3bc50e419fd 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -33,6 +33,16 @@ void cfg80211_chandef_create(struct cfg80211_chan_def *chandef, chandef->edmg.bw_config = 0; chandef->edmg.channels = 0; + /* S1G allows a single width per channel, and since chan_type seems to + * be for backwards compatibility only, ignore it and return the per + * frequency width. + */ + if (chan->band == NL80211_BAND_S1GHZ) { + chandef->width = ieee80211_s1g_channel_width(chan); + chandef->center_freq1 = chan->center_freq; + return; + } + switch (chan_type) { case NL80211_CHAN_NO_HT: chandef->width = NL80211_CHAN_WIDTH_20_NOHT; From patchwork Mon Aug 31 20:55:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 259407 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C936AC433E2 for ; Mon, 31 Aug 2020 20:56:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A4D87206E3 for ; Mon, 31 Aug 2020 20:56:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730027AbgHaU4X (ORCPT ); Mon, 31 Aug 2020 16:56:23 -0400 Received: from mail.adapt-ip.com ([173.164.178.19]:52258 "EHLO web.adapt-ip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729579AbgHaU4V (ORCPT ); Mon, 31 Aug 2020 16:56:21 -0400 Received: from localhost (localhost [127.0.0.1]) by web.adapt-ip.com (Postfix) with ESMTP id 5F8AC4F8FD1; Mon, 31 Aug 2020 20:56:20 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at web.adapt-ip.com Received: from web.adapt-ip.com ([127.0.0.1]) by localhost (web.adapt-ip.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id JkVdohn1JObb; Mon, 31 Aug 2020 20:56:17 +0000 (UTC) Received: from atlas.campbell.adapt-ip.com (gateway.adapt-ip.com [173.164.178.20]) (Authenticated sender: thomas@adapt-ip.com) by web.adapt-ip.com (Postfix) with ESMTPSA id 410D54F8DB8; Mon, 31 Aug 2020 20:56:09 +0000 (UTC) From: Thomas Pedersen To: Johannes Berg Cc: linux-wireless , Thomas Pedersen Subject: [PATCH v2 08/22] nl80211: support S1G capabilities Date: Mon, 31 Aug 2020 13:55:46 -0700 Message-Id: <20200831205600.21058-9-thomas@adapt-ip.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200831205600.21058-1-thomas@adapt-ip.com> References: <20200831205600.21058-1-thomas@adapt-ip.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Declare the structures needed to define S1G capabilities. NL80211_ATTR_S1G_CAPABILITY can be passed along with NL80211_ATTR_S1G_CAPABILITY_MASK to NL80211_CMD_ASSOCIATE to indicate S1G capabilities which should override the hardware capabilities in eg. the association request. Signed-off-by: Thomas Pedersen --- include/net/cfg80211.h | 3 +++ include/uapi/linux/nl80211.h | 9 +++++++++ net/wireless/nl80211.c | 16 ++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index d3d85bd9c0aa..de04c7996b27 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2489,6 +2489,8 @@ enum cfg80211_assoc_req_flags { * @fils_nonces: FILS nonces (part of AAD) for protecting (Re)Association * Request/Response frame or %NULL if FILS is not used. This field starts * with 16 octets of STA Nonce followed by 16 octets of AP Nonce. + * @s1g_capa: S1G capability override + * @s1g_capa_mask: S1G capability override mask */ struct cfg80211_assoc_request { struct cfg80211_bss *bss; @@ -2503,6 +2505,7 @@ struct cfg80211_assoc_request { const u8 *fils_kek; size_t fils_kek_len; const u8 *fils_nonces; + struct ieee80211_s1g_cap s1g_capa, s1g_capa_mask; }; /** diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 4e119c6afa31..70076492ebc9 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -2513,6 +2513,12 @@ enum nl80211_commands { * @NL80211_ATTR_HE_6GHZ_CAPABILITY: HE 6 GHz Band Capability element (from * association request when used with NL80211_CMD_NEW_STATION). * + * @NL80211_ATTR_S1G_CAPABILITY: S1G Capability information element (from + * association request when used with NL80211_CMD_NEW_STATION) + * @NL80211_ATTR_S1G_CAPABILITY_MASK: S1G Capability Information element + * override mask. Used with NL80211_ATTR_S1G_CAPABILITY in + * NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT. + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -2995,6 +3001,8 @@ enum nl80211_attrs { NL80211_ATTR_HE_6GHZ_CAPABILITY, + NL80211_ATTR_S1G_CAPABILITY, + NL80211_ATTR_S1G_CAPABILITY_MASK, /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -3046,6 +3054,7 @@ enum nl80211_attrs { #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 #define NL80211_HT_CAPABILITY_LEN 26 #define NL80211_VHT_CAPABILITY_LEN 12 +#define NL80211_S1G_CAPABILITY_LEN 15 #define NL80211_HE_MIN_CAPABILITY_LEN 16 #define NL80211_HE_MAX_CAPABILITY_LEN 54 #define NL80211_MAX_NR_CIPHER_SUITES 5 diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 3bf595c828db..578d99088719 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -685,6 +685,9 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_SCAN_FREQ_KHZ] = { .type = NLA_NESTED }, [NL80211_ATTR_HE_6GHZ_CAPABILITY] = NLA_POLICY_EXACT_LEN(sizeof(struct ieee80211_he_6ghz_capa)), + [NL80211_ATTR_S1G_CAPABILITY] = { .len = NL80211_S1G_CAPABILITY_LEN }, + [NL80211_ATTR_S1G_CAPABILITY_MASK] = { + .len = NL80211_S1G_CAPABILITY_LEN }, }; /* policy for the key attributes */ @@ -9698,6 +9701,19 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) nla_data(info->attrs[NL80211_ATTR_FILS_NONCES]); } + if (info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK]) + memcpy(&req.s1g_capa_mask, + nla_data(info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK]), + sizeof(req.s1g_capa_mask)); + + if (info->attrs[NL80211_ATTR_S1G_CAPABILITY]) { + if (!info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK]) + return -EINVAL; + memcpy(&req.s1g_capa, + nla_data(info->attrs[NL80211_ATTR_S1G_CAPABILITY]), + sizeof(req.s1g_capa)); + } + err = nl80211_crypto_settings(rdev, info, &req.crypto, 1); if (!err) { wdev_lock(dev->ieee80211_ptr); From patchwork Mon Aug 31 20:55:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 259406 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C9C20C433E6 for ; Mon, 31 Aug 2020 20:56:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A502D206E3 for ; Mon, 31 Aug 2020 20:56:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729323AbgHaU41 (ORCPT ); Mon, 31 Aug 2020 16:56:27 -0400 Received: from mail.adapt-ip.com ([173.164.178.19]:52298 "EHLO web.adapt-ip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729506AbgHaU40 (ORCPT ); Mon, 31 Aug 2020 16:56:26 -0400 Received: from localhost (localhost [127.0.0.1]) by web.adapt-ip.com (Postfix) with ESMTP id 3C5494F8DE3; Mon, 31 Aug 2020 20:56:26 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at web.adapt-ip.com Received: from web.adapt-ip.com ([127.0.0.1]) by localhost (web.adapt-ip.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id sBic5-lBBMW9; Mon, 31 Aug 2020 20:56:22 +0000 (UTC) Received: from atlas.campbell.adapt-ip.com (gateway.adapt-ip.com [173.164.178.20]) (Authenticated sender: thomas@adapt-ip.com) by web.adapt-ip.com (Postfix) with ESMTPSA id BC77A4F8E07; Mon, 31 Aug 2020 20:56:09 +0000 (UTC) From: Thomas Pedersen To: Johannes Berg Cc: linux-wireless , Thomas Pedersen Subject: [PATCH v2 10/22] cfg80211: convert S1G beacon to scan results Date: Mon, 31 Aug 2020 13:55:48 -0700 Message-Id: <20200831205600.21058-11-thomas@adapt-ip.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200831205600.21058-1-thomas@adapt-ip.com> References: <20200831205600.21058-1-thomas@adapt-ip.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org The S1G beacon is an extension frame as opposed to management frame for the regular beacon. This means we may have to occasionally cast the frame buffer to a different header type. Luckily this isn't too bad as scan results mostly only care about the IEs. Signed-off-by: Thomas Pedersen --- include/linux/ieee80211.h | 32 ++++++++++++++++++++++ net/wireless/scan.c | 57 ++++++++++++++++++++++++++++++++------- 2 files changed, 80 insertions(+), 9 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 53fba39d4ba6..bca4bb443291 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -151,6 +151,9 @@ #define IEEE80211_ANO_NETTYPE_WILD 15 +/* bits unique to S1G beacon */ +#define IEEE80211_S1G_BCN_NEXT_TBTT 0x100 + /* control extension - for IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTL_EXT */ #define IEEE80211_CTL_EXT_POLL 0x2000 #define IEEE80211_CTL_EXT_SPR 0x3000 @@ -553,6 +556,28 @@ static inline bool ieee80211_is_s1g_beacon(__le16 fc) cpu_to_le16(IEEE80211_FTYPE_EXT | IEEE80211_STYPE_S1G_BEACON); } +/** + * ieee80211_next_tbtt_present - check if IEEE80211_FTYPE_EXT && + * IEEE80211_STYPE_S1G_BEACON && IEEE80211_S1G_BCN_NEXT_TBTT + * @fc: frame control bytes in little-endian byteorder + */ +static inline bool ieee80211_next_tbtt_present(__le16 fc) +{ + return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == + cpu_to_le16(IEEE80211_FTYPE_EXT | IEEE80211_STYPE_S1G_BEACON) && + fc & cpu_to_le16(IEEE80211_S1G_BCN_NEXT_TBTT); +} + +/** + * ieee80211_is_s1g_short_beacon - check if next tbtt present bit is set. Only + * true for S1G beacons when they're short. + * @fc: frame control bytes in little-endian byteorder + */ +static inline bool ieee80211_is_s1g_short_beacon(__le16 fc) +{ + return ieee80211_is_s1g_beacon(fc) && ieee80211_next_tbtt_present(fc); +} + /** * ieee80211_is_atim - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ATIM * @fc: frame control bytes in little-endian byteorder @@ -1034,6 +1059,13 @@ struct ieee80211_ext { u8 change_seq; u8 variable[0]; } __packed s1g_beacon; + struct { + u8 sa[ETH_ALEN]; + __le32 timestamp; + u8 change_seq; + u8 next_tbtt[3]; + u8 variable[0]; + } __packed s1g_short_beacon; } u; } __packed __aligned(2); diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 84fc8ab16dd2..b4c85e8f2107 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -1807,8 +1807,11 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy, struct cfg80211_bss_ies *ies; struct ieee80211_channel *channel; bool signal_valid; - size_t ielen = len - offsetof(struct ieee80211_mgmt, - u.probe_resp.variable); + struct ieee80211_ext *ext = NULL; + u8 *bssid, *variable; + u16 capability, beacon_int; + size_t ielen, min_hdr_len = offsetof(struct ieee80211_mgmt, + u.probe_resp.variable); int bss_type; BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != @@ -1826,21 +1829,57 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy, (data->signal < 0 || data->signal > 100))) return NULL; - if (WARN_ON(len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable))) + if (ieee80211_is_s1g_beacon(mgmt->frame_control)) { + ext = (void *) mgmt; + min_hdr_len = offsetof(struct ieee80211_ext, u.s1g_beacon); + if (ieee80211_is_s1g_short_beacon(mgmt->frame_control)) + min_hdr_len = offsetof(struct ieee80211_ext, + u.s1g_short_beacon.variable); + } + + if (WARN_ON(len < min_hdr_len)) return NULL; - channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable, + ielen = len - min_hdr_len; + variable = mgmt->u.probe_resp.variable; + if (ext) { + if (ieee80211_is_s1g_short_beacon(mgmt->frame_control)) + variable = ext->u.s1g_short_beacon.variable; + else + variable = ext->u.s1g_beacon.variable; + } + + channel = cfg80211_get_bss_channel(wiphy, variable, ielen, data->chan, data->scan_width); if (!channel) return NULL; + if (ext) { + struct ieee80211_s1g_bcn_compat_ie *compat; + u8 *ie; + + ie = (void *)cfg80211_find_ie(WLAN_EID_S1G_BCN_COMPAT, + variable, ielen); + if (!ie) + return NULL; + compat = (void *)(ie + 2); + bssid = ext->u.s1g_beacon.sa; + capability = le16_to_cpu(compat->compat_info); + beacon_int = le16_to_cpu(compat->beacon_int); + } else { + bssid = mgmt->bssid; + beacon_int = le16_to_cpu(mgmt->u.probe_resp.beacon_int); + capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); + } + ies = kzalloc(sizeof(*ies) + ielen, gfp); if (!ies) return NULL; ies->len = ielen; ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); - ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control); - memcpy(ies->data, mgmt->u.probe_resp.variable, ielen); + ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control) || + ieee80211_is_s1g_beacon(mgmt->frame_control); + memcpy(ies->data, variable, ielen); if (ieee80211_is_probe_resp(mgmt->frame_control)) rcu_assign_pointer(tmp.pub.proberesp_ies, ies); @@ -1848,12 +1887,12 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy, rcu_assign_pointer(tmp.pub.beacon_ies, ies); rcu_assign_pointer(tmp.pub.ies, ies); - memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN); + memcpy(tmp.pub.bssid, bssid, ETH_ALEN); + tmp.pub.beacon_interval = beacon_int; + tmp.pub.capability = capability; tmp.pub.channel = channel; tmp.pub.scan_width = data->scan_width; tmp.pub.signal = data->signal; - tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); - tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); tmp.ts_boottime = data->boottime_ns; tmp.parent_tsf = data->parent_tsf; tmp.pub.chains = data->chains; From patchwork Mon Aug 31 20:55:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 259405 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 108C0C433E7 for ; Mon, 31 Aug 2020 20:56:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E4FCC208CA for ; Mon, 31 Aug 2020 20:56:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729527AbgHaU4b (ORCPT ); Mon, 31 Aug 2020 16:56:31 -0400 Received: from mail.adapt-ip.com ([173.164.178.19]:52312 "EHLO web.adapt-ip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729579AbgHaU43 (ORCPT ); Mon, 31 Aug 2020 16:56:29 -0400 Received: from localhost (localhost [127.0.0.1]) by web.adapt-ip.com (Postfix) with ESMTP id 5D7104F8E28; Mon, 31 Aug 2020 20:56:29 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at web.adapt-ip.com Received: from web.adapt-ip.com ([127.0.0.1]) by localhost (web.adapt-ip.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 1fnxCiFnXwXi; Mon, 31 Aug 2020 20:56:26 +0000 (UTC) Received: from atlas.campbell.adapt-ip.com (gateway.adapt-ip.com [173.164.178.20]) (Authenticated sender: thomas@adapt-ip.com) by web.adapt-ip.com (Postfix) with ESMTPSA id 79FD44F8E00; Mon, 31 Aug 2020 20:56:10 +0000 (UTC) From: Thomas Pedersen To: Johannes Berg Cc: linux-wireless , Thomas Pedersen Subject: [PATCH v2 12/22] mac80211: convert S1G beacon to scan results Date: Mon, 31 Aug 2020 13:55:50 -0700 Message-Id: <20200831205600.21058-13-thomas@adapt-ip.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200831205600.21058-1-thomas@adapt-ip.com> References: <20200831205600.21058-1-thomas@adapt-ip.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org This commit finds the correct offset for Information Elements in S1G beacon frames so they can be reported in scan results, and track whether a given BSS is S1G. Signed-off-by: Thomas Pedersen --- net/mac80211/ieee80211_i.h | 7 +++++++ net/mac80211/rx.c | 3 ++- net/mac80211/scan.c | 20 ++++++++++++++++---- net/mac80211/util.c | 28 ++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 9363f43887b4..8bbdc27d57c6 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -127,6 +127,9 @@ struct ieee80211_bss { /* Keep track of what bits of information we have valid info for. */ u8 valid_data; + + /* BSS info was transmitted by an S1G STA */ + u8 s1g; }; /** @@ -1524,6 +1527,10 @@ struct ieee802_11_elems { u8 dtim_count; u8 dtim_period; const struct ieee80211_addba_ext_ie *addba_ext_ie; + const struct ieee80211_s1g_cap *s1g_capab; + const struct ieee80211_s1g_oper_ie *s1g_oper; + const u8 *s1g_tsbtt; + const struct ieee80211_s1g_bcn_compat_ie *s1g_bcn_compat; /* length of them, respectively */ u8 ext_capab_len; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 836cde516a18..5b92f56682e2 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -4586,7 +4586,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, ieee80211_verify_alignment(&rx); if (unlikely(ieee80211_is_probe_resp(hdr->frame_control) || - ieee80211_is_beacon(hdr->frame_control))) + ieee80211_is_beacon(hdr->frame_control) || + ieee80211_is_s1g_beacon(hdr->frame_control))) ieee80211_scan_rx(local, skb); if (ieee80211_is_data(fc)) { diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 5002791fe165..3dd65b7c839b 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -124,6 +124,9 @@ ieee80211_update_bss_from_elems(struct ieee80211_local *local, bss->valid_data |= IEEE80211_BSS_VALID_WMM; } + if (!elems->parse_error && elems->s1g_capab) + bss->s1g = true; + if (beacon) { struct ieee80211_supported_band *sband = local->hw.wiphy->bands[rx_status->band]; @@ -146,7 +149,8 @@ ieee80211_bss_info_update(struct ieee80211_local *local, struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_channel *channel) { - bool beacon = ieee80211_is_beacon(mgmt->frame_control); + bool beacon = ieee80211_is_beacon(mgmt->frame_control) || + ieee80211_is_s1g_beacon(mgmt->frame_control); struct cfg80211_bss *cbss, *non_tx_cbss; struct ieee80211_bss *bss, *non_tx_bss; struct cfg80211_inform_bss bss_meta = { @@ -195,6 +199,11 @@ ieee80211_bss_info_update(struct ieee80211_local *local, elements = mgmt->u.probe_resp.variable; baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); + } else if (ieee80211_is_s1g_beacon(mgmt->frame_control)) { + struct ieee80211_ext *ext = (void *) mgmt; + + baselen = offsetof(struct ieee80211_ext, u.s1g_beacon.variable); + elements = ext->u.s1g_beacon.variable; } else { baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable); elements = mgmt->u.beacon.variable; @@ -246,9 +255,12 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb) struct ieee80211_bss *bss; struct ieee80211_channel *channel; - if (skb->len < 24 || - (!ieee80211_is_probe_resp(mgmt->frame_control) && - !ieee80211_is_beacon(mgmt->frame_control))) + if (ieee80211_is_s1g_beacon(mgmt->frame_control)) { + if (skb->len < 15) + return; + } else if (skb->len < 24 || + (!ieee80211_is_probe_resp(mgmt->frame_control) && + !ieee80211_is_beacon(mgmt->frame_control))) return; sdata1 = rcu_dereference(local->scan_sdata); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 27b2f1ceca69..e474b2bf227b 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1003,6 +1003,10 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, case WLAN_EID_LINK_ID: case WLAN_EID_BSS_MAX_IDLE_PERIOD: case WLAN_EID_RSNX: + case WLAN_EID_S1G_BCN_COMPAT: + case WLAN_EID_S1G_CAPABILITIES: + case WLAN_EID_S1G_OPERATION: + case WLAN_EID_S1G_SHORT_BCN_INTERVAL: /* * not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible * that if the content gets bigger it might be needed more than once @@ -1288,6 +1292,30 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, &crc : NULL, elem, elems); break; + case WLAN_EID_S1G_CAPABILITIES: + if (elen == 15) + elems->s1g_capab = (void *)pos; + else + elem_parse_failed = true; + break; + case WLAN_EID_S1G_OPERATION: + if (elen == 6) + elems->s1g_oper = (void *)pos; + else + elem_parse_failed = true; + break; + case WLAN_EID_S1G_SHORT_BCN_INTERVAL: + if (elen == 2) + elems->s1g_tsbtt = (void *)pos; + else + elem_parse_failed = true; + break; + case WLAN_EID_S1G_BCN_COMPAT: + if (elen == sizeof(struct ieee80211_s1g_bcn_compat_ie)) + elems->s1g_bcn_compat = (void *)pos; + else + elem_parse_failed = true; + break; default: break; } From patchwork Mon Aug 31 20:55:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 259404 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 44034C433E7 for ; Mon, 31 Aug 2020 20:56:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2924020866 for ; Mon, 31 Aug 2020 20:56:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730155AbgHaU4h (ORCPT ); Mon, 31 Aug 2020 16:56:37 -0400 Received: from mail.adapt-ip.com ([173.164.178.19]:52352 "EHLO web.adapt-ip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728251AbgHaU4g (ORCPT ); Mon, 31 Aug 2020 16:56:36 -0400 Received: from localhost (localhost [127.0.0.1]) by web.adapt-ip.com (Postfix) with ESMTP id AFFA64F865E; Mon, 31 Aug 2020 20:56:35 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at web.adapt-ip.com Received: from web.adapt-ip.com ([127.0.0.1]) by localhost (web.adapt-ip.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id En-zJoHxKUpY; Mon, 31 Aug 2020 20:56:32 +0000 (UTC) Received: from atlas.campbell.adapt-ip.com (gateway.adapt-ip.com [173.164.178.20]) (Authenticated sender: thomas@adapt-ip.com) by web.adapt-ip.com (Postfix) with ESMTPSA id 91CCD4F8AD5; Mon, 31 Aug 2020 20:56:11 +0000 (UTC) From: Thomas Pedersen To: Johannes Berg Cc: linux-wireless , Thomas Pedersen Subject: [PATCH v2 14/22] mac80211: encode listen interval for S1G Date: Mon, 31 Aug 2020 13:55:52 -0700 Message-Id: <20200831205600.21058-15-thomas@adapt-ip.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200831205600.21058-1-thomas@adapt-ip.com> References: <20200831205600.21058-1-thomas@adapt-ip.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org S1G allows listen interval up to 2^14 * 10000 beacon intervals. In order to do this listen interval needs a scaling factor applied to the lower 14 bits. Calculate this and properly encode the listen interval for S1G STAs. See IEEE802.11ah-2016 Table 9-44a for reference. Signed-off-by: Thomas Pedersen --- include/linux/ieee80211.h | 9 +++++++++ net/mac80211/ieee80211_i.h | 1 + net/mac80211/mlme.c | 11 +++++++---- net/mac80211/util.c | 20 ++++++++++++++++++++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 690d00505649..a63ad4b4f973 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -2446,6 +2446,15 @@ ieee80211_he_spr_size(const u8 *he_spr_ie) #define S1G_OPER_CH_WIDTH_PRIMARY_1MHZ BIT(0) #define S1G_OPER_CH_WIDTH_OPER GENMASK(4, 1) + +#define LISTEN_INT_USF GENMASK(15, 14) +#define LISTEN_INT_UI GENMASK(13, 0) + +#define IEEE80211_MAX_USF FIELD_MAX(LISTEN_INT_USF) +#define IEEE80211_MAX_UI FIELD_MAX(LISTEN_INT_UI) + +static const int listen_int_usf[] = { 1, 10, 1000, 10000 }; + /* Authentication algorithms */ #define WLAN_AUTH_OPEN 0 #define WLAN_AUTH_SHARED_KEY 1 diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8bbdc27d57c6..cf78e356b25d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2293,6 +2293,7 @@ void ieee80211_tdls_chsw_work(struct work_struct *wk); void ieee80211_tdls_handle_disconnect(struct ieee80211_sub_if_data *sdata, const u8 *peer, u16 reason); const char *ieee80211_get_reason_code_string(u16 reason_code); +__le16 ieee80211_encode_usf(int val); extern const struct ethtool_ops ieee80211_ethtool_ops; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b69889563457..6a62a221b89e 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -686,6 +686,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) struct ieee80211_local *local = sdata->local; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; + struct ieee80211_bss *bss = (void *)assoc_data->bss->priv; struct sk_buff *skb; struct ieee80211_mgmt *mgmt; u8 *pos, qos_info, *ie_start; @@ -696,6 +697,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) struct ieee80211_chanctx_conf *chanctx_conf; struct ieee80211_channel *chan; u32 rates = 0; + __le16 listen_int; struct element *ext_capa = NULL; /* we know it's writable, cast away the const */ @@ -784,13 +786,15 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); memcpy(mgmt->bssid, assoc_data->bss->bssid, ETH_ALEN); + listen_int = cpu_to_le16(bss->s1g ? + ieee80211_encode_usf(local->hw.conf.listen_interval) : + local->hw.conf.listen_interval); if (!is_zero_ether_addr(assoc_data->prev_bssid)) { skb_put(skb, 10); mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_REQ); mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab); - mgmt->u.reassoc_req.listen_interval = - cpu_to_le16(local->hw.conf.listen_interval); + mgmt->u.reassoc_req.listen_interval = listen_int; memcpy(mgmt->u.reassoc_req.current_ap, assoc_data->prev_bssid, ETH_ALEN); } else { @@ -798,8 +802,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ); mgmt->u.assoc_req.capab_info = cpu_to_le16(capab); - mgmt->u.assoc_req.listen_interval = - cpu_to_le16(local->hw.conf.listen_interval); + mgmt->u.assoc_req.listen_interval = listen_int; } /* SSID */ diff --git a/net/mac80211/util.c b/net/mac80211/util.c index e474b2bf227b..57c6f8bd2bdf 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -4391,3 +4391,23 @@ const u8 ieee80211_ac_to_qos_mask[IEEE80211_NUM_ACS] = { IEEE80211_WMM_IE_STA_QOSINFO_AC_BE, IEEE80211_WMM_IE_STA_QOSINFO_AC_BK }; + +__le16 ieee80211_encode_usf(int listen_interval) +{ + u16 ui, usf = 0; + + /* find greatest USF */ + while (usf < IEEE80211_MAX_USF) { + if (listen_interval % listen_int_usf[usf + 1]) + break; + usf += 1; + } + ui = listen_interval / listen_int_usf[usf]; + + /* error if there is a remainder. Should've been checked by user */ + WARN_ON_ONCE(ui > IEEE80211_MAX_UI); + listen_interval = FIELD_PREP(LISTEN_INT_USF, usf) | + FIELD_PREP(LISTEN_INT_UI, ui); + + return listen_interval; +} From patchwork Mon Aug 31 20:55:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 259403 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E7A9C433E2 for ; Mon, 31 Aug 2020 20:56:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 52B4520866 for ; Mon, 31 Aug 2020 20:56:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730168AbgHaU4m (ORCPT ); Mon, 31 Aug 2020 16:56:42 -0400 Received: from mail.adapt-ip.com ([173.164.178.19]:52370 "EHLO web.adapt-ip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729586AbgHaU4k (ORCPT ); Mon, 31 Aug 2020 16:56:40 -0400 Received: from localhost (localhost [127.0.0.1]) by web.adapt-ip.com (Postfix) with ESMTP id 347834F8E7F; Mon, 31 Aug 2020 20:56:39 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at web.adapt-ip.com Received: from web.adapt-ip.com ([127.0.0.1]) by localhost (web.adapt-ip.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id i16V-pMaBwnx; Mon, 31 Aug 2020 20:56:36 +0000 (UTC) Received: from atlas.campbell.adapt-ip.com (gateway.adapt-ip.com [173.164.178.20]) (Authenticated sender: thomas@adapt-ip.com) by web.adapt-ip.com (Postfix) with ESMTPSA id 4DB504F8E9B; Mon, 31 Aug 2020 20:56:12 +0000 (UTC) From: Thomas Pedersen To: Johannes Berg Cc: linux-wireless , Thomas Pedersen Subject: [PATCH v2 16/22] mac80211: handle S1G low rates Date: Mon, 31 Aug 2020 13:55:54 -0700 Message-Id: <20200831205600.21058-17-thomas@adapt-ip.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200831205600.21058-1-thomas@adapt-ip.com> References: <20200831205600.21058-1-thomas@adapt-ip.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org S1G doesn't have legacy (sband->bitrates) rates, only MCS. For now, just send a frame at MCS 0 if a low rate is requested. Note we also redefine (since we're out of TX flags) TX_RC_VHT_MCS as TX_RC_S1G_MCS to indicate an S1G MCS. This is probably OK as VHT MCS is not valid on S1G band and vice versa. Signed-off-by: Thomas Pedersen --- include/net/mac80211.h | 2 ++ net/mac80211/rate.c | 33 ++++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index ec148b3e9c41..9ea743afb986 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -812,6 +812,8 @@ enum mac80211_tx_info_flags { #define IEEE80211_TX_CTL_STBC_SHIFT 23 +#define IEEE80211_TX_RC_S1G_MCS IEEE80211_TX_RC_VHT_MCS + /** * enum mac80211_tx_control_flags - flags to describe transmit control * diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index b051f125d3af..63266d73c252 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -266,10 +266,15 @@ void ieee80211_check_rate_mask(struct ieee80211_sub_if_data *sdata) if (WARN_ON(!sdata->vif.bss_conf.chandef.chan)) return; + band = sdata->vif.bss_conf.chandef.chan->band; + if (band == NL80211_BAND_S1GHZ) { + /* TODO */ + return; + } + if (WARN_ON_ONCE(!basic_rates)) return; - band = sdata->vif.bss_conf.chandef.chan->band; user_mask = sdata->rc_rateidx_mask[band]; sband = local->hw.wiphy->bands[band]; @@ -296,21 +301,29 @@ static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc) !ieee80211_is_data(fc); } -static void rc_send_low_basicrate(s8 *idx, u32 basic_rates, +static void rc_send_low_basicrate(struct ieee80211_tx_rate *rate, + u32 basic_rates, struct ieee80211_supported_band *sband) { u8 i; + if (sband->band == NL80211_BAND_S1GHZ) { + /* TODO */ + rate->flags |= IEEE80211_TX_RC_S1G_MCS; + rate->idx = 0; + return; + } + if (basic_rates == 0) return; /* assume basic rates unknown and accept rate */ - if (*idx < 0) + if (rate->idx < 0) return; - if (basic_rates & (1 << *idx)) + if (basic_rates & (1 << rate->idx)) return; /* selected rate is a basic rate */ - for (i = *idx + 1; i <= sband->n_bitrates; i++) { + for (i = rate->idx + 1; i <= sband->n_bitrates; i++) { if (basic_rates & (1 << i)) { - *idx = i; + rate->idx = i; return; } } @@ -328,6 +341,12 @@ static void __rate_control_send_low(struct ieee80211_hw *hw, u32 rate_flags = ieee80211_chandef_rate_flags(&hw->conf.chandef); + if (sband->band == NL80211_BAND_S1GHZ) { + info->control.rates[0].flags |= IEEE80211_TX_RC_S1G_MCS; + info->control.rates[0].idx = 0; + return; + } + if ((sband->band == NL80211_BAND_2GHZ) && (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)) rate_flags |= IEEE80211_RATE_ERP_G; @@ -388,7 +407,7 @@ static bool rate_control_send_low(struct ieee80211_sta *pubsta, } if (use_basicrate) - rc_send_low_basicrate(&info->control.rates[0].idx, + rc_send_low_basicrate(&info->control.rates[0], txrc->bss_conf->basic_rates, sband); From patchwork Mon Aug 31 20:55:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 259402 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 28493C433E6 for ; Mon, 31 Aug 2020 20:56:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F0F36206E3 for ; Mon, 31 Aug 2020 20:56:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730173AbgHaU4r (ORCPT ); Mon, 31 Aug 2020 16:56:47 -0400 Received: from mail.adapt-ip.com ([173.164.178.19]:52406 "EHLO web.adapt-ip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728576AbgHaU4r (ORCPT ); Mon, 31 Aug 2020 16:56:47 -0400 Received: from localhost (localhost [127.0.0.1]) by web.adapt-ip.com (Postfix) with ESMTP id E2A334F907C; Mon, 31 Aug 2020 20:56:45 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at web.adapt-ip.com Received: from web.adapt-ip.com ([127.0.0.1]) by localhost (web.adapt-ip.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id uukhJ6T_obtK; Mon, 31 Aug 2020 20:56:41 +0000 (UTC) Received: from atlas.campbell.adapt-ip.com (gateway.adapt-ip.com [173.164.178.20]) (Authenticated sender: thomas@adapt-ip.com) by web.adapt-ip.com (Postfix) with ESMTPSA id 29E094F8F11; Mon, 31 Aug 2020 20:56:13 +0000 (UTC) From: Thomas Pedersen To: Johannes Berg Cc: linux-wireless , Thomas Pedersen Subject: [PATCH v2 18/22] mac80211: receive and process S1G beacons Date: Mon, 31 Aug 2020 13:55:56 -0700 Message-Id: <20200831205600.21058-19-thomas@adapt-ip.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200831205600.21058-1-thomas@adapt-ip.com> References: <20200831205600.21058-1-thomas@adapt-ip.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org S1G beacons are 802.11 Extension Frames, so the fixed header part differs from regular beacons. Add a handler to process S1G beacons and abstract out the fetching of BSSID and element start locations in the beacon body handler. Signed-off-by: Thomas Pedersen --- net/mac80211/ieee80211_i.h | 4 ++ net/mac80211/iface.c | 5 +++ net/mac80211/mlme.c | 87 +++++++++++++++++++++++++++++--------- net/mac80211/rx.c | 84 ++++++++++++++++-------------------- net/mac80211/util.c | 52 +++++++++++++++++++++++ 5 files changed, 164 insertions(+), 68 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index cf78e356b25d..9847cfa0e08c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1649,6 +1649,8 @@ int ieee80211_set_arp_filter(struct ieee80211_sub_if_data *sdata); void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata); void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); +void ieee80211_sta_rx_queued_ext(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb); void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata); void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata); void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata); @@ -2294,6 +2296,8 @@ void ieee80211_tdls_handle_disconnect(struct ieee80211_sub_if_data *sdata, const u8 *peer, u16 reason); const char *ieee80211_get_reason_code_string(u16 reason_code); __le16 ieee80211_encode_usf(int val); +u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, + enum nl80211_iftype type); extern const struct ethtool_ops ieee80211_ethtool_ops; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 9740ae8fa697..1369f6e575d7 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1379,6 +1379,11 @@ static void ieee80211_iface_work(struct work_struct *work) WARN_ON(1); break; } + } else if (ieee80211_is_ext(mgmt->frame_control)) { + if (sdata->vif.type == NL80211_IFTYPE_STATION) + ieee80211_sta_rx_queued_ext(sdata, skb); + else + WARN_ON(1); } else if (ieee80211_is_data_qos(mgmt->frame_control)) { struct ieee80211_hdr *hdr = (void *)mgmt; /* diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 6a62a221b89e..9a26ef99cef9 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1604,6 +1604,9 @@ static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, int new_ap_level; __le16 capab = mgmt->u.probe_resp.capab_info; + if (ieee80211_is_s1g_beacon(mgmt->frame_control)) + return 0; /* TODO */ + if (country_ie && (capab & cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT) || capab & cpu_to_le16(WLAN_CAPABILITY_RADIO_MEASURE))) { @@ -2450,7 +2453,8 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, * data idle periods for sending the periodic probe request to the * AP we're connected to. */ - if (is_multicast_ether_addr(hdr->addr1)) + if (is_multicast_ether_addr(hdr->addr1) || + ieee80211_is_s1g_beacon(hdr->frame_control)) return; ieee80211_sta_reset_conn_monitor(sdata); @@ -3919,12 +3923,13 @@ static bool ieee80211_rx_our_beacon(const u8 *tx_bssid, return ether_addr_equal(tx_bssid, bss->transmitted_bss->bssid); } -static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, - struct ieee80211_mgmt *mgmt, size_t len, - struct ieee80211_rx_status *rx_status) +static void ieee80211_rx_beacon(struct ieee80211_sub_if_data *sdata, + struct ieee80211_hdr *hdr, size_t len, + struct ieee80211_rx_status *rx_status) { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; + struct ieee80211_mgmt *mgmt = (void *) hdr; size_t baselen; struct ieee802_11_elems elems; struct ieee80211_local *local = sdata->local; @@ -3934,14 +3939,24 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, u32 changed = 0; bool erp_valid; u8 erp_value = 0; - u32 ncrc; - u8 *bssid; + u32 ncrc = 0; + u8 *bssid, *variable = mgmt->u.beacon.variable; u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN]; sdata_assert_lock(sdata); /* Process beacon from the current BSS */ - baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; + bssid = ieee80211_get_bssid(hdr, len, sdata->vif.type); + if (ieee80211_is_s1g_beacon(mgmt->frame_control)) { + struct ieee80211_ext *ext = (void *) mgmt; + + if (ieee80211_is_s1g_short_beacon(ext->frame_control)) + variable = ext->u.s1g_short_beacon.variable; + else + variable = ext->u.s1g_beacon.variable; + } + + baselen = (u8 *) variable - (u8 *) mgmt; if (baselen > len) return; @@ -3961,10 +3976,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, rcu_read_unlock(); if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon && - ieee80211_rx_our_beacon(mgmt->bssid, ifmgd->assoc_data->bss)) { - ieee802_11_parse_elems(mgmt->u.beacon.variable, + ieee80211_rx_our_beacon(bssid, ifmgd->assoc_data->bss)) { + ieee802_11_parse_elems(variable, len - baselen, false, &elems, - mgmt->bssid, + bssid, ifmgd->assoc_data->bss->bssid); ieee80211_rx_bss_info(sdata, mgmt, len, rx_status); @@ -3997,7 +4012,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, } if (!ifmgd->associated || - !ieee80211_rx_our_beacon(mgmt->bssid, ifmgd->associated)) + !ieee80211_rx_our_beacon(bssid, ifmgd->associated)) return; bssid = ifmgd->associated->bssid; @@ -4017,8 +4032,14 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, */ ieee80211_sta_reset_beacon_monitor(sdata); - ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); - ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable, + /* TODO: CRC urrently not calculated on S1G Beacon Compatibility + * element (which carries the beacon interval). Don't forget to add a + * bit to care_about_ies[] above if mac80211 is interested in a + * changing S1G element. + */ + if (!ieee80211_is_s1g_beacon(hdr->frame_control)) + ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); + ncrc = ieee802_11_parse_elems_crc(variable, len - baselen, false, &elems, care_about_ies, ncrc, mgmt->bssid, bssid); @@ -4052,7 +4073,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, struct ieee80211_p2p_noa_attr noa = {}; int ret; - ret = cfg80211_get_p2p_attr(mgmt->u.beacon.variable, + ret = cfg80211_get_p2p_attr(variable, len - baselen, IEEE80211_P2P_ATTR_ABSENCE_NOTICE, (u8 *) &noa, sizeof(noa)); @@ -4088,7 +4109,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, * the driver will use them. The synchronized view is currently * guaranteed only in certain callbacks. */ - if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) { + if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY) && + !ieee80211_is_s1g_beacon(hdr->frame_control)) { sdata->vif.bss_conf.sync_tsf = le64_to_cpu(mgmt->u.beacon.timestamp); sdata->vif.bss_conf.sync_device_ts = @@ -4096,7 +4118,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, sdata->vif.bss_conf.sync_dtim_count = elems.dtim_count; } - if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) + if ((ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) || + ieee80211_is_s1g_short_beacon(mgmt->frame_control)) return; ifmgd->beacon_crc = ncrc; ifmgd->beacon_crc_valid = true; @@ -4137,9 +4160,12 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, } else { erp_valid = false; } - changed |= ieee80211_handle_bss_capability(sdata, - le16_to_cpu(mgmt->u.beacon.capab_info), - erp_valid, erp_value); + + if (!ieee80211_is_s1g_beacon(hdr->frame_control)) { + changed |= ieee80211_handle_bss_capability(sdata, + le16_to_cpu(mgmt->u.beacon.capab_info), + erp_valid, erp_value); + } mutex_lock(&local->sta_mtx); sta = sta_info_get(sdata, bssid); @@ -4177,6 +4203,26 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, ieee80211_bss_info_change_notify(sdata, changed); } +void ieee80211_sta_rx_queued_ext(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb) +{ + struct ieee80211_rx_status *rx_status; + struct ieee80211_hdr *hdr; + u16 fc; + + rx_status = (struct ieee80211_rx_status *) skb->cb; + hdr = (struct ieee80211_hdr *) skb->data; + fc = le16_to_cpu(hdr->frame_control); + + sdata_lock(sdata); + switch (fc & IEEE80211_FCTL_STYPE) { + case IEEE80211_STYPE_S1G_BEACON: + ieee80211_rx_beacon(sdata, hdr, skb->len, rx_status); + break; + } + sdata_unlock(sdata); +} + void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) { @@ -4194,7 +4240,8 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, switch (fc & IEEE80211_FCTL_STYPE) { case IEEE80211_STYPE_BEACON: - ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status); + ieee80211_rx_beacon(sdata, (struct ieee80211_hdr *) mgmt, + skb->len, rx_status); break; case IEEE80211_STYPE_PROBE_RESP: ieee80211_rx_mgmt_probe_resp(sdata, skb); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5b92f56682e2..e1291898bde8 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -42,51 +42,6 @@ static inline void ieee80211_rx_stats(struct net_device *dev, u32 len) u64_stats_update_end(&tstats->syncp); } -static u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, - enum nl80211_iftype type) -{ - __le16 fc = hdr->frame_control; - - if (ieee80211_is_data(fc)) { - if (len < 24) /* drop incorrect hdr len (data) */ - return NULL; - - if (ieee80211_has_a4(fc)) - return NULL; - if (ieee80211_has_tods(fc)) - return hdr->addr1; - if (ieee80211_has_fromds(fc)) - return hdr->addr2; - - return hdr->addr3; - } - - if (ieee80211_is_mgmt(fc)) { - if (len < 24) /* drop incorrect hdr len (mgmt) */ - return NULL; - return hdr->addr3; - } - - if (ieee80211_is_ctl(fc)) { - if (ieee80211_is_pspoll(fc)) - return hdr->addr1; - - if (ieee80211_is_back_req(fc)) { - switch (type) { - case NL80211_IFTYPE_STATION: - return hdr->addr2; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_AP_VLAN: - return hdr->addr1; - default: - break; /* fall through to the return */ - } - } - } - - return NULL; -} - /* * monitor mode reception * @@ -1801,7 +1756,8 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) } } else if (rx->sdata->vif.type == NL80211_IFTYPE_OCB) { sta->rx_stats.last_rx = jiffies; - } else if (!is_multicast_ether_addr(hdr->addr1)) { + } else if (!ieee80211_is_s1g_beacon(hdr->frame_control) && + is_multicast_ether_addr(hdr->addr1)) { /* * Mesh beacons will update last_rx when if they are found to * match the current local configuration when processed. @@ -1839,6 +1795,9 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) } } + if (ieee80211_is_s1g_beacon(hdr->frame_control)) + return RX_CONTINUE; + /* * Change STA power saving mode only at the end of a frame * exchange sequence, and only for a data or management @@ -1949,6 +1908,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) __le16 fc; const struct ieee80211_cipher_scheme *cs = NULL; + if (ieee80211_is_ext(hdr->frame_control)) + return RX_CONTINUE; + /* * Key selection 101 * @@ -2257,7 +2219,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) hdr = (struct ieee80211_hdr *)rx->skb->data; fc = hdr->frame_control; - if (ieee80211_is_ctl(fc)) + if (ieee80211_is_ctl(fc) || ieee80211_is_ext(fc)) return RX_CONTINUE; sc = le16_to_cpu(hdr->seq_ctrl); @@ -3131,6 +3093,9 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); + if (ieee80211_is_s1g_beacon(mgmt->frame_control)) + return RX_CONTINUE; + /* * From here on, look only at management frames. * Data and control frames are already handled, @@ -3597,6 +3562,27 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) return RX_QUEUED; } +static ieee80211_rx_result debug_noinline +ieee80211_rx_h_ext(struct ieee80211_rx_data *rx) +{ + struct ieee80211_sub_if_data *sdata = rx->sdata; + struct ieee80211_hdr *hdr = (void *)rx->skb->data; + + if (!ieee80211_is_ext(hdr->frame_control)) + return RX_CONTINUE; + + if (sdata->vif.type != NL80211_IFTYPE_STATION) + return RX_DROP_MONITOR; + + /* for now only beacons are ext, so queue them */ + skb_queue_tail(&sdata->skb_queue, rx->skb); + ieee80211_queue_work(&rx->local->hw, &sdata->work); + if (rx->sta) + rx->sta->rx_stats.packets++; + + return RX_QUEUED; +} + static ieee80211_rx_result debug_noinline ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) { @@ -3816,6 +3802,7 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, CALL_RXH(ieee80211_rx_h_userspace_mgmt); CALL_RXH(ieee80211_rx_h_action_post_userspace); CALL_RXH(ieee80211_rx_h_action_return); + CALL_RXH(ieee80211_rx_h_ext); CALL_RXH(ieee80211_rx_h_mgmt); rxh_next: @@ -3982,7 +3969,8 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx) struct ieee80211_hdr *hdr = (void *)skb->data; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); - bool multicast = is_multicast_ether_addr(hdr->addr1); + bool multicast = is_multicast_ether_addr(hdr->addr1) || + ieee80211_is_s1g_beacon(hdr->frame_control); switch (sdata->vif.type) { case NL80211_IFTYPE_STATION: diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 57c6f8bd2bdf..31845e392759 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -45,6 +45,58 @@ struct ieee80211_hw *wiphy_to_ieee80211_hw(struct wiphy *wiphy) } EXPORT_SYMBOL(wiphy_to_ieee80211_hw); +u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, + enum nl80211_iftype type) +{ + __le16 fc = hdr->frame_control; + + if (ieee80211_is_data(fc)) { + if (len < 24) /* drop incorrect hdr len (data) */ + return NULL; + + if (ieee80211_has_a4(fc)) + return NULL; + if (ieee80211_has_tods(fc)) + return hdr->addr1; + if (ieee80211_has_fromds(fc)) + return hdr->addr2; + + return hdr->addr3; + } + + if (ieee80211_is_s1g_beacon(fc)) { + struct ieee80211_ext *ext = (void *) hdr; + + return ext->u.s1g_beacon.sa; + } + + if (ieee80211_is_mgmt(fc)) { + if (len < 24) /* drop incorrect hdr len (mgmt) */ + return NULL; + return hdr->addr3; + } + + if (ieee80211_is_ctl(fc)) { + if (ieee80211_is_pspoll(fc)) + return hdr->addr1; + + if (ieee80211_is_back_req(fc)) { + switch (type) { + case NL80211_IFTYPE_STATION: + return hdr->addr2; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_AP_VLAN: + return hdr->addr1; + default: + break; /* fall through to the return */ + } + } + } + + return NULL; +} +EXPORT_SYMBOL(ieee80211_get_bssid); + void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx) { struct sk_buff *skb; From patchwork Mon Aug 31 20:55:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 259401 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80EEDC433E2 for ; Mon, 31 Aug 2020 20:56:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 61BF4206E3 for ; Mon, 31 Aug 2020 20:56:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730177AbgHaU4x (ORCPT ); Mon, 31 Aug 2020 16:56:53 -0400 Received: from mail.adapt-ip.com ([173.164.178.19]:52444 "EHLO web.adapt-ip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729433AbgHaU4w (ORCPT ); Mon, 31 Aug 2020 16:56:52 -0400 Received: from localhost (localhost [127.0.0.1]) by web.adapt-ip.com (Postfix) with ESMTP id 4A4894F8D69; Mon, 31 Aug 2020 20:56:52 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at web.adapt-ip.com Received: from web.adapt-ip.com ([127.0.0.1]) by localhost (web.adapt-ip.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id aOxkkUWwJDvo; Mon, 31 Aug 2020 20:56:49 +0000 (UTC) Received: from atlas.campbell.adapt-ip.com (gateway.adapt-ip.com [173.164.178.20]) (Authenticated sender: thomas@adapt-ip.com) by web.adapt-ip.com (Postfix) with ESMTPSA id E8A3D4F8F84; Mon, 31 Aug 2020 20:56:13 +0000 (UTC) From: Thomas Pedersen To: Johannes Berg Cc: linux-wireless , Thomas Pedersen Subject: [PATCH v2 20/22] nl80211: include frequency offset in survey info Date: Mon, 31 Aug 2020 13:55:58 -0700 Message-Id: <20200831205600.21058-21-thomas@adapt-ip.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200831205600.21058-1-thomas@adapt-ip.com> References: <20200831205600.21058-1-thomas@adapt-ip.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Recently channels gained a potential frequency offset, so include this in the per-channel survey info. Signed-off-by: Thomas Pedersen --- include/uapi/linux/nl80211.h | 2 ++ net/wireless/nl80211.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 70076492ebc9..dd5591794e48 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -4085,6 +4085,7 @@ enum nl80211_user_reg_hint_type { * receiving frames destined to the local BSS * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number * currently defined + * @NL80211_SURVEY_INFO_FREQUENCY_OFFSET: center frequency offset in KHz * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use */ enum nl80211_survey_info { @@ -4100,6 +4101,7 @@ enum nl80211_survey_info { NL80211_SURVEY_INFO_TIME_SCAN, NL80211_SURVEY_INFO_PAD, NL80211_SURVEY_INFO_TIME_BSS_RX, + NL80211_SURVEY_INFO_FREQUENCY_OFFSET, /* keep last */ __NL80211_SURVEY_INFO_AFTER_LAST, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 578d99088719..5468c02d0927 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -9224,6 +9224,11 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, survey->channel->center_freq)) goto nla_put_failure; + if (survey->channel && + nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY_OFFSET, + survey->channel->freq_offset)) + goto nla_put_failure; + if ((survey->filled & SURVEY_INFO_NOISE_DBM) && nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise)) goto nla_put_failure; From patchwork Mon Aug 31 20:56:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 259400 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5333CC433E7 for ; Mon, 31 Aug 2020 20:56:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2E454206E3 for ; Mon, 31 Aug 2020 20:56:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730181AbgHaU45 (ORCPT ); Mon, 31 Aug 2020 16:56:57 -0400 Received: from mail.adapt-ip.com ([173.164.178.19]:52460 "EHLO web.adapt-ip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728597AbgHaU45 (ORCPT ); Mon, 31 Aug 2020 16:56:57 -0400 Received: from localhost (localhost [127.0.0.1]) by web.adapt-ip.com (Postfix) with ESMTP id 4CE924F90AD; Mon, 31 Aug 2020 20:56:56 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at web.adapt-ip.com Received: from web.adapt-ip.com ([127.0.0.1]) by localhost (web.adapt-ip.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id UFvmJPRPtpfn; Mon, 31 Aug 2020 20:56:53 +0000 (UTC) Received: from atlas.campbell.adapt-ip.com (gateway.adapt-ip.com [173.164.178.20]) (Authenticated sender: thomas@adapt-ip.com) by web.adapt-ip.com (Postfix) with ESMTPSA id 200304EC91A; Mon, 31 Aug 2020 20:56:14 +0000 (UTC) From: Thomas Pedersen To: Johannes Berg Cc: linux-wireless , Thomas Pedersen Subject: [PATCH v2 22/22] mac80211_hwsim: fix TSF timestamp write to S1G beacon Date: Mon, 31 Aug 2020 13:56:00 -0700 Message-Id: <20200831205600.21058-23-thomas@adapt-ip.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200831205600.21058-1-thomas@adapt-ip.com> References: <20200831205600.21058-1-thomas@adapt-ip.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org mac80211_hwsim was corrupting the S1G beacon because the timestamp location (and size) does not match the management beacon. Signed-off-by: Thomas Pedersen --- drivers/net/wireless/mac80211_hwsim.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 83d8f54ef93e..18dd23a11ddf 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1742,9 +1742,18 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, mgmt = (struct ieee80211_mgmt *) skb->data; /* fake header transmission time */ data->abs_bcn_ts = mac80211_hwsim_get_tsf_raw(); - mgmt->u.beacon.timestamp = cpu_to_le64(data->abs_bcn_ts + - data->tsf_offset + - 24 * 8 * 10 / bitrate); + if (ieee80211_is_s1g_beacon(mgmt->frame_control)) { + struct ieee80211_ext *ext = (void *) mgmt; + + ext->u.s1g_beacon.timestamp = cpu_to_le32(data->abs_bcn_ts + + data->tsf_offset + + 10 * 8 * 10 / + bitrate); + } else { + mgmt->u.beacon.timestamp = cpu_to_le64(data->abs_bcn_ts + + data->tsf_offset + + 24 * 8 * 10 / bitrate); + } mac80211_hwsim_tx_frame(hw, skb, rcu_dereference(vif->chanctx_conf)->def.chan);