From patchwork Wed Dec 22 15:57:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691784 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 4F644C433F5 for ; Wed, 22 Dec 2021 15:57:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343798AbhLVP5u (ORCPT ); Wed, 22 Dec 2021 10:57:50 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:42625 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343791AbhLVP5s (ORCPT ); Wed, 22 Dec 2021 10:57:48 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id E421060006; Wed, 22 Dec 2021 15:57:45 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 01/18] ieee802154: hwsim: Ensure proper channel selection at probe time Date: Wed, 22 Dec 2021 16:57:26 +0100 Message-Id: <20211222155743.256280-2-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org A default channel is selected by default (13), let's clarify that this is page 0 channel 13. Call the right helper to ensure the necessary configuration for this channel has been applied. So far there is very little configuration done in this helper but we will soon add more information (like the symbol duration which is missing) and having this helper called at probe time will prevent us to this type of initialization at two different locations. So far there is very little configuration done in this helper but thanks to this improvement, future enhancements in this area (like setting a symbol duration, which is missing) will be reflected automatically in the default probe state. Signed-off-by: Miquel Raynal --- drivers/net/ieee802154/mac802154_hwsim.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c index 62ced7a30d92..b1a4ee7dceda 100644 --- a/drivers/net/ieee802154/mac802154_hwsim.c +++ b/drivers/net/ieee802154/mac802154_hwsim.c @@ -778,8 +778,6 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev, ieee802154_random_extended_addr(&hw->phy->perm_extended_addr); - /* hwsim phy channel 13 as default */ - hw->phy->current_channel = 13; pib = kzalloc(sizeof(*pib), GFP_KERNEL); if (!pib) { err = -ENOMEM; @@ -793,6 +791,11 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev, hw->flags = IEEE802154_HW_PROMISCUOUS | IEEE802154_HW_RX_DROP_BAD_CKSUM; hw->parent = dev; + /* Set page 0 / channel 13 as default */ + hw->phy->current_page = 0; + hw->phy->current_channel = 13; + hwsim_hw_channel(hw, hw->phy->current_page, hw->phy->current_channel); + err = ieee802154_register_hw(hw); if (err) goto err_reg; From patchwork Wed Dec 22 15:57:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691786 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 A6503C433EF for ; Wed, 22 Dec 2021 15:57:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241559AbhLVP54 (ORCPT ); Wed, 22 Dec 2021 10:57:56 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:43853 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343806AbhLVP5u (ORCPT ); Wed, 22 Dec 2021 10:57:50 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 4CD4660011; Wed, 22 Dec 2021 15:57:47 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 02/18] ieee802154: hwsim: Provide a symbol duration Date: Wed, 22 Dec 2021 16:57:27 +0100 Message-Id: <20211222155743.256280-3-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org Add support for the symbol duration in the softMAC hwsim driver. The symbol durations are provided in micro-seconds and are extracted from the IEEE 802.15.4 specification thanks to the other parameters and comments from this driver. Some of these durations are hard to find/derive, so they are left to 1 in order to avoid null values (for the upcoming changes related to scanning). In this case a comment is stating that the value in unknown. Signed-off-by: Miquel Raynal --- drivers/net/ieee802154/mac802154_hwsim.c | 70 ++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c index b1a4ee7dceda..38be88db5f7a 100644 --- a/drivers/net/ieee802154/mac802154_hwsim.c +++ b/drivers/net/ieee802154/mac802154_hwsim.c @@ -92,6 +92,7 @@ static int hwsim_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel) { struct hwsim_phy *phy = hw->priv; struct hwsim_pib *pib, *pib_old; + int ret = 0; pib = kzalloc(sizeof(*pib), GFP_KERNEL); if (!pib) @@ -99,6 +100,75 @@ static int hwsim_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel) pib->page = page; pib->channel = channel; + switch (page) { + case 0: + if (BIT(channel) & 0x1) + /* 868 MHz BPSK 802.15.4-2003: 20 ksym/s */ + hw->phy->symbol_duration = 50; + else if (BIT(channel) & 0x7fe) + /* 915 MHz BPSK 802.15.4-2003: 40 ksym/s */ + hw->phy->symbol_duration = 25; + else if (BIT(channel) & 0x7FFF800) + /* 2.4 GHz O-QPSK 802.15.4-2003: 62.5 ksym/s */ + hw->phy->symbol_duration = 16; + else + ret = -EINVAL; + break; + case 1: + if (BIT(channel) & (0x1 | 0x7fe)) + /* unknown rate */ + hw->phy->symbol_duration = 1; + else + ret = -EINVAL; + break; + case 2: + if (BIT(channel) & 0x1) + /* 868 MHz O-QPSK 802.15.4-2006: 25 ksym/s */ + hw->phy->symbol_duration = 40; + else if (BIT(channel) & 0x7fe) + /* 915 MHz O-QPSK 802.15.4-2006: 62.5 ksym/s */ + hw->phy->symbol_duration = 16; + else + ret = -EINVAL; + break; + case 3: + if (BIT(channel) & 0x3fff) + /* 2.4 GHz CSS 802.15.4a-2007: 1/6 Msym/s */ + hw->phy->symbol_duration = 6; + else + ret = -EINVAL; + break; + case 4: + if (BIT(channel) & (0x1 | 0x1e | 0xffe0)) + /* UWB 802.15.4a-2007: 993.6 or 1017.6 or 3974.4 us */ + hw->phy->symbol_duration = 1; + else + ret = -EINVAL; + break; + case 5: + if (BIT(channel) & (0xf | 0xf0)) + /* unknown rate */ + hw->phy->symbol_duration = 1; + else + ret = -EINVAL; + break; + case 6: + if (BIT(channel) & (0x3ff | 0x3ffc00)) + /* unknown rate */ + hw->phy->symbol_duration = 1; + else + ret = -EINVAL; + break; + default: + ret = -EINVAL; + } + + if (ret) { + dev_err(hw->parent, "Invalid channel %d on page %d\n", + page, channel); + kfree(pib); + return ret; + } pib_old = rtnl_dereference(phy->pib); rcu_assign_pointer(phy->pib, pib); From patchwork Wed Dec 22 15:57:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691785 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 6E974C433F5 for ; Wed, 22 Dec 2021 15:57:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343808AbhLVP54 (ORCPT ); Wed, 22 Dec 2021 10:57:56 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:49907 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343803AbhLVP5v (ORCPT ); Wed, 22 Dec 2021 10:57:51 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id C64D760017; Wed, 22 Dec 2021 15:57:48 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 03/18] net: ieee802154: Move IEEE 802.15.4 Kconfig main entry Date: Wed, 22 Dec 2021 16:57:28 +0100 Message-Id: <20211222155743.256280-4-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org From: David Girault It makes certainly more sense to have all the low-range wireless protocols such as Bluetooth, IEEE 802.11 (WiFi) and IEEE 802.15.4 together, so let's move the main IEEE 802.15.4 stack Kconfig entry at a better location. Signed-off-by: David Girault [miquel.raynal@bootlin.com: Isolate this change from a bigger commit and rewrite the commit message.] Signed-off-by: Miquel Raynal --- net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/Kconfig b/net/Kconfig index 8a1f9d0287de..0da89d09ffa6 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -228,7 +228,6 @@ source "net/x25/Kconfig" source "net/lapb/Kconfig" source "net/phonet/Kconfig" source "net/6lowpan/Kconfig" -source "net/ieee802154/Kconfig" source "net/mac802154/Kconfig" source "net/sched/Kconfig" source "net/dcb/Kconfig" @@ -380,6 +379,7 @@ source "net/mac80211/Kconfig" endif # WIRELESS +source "net/ieee802154/Kconfig" source "net/rfkill/Kconfig" source "net/9p/Kconfig" source "net/caif/Kconfig" From patchwork Wed Dec 22 15:57:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691787 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 4CE4FC433FE for ; Wed, 22 Dec 2021 15:57:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343830AbhLVP55 (ORCPT ); Wed, 22 Dec 2021 10:57:57 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:47309 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343813AbhLVP5w (ORCPT ); Wed, 22 Dec 2021 10:57:52 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 2E1C960007; Wed, 22 Dec 2021 15:57:50 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 04/18] net: mac802154: Include the softMAC stack inside the IEEE 802.15.4 menu Date: Wed, 22 Dec 2021 16:57:29 +0100 Message-Id: <20211222155743.256280-5-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org From: David Girault The softMAC stack has no meaning outside of the IEEE 802.15.4 stack and cannot be used without it. Signed-off-by: David Girault [miquel.raynal@bootlin.com: Isolate this change from a bigger commit] Signed-off-by: Miquel Raynal --- net/Kconfig | 1 - net/ieee802154/Kconfig | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/net/Kconfig b/net/Kconfig index 0da89d09ffa6..a5e31078fd14 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -228,7 +228,6 @@ source "net/x25/Kconfig" source "net/lapb/Kconfig" source "net/phonet/Kconfig" source "net/6lowpan/Kconfig" -source "net/mac802154/Kconfig" source "net/sched/Kconfig" source "net/dcb/Kconfig" source "net/dns_resolver/Kconfig" diff --git a/net/ieee802154/Kconfig b/net/ieee802154/Kconfig index 31aed75fe62d..7e4b1d49d445 100644 --- a/net/ieee802154/Kconfig +++ b/net/ieee802154/Kconfig @@ -36,6 +36,7 @@ config IEEE802154_SOCKET for 802.15.4 dataframes. Also RAW socket interface to build MAC header from userspace. +source "net/mac802154/Kconfig" source "net/ieee802154/6lowpan/Kconfig" endif From patchwork Wed Dec 22 15:57:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691788 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 5D7ECC433F5 for ; Wed, 22 Dec 2021 15:58:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343846AbhLVP56 (ORCPT ); Wed, 22 Dec 2021 10:57:58 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:60701 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343791AbhLVP5y (ORCPT ); Wed, 22 Dec 2021 10:57:54 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id A9C7860015; Wed, 22 Dec 2021 15:57:51 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 05/18] net: ieee802154: Move the address structure earlier Date: Wed, 22 Dec 2021 16:57:30 +0100 Message-Id: <20211222155743.256280-6-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org From: David Girault Move the address structure earlier in the cfg802154.h header in order to use it in subsequent additions. There is no functional change here. Signed-off-by: David Girault [miquel.raynal@bootlin.com: Isolate this change from a bigger commit] Signed-off-by: Miquel Raynal --- include/net/cfg802154.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 6ed07844eb24..9f57bafeb3bb 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -29,6 +29,15 @@ struct ieee802154_llsec_key_id; struct ieee802154_llsec_key; #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ +struct ieee802154_addr { + u8 mode; + __le16 pan_id; + union { + __le16 short_addr; + __le64 extended_addr; + }; +}; + struct cfg802154_ops { struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, const char *name, @@ -227,15 +236,6 @@ static inline void wpan_phy_net_set(struct wpan_phy *wpan_phy, struct net *net) write_pnet(&wpan_phy->_net, net); } -struct ieee802154_addr { - u8 mode; - __le16 pan_id; - union { - __le16 short_addr; - __le64 extended_addr; - }; -}; - struct ieee802154_llsec_key_id { u8 mode; u8 id; From patchwork Wed Dec 22 15:57:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691808 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 0DC0FC433EF for ; Wed, 22 Dec 2021 15:59:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344107AbhLVP7E (ORCPT ); Wed, 22 Dec 2021 10:59:04 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:59117 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343835AbhLVP54 (ORCPT ); Wed, 22 Dec 2021 10:57:56 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 3377C60016; Wed, 22 Dec 2021 15:57:53 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 06/18] net: ieee802154: Add a kernel doc header to the ieee802154_addr structure Date: Wed, 22 Dec 2021 16:57:31 +0100 Message-Id: <20211222155743.256280-7-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org From: David Girault While not being absolutely needed, it at least explain the mode vs. enum fields. Signed-off-by: David Girault [miquel.raynal@bootlin.com: Isolate this change from a bigger commit and reword the comment] Signed-off-by: Miquel Raynal --- include/net/cfg802154.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 9f57bafeb3bb..4f36003bca98 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -29,6 +29,16 @@ struct ieee802154_llsec_key_id; struct ieee802154_llsec_key; #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ +/** + * struct ieee802154_addr - IEEE802.15.4 device address + * @mode: Address mode from frame header. Can be one of: + * - @IEEE802154_ADDR_NONE + * - @IEEE802154_ADDR_SHORT + * - @IEEE802154_ADDR_LONG + * @pan_id: The PAN ID this address belongs to + * @short_addr: address if @mode is @IEEE802154_ADDR_SHORT + * @extended_addr: address if @mode is @IEEE802154_ADDR_LONG + */ struct ieee802154_addr { u8 mode; __le16 pan_id; From patchwork Wed Dec 22 15:57:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691790 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 10C85C4332F for ; Wed, 22 Dec 2021 15:58:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343842AbhLVP6C (ORCPT ); Wed, 22 Dec 2021 10:58:02 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:49907 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343825AbhLVP55 (ORCPT ); Wed, 22 Dec 2021 10:57:57 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 76E896000C; Wed, 22 Dec 2021 15:57:55 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 07/18] net: ieee802154: Return meaningful error codes from the netlink helpers Date: Wed, 22 Dec 2021 16:57:32 +0100 Message-Id: <20211222155743.256280-8-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org Returning -1 does not indicate anything useful. Use a standard and meaningful error code instead. Signed-off-by: Miquel Raynal --- net/ieee802154/nl802154.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 277124f206e0..e0b072aecf0f 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -1441,7 +1441,7 @@ static int nl802154_send_key(struct sk_buff *msg, u32 cmd, u32 portid, hdr = nl802154hdr_put(msg, portid, seq, flags, cmd); if (!hdr) - return -1; + return -ENOBUFS; if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex)) goto nla_put_failure; @@ -1634,7 +1634,7 @@ static int nl802154_send_device(struct sk_buff *msg, u32 cmd, u32 portid, hdr = nl802154hdr_put(msg, portid, seq, flags, cmd); if (!hdr) - return -1; + return -ENOBUFS; if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex)) goto nla_put_failure; @@ -1812,7 +1812,7 @@ static int nl802154_send_devkey(struct sk_buff *msg, u32 cmd, u32 portid, hdr = nl802154hdr_put(msg, portid, seq, flags, cmd); if (!hdr) - return -1; + return -ENOBUFS; if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex)) goto nla_put_failure; @@ -1988,7 +1988,7 @@ static int nl802154_send_seclevel(struct sk_buff *msg, u32 cmd, u32 portid, hdr = nl802154hdr_put(msg, portid, seq, flags, cmd); if (!hdr) - return -1; + return -ENOBUFS; if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex)) goto nla_put_failure; From patchwork Wed Dec 22 15:57:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691796 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 35C14C433F5 for ; Wed, 22 Dec 2021 15:58:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344050AbhLVP6Y (ORCPT ); Wed, 22 Dec 2021 10:58:24 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:59117 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343849AbhLVP57 (ORCPT ); Wed, 22 Dec 2021 10:57:59 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id E1CC560012; Wed, 22 Dec 2021 15:57:56 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 08/18] net: ieee802154: Add support for internal PAN management Date: Wed, 22 Dec 2021 16:57:33 +0100 Message-Id: <20211222155743.256280-9-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org Let's introduce the basics of PAN management: - structures defining PANs - helpers for PANs registration - helpers discarding old PANs Co-developed-by: David Girault Signed-off-by: David Girault Signed-off-by: Miquel Raynal --- include/net/cfg802154.h | 31 ++++++ net/ieee802154/Makefile | 2 +- net/ieee802154/core.c | 2 + net/ieee802154/core.h | 20 ++++ net/ieee802154/pan.c | 208 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 net/ieee802154/pan.c diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 4f36003bca98..4402f93cda32 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -48,6 +48,24 @@ struct ieee802154_addr { }; }; +/** + * struct ieee802154_pan_desc - PAN descriptor information + * @coord: PAN ID and coordinator address + * @page: page this PAN is on + * @channel: channel this PAN is on + * @superframe_spec: SuperFrame specification as received + * @link_quality: link quality indicator at which the beacon was received + * @gts_permit: the PAN coordinator accepts GTS requests + */ +struct ieee802154_pan_desc { + struct ieee802154_addr *coord; + u8 page; + u8 channel; + u16 superframe_spec; + u8 link_quality; + bool gts_permit; +}; + struct cfg802154_ops { struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, const char *name, @@ -415,4 +433,17 @@ static inline const char *wpan_phy_name(struct wpan_phy *phy) return dev_name(&phy->dev); } +/** + * cfg802154_record_pan - Advertize a new PAN following a beacon's reception + * @wpan_phy: PHY receiving the beacon + * @pan: PAN descriptor + * + * Tells the internal pan management layer to either register this PAN if it is + * new or at least update its entry if already discovered. + * + * Returns 0 on success, a negative error code otherwise. + */ +int cfg802154_record_pan(struct wpan_phy *wpan_phy, + struct ieee802154_pan_desc *pan); + #endif /* __NET_CFG802154_H */ diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile index f05b7bdae2aa..6b7c66de730d 100644 --- a/net/ieee802154/Makefile +++ b/net/ieee802154/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_IEEE802154_SOCKET) += ieee802154_socket.o obj-y += 6lowpan/ ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o core.o \ - header_ops.o sysfs.o nl802154.o trace.o + header_ops.o sysfs.o nl802154.o pan.o trace.o ieee802154_socket-y := socket.o CFLAGS_trace.o := -I$(src) diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c index de259b5170ab..0f73e0571883 100644 --- a/net/ieee802154/core.c +++ b/net/ieee802154/core.c @@ -115,6 +115,8 @@ wpan_phy_new(const struct cfg802154_ops *ops, size_t priv_size) kfree(rdev); return NULL; } + spin_lock_init(&rdev->pan_lock); + INIT_LIST_HEAD(&rdev->pan_list); /* atomic_inc_return makes it start at 1, make it start at 0 */ rdev->wpan_phy_idx--; diff --git a/net/ieee802154/core.h b/net/ieee802154/core.h index 1c19f575d574..dea1d6f70489 100644 --- a/net/ieee802154/core.h +++ b/net/ieee802154/core.h @@ -22,6 +22,12 @@ struct cfg802154_registered_device { struct list_head wpan_dev_list; int devlist_generation, wpan_dev_id; + /* pan management */ + spinlock_t pan_lock; + struct list_head pan_list; + int pan_entries; + int pan_generation; + /* must be last because of the way we do wpan_phy_priv(), * and it should at least be aligned to NETDEV_ALIGN */ @@ -39,6 +45,17 @@ wpan_phy_to_rdev(struct wpan_phy *wpan_phy) extern struct list_head cfg802154_rdev_list; extern int cfg802154_rdev_list_generation; +struct cfg802154_internal_pan { + struct list_head list; + unsigned long discovery_ts; + struct ieee802154_pan_desc desc; +}; + +/* Always update the list by dropping the expired PANs before iterating */ +#define ieee802154_for_each_pan(pan, rdev) \ + cfg802154_expire_pans(rdev); \ + list_for_each_entry((pan), &(rdev)->pan_list, list) + int cfg802154_switch_netns(struct cfg802154_registered_device *rdev, struct net *net); /* free object */ @@ -47,4 +64,7 @@ struct cfg802154_registered_device * cfg802154_rdev_by_wpan_phy_idx(int wpan_phy_idx); struct wpan_phy *wpan_phy_idx_to_wpan_phy(int wpan_phy_idx); +void cfg802154_expire_pans(struct cfg802154_registered_device *rdev); +void cfg802154_flush_pans(struct cfg802154_registered_device *rdev); + #endif /* __IEEE802154_CORE_H */ diff --git a/net/ieee802154/pan.c b/net/ieee802154/pan.c new file mode 100644 index 000000000000..c71a3664d5c3 --- /dev/null +++ b/net/ieee802154/pan.c @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IEEE 802.15.4 PAN management + * + * Copyright (C) Qorvo, 2021 + * Authors: + * - David Girault + * - Miquel Raynal + */ + +#include +#include +#include +#include + +#include +#include + +#include "ieee802154.h" +#include "core.h" + +/* Maximum number of PAN entries to store */ +static int max_pan_entries = 100; +module_param(max_pan_entries, uint, 0644); +MODULE_PARM_DESC(max_pan_entries, + "Maximum number of PANs to discover per scan (default is 100)"); + +static int pan_expiration = 60; +module_param(pan_expiration, uint, 0644); +MODULE_PARM_DESC(pan_expiration, + "Expiration of the scan validity in seconds (default is 60s)"); + +static struct cfg802154_internal_pan * +cfg802154_alloc_pan(struct ieee802154_pan_desc *desc) +{ + struct cfg802154_internal_pan *new; + struct ieee802154_addr *coord; + + new = kzalloc(sizeof(*new), GFP_KERNEL); + if (!new) + return ERR_PTR(-ENOMEM); + + coord = kzalloc(sizeof(*coord), GFP_KERNEL); + if (!coord) { + kfree(new); + return ERR_PTR(-ENOMEM); + } + + new->discovery_ts = jiffies; + new->desc = *desc; + + *coord = *desc->coord; + new->desc.coord = coord; + + return new; +} + +static void cfg802154_free_pan(struct cfg802154_internal_pan *pan) +{ + kfree(pan->desc.coord); + kfree(pan); +} + +static void cfg802154_unlink_pan(struct cfg802154_registered_device *rdev, + struct cfg802154_internal_pan *pan) +{ + lockdep_assert_held(&rdev->pan_lock); + + list_del(&pan->list); + cfg802154_free_pan(pan); + rdev->pan_entries--; + rdev->pan_generation++; +} + +static void cfg802154_link_pan(struct cfg802154_registered_device *rdev, + struct cfg802154_internal_pan *pan) +{ + lockdep_assert_held(&rdev->pan_lock); + + list_add_tail(&pan->list, &rdev->pan_list); + rdev->pan_entries++; + rdev->pan_generation++; +} + +void cfg802154_expire_pans(struct cfg802154_registered_device *rdev) +{ + unsigned long expiration_time = jiffies - (pan_expiration * HZ); + struct cfg802154_internal_pan *pan, *tmp; + + lockdep_assert_held(&rdev->pan_lock); + + list_for_each_entry_safe(pan, tmp, &rdev->pan_list, list) { + if (!time_after(expiration_time, pan->discovery_ts)) + continue; + + cfg802154_unlink_pan(rdev, pan); + } +} +EXPORT_SYMBOL(cfg802154_expire_pans); + +static void cfg802154_expire_oldest_pan(struct cfg802154_registered_device *rdev) +{ + struct cfg802154_internal_pan *pan, *oldest; + + lockdep_assert_held(&rdev->pan_lock); + + if (WARN_ON(!max_pan_entries || list_empty(&rdev->pan_list))) + return; + + oldest = list_first_entry(&rdev->pan_list, + struct cfg802154_internal_pan, list); + + list_for_each_entry(pan, &rdev->pan_list, list) { + if (!time_before(oldest->discovery_ts, pan->discovery_ts)) + oldest = pan; + } + + cfg802154_unlink_pan(rdev, oldest); +} + +void cfg802154_flush_pans(struct cfg802154_registered_device *rdev) +{ + struct cfg802154_internal_pan *pan, *tmp; + + lockdep_assert_held(&rdev->pan_lock); + + list_for_each_entry_safe(pan, tmp, &rdev->pan_list, list) + cfg802154_unlink_pan(rdev, pan); +} +EXPORT_SYMBOL(cfg802154_flush_pans); + +static bool cfg802154_same_pan(struct ieee802154_pan_desc *a, + struct ieee802154_pan_desc *b) +{ + int ret; + + if (a->page != b->page) + return false; + + if (a->channel != b->channel) + return false; + + ret = memcmp(&a->coord->pan_id, &b->coord->pan_id, + sizeof(a->coord->pan_id)); + if (ret) + return false; + + if (a->coord->mode != b->coord->mode) + return false; + + if (a->coord->mode == IEEE802154_ADDR_SHORT) + ret = memcmp(&a->coord->short_addr, &b->coord->short_addr, + IEEE802154_SHORT_ADDR_LEN); + else + ret = memcmp(&a->coord->extended_addr, &b->coord->extended_addr, + IEEE802154_EXTENDED_ADDR_LEN); + + return true; +} + +static struct cfg802154_internal_pan * +cfg802154_find_matching_pan(struct cfg802154_registered_device *rdev, + struct cfg802154_internal_pan *tmp) +{ + struct cfg802154_internal_pan *pan; + + list_for_each_entry(pan, &rdev->pan_list, list) { + if (cfg802154_same_pan(&pan->desc, &tmp->desc)) + return pan; + } + + return NULL; +} + +static void cfg802154_pan_update(struct cfg802154_registered_device *rdev, + struct cfg802154_internal_pan *new) +{ + struct cfg802154_internal_pan *found; + + spin_lock_bh(&rdev->pan_lock); + + found = cfg802154_find_matching_pan(rdev, new); + if (found) + cfg802154_unlink_pan(rdev, found); + + if (unlikely(rdev->pan_entries >= max_pan_entries)) + cfg802154_expire_oldest_pan(rdev); + + cfg802154_link_pan(rdev, new); + + spin_unlock_bh(&rdev->pan_lock); +} + +int cfg802154_record_pan(struct wpan_phy *wpan_phy, + struct ieee802154_pan_desc *desc) +{ + struct cfg802154_registered_device *rdev = wpan_phy_to_rdev(wpan_phy); + struct cfg802154_internal_pan *new; + + new = cfg802154_alloc_pan(desc); + if (IS_ERR(new)) + return (PTR_ERR(new)); + + cfg802154_pan_update(rdev, new); + + return 0; +} +EXPORT_SYMBOL(cfg802154_record_pan); From patchwork Wed Dec 22 15:57:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691792 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 90C80C4332F for ; Wed, 22 Dec 2021 15:58:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241700AbhLVP6S (ORCPT ); Wed, 22 Dec 2021 10:58:18 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:49907 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343864AbhLVP6A (ORCPT ); Wed, 22 Dec 2021 10:58:00 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 5473660013; Wed, 22 Dec 2021 15:57:58 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 09/18] net: ieee802154: Define a beacon frame header Date: Wed, 22 Dec 2021 16:57:34 +0100 Message-Id: <20211222155743.256280-10-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org This definition will be used when adding support for scanning and defines the content of a beacon frame header as in the 802.15.4 specification. Signed-off-by: Miquel Raynal --- include/net/ieee802154_netdev.h | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index d0d188c3294b..a92999817dc0 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -22,6 +22,42 @@ #include +struct ieee802154_beaconhdr { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u16 beacon_order:4, + superframe_order:4, + final_cap_slot:4, + battery_life_ext:1, + reserved0:1, + pan_coordinator:1, + assoc_permit:1; + u8 gts_count:3, + gts_reserved:4, + gts_permit:1; + u8 pend_short_addr_count:3, + reserved1:1, + pend_ext_addr_count:3, + reserved2:1; +#elif defined(__BIG_ENDIAN_BITFIELD) + u16 assoc_permit:1, + pan_coordinator:1, + reserved0:1, + battery_life_ext:1, + final_cap_slot:4, + superframe_order:4, + beacon_order:4; + u8 gts_permit:1, + gts_reserved:4, + gts_count:3; + u8 reserved2:1, + pend_ext_addr_count:3, + reserved1:1, + pend_short_addr_count:3; +#else +#error "Please fix " +#endif +} __packed; + struct ieee802154_sechdr { #if defined(__LITTLE_ENDIAN_BITFIELD) u8 level:3, From patchwork Wed Dec 22 15:57:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691791 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 D36C3C433F5 for ; Wed, 22 Dec 2021 15:58:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343872AbhLVP6P (ORCPT ); Wed, 22 Dec 2021 10:58:15 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:60803 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343873AbhLVP6C (ORCPT ); Wed, 22 Dec 2021 10:58:02 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id B201D60002; Wed, 22 Dec 2021 15:57:59 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 10/18] net: ieee802154: Define frame types Date: Wed, 22 Dec 2021 16:57:35 +0100 Message-Id: <20211222155743.256280-11-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org A 802.15.4 frame can be of different types, here is a definition matching the specification. This enumeration will be soon be used when adding scanning support. Signed-off-by: Miquel Raynal --- include/net/ieee802154_netdev.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index a92999817dc0..04738ae3b25e 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -105,6 +105,17 @@ struct ieee802154_hdr_fc { #endif }; +enum ieee802154_frame_type { + IEEE802154_BEACON_FRAME, + IEEE802154_DATA_FRAME, + IEEE802154_ACKNOWLEDGEMENT_FRAME, + IEEE802154_MAC_COMMAND_FRAME, + IEEE802154_RESERVED_FRAME, + IEEE802154_MULTIPURPOSE_FRAME, + IEEE802154_FRAGMENT_FRAME, + IEEE802154_EXTENDED_FRAME, +}; + struct ieee802154_hdr { struct ieee802154_hdr_fc fc; u8 seq; From patchwork Wed Dec 22 15:57:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691789 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 1F5BDC433F5 for ; Wed, 22 Dec 2021 15:58:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343966AbhLVP6L (ORCPT ); Wed, 22 Dec 2021 10:58:11 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:56615 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241620AbhLVP6D (ORCPT ); Wed, 22 Dec 2021 10:58:03 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 29FA260010; Wed, 22 Dec 2021 15:58:01 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 11/18] net: ieee802154: Add support for scanning requests Date: Wed, 22 Dec 2021 16:57:36 +0100 Message-Id: <20211222155743.256280-12-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org This involves processing triggering scan requests, abort scan requests, as well as providing information about if the last scan was finished or not. A scan request structure is created to list the requirements. A netlink multicast scan group is also created for the occasion so that listeners can only focus on scan activity. Mac layers may now implement the ->trigger_scan() and ->abort_scan() hooks. Co-developed-by: David Girault Signed-off-by: David Girault Signed-off-by: Miquel Raynal --- include/linux/ieee802154.h | 2 + include/net/cfg802154.h | 26 +++++ include/net/nl802154.h | 49 ++++++++ net/ieee802154/core.h | 3 + net/ieee802154/nl802154.c | 234 +++++++++++++++++++++++++++++++++++++ net/ieee802154/nl802154.h | 4 + net/ieee802154/rdev-ops.h | 28 +++++ net/ieee802154/trace.h | 40 +++++++ 8 files changed, 386 insertions(+) diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h index 95c831162212..a9b09a9b8f70 100644 --- a/include/linux/ieee802154.h +++ b/include/linux/ieee802154.h @@ -44,6 +44,8 @@ #define IEEE802154_SHORT_ADDR_LEN 2 #define IEEE802154_PAN_ID_LEN 2 +/* Duration in superframe order */ +#define IEEE802154_MAX_SCAN_DURATION 14 #define IEEE802154_LIFS_PERIOD 40 #define IEEE802154_SIFS_PERIOD 12 #define IEEE802154_MAX_SIFS_FRAME_SIZE 18 diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 4402f93cda32..292eaf280f01 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -66,6 +66,28 @@ struct ieee802154_pan_desc { bool gts_permit; }; +/** + * struct cfg802154_scan_req - Scan request + * + * @type: type of scan to be performed + * @flags: flags bitfield controlling the operation + * @page: page on which to perform the scan + * @channels: channels in te %page to be scanned + * @duration: time spent on each channel, calculated with: + * aBaseSuperframeDuration * (2 ^ duration + 1) + * @wpan_dev: the wpan device on which to perform the scan + * @wpan_phy: the wpan phy on which to perform the scan + */ +struct cfg802154_scan_request { + enum nl802154_scan_types type; + u32 flags; + u8 page; + u32 channels; + u8 duration; + struct wpan_dev *wpan_dev; + struct wpan_phy *wpan_phy; +}; + struct cfg802154_ops { struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, const char *name, @@ -104,6 +126,10 @@ struct cfg802154_ops { struct wpan_dev *wpan_dev, bool mode); int (*set_ackreq_default)(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, bool ackreq); + int (*trigger_scan)(struct wpan_phy *wpan_phy, + struct cfg802154_scan_request *request); + int (*abort_scan)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev); #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL void (*get_llsec_table)(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, diff --git a/include/net/nl802154.h b/include/net/nl802154.h index 145acb8f2509..51eca3a2b14e 100644 --- a/include/net/nl802154.h +++ b/include/net/nl802154.h @@ -58,6 +58,10 @@ enum nl802154_commands { NL802154_CMD_SET_WPAN_PHY_NETNS, + NL802154_CMD_TRIGGER_SCAN, + NL802154_CMD_ABORT_SCAN, + NL802154_CMD_SCAN_DONE, + /* add new commands above here */ #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL @@ -133,6 +137,11 @@ enum nl802154_attrs { NL802154_ATTR_PID, NL802154_ATTR_NETNS_FD, + NL802154_ATTR_SCAN_TYPE, + NL802154_ATTR_SCAN_FLAGS, + NL802154_ATTR_SCAN_CHANNELS, + NL802154_ATTR_SCAN_DURATION, + /* add attributes here, update the policy in nl802154.c */ #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL @@ -218,6 +227,46 @@ enum nl802154_wpan_phy_capability_attr { NL802154_CAP_ATTR_MAX = __NL802154_CAP_ATTR_AFTER_LAST - 1 }; +/** + * enum nl802154_scan_types - Scan types + * + * @__NL802154_SCAN_INVALID: scan type number 0 is reserved + * @NL802154_SCAN_ED: An ED scan allows a device to obtain a measure of the peak + * energy in each requested channel + * @NL802154_SCAN_ACTIVE: Locate any coordinator transmitting Beacon frames using + * a Beacon Request command + * @NL802154_SCAN_PASSIVE: Locate any coordinator transmitting Beacon frames + * @NL802154_SCAN_ORPHAN: Relocate coordinator following a loss of synchronisation + * @NL802154_SCAN_ENHANCED_ACTIVE: Same as Active using Enhanced Beacon Request + * command instead of Beacon Request command + * @NL802154_SCAN_RIT_PASSIVE: Passive scan for RIT Data Request command frames + * instead of Beacon frames + * @NL802154_SCAN_ATTR_MAX: Maximum SCAN attribute number + */ +enum nl802154_scan_types { + __NL802154_SCAN_INVALID, + NL802154_SCAN_ED, + NL802154_SCAN_ACTIVE, + NL802154_SCAN_PASSIVE, + NL802154_SCAN_ORPHAN, + NL802154_SCAN_ENHANCED_ACTIVE, + NL802154_SCAN_RIT_PASSIVE, + + /* keep last */ + NL802154_SCAN_ATTR_MAX, +}; + +/** + * enum nl802154_scan_flags - Scan request control flags + * + * @NL802154_SCAN_FLAG_RANDOM_ADDR: use a random MAC address for this scan (ie. + * a different one for every scan iteration). When the flag is set, full + * randomisation is assumed. + */ +enum nl802154_scan_flags { + NL802154_SCAN_FLAG_RANDOM_ADDR = BIT(0), +}; + /** * enum nl802154_cca_modes - cca modes * diff --git a/net/ieee802154/core.h b/net/ieee802154/core.h index dea1d6f70489..190513ee4b51 100644 --- a/net/ieee802154/core.h +++ b/net/ieee802154/core.h @@ -28,6 +28,9 @@ struct cfg802154_registered_device { int pan_entries; int pan_generation; + /* scanning */ + struct cfg802154_scan_request *scan_req; + /* must be last because of the way we do wpan_phy_priv(), * and it should at least be aligned to NETDEV_ALIGN */ diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index e0b072aecf0f..d59de9812721 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -26,10 +26,12 @@ static struct genl_family nl802154_fam; /* multicast groups */ enum nl802154_multicast_groups { NL802154_MCGRP_CONFIG, + NL802154_MCGRP_SCAN, }; static const struct genl_multicast_group nl802154_mcgrps[] = { [NL802154_MCGRP_CONFIG] = { .name = "config", }, + [NL802154_MCGRP_SCAN] = { .name = "scan", }, }; /* returns ERR_PTR values */ @@ -216,6 +218,12 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = { [NL802154_ATTR_PID] = { .type = NLA_U32 }, [NL802154_ATTR_NETNS_FD] = { .type = NLA_U32 }, + + [NL802154_ATTR_SCAN_TYPE] = { .type = NLA_U8, }, + [NL802154_ATTR_SCAN_FLAGS] = { .type = NLA_U32, }, + [NL802154_ATTR_SCAN_CHANNELS] = { .type = NLA_U32, }, + [NL802154_ATTR_SCAN_DURATION] = { .type = NLA_U8, }, + #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL [NL802154_ATTR_SEC_ENABLED] = { .type = NLA_U8, }, [NL802154_ATTR_SEC_OUT_LEVEL] = { .type = NLA_U32, }, @@ -1281,6 +1289,216 @@ static int nl802154_wpan_phy_netns(struct sk_buff *skb, struct genl_info *info) return err; } +static int nl802154_trigger_scan(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wpan_dev *wpan_dev = dev->ieee802154_ptr; + struct wpan_phy *wpan_phy = &rdev->wpan_phy; + struct cfg802154_scan_request *request; + u8 type; + int err; + + /* Test iftype and avoid scanning if monitor type. */ + if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) + return -EOPNOTSUPP; + + request = kzalloc(sizeof(*request), GFP_KERNEL); + if (!request) + return -ENOMEM; + + request->wpan_dev = wpan_dev; + request->wpan_phy = wpan_phy; + + type = nla_get_u8(info->attrs[NL802154_ATTR_SCAN_TYPE]); + switch (type) { + case NL802154_SCAN_ACTIVE: + case NL802154_SCAN_PASSIVE: + request->type = type; + break; + default: + pr_err("Invalid scan type: %d\n", type); + err = -EINVAL; + goto free_request; + } + + if (info->attrs[NL802154_ATTR_SCAN_FLAGS]) + request->flags = nla_get_u32(info->attrs[NL802154_ATTR_SCAN_FLAGS]); + + if (info->attrs[NL802154_ATTR_PAGE]) { + request->page = nla_get_u8(info->attrs[NL802154_ATTR_PAGE]); + if (request->page > IEEE802154_MAX_PAGE) { + pr_err("Invalid page %d > %d\n", + request->page, IEEE802154_MAX_PAGE); + err = -EINVAL; + goto free_request; + } + } else { + /* Use current page by default */ + request->page = wpan_phy->current_page; + } + + if (info->attrs[NL802154_ATTR_SCAN_CHANNELS]) { + request->channels = nla_get_u32(info->attrs[NL802154_ATTR_SCAN_CHANNELS]); + if (request->channels >= BIT(IEEE802154_MAX_CHANNEL + 1)) { + pr_err("Invalid channels bitfield %x ≥ %lx\n", + request->channels, + BIT(IEEE802154_MAX_CHANNEL + 1)); + err = -EINVAL; + goto free_request; + } + } else { + /* Scan all supported channels by default */ + request->channels = rdev->wpan_phy.supported.channels[request->page]; + } + + if (info->attrs[NL802154_ATTR_SCAN_DURATION]) { + request->duration = nla_get_u8(info->attrs[NL802154_ATTR_SCAN_DURATION]); + if (request->duration > IEEE802154_MAX_SCAN_DURATION) { + pr_err("Invalid duration %d > %d\n", + request->duration, IEEE802154_MAX_SCAN_DURATION); + err = -EINVAL; + goto free_request; + } + } else { + /* Use maximum duration order by default */ + request->duration = IEEE802154_MAX_SCAN_DURATION; + } + + err = rdev_trigger_scan(rdev, request); + if (err) { + pr_err("Failure starting scanning (%d)\n", err); + goto free_request; + } + + rdev->scan_req = request; + + if (wpan_dev->netdev) + dev_hold(wpan_dev->netdev); + + return 0; + +free_request: + kfree(request); + + return err; +} + +static int nl802154_add_scan_req(struct sk_buff *msg, + struct cfg802154_scan_request *req) +{ + if (req->type && + nla_put_u8(msg, NL802154_ATTR_SCAN_TYPE, req->type)) + goto nla_put_failure; + + if (req->flags && + nla_put_u32(msg, NL802154_ATTR_SCAN_FLAGS, req->flags)) + goto nla_put_failure; + + if (req->page && + nla_put_u8(msg, NL802154_ATTR_PAGE, req->page)) + goto nla_put_failure; + + if (req->channels && + nla_put_u32(msg, NL802154_ATTR_SCAN_CHANNELS, req->channels)) + goto nla_put_failure; + + return 0; + +nla_put_failure: + return -ENOBUFS; +} + +static int nl802154_prep_scan_msg(struct sk_buff *msg, + struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev, + u32 portid, u32 seq, int flags, u8 cmd) +{ + void *hdr; + + hdr = nl802154hdr_put(msg, portid, seq, flags, cmd); + if (!hdr) + return -ENOBUFS; + + if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx)) + goto nla_put_failure; + + if (wpan_dev->netdev && + nla_put_u32(msg, NL802154_ATTR_IFINDEX, wpan_dev->netdev->ifindex)) + goto nla_put_failure; + + if (nla_put_u64_64bit(msg, NL802154_ATTR_WPAN_DEV, + wpan_dev_id(wpan_dev), NL802154_ATTR_PAD)) + goto nla_put_failure; + + if (nl802154_add_scan_req(msg, rdev->scan_req)) + goto nla_put_failure; + + genlmsg_end(msg, hdr); + + return 0; + + nla_put_failure: + genlmsg_cancel(msg, hdr); + + return -EMSGSIZE; +} + +static int nl802154_send_scan_done_msg(struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev) +{ + struct sk_buff *msg; + int ret; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + ret = nl802154_prep_scan_msg(msg, rdev, wpan_dev, 0, 0, 0, + NL802154_CMD_SCAN_DONE); + if (ret < 0) { + nlmsg_free(msg); + return ret; + } + + return genlmsg_multicast_netns(&nl802154_fam, + wpan_phy_net(&rdev->wpan_phy), msg, 0, + NL802154_MCGRP_SCAN, GFP_KERNEL); +} + +int nl802154_send_scan_done(struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev) +{ + int err; + + err = nl802154_send_scan_done_msg(rdev, wpan_dev); + + /* Ignore errors when there are no listeners */ + if (err == -ESRCH) + err = 0; + + if (wpan_dev->netdev) + dev_put(wpan_dev->netdev); + + kfree(rdev->scan_req); + rdev->scan_req = NULL; + + return err; +} +EXPORT_SYMBOL(nl802154_send_scan_done); + +static int nl802154_abort_scan(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wpan_dev *wpan_dev = dev->ieee802154_ptr; + + /* Resources will be released in the notification helper above when we + * are sure all actions have ended. + */ + return rdev_abort_scan(rdev, wpan_dev); +} + #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL static const struct nla_policy nl802154_dev_addr_policy[NL802154_DEV_ADDR_ATTR_MAX + 1] = { [NL802154_DEV_ADDR_ATTR_PAN_ID] = { .type = NLA_U16 }, @@ -2369,6 +2587,22 @@ static const struct genl_ops nl802154_ops[] = { .internal_flags = NL802154_FLAG_NEED_NETDEV | NL802154_FLAG_NEED_RTNL, }, + { + .cmd = NL802154_CMD_TRIGGER_SCAN, + .doit = nl802154_trigger_scan, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_NETDEV | + NL802154_FLAG_CHECK_NETDEV_UP | + NL802154_FLAG_NEED_RTNL, + }, + { + .cmd = NL802154_CMD_ABORT_SCAN, + .doit = nl802154_abort_scan, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_NETDEV | + NL802154_FLAG_CHECK_NETDEV_UP | + NL802154_FLAG_NEED_RTNL, + }, #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL { .cmd = NL802154_CMD_SET_SEC_PARAMS, diff --git a/net/ieee802154/nl802154.h b/net/ieee802154/nl802154.h index 8c4b6d08954c..84567cd4ea83 100644 --- a/net/ieee802154/nl802154.h +++ b/net/ieee802154/nl802154.h @@ -2,7 +2,11 @@ #ifndef __IEEE802154_NL802154_H #define __IEEE802154_NL802154_H +#include "core.h" + int nl802154_init(void); void nl802154_exit(void); +int nl802154_send_scan_done(struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev); #endif /* __IEEE802154_NL802154_H */ diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index 598f5af49775..e171d74c3251 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -209,6 +209,34 @@ rdev_set_ackreq_default(struct cfg802154_registered_device *rdev, return ret; } +static inline int rdev_trigger_scan(struct cfg802154_registered_device *rdev, + struct cfg802154_scan_request *request) +{ + int ret; + + if (!rdev->ops->trigger_scan) + return -EOPNOTSUPP; + + trace_802154_rdev_trigger_scan(&rdev->wpan_phy, request); + ret = rdev->ops->trigger_scan(&rdev->wpan_phy, request); + trace_802154_rdev_return_int(&rdev->wpan_phy, ret); + return ret; +} + +static inline int rdev_abort_scan(struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev) +{ + int ret; + + if (!rdev->ops->abort_scan) + return -EOPNOTSUPP; + + trace_802154_rdev_abort_scan(&rdev->wpan_phy, wpan_dev); + ret = rdev->ops->abort_scan(&rdev->wpan_phy, wpan_dev); + trace_802154_rdev_return_int(&rdev->wpan_phy, ret); + return ret; +} + #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL /* TODO this is already a nl802154, so move into ieee802154 */ static inline void diff --git a/net/ieee802154/trace.h b/net/ieee802154/trace.h index 19c2e5d60e76..e5405f737ded 100644 --- a/net/ieee802154/trace.h +++ b/net/ieee802154/trace.h @@ -295,6 +295,46 @@ TRACE_EVENT(802154_rdev_set_ackreq_default, WPAN_DEV_PR_ARG, BOOL_TO_STR(__entry->ackreq)) ); +TRACE_EVENT(802154_rdev_trigger_scan, + TP_PROTO(struct wpan_phy *wpan_phy, + struct cfg802154_scan_request *request), + TP_ARGS(wpan_phy, request), + TP_STRUCT__entry( + WPAN_PHY_ENTRY + __field(u8, page) + __field(u32, channels) + __field(u8, duration) + ), + TP_fast_assign( + WPAN_PHY_ASSIGN; + __entry->page = request->page; + __entry->channels = request->channels; + __entry->duration = request->duration; + ), + TP_printk(WPAN_PHY_PR_FMT ", scan, page: %d, channels: %x, duration %d", + WPAN_PHY_PR_ARG, __entry->page, __entry->channels, __entry->duration) +); + +DECLARE_EVENT_CLASS(802154_wdev_template, + TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev), + TP_ARGS(wpan_phy, wpan_dev), + TP_STRUCT__entry( + WPAN_PHY_ENTRY + WPAN_DEV_ENTRY + ), + TP_fast_assign( + WPAN_PHY_ASSIGN; + WPAN_DEV_ASSIGN; + ), + TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT, + WPAN_PHY_PR_ARG, WPAN_DEV_PR_ARG) +); + +DEFINE_EVENT(802154_wdev_template, 802154_rdev_abort_scan, + TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev), + TP_ARGS(wpan_phy, wpan_dev) +); + TRACE_EVENT(802154_rdev_return_int, TP_PROTO(struct wpan_phy *wpan_phy, int ret), TP_ARGS(wpan_phy, ret), From patchwork Wed Dec 22 15:57:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691793 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 6B68EC433EF for ; Wed, 22 Dec 2021 15:58:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343867AbhLVP6R (ORCPT ); Wed, 22 Dec 2021 10:58:17 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:59909 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343888AbhLVP6F (ORCPT ); Wed, 22 Dec 2021 10:58:05 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 90B3C60019; Wed, 22 Dec 2021 15:58:02 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 12/18] net: mac802154: Handle scan requests Date: Wed, 22 Dec 2021 16:57:37 +0100 Message-Id: <20211222155743.256280-13-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org Implement the core hooks in order to provide the softMAC layer support for scan requests and aborts. Changing the channels is prohibited during the scan. The implementation uses a workqueue triggered at a certain interval depending on the symbol duration for the current channel and the duration order provided. Received beacons during a passive scanning procedure are processed and either registered in the list of known PANs or the existing entry gets updated accordingly. Active scanning is not supported yet. Co-developed-by: David Girault Signed-off-by: David Girault Signed-off-by: Miquel Raynal --- include/linux/ieee802154.h | 4 + include/net/mac802154.h | 14 ++ net/mac802154/Makefile | 2 +- net/mac802154/cfg.c | 39 ++++++ net/mac802154/ieee802154_i.h | 15 +++ net/mac802154/main.c | 2 + net/mac802154/rx.c | 10 +- net/mac802154/scan.c | 248 +++++++++++++++++++++++++++++++++++ net/mac802154/util.c | 26 ++++ 9 files changed, 357 insertions(+), 3 deletions(-) create mode 100644 net/mac802154/scan.c diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h index a9b09a9b8f70..60b09ff65d3d 100644 --- a/include/linux/ieee802154.h +++ b/include/linux/ieee802154.h @@ -46,6 +46,10 @@ /* Duration in superframe order */ #define IEEE802154_MAX_SCAN_DURATION 14 +/* Superframe duration in slots */ +#define IEEE802154_SUPERFRAME_PERIOD 16 +/* Various periods expressed in symbols */ +#define IEEE802154_SLOT_PERIOD 60 #define IEEE802154_LIFS_PERIOD 40 #define IEEE802154_SIFS_PERIOD 12 #define IEEE802154_MAX_SIFS_FRAME_SIZE 18 diff --git a/include/net/mac802154.h b/include/net/mac802154.h index d524ffb9eb25..19bfbf591ea1 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -486,4 +486,18 @@ void ieee802154_stop_queue(struct ieee802154_hw *hw); void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb, bool ifs_handling); +/** + * ieee802154_queue_delayed_work - add work onto the mac802154 workqueue + * + * Drivers and mac802154 use this to queue delayed work onto the mac802154 + * workqueue. + * + * @hw: the hardware struct for the interface we are adding work for + * @dwork: delayable work to queue onto the mac802154 workqueue + * @delay: number of jiffies to wait before queueing + */ +void ieee802154_queue_delayed_work(struct ieee802154_hw *hw, + struct delayed_work *dwork, + unsigned long delay); + #endif /* NET_MAC802154_H */ diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile index 4059295fdbf8..43d1347b37ee 100644 --- a/net/mac802154/Makefile +++ b/net/mac802154/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_MAC802154) += mac802154.o mac802154-objs := main.o rx.o tx.o mac_cmd.o mib.o \ - iface.o llsec.o util.o cfg.o trace.o + iface.o llsec.o util.o cfg.o scan.o trace.o CFLAGS_trace.o := -I$(src) diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index fbeebe3bc31d..5c19d6f8e3eb 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -114,6 +114,10 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) wpan_phy->current_channel == channel) return 0; + /* Refuse to change channels during a scanning operation */ + if (local->scanning) + return -EBUSY; + ret = drv_set_channel(local, page, channel); if (!ret) { wpan_phy->current_page = page; @@ -260,6 +264,39 @@ ieee802154_set_ackreq_default(struct wpan_phy *wpan_phy, return 0; } +static int mac802154_trigger_scan(struct wpan_phy *wpan_phy, + struct cfg802154_scan_request *req) +{ + struct ieee802154_local *local = wpan_phy_priv(wpan_phy); + struct ieee802154_sub_if_data *sdata; + int ret; + + sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(req->wpan_dev); + + ASSERT_RTNL(); + + mutex_lock(&local->scan_lock); + ret = mac802154_trigger_scan_locked(sdata, req); + mutex_unlock(&local->scan_lock); + + return ret; +} + +static int mac802154_abort_scan(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev) +{ + struct ieee802154_local *local = wpan_phy_priv(wpan_phy); + int ret; + + ASSERT_RTNL(); + + mutex_lock(&local->scan_lock); + ret = mac802154_abort_scan_locked(local); + mutex_unlock(&local->scan_lock); + + return ret; +} + #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL static void ieee802154_get_llsec_table(struct wpan_phy *wpan_phy, @@ -467,6 +504,8 @@ const struct cfg802154_ops mac802154_config_ops = { .set_max_frame_retries = ieee802154_set_max_frame_retries, .set_lbt_mode = ieee802154_set_lbt_mode, .set_ackreq_default = ieee802154_set_ackreq_default, + .trigger_scan = mac802154_trigger_scan, + .abort_scan = mac802154_abort_scan, #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL .get_llsec_table = ieee802154_get_llsec_table, .lock_llsec_table = ieee802154_lock_llsec_table, diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 702560acc8ce..4945edf5c2ce 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -48,6 +48,15 @@ struct ieee802154_local { struct hrtimer ifs_timer; + /* Scanning */ + struct mutex scan_lock; + unsigned long scanning; + __le64 scan_addr; + int scan_channel_idx; + struct cfg802154_scan_request __rcu *scan_req; + struct ieee802154_sub_if_data __rcu *scan_sdata; + struct delayed_work scan_work; + bool started; bool suspended; @@ -166,6 +175,12 @@ void mac802154_unlock_table(struct net_device *dev); int mac802154_wpan_update_llsec(struct net_device *dev); +/* scanning handling */ +void mac802154_scan_work(struct work_struct *work); +int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata, + struct cfg802154_scan_request *request); +int mac802154_abort_scan_locked(struct ieee802154_local *local); +int mac802154_scan_rx(struct ieee802154_local *local, struct sk_buff *skb); /* interface handling */ int ieee802154_iface_init(void); void ieee802154_iface_exit(void); diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 520cedc594e1..568991734610 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -90,12 +90,14 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops) INIT_LIST_HEAD(&local->interfaces); mutex_init(&local->iflist_mtx); + mutex_init(&local->scan_lock); tasklet_setup(&local->tasklet, ieee802154_tasklet_handler); skb_queue_head_init(&local->skb_queue); INIT_WORK(&local->tx_work, ieee802154_xmit_worker); + INIT_DELAYED_WORK(&local->scan_work, mac802154_scan_work); /* init supported flags with 802.15.4 default ranges */ phy->supported.max_minbe = 8; diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index b8ce84618a55..acbce67caedc 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -198,8 +198,13 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local, ret = ieee802154_parse_frame_start(skb, &hdr); if (ret) { pr_debug("got invalid frame\n"); - kfree_skb(skb); - return; + goto free_skb; + } + + if (unlikely(local->scanning)) { + if (mac_cb(skb)->type == IEEE802154_FC_TYPE_BEACON) + mac802154_scan_rx(local, skb); + goto free_skb; } list_for_each_entry_rcu(sdata, &local->interfaces, list) { @@ -214,6 +219,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local, break; } +free_skb: kfree_skb(skb); } diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c new file mode 100644 index 000000000000..c5b85eaec319 --- /dev/null +++ b/net/mac802154/scan.c @@ -0,0 +1,248 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * IEEE 802.15.4 scanning management + * + * Copyright (C) Qorvo, 2021 + * Authors: + * - David Girault + * - Miquel Raynal + */ + +#include +#include +#include +#include + +#include "ieee802154_i.h" +#include "driver-ops.h" +#include "../ieee802154/nl802154.h" + +static bool mac802154_check_promiscuous(struct ieee802154_local *local) +{ + struct ieee802154_sub_if_data *sdata; + bool promiscuous_on = false; + + /* Check if one subif is already in promiscuous mode. Since the list is + * protected by its own mutex, take it here to ensure no modification + * occurs during the check. + */ + mutex_lock(&local->iflist_mtx); + list_for_each_entry(sdata, &local->interfaces, list) { + if (ieee802154_sdata_running(sdata) && + sdata->wpan_dev.promiscuous_mode) { + /* At least one is in promiscuous mode */ + promiscuous_on = true; + break; + } + } + mutex_unlock(&local->iflist_mtx); + return promiscuous_on; +} + +static int mac802154_set_promiscuous_mode(struct ieee802154_local *local, + bool state) +{ + bool promiscuous_on = mac802154_check_promiscuous(local); + int ret; + + if ((state && promiscuous_on) || (!state && !promiscuous_on)) + return 0; + + ret = drv_set_promiscuous_mode(local, state); + if (ret) + pr_err("Failed to %s promiscuous mode for SW scanning", + state ? "set" : "reset"); + + return ret; +} + +static int mac802154_send_scan_done(struct ieee802154_local *local) +{ + struct cfg802154_registered_device *rdev; + struct cfg802154_scan_request *scan_req; + struct wpan_dev *wpan_dev; + + scan_req = rcu_dereference_protected(local->scan_req, + lockdep_is_held(&local->scan_lock)); + rdev = wpan_phy_to_rdev(scan_req->wpan_phy); + wpan_dev = scan_req->wpan_dev; + + return nl802154_send_scan_done(rdev, wpan_dev); +} + +static int mac802154_end_of_scan(struct ieee802154_local *local) +{ + drv_set_channel(local, local->phy->current_page, + local->phy->current_channel); + local->scanning = false; + mac802154_set_promiscuous_mode(local, false); + + return mac802154_send_scan_done(local); +} + +int mac802154_abort_scan_locked(struct ieee802154_local *local) +{ + lockdep_assert_held(&local->scan_lock); + + if (!local->scanning) + return -ESRCH; + + cancel_delayed_work(&local->scan_work); + + return mac802154_end_of_scan(local); +} + +static unsigned int mac802154_scan_get_channel_time(u8 duration_order, + u8 symbol_duration) +{ + u64 base_super_frame_duration = (u64)symbol_duration * + IEEE802154_SUPERFRAME_PERIOD * IEEE802154_SLOT_PERIOD; + + return usecs_to_jiffies(base_super_frame_duration * + (BIT(duration_order) + 1)); +} + +void mac802154_scan_work(struct work_struct *work) +{ + struct ieee802154_local *local = + container_of(work, struct ieee802154_local, scan_work.work); + struct cfg802154_scan_request *scan_req; + struct ieee802154_sub_if_data *sdata; + unsigned int scan_duration; + bool end_of_scan = false; + unsigned long chan; + int ret; + + mutex_lock(&local->scan_lock); + + if (!local->scanning) + goto unlock_mutex; + + sdata = rcu_dereference_protected(local->scan_sdata, + lockdep_is_held(&local->scan_lock)); + scan_req = rcu_dereference_protected(local->scan_req, + lockdep_is_held(&local->scan_lock)); + + if (local->suspended || !ieee802154_sdata_running(sdata)) + goto queue_work; + + do { + chan = find_next_bit((const unsigned long *)&scan_req->channels, + IEEE802154_MAX_CHANNEL + 1, + local->scan_channel_idx + 1); + + /* If there are no more channels left, complete the scan */ + if (chan > IEEE802154_MAX_CHANNEL) { + end_of_scan = true; + goto unlock_mutex; + } + + /* Channel switch cannot be made atomic so hide the chan number + * in order to prevent beacon processing during this timeframe. + */ + local->scan_channel_idx = -1; + /* Bypass the stack on purpose */ + ret = drv_set_channel(local, scan_req->page, chan); + local->scan_channel_idx = chan; + } while (ret); + +queue_work: + scan_duration = mac802154_scan_get_channel_time(scan_req->duration, + local->phy->symbol_duration); + pr_debug("Scan channel %lu of page %u for %ums\n", + chan, scan_req->page, jiffies_to_msecs(scan_duration)); + ieee802154_queue_delayed_work(&local->hw, &local->scan_work, + scan_duration); + +unlock_mutex: + if (end_of_scan) + mac802154_end_of_scan(local); + + mutex_unlock(&local->scan_lock); +} + +int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata, + struct cfg802154_scan_request *request) +{ + struct ieee802154_local *local = sdata->local; + int ret; + + lockdep_assert_held(&local->scan_lock); + + if (local->scanning) + return -EBUSY; + + /* TODO: support other scanning type */ + if (request->type != NL802154_SCAN_PASSIVE) + return -EOPNOTSUPP; + + /* Store scanning parameters */ + rcu_assign_pointer(local->scan_req, request); + rcu_assign_pointer(local->scan_sdata, sdata); + + /* Configure scan_addr to use net_device addr or random */ + if (request->flags & NL802154_SCAN_FLAG_RANDOM_ADDR) + get_random_bytes(&local->scan_addr, sizeof(local->scan_addr)); + else + local->scan_addr = cpu_to_le64(get_unaligned_be64(sdata->dev->dev_addr)); + + local->scan_channel_idx = -1; + local->scanning = true; + + /* Software scanning requires to set promiscuous mode */ + ret = mac802154_set_promiscuous_mode(local, true); + if (ret) + return mac802154_end_of_scan(local); + + ieee802154_queue_delayed_work(&local->hw, &local->scan_work, 0); + + return 0; +} + +int mac802154_scan_rx(struct ieee802154_local *local, struct sk_buff *skb) +{ + struct ieee802154_beaconhdr *bh = (void *)skb->data; + struct ieee802154_addr *src = &mac_cb(skb)->source; + struct cfg802154_scan_request *scan_req; + struct ieee802154_pan_desc desc = {}; + int ret; + + /* Check the validity of the frame length */ + if (skb->len < sizeof(*bh)) + return -EINVAL; + + if (unlikely(src->mode == IEEE802154_ADDR_NONE)) + return -EINVAL; + + if (unlikely(!bh->pan_coordinator)) + return -ENODEV; + + scan_req = rcu_dereference(local->scan_req); + if (unlikely(!scan_req)) + return -EINVAL; + + if (unlikely(local->scan_channel_idx < 0)) { + pr_info("Dropping beacon received during channel change\n"); + return 0; + } + + pr_debug("Beacon received on channel %d of page %d\n", + local->scan_channel_idx, scan_req->page); + + /* Parse beacon and create PAN information */ + desc.coord = src; + desc.page = scan_req->page; + desc.channel = local->scan_channel_idx; + desc.link_quality = mac_cb(skb)->lqi; + desc.superframe_spec = get_unaligned_le16(skb->data); + desc.gts_permit = bh->gts_permit; + + /* Create or update the PAN entry in the management layer */ + ret = cfg802154_record_pan(local->phy, &desc); + if (ret) { + pr_err("Failed to save PAN descriptor\n"); + return ret; + } + + return 0; +} diff --git a/net/mac802154/util.c b/net/mac802154/util.c index f2078238718b..5ee65cb1dbcd 100644 --- a/net/mac802154/util.c +++ b/net/mac802154/util.c @@ -94,3 +94,29 @@ void ieee802154_stop_device(struct ieee802154_local *local) hrtimer_cancel(&local->ifs_timer); drv_stop(local); } + +/* Nothing should have been stuffed into the workqueue during + * the suspend->resume cycle. + */ +static bool ieee802154_can_queue_work(struct ieee802154_local *local) +{ + if (local->suspended) { + pr_warn("queueing ieee802154 work while suspended\n"); + return false; + } + + return true; +} + +void ieee802154_queue_delayed_work(struct ieee802154_hw *hw, + struct delayed_work *dwork, + unsigned long delay) +{ + struct ieee802154_local *local = hw_to_local(hw); + + if (!ieee802154_can_queue_work(local)) + return; + + queue_delayed_work(local->workqueue, dwork, delay); +} +EXPORT_SYMBOL(ieee802154_queue_delayed_work); From patchwork Wed Dec 22 15:57:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691794 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 DE2C2C433FE for ; Wed, 22 Dec 2021 15:58:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343854AbhLVP6W (ORCPT ); Wed, 22 Dec 2021 10:58:22 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:59117 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343902AbhLVP6G (ORCPT ); Wed, 22 Dec 2021 10:58:06 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 3C0786000C; Wed, 22 Dec 2021 15:58:04 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 13/18] net: mac802154: Inform device drivers about the scanning operation Date: Wed, 22 Dec 2021 16:57:38 +0100 Message-Id: <20211222155743.256280-14-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org Let's create a couple of driver hooks in order to tell the device drivers that a scan is ongoing, if they need to apply a particular configuration. These hooks are optional. Co-developed-by: David Girault Signed-off-by: David Girault Signed-off-by: Miquel Raynal --- include/net/mac802154.h | 13 +++++++++++++ net/mac802154/driver-ops.h | 33 +++++++++++++++++++++++++++++++++ net/mac802154/scan.c | 7 +++++++ net/mac802154/trace.h | 28 ++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+) diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 19bfbf591ea1..97aefba7bf96 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -204,6 +204,16 @@ enum ieee802154_hw_flags { * * set_promiscuous_mode * Enables or disable promiscuous mode. + * + * enter_scan_mode + * Enters the scan mode, may then refuse certain operations. + * Can be NULL, if the driver has no internal configuration to do. + * Returns either zero, or negative errno. + * + * exit_scan_mode + * Exits the scan mode and returns to a fully functioning state. + * Should only be provided if ->enter_scan_mode() is populated. + * Returns either zero, or negative errno. */ struct ieee802154_ops { struct module *owner; @@ -230,6 +240,9 @@ struct ieee802154_ops { s8 retries); int (*set_promiscuous_mode)(struct ieee802154_hw *hw, const bool on); + int (*enter_scan_mode)(struct ieee802154_hw *hw, + struct cfg802154_scan_request *request); + int (*exit_scan_mode)(struct ieee802154_hw *hw); }; /** diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h index d23f0db98015..2f5650f7bf91 100644 --- a/net/mac802154/driver-ops.h +++ b/net/mac802154/driver-ops.h @@ -282,4 +282,37 @@ drv_set_promiscuous_mode(struct ieee802154_local *local, bool on) return ret; } +static inline int drv_enter_scan_mode(struct ieee802154_local *local, + struct cfg802154_scan_request *request) +{ + int ret; + + might_sleep(); + + if (!local->ops->enter_scan_mode || !local->ops->exit_scan_mode) + return 0; + + trace_802154_drv_enter_scan_mode(local, request); + ret = local->ops->enter_scan_mode(&local->hw, request); + trace_802154_drv_return_int(local, ret); + + return ret; +} + +static inline int drv_exit_scan_mode(struct ieee802154_local *local) +{ + int ret; + + might_sleep(); + + if (!local->ops->exit_scan_mode) + return 0; + + trace_802154_drv_exit_scan_mode(local); + ret = local->ops->exit_scan_mode(&local->hw); + trace_802154_drv_return_int(local, ret); + + return ret; +} + #endif /* __MAC802154_DRIVER_OPS */ diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c index c5b85eaec319..1382489d4e58 100644 --- a/net/mac802154/scan.c +++ b/net/mac802154/scan.c @@ -87,6 +87,8 @@ int mac802154_abort_scan_locked(struct ieee802154_local *local) if (!local->scanning) return -ESRCH; + drv_exit_scan_mode(local); + cancel_delayed_work(&local->scan_work); return mac802154_end_of_scan(local); @@ -186,6 +188,11 @@ int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata, else local->scan_addr = cpu_to_le64(get_unaligned_be64(sdata->dev->dev_addr)); + /* Inform the hardware about the scanning operation starting */ + ret = drv_enter_scan_mode(local, request); + if (ret) + return ret; + local->scan_channel_idx = -1; local->scanning = true; diff --git a/net/mac802154/trace.h b/net/mac802154/trace.h index df855c33daf2..9c0a4f07ced1 100644 --- a/net/mac802154/trace.h +++ b/net/mac802154/trace.h @@ -264,6 +264,34 @@ TRACE_EVENT(802154_drv_set_promiscuous_mode, BOOL_TO_STR(__entry->on)) ); +TRACE_EVENT(802154_drv_enter_scan_mode, + TP_PROTO(struct ieee802154_local *local, + struct cfg802154_scan_request *request), + TP_ARGS(local, request), + TP_STRUCT__entry( + LOCAL_ENTRY + __field(u8, page) + __field(u32, channels) + __field(u8, duration) + __field(u64, addr) + ), + TP_fast_assign( + LOCAL_ASSIGN; + __entry->page = request->page; + __entry->channels = request->channels; + __entry->duration = request->duration; + __entry->addr = local->scan_addr; + ), + TP_printk(LOCAL_PR_FMT ", scan, page: %d, channels: %x, duration %d, addr: 0x%llx", + LOCAL_PR_ARG, __entry->page, __entry->channels, + __entry->duration, __entry->addr) +); + +DEFINE_EVENT(local_only_evt4, 802154_drv_exit_scan_mode, + TP_PROTO(struct ieee802154_local *local), + TP_ARGS(local) +); + #endif /* !__MAC802154_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ #undef TRACE_INCLUDE_PATH From patchwork Wed Dec 22 15:57:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691795 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 AAEDAC433EF for ; Wed, 22 Dec 2021 15:58:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343929AbhLVP6Y (ORCPT ); Wed, 22 Dec 2021 10:58:24 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:49907 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343918AbhLVP6I (ORCPT ); Wed, 22 Dec 2021 10:58:08 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 8E3DA60007; Wed, 22 Dec 2021 15:58:05 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 14/18] net: ieee802154: Full PAN management Date: Wed, 22 Dec 2021 16:57:39 +0100 Message-Id: <20211222155743.256280-15-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org Now that scanning is supported and PANs properly registered, give certain rights to the user, such as listing asynchronously the listed PANs as well as flushing the list. By default, the list gets automatically updated every time users request the list of pans. Too old PANs are automatically dropped from the list. The expiration time is configurable with a module parameter. Co-developed-by: David Girault Signed-off-by: David Girault Signed-off-by: Miquel Raynal --- include/net/nl802154.h | 43 ++++++++++++ net/ieee802154/nl802154.c | 143 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+) diff --git a/include/net/nl802154.h b/include/net/nl802154.h index 51eca3a2b14e..e185e92d29d6 100644 --- a/include/net/nl802154.h +++ b/include/net/nl802154.h @@ -61,6 +61,8 @@ enum nl802154_commands { NL802154_CMD_TRIGGER_SCAN, NL802154_CMD_ABORT_SCAN, NL802154_CMD_SCAN_DONE, + NL802154_CMD_DUMP_PANS, + NL802154_CMD_FLUSH_PANS, /* add new commands above here */ @@ -141,6 +143,7 @@ enum nl802154_attrs { NL802154_ATTR_SCAN_FLAGS, NL802154_ATTR_SCAN_CHANNELS, NL802154_ATTR_SCAN_DURATION, + NL802154_ATTR_PAN, /* add attributes here, update the policy in nl802154.c */ @@ -267,6 +270,46 @@ enum nl802154_scan_flags { NL802154_SCAN_FLAG_RANDOM_ADDR = BIT(0), }; +/** + * enum nl802154_pan - Netlink attributes for a PAN + * + * @__NL802154_PAN_INVALID: invalid + * @NL802154_PAN_PANID: PANID of the PAN (2 bytes) + * @NL802154_PAN_COORD_ADDR: Coordinator address, (8 bytes or 2 bytes) + * @NL802154_PAN_CHANNEL: channel number, related to @NL802154_PAN_PAGE (u8) + * @NL802154_PAN_PAGE: channel page, related to @NL802154_PAN_CHANNEL (u8) + * @NL802154_PAN_PREAMBLE_CODE: Preamble code while the beacon was received, + * this is PHY dependent and optional (4 bytes) + * @NL802154_PAN_SUPERFRAME_SPEC: superframe specification of the PAN (u16) + * @NL802154_PAN_LINK_QUALITY: signal quality of beacon in unspecified units, + * scaled to 0..255 (u8) + * @NL802154_PAN_GTS_PERMIT: set to true if GTS is permitted on this PAN + * @NL802154_PAN_PAYLOAD_DATA: binary data containing the raw data from the + * frame payload, (only if beacon or probe response had data) + * @NL802154_PAN_STATUS: status, if this PAN is "used" + * @NL802154_PAN_SEEN_MS_AGO: age of this PAN entry in ms + * @NL802154_PAN_PAD: attribute used for padding for 64-bit alignment + * @NL802154_PAN_MAX: highest PAN attribute + */ +enum nl802154_pan { + __NL802154_PAN_INVALID, + NL802154_PAN_PANID, + NL802154_PAN_COORD_ADDR, + NL802154_PAN_CHANNEL, + NL802154_PAN_PAGE, + NL802154_PAN_PREAMBLE_CODE, + NL802154_PAN_SUPERFRAME_SPEC, + NL802154_PAN_LINK_QUALITY, + NL802154_PAN_GTS_PERMIT, + NL802154_PAN_PAYLOAD_DATA, + NL802154_PAN_STATUS, + NL802154_PAN_SEEN_MS_AGO, + NL802154_PAN_PAD, + + /* keep last */ + NL802154_PAN_MAX, +}; + /** * enum nl802154_cca_modes - cca modes * diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index d59de9812721..8de8f7c31bfe 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -223,6 +223,7 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = { [NL802154_ATTR_SCAN_FLAGS] = { .type = NLA_U32, }, [NL802154_ATTR_SCAN_CHANNELS] = { .type = NLA_U32, }, [NL802154_ATTR_SCAN_DURATION] = { .type = NLA_U8, }, + [NL802154_ATTR_PAN] = { .type = NLA_NESTED }, #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL [NL802154_ATTR_SEC_ENABLED] = { .type = NLA_U8, }, @@ -1499,6 +1500,136 @@ static int nl802154_abort_scan(struct sk_buff *skb, struct genl_info *info) return rdev_abort_scan(rdev, wpan_dev); } +static int nl802154_send_pan_info(struct sk_buff *msg, + struct netlink_callback *cb, + u32 seq, int flags, + struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev, + struct cfg802154_internal_pan *intpan) +{ + struct ieee802154_pan_desc *pan = &intpan->desc; + struct nlattr *nla; + void *hdr; + + ASSERT_RTNL(); + + hdr = nl802154hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags, + NL802154_CMD_SCAN_DONE); + if (!hdr) + return -ENOBUFS; + + genl_dump_check_consistent(cb, hdr); + + if (nla_put_u32(msg, NL802154_ATTR_GENERATION, rdev->pan_generation)) + goto nla_put_failure; + + if (wpan_dev->netdev && + nla_put_u32(msg, NL802154_ATTR_IFINDEX, wpan_dev->netdev->ifindex)) + goto nla_put_failure; + + if (nla_put_u64_64bit(msg, NL802154_ATTR_WPAN_DEV, wpan_dev_id(wpan_dev), + NL802154_ATTR_PAD)) + goto nla_put_failure; + + nla = nla_nest_start_noflag(msg, NL802154_ATTR_PAN); + if (!nla) + goto nla_put_failure; + + if (nla_put(msg, NL802154_PAN_PANID, IEEE802154_PAN_ID_LEN, + &pan->coord->pan_id)) + goto nla_put_failure; + + if (pan->coord->mode == IEEE802154_ADDR_SHORT) { + if (nla_put(msg, NL802154_PAN_COORD_ADDR, + IEEE802154_SHORT_ADDR_LEN, + &pan->coord->short_addr)) + goto nla_put_failure; + } else { + if (nla_put(msg, NL802154_PAN_COORD_ADDR, + IEEE802154_EXTENDED_ADDR_LEN, + &pan->coord->extended_addr)) + goto nla_put_failure; + } + + if (nla_put_u8(msg, NL802154_PAN_CHANNEL, pan->channel)) + goto nla_put_failure; + + if (nla_put_u8(msg, NL802154_PAN_PAGE, pan->page)) + goto nla_put_failure; + + if (nla_put_u16(msg, NL802154_PAN_SUPERFRAME_SPEC, + pan->superframe_spec)) + goto nla_put_failure; + + if (nla_put_u8(msg, NL802154_PAN_LINK_QUALITY, pan->link_quality)) + goto nla_put_failure; + + if (nla_put_u32(msg, NL802154_PAN_SEEN_MS_AGO, + jiffies_to_msecs(jiffies - intpan->discovery_ts))) + goto nla_put_failure; + + if (pan->gts_permit && nla_put_flag(msg, NL802154_PAN_GTS_PERMIT)) + goto nla_put_failure; + + /* TODO: NL802154_PAN_PAYLOAD_DATA if any */ + + nla_nest_end(msg, nla); + genlmsg_end(msg, hdr); + + return 0; + + nla_put_failure: + genlmsg_cancel(msg, hdr); + return -EMSGSIZE; +} + +static int nl802154_dump_pans(struct sk_buff *skb, struct netlink_callback *cb) +{ + struct cfg802154_registered_device *rdev; + struct cfg802154_internal_pan *pan; + struct wpan_dev *wpan_dev; + int err; + + err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev); + if (err) + return err; + + spin_lock_bh(&rdev->pan_lock); + + if (cb->args[2]) + goto out; + + cb->seq = rdev->pan_generation; + + ieee802154_for_each_pan(pan, rdev) { + err = nl802154_send_pan_info(skb, cb, cb->nlh->nlmsg_seq, + NLM_F_MULTI, rdev, wpan_dev, pan); + if (err < 0) + goto out_err; + } + + cb->args[2] = 1; +out: + err = skb->len; +out_err: + spin_unlock_bh(&rdev->pan_lock); + + nl802154_finish_wpan_dev_dump(rdev); + + return err; +} + +static int nl802154_flush_pans(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + + spin_lock_bh(&rdev->pan_lock); + cfg802154_flush_pans(rdev); + spin_unlock_bh(&rdev->pan_lock); + + return 0; +} + #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL static const struct nla_policy nl802154_dev_addr_policy[NL802154_DEV_ADDR_ATTR_MAX + 1] = { [NL802154_DEV_ADDR_ATTR_PAN_ID] = { .type = NLA_U16 }, @@ -2603,6 +2734,18 @@ static const struct genl_ops nl802154_ops[] = { NL802154_FLAG_CHECK_NETDEV_UP | NL802154_FLAG_NEED_RTNL, }, + { + .cmd = NL802154_CMD_DUMP_PANS, + .dumpit = nl802154_dump_pans, + /* can be retrieved by unprivileged users */ + }, + { + .cmd = NL802154_CMD_FLUSH_PANS, + .doit = nl802154_flush_pans, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_NETDEV | + NL802154_FLAG_NEED_RTNL, + }, #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL { .cmd = NL802154_CMD_SET_SEC_PARAMS, From patchwork Wed Dec 22 15:57:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691797 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 58F32C433F5 for ; Wed, 22 Dec 2021 15:58:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344078AbhLVP62 (ORCPT ); Wed, 22 Dec 2021 10:58:28 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:36505 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343943AbhLVP6J (ORCPT ); Wed, 22 Dec 2021 10:58:09 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 0612860013; Wed, 22 Dec 2021 15:58:06 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 15/18] net: ieee802154: Add support for beacon requests Date: Wed, 22 Dec 2021 16:57:40 +0100 Message-Id: <20211222155743.256280-16-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org This involves processing beacons requests: starting or stopping the flow of beacons sent passively on a specific interface. The page and channel must be changed beforehands if needed. Interval orders above 14 are reserved to tell a device it must answer BEACON_REQ coming from an active scan procedure (this is not supported yet). A beacons request structure is created to list the requirements. Mac layers may now implement the ->send_beacons() and ->stop_beacons() hooks. Co-developed-by: David Girault Signed-off-by: David Girault Signed-off-by: Miquel Raynal --- include/net/cfg802154.h | 22 +++++++++++ include/net/nl802154.h | 3 ++ net/ieee802154/nl802154.c | 81 +++++++++++++++++++++++++++++++++++++++ net/ieee802154/rdev-ops.h | 24 ++++++++++++ net/ieee802154/trace.h | 21 ++++++++++ 5 files changed, 151 insertions(+) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 292eaf280f01..e4132bd2b636 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -88,6 +88,24 @@ struct cfg802154_scan_request { struct wpan_phy *wpan_phy; }; +/** + * struct cfg802154_beacons_request - beacons request descriptor + * + * @interval: interval n between sendings, in multiple order of the super frame + * duration: aBaseSuperframeDuration * (2^n) unless the interval + * order is greater or equal to 15, in this case beacons won't be + * passively sent out at a fixed rate but instead inform the device + * that it should answer beacon requests as part of active scan + * procedures + * @wpan_dev: the concerned wpan device + * @wpan_phy: the wpan phy this was for + */ +struct cfg802154_beacons_request { + u8 interval; + struct wpan_dev *wpan_dev; + struct wpan_phy *wpan_phy; +}; + struct cfg802154_ops { struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, const char *name, @@ -130,6 +148,10 @@ struct cfg802154_ops { struct cfg802154_scan_request *request); int (*abort_scan)(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev); + int (*send_beacons)(struct wpan_phy *wpan_phy, + struct cfg802154_beacons_request *request); + int (*stop_beacons)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev); #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL void (*get_llsec_table)(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, diff --git a/include/net/nl802154.h b/include/net/nl802154.h index e185e92d29d6..a20d19b6d0d4 100644 --- a/include/net/nl802154.h +++ b/include/net/nl802154.h @@ -63,6 +63,8 @@ enum nl802154_commands { NL802154_CMD_SCAN_DONE, NL802154_CMD_DUMP_PANS, NL802154_CMD_FLUSH_PANS, + NL802154_CMD_SEND_BEACONS, + NL802154_CMD_STOP_BEACONS, /* add new commands above here */ @@ -144,6 +146,7 @@ enum nl802154_attrs { NL802154_ATTR_SCAN_CHANNELS, NL802154_ATTR_SCAN_DURATION, NL802154_ATTR_PAN, + NL802154_ATTR_BEACON_INTERVAL, /* add attributes here, update the policy in nl802154.c */ diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 8de8f7c31bfe..11112b515a82 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -224,6 +224,7 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = { [NL802154_ATTR_SCAN_CHANNELS] = { .type = NLA_U32, }, [NL802154_ATTR_SCAN_DURATION] = { .type = NLA_U8, }, [NL802154_ATTR_PAN] = { .type = NLA_NESTED }, + [NL802154_ATTR_BEACON_INTERVAL] = { .type = NLA_U8, }, #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL [NL802154_ATTR_SEC_ENABLED] = { .type = NLA_U8, }, @@ -1630,6 +1631,70 @@ static int nl802154_flush_pans(struct sk_buff *skb, struct genl_info *info) return 0; } +static int +nl802154_send_beacons(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wpan_dev *wpan_dev = dev->ieee802154_ptr; + struct wpan_phy *wpan_phy = &rdev->wpan_phy; + struct cfg802154_beacons_request *request; + int err; + + /* Avoid sending beacons on monitor interfaces */ + if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) + return -EOPNOTSUPP; + + request = kzalloc(sizeof(*request), GFP_KERNEL); + if (!request) + return -ENOMEM; + + request->wpan_dev = wpan_dev; + request->wpan_phy = wpan_phy; + + if (info->attrs[NL802154_ATTR_BEACON_INTERVAL]) { + request->interval = nla_get_u8(info->attrs[NL802154_ATTR_BEACON_INTERVAL]); + if (request->interval > IEEE802154_MAX_SCAN_DURATION) { + pr_err("Answering active scan requests is not supported yet\n"); + err = -EINVAL; + goto free_request; + } + } else { + /* Use maximum duration order by default */ + request->interval = IEEE802154_MAX_SCAN_DURATION; + } + + err = rdev_send_beacons(rdev, request); + if (err) { + pr_err("Failure starting sending beacons (%d)\n", err); + goto free_request; + } + + if (wpan_dev->netdev) + dev_hold(wpan_dev->netdev); + +free_request: + kfree(request); + + return err; +} + +static int +nl802154_stop_beacons(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wpan_dev *wpan_dev = dev->ieee802154_ptr; + int err; + + err = rdev_stop_beacons(rdev, wpan_dev); + + if (err != -ESRCH && wpan_dev->netdev) + dev_put(wpan_dev->netdev); + + return err; +} + #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL static const struct nla_policy nl802154_dev_addr_policy[NL802154_DEV_ADDR_ATTR_MAX + 1] = { [NL802154_DEV_ADDR_ATTR_PAN_ID] = { .type = NLA_U16 }, @@ -2746,6 +2811,22 @@ static const struct genl_ops nl802154_ops[] = { .internal_flags = NL802154_FLAG_NEED_NETDEV | NL802154_FLAG_NEED_RTNL, }, + { + .cmd = NL802154_CMD_SEND_BEACONS, + .doit = nl802154_send_beacons, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_NETDEV | + NL802154_FLAG_CHECK_NETDEV_UP | + NL802154_FLAG_NEED_RTNL, + }, + { + .cmd = NL802154_CMD_STOP_BEACONS, + .doit = nl802154_stop_beacons, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_NETDEV | + NL802154_FLAG_CHECK_NETDEV_UP | + NL802154_FLAG_NEED_RTNL, + }, #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL { .cmd = NL802154_CMD_SET_SEC_PARAMS, diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index e171d74c3251..fa85efeaa150 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -237,6 +237,30 @@ static inline int rdev_abort_scan(struct cfg802154_registered_device *rdev, return ret; } +static inline int rdev_send_beacons(struct cfg802154_registered_device *rdev, + struct cfg802154_beacons_request *request) +{ + int ret; + + /* TODO: check if this is an FFD? */ + + trace_802154_rdev_send_beacons(&rdev->wpan_phy, request); + ret = rdev->ops->send_beacons(&rdev->wpan_phy, request); + trace_802154_rdev_return_int(&rdev->wpan_phy, ret); + return ret; +} + +static inline int rdev_stop_beacons(struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev) +{ + int ret; + + trace_802154_rdev_stop_beacons(&rdev->wpan_phy, wpan_dev); + ret = rdev->ops->stop_beacons(&rdev->wpan_phy, wpan_dev); + trace_802154_rdev_return_int(&rdev->wpan_phy, ret); + return ret; +} + #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL /* TODO this is already a nl802154, so move into ieee802154 */ static inline void diff --git a/net/ieee802154/trace.h b/net/ieee802154/trace.h index e5405f737ded..353ba799244f 100644 --- a/net/ieee802154/trace.h +++ b/net/ieee802154/trace.h @@ -315,6 +315,22 @@ TRACE_EVENT(802154_rdev_trigger_scan, WPAN_PHY_PR_ARG, __entry->page, __entry->channels, __entry->duration) ); +TRACE_EVENT(802154_rdev_send_beacons, + TP_PROTO(struct wpan_phy *wpan_phy, + struct cfg802154_beacons_request *request), + TP_ARGS(wpan_phy, request), + TP_STRUCT__entry( + WPAN_PHY_ENTRY + __field(u8, interval) + ), + TP_fast_assign( + WPAN_PHY_ASSIGN; + __entry->interval = request->interval; + ), + TP_printk(WPAN_PHY_PR_FMT ", sending beacons (interval order: %d)", + WPAN_PHY_PR_ARG, __entry->interval) +); + DECLARE_EVENT_CLASS(802154_wdev_template, TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev), TP_ARGS(wpan_phy, wpan_dev), @@ -335,6 +351,11 @@ DEFINE_EVENT(802154_wdev_template, 802154_rdev_abort_scan, TP_ARGS(wpan_phy, wpan_dev) ); +DEFINE_EVENT(802154_wdev_template, 802154_rdev_stop_beacons, + TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev), + TP_ARGS(wpan_phy, wpan_dev) +); + TRACE_EVENT(802154_rdev_return_int, TP_PROTO(struct wpan_phy *wpan_phy, int ret), TP_ARGS(wpan_phy, ret), From patchwork Wed Dec 22 15:57:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691800 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 2C88FC433EF for ; Wed, 22 Dec 2021 15:58:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343878AbhLVP6k (ORCPT ); Wed, 22 Dec 2021 10:58:40 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:53269 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343952AbhLVP6L (ORCPT ); Wed, 22 Dec 2021 10:58:11 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 6064260014; Wed, 22 Dec 2021 15:58:08 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 16/18] net: mac802154: Handle beacons requests Date: Wed, 22 Dec 2021 16:57:41 +0100 Message-Id: <20211222155743.256280-17-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org Implement the core hooks in order to provide the softMAC layer support for sending beacons. Besides being able to test the full passive scanning procedure, this will also be used when defining PAN coordinator status, in order to give a device the right to answer received BEACON_REQ. Changing the channels is prohibited while a beacon operation is ongoing. The implementation uses a workqueue triggered at a certain interval depending on the symbol duration for the current channel and the interval order provided. Sending beacons in response to an active scan request is not yet supported. Co-developed-by: David Girault Signed-off-by: David Girault Signed-off-by: Miquel Raynal --- include/net/ieee802154_netdev.h | 24 ++++++++ net/ieee802154/header_ops.c | 29 +++++++++ net/mac802154/cfg.c | 41 ++++++++++++- net/mac802154/ieee802154_i.h | 13 ++++ net/mac802154/main.c | 2 + net/mac802154/scan.c | 102 ++++++++++++++++++++++++++++++++ 6 files changed, 209 insertions(+), 2 deletions(-) diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index 04738ae3b25e..042f0196cced 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -116,6 +116,21 @@ enum ieee802154_frame_type { IEEE802154_EXTENDED_FRAME, }; +enum ieee802154_frame_version { + IEEE802154_2003_STD, + IEEE802154_2006_STD, + IEEE802154_STD, + IEEE802154_RESERVED_STD, + IEEE802154_MULTIPURPOSE_STD = IEEE802154_2003_STD, +}; + +enum ieee802154_addressing_mode { + IEEE802154_NO_ADDRESSING, + IEEE802154_RESERVED, + IEEE802154_SHORT_ADDRESSING, + IEEE802154_EXTENDED_ADDRESSING, +}; + struct ieee802154_hdr { struct ieee802154_hdr_fc fc; u8 seq; @@ -124,6 +139,11 @@ struct ieee802154_hdr { struct ieee802154_sechdr sec; }; +struct ieee802154_beacon_frame { + struct ieee802154_hdr mhr; + struct ieee802154_beaconhdr mac_pl; +}; + /* pushes hdr onto the skb. fields of hdr->fc that can be calculated from * the contents of hdr will be, and the actual value of those bits in * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame @@ -149,6 +169,10 @@ int ieee802154_hdr_peek_addrs(const struct sk_buff *skb, */ int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr); +/* pushes a beacon frame into an skb */ +int ieee802154_beacon_push(struct sk_buff *skb, + struct ieee802154_beacon_frame *beacon); + int ieee802154_max_payload(const struct ieee802154_hdr *hdr); static inline int diff --git a/net/ieee802154/header_ops.c b/net/ieee802154/header_ops.c index af337cf62764..5b8d67169312 100644 --- a/net/ieee802154/header_ops.c +++ b/net/ieee802154/header_ops.c @@ -6,6 +6,7 @@ * Phoebe Buckheister */ +#include #include #include @@ -120,6 +121,34 @@ ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr) } EXPORT_SYMBOL_GPL(ieee802154_hdr_push); +int ieee802154_beacon_push(struct sk_buff *skb, + struct ieee802154_beacon_frame *beacon) +{ + struct ieee802154_beaconhdr *mac_pl = &beacon->mac_pl; + struct ieee802154_hdr *mhr = &beacon->mhr; + u16 crc; + int ret; + + skb_reserve(skb, sizeof(*mhr)); + ret = ieee802154_hdr_push(skb, mhr); + if (ret < 0) + return ret; + + skb_reset_mac_header(skb); + skb->mac_len = ret; + + skb_put_data(skb, mac_pl, sizeof(*mac_pl)); + + if (mac_pl->pend_short_addr_count || mac_pl->pend_ext_addr_count) + return -EOPNOTSUPP; + + crc = crc_ccitt(0, skb->data, skb->len); + put_unaligned_le16(crc, skb_put(skb, 2)); + + return 0; +} +EXPORT_SYMBOL_GPL(ieee802154_beacon_push); + static int ieee802154_hdr_get_addr(const u8 *buf, int mode, bool omit_pan, struct ieee802154_addr *addr) diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 5c19d6f8e3eb..87be6969ca65 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -114,8 +114,10 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) wpan_phy->current_channel == channel) return 0; - /* Refuse to change channels during a scanning operation */ - if (local->scanning) + /* Refuse to change channels during a scanning operation or when a + * beacons request is ongoing. + */ + if (local->scanning || local->ongoing_beacons_request) return -EBUSY; ret = drv_set_channel(local, page, channel); @@ -297,6 +299,39 @@ static int mac802154_abort_scan(struct wpan_phy *wpan_phy, return ret; } +static int mac802154_send_beacons(struct wpan_phy *wpan_phy, + struct cfg802154_beacons_request *request) +{ + struct ieee802154_local *local = wpan_phy_priv(wpan_phy); + struct ieee802154_sub_if_data *sdata; + int ret; + + sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(request->wpan_dev); + + ASSERT_RTNL(); + + mutex_lock(&local->beacons_lock); + ret = mac802154_send_beacons_locked(sdata, request); + mutex_unlock(&local->beacons_lock); + + return ret; +} + +static int mac802154_stop_beacons(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev) +{ + struct ieee802154_local *local = wpan_phy_priv(wpan_phy); + int ret; + + ASSERT_RTNL(); + + mutex_lock(&local->beacons_lock); + ret = mac802154_stop_beacons_locked(local); + mutex_unlock(&local->beacons_lock); + + return ret; +} + #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL static void ieee802154_get_llsec_table(struct wpan_phy *wpan_phy, @@ -506,6 +541,8 @@ const struct cfg802154_ops mac802154_config_ops = { .set_ackreq_default = ieee802154_set_ackreq_default, .trigger_scan = mac802154_trigger_scan, .abort_scan = mac802154_abort_scan, + .send_beacons = mac802154_send_beacons, + .stop_beacons = mac802154_stop_beacons, #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL .get_llsec_table = ieee802154_get_llsec_table, .lock_llsec_table = ieee802154_lock_llsec_table, diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 4945edf5c2ce..9d7bd0694ec7 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -57,6 +57,14 @@ struct ieee802154_local { struct ieee802154_sub_if_data __rcu *scan_sdata; struct delayed_work scan_work; + /* Beacons handling */ + bool ongoing_beacons_request; + struct mutex beacons_lock; + unsigned int beacons_interval; + struct delayed_work beacons_work; + struct ieee802154_sub_if_data __rcu *beacons_sdata; + struct ieee802154_beacon_frame beacon; + bool started; bool suspended; @@ -181,6 +189,11 @@ int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata, struct cfg802154_scan_request *request); int mac802154_abort_scan_locked(struct ieee802154_local *local); int mac802154_scan_rx(struct ieee802154_local *local, struct sk_buff *skb); +void mac802154_beacons_work(struct work_struct *work); +int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata, + struct cfg802154_beacons_request *request); +int mac802154_stop_beacons_locked(struct ieee802154_local *local); + /* interface handling */ int ieee802154_iface_init(void); void ieee802154_iface_exit(void); diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 568991734610..f831a1c8d885 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -91,6 +91,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops) INIT_LIST_HEAD(&local->interfaces); mutex_init(&local->iflist_mtx); mutex_init(&local->scan_lock); + mutex_init(&local->beacons_lock); tasklet_setup(&local->tasklet, ieee802154_tasklet_handler); @@ -98,6 +99,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops) INIT_WORK(&local->tx_work, ieee802154_xmit_worker); INIT_DELAYED_WORK(&local->scan_work, mac802154_scan_work); + INIT_DELAYED_WORK(&local->beacons_work, mac802154_beacons_work); /* init supported flags with 802.15.4 default ranges */ phy->supported.max_minbe = 8; diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c index 1382489d4e58..b334fa856c00 100644 --- a/net/mac802154/scan.c +++ b/net/mac802154/scan.c @@ -104,6 +104,64 @@ static unsigned int mac802154_scan_get_channel_time(u8 duration_order, (BIT(duration_order) + 1)); } +int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata, + struct cfg802154_beacons_request *request) +{ + struct ieee802154_local *local = sdata->local; + unsigned int interval; + + lockdep_assert_held(&local->beacons_lock); + + if (local->ongoing_beacons_request) + return -EBUSY; + + local->ongoing_beacons_request = true; + + interval = mac802154_scan_get_channel_time(request->interval, + request->wpan_phy->symbol_duration); + + memset(&local->beacon, 0, sizeof(local->beacon)); + local->beacon.mhr.fc.type = IEEE802154_BEACON_FRAME; + local->beacon.mhr.fc.security_enabled = 0; + local->beacon.mhr.fc.frame_pending = 0; + local->beacon.mhr.fc.ack_request = 0; + local->beacon.mhr.fc.intra_pan = 0; + local->beacon.mhr.fc.dest_addr_mode = IEEE802154_NO_ADDRESSING; + local->beacon.mhr.fc.version = IEEE802154_2003_STD; + local->beacon.mhr.fc.source_addr_mode = IEEE802154_EXTENDED_ADDRESSING; + atomic_set(&request->wpan_dev->bsn, -1); + local->beacon.mhr.source.mode = IEEE802154_ADDR_LONG; + local->beacon.mhr.source.pan_id = request->wpan_dev->pan_id; + local->beacon.mhr.source.extended_addr = request->wpan_dev->extended_addr; + local->beacon.mac_pl.beacon_order = request->interval; + local->beacon.mac_pl.superframe_order = request->interval; + local->beacon.mac_pl.final_cap_slot = 0xf; + local->beacon.mac_pl.battery_life_ext = 0; + local->beacon.mac_pl.pan_coordinator = 1; + local->beacon.mac_pl.assoc_permit = 1; + + rcu_assign_pointer(local->beacons_sdata, sdata); + local->beacons_interval = interval; + + /* Start the beacon work */ + ieee802154_queue_delayed_work(&local->hw, &local->beacons_work, 0); + + return 0; +} + +int mac802154_stop_beacons_locked(struct ieee802154_local *local) +{ + lockdep_assert_held(&local->beacons_lock); + + if (!local->ongoing_beacons_request) + return -ESRCH; + + local->ongoing_beacons_request = false; + cancel_delayed_work(&local->beacons_work); + + return 0; +} + void mac802154_scan_work(struct work_struct *work) { struct ieee802154_local *local = @@ -206,6 +264,50 @@ int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata, return 0; } +void mac802154_beacons_work(struct work_struct *work) +{ + struct ieee802154_local *local = + container_of(work, struct ieee802154_local, beacons_work.work); + struct ieee802154_sub_if_data *sdata; + struct wpan_dev *wpan_dev; + struct sk_buff *skb; + int ret; + + mutex_lock(&local->beacons_lock); + + if (!local->ongoing_beacons_request) + goto unlock_mutex; + + if (local->suspended) + goto queue_work; + + sdata = rcu_dereference_protected(local->beacons_sdata, + lockdep_is_held(&local->beacons_lock)); + wpan_dev = &sdata->wpan_dev; + + /* Update the sequence number */ + local->beacon.mhr.seq = atomic_inc_return(&wpan_dev->bsn); + + skb = alloc_skb(17 + 2, GFP_KERNEL); + if (!skb) + goto queue_work; + + ret = ieee802154_beacon_push(skb, &local->beacon); + if (ret) + goto queue_work; + + ret = drv_xmit_async(local, skb); + if (ret) + pr_err("Error when transmitting beacon (%d)\n", ret); + +queue_work: + ieee802154_queue_delayed_work(&local->hw, &local->beacons_work, + local->beacons_interval); + +unlock_mutex: + mutex_unlock(&local->beacons_lock); +} + int mac802154_scan_rx(struct ieee802154_local *local, struct sk_buff *skb) { struct ieee802154_beaconhdr *bh = (void *)skb->data; From patchwork Wed Dec 22 15:57:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691798 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 BA93FC433F5 for ; Wed, 22 Dec 2021 15:58:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344115AbhLVP6c (ORCPT ); Wed, 22 Dec 2021 10:58:32 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:56615 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343967AbhLVP6M (ORCPT ); Wed, 22 Dec 2021 10:58:12 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id B9E3E60012; Wed, 22 Dec 2021 15:58:09 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 17/18] net: mac802154: Let drivers provide their own beacons implementation Date: Wed, 22 Dec 2021 16:57:42 +0100 Message-Id: <20211222155743.256280-18-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org So far only a pure software procedure for sending beacons was possible. Let's create a couple of driver's hooks in order to allow the device drivers to provide their own implementation. If not provided, fallback to the pure software logic. It is possible for device drivers to only support a specific type of request and return -EOPNOTSUPP otherwise, this will have the same effect as not providing any hooks for these specific cases. Co-developed-by: David Girault Signed-off-by: David Girault Signed-off-by: Miquel Raynal --- include/net/mac802154.h | 13 +++++++++++++ net/mac802154/driver-ops.h | 33 +++++++++++++++++++++++++++++++++ net/mac802154/scan.c | 17 +++++++++++++++++ net/mac802154/trace.h | 21 +++++++++++++++++++++ 4 files changed, 84 insertions(+) diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 97aefba7bf96..72978fb72a3a 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -214,6 +214,16 @@ enum ieee802154_hw_flags { * Exits the scan mode and returns to a fully functioning state. * Should only be provided if ->enter_scan_mode() is populated. * Returns either zero, or negative errno. + * + * send_beacons + * Send beacons at a fixed rate over the current channel. + * Can be NULL, if the driver doesn't support sending beacons by itself. + * Returns either zero, or negative errno. + * + * stop_beacons + * Stops sending beacons. + * Should only be provided if ->send_beacons() is populated. + * Returns either zero, or negative errno. */ struct ieee802154_ops { struct module *owner; @@ -243,6 +253,9 @@ struct ieee802154_ops { int (*enter_scan_mode)(struct ieee802154_hw *hw, struct cfg802154_scan_request *request); int (*exit_scan_mode)(struct ieee802154_hw *hw); + int (*send_beacons)(struct ieee802154_hw *hw, + struct cfg802154_beacons_request *request); + int (*stop_beacons)(struct ieee802154_hw *hw); }; /** diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h index 2f5650f7bf91..003e6edee049 100644 --- a/net/mac802154/driver-ops.h +++ b/net/mac802154/driver-ops.h @@ -315,4 +315,37 @@ static inline int drv_exit_scan_mode(struct ieee802154_local *local) return ret; } +static inline int drv_send_beacons(struct ieee802154_local *local, + struct cfg802154_beacons_request *request) +{ + int ret; + + might_sleep(); + + if (!local->ops->send_beacons || !local->ops->stop_beacons) + return -EOPNOTSUPP; + + trace_802154_drv_send_beacons(local, request); + ret = local->ops->send_beacons(&local->hw, request); + trace_802154_drv_return_int(local, ret); + + return ret; +} + +static inline int drv_stop_beacons(struct ieee802154_local *local) +{ + int ret; + + might_sleep(); + + if (!local->ops->send_beacons || !local->ops->stop_beacons) + return -EOPNOTSUPP; + + trace_802154_drv_stop_beacons(local); + ret = local->ops->stop_beacons(&local->hw); + trace_802154_drv_return_int(local, ret); + + return ret; +} + #endif /* __MAC802154_DRIVER_OPS */ diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c index b334fa856c00..55af9d16744a 100644 --- a/net/mac802154/scan.c +++ b/net/mac802154/scan.c @@ -109,6 +109,7 @@ int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata, { struct ieee802154_local *local = sdata->local; unsigned int interval; + int ret; lockdep_assert_held(&local->beacons_lock); @@ -117,6 +118,14 @@ int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata, local->ongoing_beacons_request = true; + /* Either let the hardware handle the beacons or handle them manually */ + ret = drv_send_beacons(local, request); + if (ret != -EOPNOTSUPP) { + if (ret) + local->ongoing_beacons_request = false; + return ret; + } + interval = mac802154_scan_get_channel_time(request->interval, request->wpan_phy->symbol_duration); @@ -151,6 +160,8 @@ int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata, int mac802154_stop_beacons_locked(struct ieee802154_local *local) { + int ret; + lockdep_assert_held(&local->beacons_lock); if (!local->ongoing_beacons_request) @@ -159,6 +170,12 @@ int mac802154_stop_beacons_locked(struct ieee802154_local *local) local->ongoing_beacons_request = false; cancel_delayed_work(&local->beacons_work); + ret = drv_stop_beacons(local); + if (ret != -EOPNOTSUPP) + return ret; + + cancel_delayed_work(&local->beacons_work); + return 0; } diff --git a/net/mac802154/trace.h b/net/mac802154/trace.h index 9c0a4f07ced1..b487523f83c3 100644 --- a/net/mac802154/trace.h +++ b/net/mac802154/trace.h @@ -292,6 +292,27 @@ DEFINE_EVENT(local_only_evt4, 802154_drv_exit_scan_mode, TP_ARGS(local) ); +TRACE_EVENT(802154_drv_send_beacons, + TP_PROTO(struct ieee802154_local *local, + struct cfg802154_beacons_request *request), + TP_ARGS(local, request), + TP_STRUCT__entry( + LOCAL_ENTRY + __field(u8, interval) + ), + TP_fast_assign( + LOCAL_ASSIGN; + __entry->interval = request->interval; + ), + TP_printk(LOCAL_PR_FMT ", send beacons at interval: %d", + LOCAL_PR_ARG, __entry->interval) +); + +DEFINE_EVENT(local_only_evt4, 802154_drv_stop_beacons, + TP_PROTO(struct ieee802154_local *local), + TP_ARGS(local) +); + #endif /* !__MAC802154_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ #undef TRACE_INCLUDE_PATH From patchwork Wed Dec 22 15:57:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12691799 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 88CDBC433FE for ; Wed, 22 Dec 2021 15:58:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344173AbhLVP6j (ORCPT ); Wed, 22 Dec 2021 10:58:39 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:32853 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343986AbhLVP6N (ORCPT ); Wed, 22 Dec 2021 10:58:13 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 22D2660010; Wed, 22 Dec 2021 15:58:11 +0000 (UTC) From: Miquel Raynal To: "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org, Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org Cc: David Girault , Romuald Despres , Frederic Blain , Thomas Petazzoni , , Miquel Raynal Subject: [net-next 18/18] net: ieee802154: Trace the registration of new PANs Date: Wed, 22 Dec 2021 16:57:43 +0100 Message-Id: <20211222155743.256280-19-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211222155743.256280-1-miquel.raynal@bootlin.com> References: <20211222155743.256280-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org From: David Girault Add an internal trace when new PANs get discovered. Signed-off-by: David Girault Signed-off-by: Miquel Raynal --- net/ieee802154/pan.c | 3 +++ net/ieee802154/trace.h | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/net/ieee802154/pan.c b/net/ieee802154/pan.c index c71a3664d5c3..451576d9ab41 100644 --- a/net/ieee802154/pan.c +++ b/net/ieee802154/pan.c @@ -18,6 +18,7 @@ #include "ieee802154.h" #include "core.h" +#include "trace.h" /* Maximum number of PAN entries to store */ static int max_pan_entries = 100; @@ -182,6 +183,8 @@ static void cfg802154_pan_update(struct cfg802154_registered_device *rdev, found = cfg802154_find_matching_pan(rdev, new); if (found) cfg802154_unlink_pan(rdev, found); + else + trace_802154_new_pan(&new->desc); if (unlikely(rdev->pan_entries >= max_pan_entries)) cfg802154_expire_oldest_pan(rdev); diff --git a/net/ieee802154/trace.h b/net/ieee802154/trace.h index 353ba799244f..506fe4930440 100644 --- a/net/ieee802154/trace.h +++ b/net/ieee802154/trace.h @@ -356,6 +356,31 @@ DEFINE_EVENT(802154_wdev_template, 802154_rdev_stop_beacons, TP_ARGS(wpan_phy, wpan_dev) ); +DECLARE_EVENT_CLASS(802154_pan_evt, + TP_PROTO(struct ieee802154_pan_desc *desc), + TP_ARGS(desc), + TP_STRUCT__entry( + __field(u16, pan_id) + __field(__le64, coord_addr) + __field(u8, channel) + __field(u8, page) + ), + TP_fast_assign( + __entry->page = desc->page; + __entry->channel = desc->channel; + memcpy(&__entry->pan_id, &desc->coord->pan_id, 2); + memcpy(&__entry->coord_addr, &desc->coord->extended_addr, 8); + ), + TP_printk("panid: %u, coord_addr: 0x%llx, page: %u, channel: %u", + __entry->pan_id, __le64_to_cpu(__entry->coord_addr), + __entry->page, __entry->channel) +); + +DEFINE_EVENT(802154_pan_evt, 802154_new_pan, + TP_PROTO(struct ieee802154_pan_desc *desc), + TP_ARGS(desc) +); + TRACE_EVENT(802154_rdev_return_int, TP_PROTO(struct wpan_phy *wpan_phy, int ret), TP_ARGS(wpan_phy, ret),