From patchwork Wed Jan 12 17:32:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711668 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 28377C433FE for ; Wed, 12 Jan 2022 17:33:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350013AbiALRdT (ORCPT ); Wed, 12 Jan 2022 12:33:19 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:34129 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239618AbiALRdT (ORCPT ); Wed, 12 Jan 2022 12:33:19 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id B8EDE20008; Wed, 12 Jan 2022 17:33:15 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 01/27] net: mac802154: Split the set channel hook implementation Date: Wed, 12 Jan 2022 18:32:46 +0100 Message-Id: <20220112173312.764660-2-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org As it is currently designed, the set_channel() cfg802154 hook implemented in the softMAC is doing a couple of checks before actually performing the channel change. However, as we enhance the support for automatically setting the symbol duration during channel changes, it will also be needed to ensure that the corresponding channel as properly be selected at probe time. In order to verify this, we will need to separate the channel change from the previous checks. These checks are actually here to speed up the process when the user request necessitates no change, so we can safely bypass them. Signed-off-by: Miquel Raynal --- net/mac802154/cfg.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index fbeebe3bc31d..870e442bbff0 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -103,17 +103,13 @@ ieee802154_del_iface(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev) } static int -ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) +ieee802154_change_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) { struct ieee802154_local *local = wpan_phy_priv(wpan_phy); int ret; ASSERT_RTNL(); - if (wpan_phy->current_page == page && - wpan_phy->current_channel == channel) - return 0; - ret = drv_set_channel(local, page, channel); if (!ret) { wpan_phy->current_page = page; @@ -123,6 +119,18 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) return ret; } +static int +ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) +{ + ASSERT_RTNL(); + + if (wpan_phy->current_page == page && + wpan_phy->current_channel == channel) + return 0; + + return ieee802154_change_channel(wpan_phy, page, channel); +} + static int ieee802154_set_cca_mode(struct wpan_phy *wpan_phy, const struct wpan_phy_cca *cca) From patchwork Wed Jan 12 17:32:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711669 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CAAA1C4332F for ; Wed, 12 Jan 2022 17:33:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355626AbiALRd3 (ORCPT ); Wed, 12 Jan 2022 12:33:29 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:48927 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355606AbiALRdX (ORCPT ); Wed, 12 Jan 2022 12:33:23 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 9E37320004; Wed, 12 Jan 2022 17:33:17 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 02/27] net: mac802154: Ensure proper channel selection at probe time Date: Wed, 12 Jan 2022 18:32:47 +0100 Message-Id: <20220112173312.764660-3-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Right now device drivers are encouraged to just set the ->current_page and ->current_channel to indicate about the current state of the hardware but this is far from ideal given the fact that we might want to configure a few things internally, such as the symbol duration. Call the ieee802154_change_channel() helper from the code section registering the hardware to ensure proper channel selection and configuration both on the device side and the core side. This change somehow "fixes" the hwsim driver which advertises using page 0 channel 13, but does not actually update its own internal pib structure to reflect that configuration. Signed-off-by: Miquel Raynal --- net/mac802154/cfg.c | 3 +-- net/mac802154/ieee802154_i.h | 1 + net/mac802154/main.c | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 870e442bbff0..6969f1330ccd 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -102,8 +102,7 @@ ieee802154_del_iface(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev) return 0; } -static int -ieee802154_change_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) +int ieee802154_change_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) { struct ieee802154_local *local = wpan_phy_priv(wpan_phy); int ret; diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 702560acc8ce..8a7f4c83c5b6 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -127,6 +127,7 @@ ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); netdev_tx_t ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); enum hrtimer_restart ieee802154_xmit_ifs_timer(struct hrtimer *timer); +int ieee802154_change_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel); /* MIB callbacks */ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan); diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 520cedc594e1..12ab1545e871 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -157,6 +157,14 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) ieee802154_setup_wpan_phy_pib(local->phy); + /* Ensure proper channel selection */ + rtnl_lock(); + rc = ieee802154_change_channel(local->phy, local->phy->current_page, + local->phy->current_channel); + rtnl_unlock(); + if (rc) + goto out_wq; + if (!(hw->flags & IEEE802154_HW_CSMA_PARAMS)) { local->phy->supported.min_csma_backoffs = 4; local->phy->supported.max_csma_backoffs = 4; From patchwork Wed Jan 12 17:32:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711672 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AA588C4167B for ; Wed, 12 Jan 2022 17:33:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355608AbiALRda (ORCPT ); Wed, 12 Jan 2022 12:33:30 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:39961 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355615AbiALRdZ (ORCPT ); Wed, 12 Jan 2022 12:33:25 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id CCE1B20014; Wed, 12 Jan 2022 17:33:19 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 03/27] net: ieee802154: Improve the way supported channels are declared Date: Wed, 12 Jan 2022 18:32:48 +0100 Message-Id: <20220112173312.764660-4-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org The idea here is to create a structure per set of channels so that we can define much more than basic bitfields for these. The structure is currently almost empty on purpose because this change is supposed to be a mechanical update without additional information but more details will be added in the following commits. For each page, the core now has access to how many "chunks" of channels are defined. Overall up to only 3 chunks have been defined so let's hardcode this value to simplify a lot the handling. Then, for each chunk, we define an independent bitfield of channels. As there are several users of these bitfields, we also create the cfg802154_get_supported_chans() helper to reconstruct the bitfield as it was before when the only information that matters is identifying the supported/unsupported channels. Signed-off-by: Miquel Raynal --- drivers/net/ieee802154/adf7242.c | 3 +- drivers/net/ieee802154/at86rf230.c | 12 ++++--- drivers/net/ieee802154/atusb.c | 12 ++++--- drivers/net/ieee802154/ca8210.c | 3 +- drivers/net/ieee802154/cc2520.c | 3 +- drivers/net/ieee802154/fakelb.c | 43 +++++++++++++++--------- drivers/net/ieee802154/mac802154_hwsim.c | 43 +++++++++++++++--------- drivers/net/ieee802154/mcr20a.c | 3 +- drivers/net/ieee802154/mrf24j40.c | 3 +- include/net/cfg802154.h | 13 +++++-- net/ieee802154/core.h | 2 ++ net/ieee802154/nl-phy.c | 8 +++-- net/ieee802154/nl802154.c | 30 +++++++++++++---- 13 files changed, 125 insertions(+), 53 deletions(-) diff --git a/drivers/net/ieee802154/adf7242.c b/drivers/net/ieee802154/adf7242.c index 7db9cbd0f5de..40c77a643b78 100644 --- a/drivers/net/ieee802154/adf7242.c +++ b/drivers/net/ieee802154/adf7242.c @@ -1211,7 +1211,8 @@ static int adf7242_probe(struct spi_device *spi) hw->extra_tx_headroom = 0; /* We support only 2.4 Ghz */ - hw->phy->supported.channels[0] = 0x7FFF800; + hw->phy->supported.page[0].nchunks = 1; + hw->phy->supported.page[0].chunk[0].channels = 0x7FFF800; hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_CSMA_PARAMS | diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 7d67f41387f5..cdf5d2a4f763 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1558,7 +1558,8 @@ at86rf230_detect_device(struct at86rf230_local *lp) case 3: chip = "at86rf231"; lp->data = &at86rf231_data; - lp->hw->phy->supported.channels[0] = 0x7FFF800; + lp->hw->phy->supported.page[0].nchunks = 1; + lp->hw->phy->supported.page[0].chunk[0].channels = 0x7FFF800; lp->hw->phy->current_channel = 11; lp->hw->phy->symbol_duration = 16; lp->hw->phy->supported.tx_powers = at86rf231_powers; @@ -1570,8 +1571,10 @@ at86rf230_detect_device(struct at86rf230_local *lp) chip = "at86rf212"; lp->data = &at86rf212_data; lp->hw->flags |= IEEE802154_HW_LBT; - lp->hw->phy->supported.channels[0] = 0x00007FF; - lp->hw->phy->supported.channels[2] = 0x00007FF; + lp->hw->phy->supported.page[0].nchunks = 1; + lp->hw->phy->supported.page[0].chunk[0].channels = 0x00007FF; + lp->hw->phy->supported.page[2].nchunks = 1; + lp->hw->phy->supported.page[2].chunk[0].channels = 0x00007FF; lp->hw->phy->current_channel = 5; lp->hw->phy->symbol_duration = 25; lp->hw->phy->supported.lbt = NL802154_SUPPORTED_BOOL_BOTH; @@ -1583,7 +1586,8 @@ at86rf230_detect_device(struct at86rf230_local *lp) case 11: chip = "at86rf233"; lp->data = &at86rf233_data; - lp->hw->phy->supported.channels[0] = 0x7FFF800; + lp->hw->phy->supported.page[0].nchunks = 1; + lp->hw->phy->supported.page[0].chunk[0].channels = 0x7FFF800; lp->hw->phy->current_channel = 13; lp->hw->phy->symbol_duration = 16; lp->hw->phy->supported.tx_powers = at86rf233_powers; diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c index 23ee0b14cbfa..38ebfacf2698 100644 --- a/drivers/net/ieee802154/atusb.c +++ b/drivers/net/ieee802154/atusb.c @@ -914,7 +914,8 @@ static int atusb_get_and_conf_chip(struct atusb *atusb) switch (part_num) { case 2: chip = "AT86RF230"; - atusb->hw->phy->supported.channels[0] = 0x7FFF800; + atusb->hw->phy->supported.page[0].nchunks = 1; + atusb->hw->phy->supported.page[0].chunk[0].channels = 0x7FFF800; atusb->hw->phy->current_channel = 11; /* reset default */ atusb->hw->phy->symbol_duration = 16; atusb->hw->phy->supported.tx_powers = atusb_powers; @@ -924,7 +925,8 @@ static int atusb_get_and_conf_chip(struct atusb *atusb) break; case 3: chip = "AT86RF231"; - atusb->hw->phy->supported.channels[0] = 0x7FFF800; + atusb->hw->phy->supported.page[0].nchunks = 1; + atusb->hw->phy->supported.page[0].chunk[0].channels = 0x7FFF800; atusb->hw->phy->current_channel = 11; /* reset default */ atusb->hw->phy->symbol_duration = 16; atusb->hw->phy->supported.tx_powers = atusb_powers; @@ -935,8 +937,10 @@ static int atusb_get_and_conf_chip(struct atusb *atusb) case 7: chip = "AT86RF212"; atusb->hw->flags |= IEEE802154_HW_LBT; - atusb->hw->phy->supported.channels[0] = 0x00007FF; - atusb->hw->phy->supported.channels[2] = 0x00007FF; + atusb->hw->phy->supported.page[0].nchunks = 1; + atusb->hw->phy->supported.page[0].chunk[0].channels = 0x00007FF; + atusb->hw->phy->supported.page[2].nchunks = 1; + atusb->hw->phy->supported.page[2].chunk[0].channels = 0x00007FF; atusb->hw->phy->current_channel = 5; atusb->hw->phy->symbol_duration = 25; atusb->hw->phy->supported.lbt = NL802154_SUPPORTED_BOOL_BOTH; diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c index ece6ff6049f6..1a667fceb8ba 100644 --- a/drivers/net/ieee802154/ca8210.c +++ b/drivers/net/ieee802154/ca8210.c @@ -2962,7 +2962,8 @@ static const s32 ca8210_ed_levels[CA8210_MAX_ED_LEVELS] = { static void ca8210_hw_setup(struct ieee802154_hw *ca8210_hw) { /* Support channels 11-26 */ - ca8210_hw->phy->supported.channels[0] = CA8210_VALID_CHANNELS; + ca8210_hw->phy->supported.page[0].nchunks = 1; + ca8210_hw->phy->supported.page[0].chunk[0].channels = CA8210_VALID_CHANNELS; ca8210_hw->phy->supported.tx_powers_size = CA8210_MAX_TX_POWERS; ca8210_hw->phy->supported.tx_powers = ca8210_tx_powers; ca8210_hw->phy->supported.cca_ed_levels_size = CA8210_MAX_ED_LEVELS; diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 89c046b204e0..587f050ef4e8 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -836,7 +836,8 @@ static int cc2520_register(struct cc2520_private *priv) ieee802154_random_extended_addr(&priv->hw->phy->perm_extended_addr); /* We do support only 2.4 Ghz */ - priv->hw->phy->supported.channels[0] = 0x7FFF800; + priv->hw->phy->supported.page[0].nchunks = 1; + priv->hw->phy->supported.page[0].chunk[0].channels = 0x7FFF800; priv->hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT | IEEE802154_HW_PROMISCUOUS; diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index 523d13ee02bf..bc44d1f7551c 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -137,36 +137,49 @@ static int fakelb_add_one(struct device *dev) phy = hw->priv; phy->hw = hw; + hw->phy->supported.page[0].nchunks = 3; /* 868 MHz BPSK 802.15.4-2003 */ - hw->phy->supported.channels[0] |= 1; + hw->phy->supported.page[0].chunk[0].channels |= 1; /* 915 MHz BPSK 802.15.4-2003 */ - hw->phy->supported.channels[0] |= 0x7fe; + hw->phy->supported.page[0].chunk[1].channels |= 0x7fe; /* 2.4 GHz O-QPSK 802.15.4-2003 */ - hw->phy->supported.channels[0] |= 0x7FFF800; + hw->phy->supported.page[0].chunk[2].channels |= 0x7FFF800; + + hw->phy->supported.page[1].nchunks = 2; /* 868 MHz ASK 802.15.4-2006 */ - hw->phy->supported.channels[1] |= 1; + hw->phy->supported.page[1].chunk[0].channels |= 1; /* 915 MHz ASK 802.15.4-2006 */ - hw->phy->supported.channels[1] |= 0x7fe; + hw->phy->supported.page[1].chunk[1].channels |= 0x7fe; + + hw->phy->supported.page[2].nchunks = 2; /* 868 MHz O-QPSK 802.15.4-2006 */ - hw->phy->supported.channels[2] |= 1; + hw->phy->supported.page[2].chunk[0].channels |= 1; /* 915 MHz O-QPSK 802.15.4-2006 */ - hw->phy->supported.channels[2] |= 0x7fe; + hw->phy->supported.page[2].chunk[1].channels |= 0x7fe; + + hw->phy->supported.page[3].nchunks = 1; /* 2.4 GHz CSS 802.15.4a-2007 */ - hw->phy->supported.channels[3] |= 0x3fff; + hw->phy->supported.page[3].chunk[0].channels |= 0x3fff; + + hw->phy->supported.page[4].nchunks = 3; /* UWB Sub-gigahertz 802.15.4a-2007 */ - hw->phy->supported.channels[4] |= 1; + hw->phy->supported.page[4].chunk[0].channels |= 1; /* UWB Low band 802.15.4a-2007 */ - hw->phy->supported.channels[4] |= 0x1e; + hw->phy->supported.page[4].chunk[1].channels |= 0x1e; /* UWB High band 802.15.4a-2007 */ - hw->phy->supported.channels[4] |= 0xffe0; + hw->phy->supported.page[4].chunk[2].channels |= 0xffe0; + + hw->phy->supported.page[5].nchunks = 2; /* 750 MHz O-QPSK 802.15.4c-2009 */ - hw->phy->supported.channels[5] |= 0xf; + hw->phy->supported.page[5].chunk[0].channels |= 0xf; /* 750 MHz MPSK 802.15.4c-2009 */ - hw->phy->supported.channels[5] |= 0xf0; + hw->phy->supported.page[5].chunk[1].channels |= 0xf0; + + hw->phy->supported.page[6].nchunks = 2; /* 950 MHz BPSK 802.15.4d-2009 */ - hw->phy->supported.channels[6] |= 0x3ff; + hw->phy->supported.page[6].chunk[0].channels |= 0x3ff; /* 950 MHz GFSK 802.15.4d-2009 */ - hw->phy->supported.channels[6] |= 0x3ffc00; + hw->phy->supported.page[6].chunk[1].channels |= 0x3ffc00; ieee802154_random_extended_addr(&hw->phy->perm_extended_addr); /* fake phy channel 13 as default */ diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c index 8caa61ec718f..3a491e755022 100644 --- a/drivers/net/ieee802154/mac802154_hwsim.c +++ b/drivers/net/ieee802154/mac802154_hwsim.c @@ -745,36 +745,49 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev, phy = hw->priv; phy->hw = hw; + hw->phy->supported.page[0].nchunks = 3; /* 868 MHz BPSK 802.15.4-2003 */ - hw->phy->supported.channels[0] |= 1; + hw->phy->supported.page[0].chunk[0].channels |= 1; /* 915 MHz BPSK 802.15.4-2003 */ - hw->phy->supported.channels[0] |= 0x7fe; + hw->phy->supported.page[0].chunk[1].channels |= 0x7fe; /* 2.4 GHz O-QPSK 802.15.4-2003 */ - hw->phy->supported.channels[0] |= 0x7FFF800; + hw->phy->supported.page[0].chunk[2].channels |= 0x7FFF800; + + hw->phy->supported.page[1].nchunks = 2; /* 868 MHz ASK 802.15.4-2006 */ - hw->phy->supported.channels[1] |= 1; + hw->phy->supported.page[1].chunk[0].channels |= 1; /* 915 MHz ASK 802.15.4-2006 */ - hw->phy->supported.channels[1] |= 0x7fe; + hw->phy->supported.page[1].chunk[1].channels |= 0x7fe; + + hw->phy->supported.page[2].nchunks = 2; /* 868 MHz O-QPSK 802.15.4-2006 */ - hw->phy->supported.channels[2] |= 1; + hw->phy->supported.page[2].chunk[0].channels |= 1; /* 915 MHz O-QPSK 802.15.4-2006 */ - hw->phy->supported.channels[2] |= 0x7fe; + hw->phy->supported.page[2].chunk[1].channels |= 0x7fe; + + hw->phy->supported.page[3].nchunks = 1; /* 2.4 GHz CSS 802.15.4a-2007 */ - hw->phy->supported.channels[3] |= 0x3fff; + hw->phy->supported.page[3].chunk[0].channels |= 0x3fff; + + hw->phy->supported.page[4].nchunks = 3; /* UWB Sub-gigahertz 802.15.4a-2007 */ - hw->phy->supported.channels[4] |= 1; + hw->phy->supported.page[4].chunk[0].channels |= 1; /* UWB Low band 802.15.4a-2007 */ - hw->phy->supported.channels[4] |= 0x1e; + hw->phy->supported.page[4].chunk[1].channels |= 0x1e; /* UWB High band 802.15.4a-2007 */ - hw->phy->supported.channels[4] |= 0xffe0; + hw->phy->supported.page[4].chunk[2].channels |= 0xffe0; + + hw->phy->supported.page[5].nchunks = 2; /* 750 MHz O-QPSK 802.15.4c-2009 */ - hw->phy->supported.channels[5] |= 0xf; + hw->phy->supported.page[5].chunk[0].channels |= 0xf; /* 750 MHz MPSK 802.15.4c-2009 */ - hw->phy->supported.channels[5] |= 0xf0; + hw->phy->supported.page[5].chunk[1].channels |= 0xf0; + + hw->phy->supported.page[6].nchunks = 2; /* 950 MHz BPSK 802.15.4d-2009 */ - hw->phy->supported.channels[6] |= 0x3ff; + hw->phy->supported.page[6].chunk[0].channels |= 0x3ff; /* 950 MHz GFSK 802.15.4d-2009 */ - hw->phy->supported.channels[6] |= 0x3ffc00; + hw->phy->supported.page[6].chunk[1].channels |= 0x3ffc00; ieee802154_random_extended_addr(&hw->phy->perm_extended_addr); diff --git a/drivers/net/ieee802154/mcr20a.c b/drivers/net/ieee802154/mcr20a.c index 8dc04e2590b1..5190c4d4f505 100644 --- a/drivers/net/ieee802154/mcr20a.c +++ b/drivers/net/ieee802154/mcr20a.c @@ -1002,7 +1002,8 @@ static void mcr20a_hw_setup(struct mcr20a_local *lp) phy->cca.mode = NL802154_CCA_ENERGY; - phy->supported.channels[0] = MCR20A_VALID_CHANNELS; + phy->supported.page[0].nchunks = 1; + phy->supported.page[0].chunk[0].channels = MCR20A_VALID_CHANNELS; phy->current_page = 0; /* MCR20A default reset value */ phy->current_channel = 20; diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index ff83e00b77af..5a38f3077771 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -1287,7 +1287,8 @@ static int mrf24j40_probe(struct spi_device *spi) spi_set_drvdata(spi, devrec); devrec->hw = hw; devrec->hw->parent = &spi->dev; - devrec->hw->phy->supported.channels[0] = CHANNEL_MASK; + devrec->hw->phy->supported.page[0].nchunks = 1; + devrec->hw->phy->supported.page[0].chunk[0].channels = CHANNEL_MASK; devrec->hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT | IEEE802154_HW_CSMA_PARAMS | IEEE802154_HW_PROMISCUOUS; diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 6ed07844eb24..ef49a23801c6 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -131,9 +131,18 @@ wpan_phy_supported_bool(bool b, enum nl802154_supported_bool_states st) return false; } +struct phy_channels { + u32 channels; +}; + +struct phy_page { + unsigned int nchunks; + struct phy_channels chunk[3]; +}; + struct wpan_phy_supported { - u32 channels[IEEE802154_MAX_PAGE + 1], - cca_modes, cca_opts, iftypes; + struct phy_page page[IEEE802154_MAX_PAGE + 1]; + u32 cca_modes, cca_opts, iftypes; enum nl802154_supported_bool_states lbt; u8 min_minbe, max_minbe, min_maxbe, max_maxbe, min_csma_backoffs, max_csma_backoffs; diff --git a/net/ieee802154/core.h b/net/ieee802154/core.h index 1c19f575d574..a0cf6feffc6a 100644 --- a/net/ieee802154/core.h +++ b/net/ieee802154/core.h @@ -47,4 +47,6 @@ 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); +u32 cfg802154_get_supported_chans(struct wpan_phy *phy, unsigned int page); + #endif /* __IEEE802154_CORE_H */ diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index dd5a45f8a78a..59e45e554834 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c @@ -31,6 +31,7 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid, void *hdr; int i, pages = 0; uint32_t *buf = kcalloc(32, sizeof(uint32_t), GFP_KERNEL); + u32 chans; pr_debug("%s\n", __func__); @@ -48,8 +49,11 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid, nla_put_u8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel)) goto nla_put_failure; for (i = 0; i < 32; i++) { - if (phy->supported.channels[i]) - buf[pages++] = phy->supported.channels[i] | (i << 27); + chans = cfg802154_get_supported_chans(phy, i); + if (!chans) + continue; + + buf[pages++] = chans | (i << 27); } if (pages && nla_put(msg, IEEE802154_ATTR_CHANNEL_PAGE_LIST, diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 277124f206e0..45e2c9b0505a 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -320,6 +320,21 @@ nl802154_put_flags(struct sk_buff *msg, int attr, u32 mask) return 0; } +u32 cfg802154_get_supported_chans(struct wpan_phy *phy, unsigned int page) +{ + struct phy_page *ppage; + unsigned int chunk; + u32 supported = 0; + + ppage = &phy->supported.page[page]; + + for (chunk = 0; chunk <= ppage->nchunks; chunk++) + supported |= ppage->chunk[chunk].channels; + + return supported; +} +EXPORT_SYMBOL(cfg802154_get_supported_chans); + static int nl802154_send_wpan_phy_channels(struct cfg802154_registered_device *rdev, struct sk_buff *msg) @@ -333,7 +348,7 @@ nl802154_send_wpan_phy_channels(struct cfg802154_registered_device *rdev, for (page = 0; page <= IEEE802154_MAX_PAGE; page++) { if (nla_put_u32(msg, NL802154_ATTR_SUPPORTED_CHANNEL, - rdev->wpan_phy.supported.channels[page])) + cfg802154_get_supported_chans(&rdev->wpan_phy, page))) return -ENOBUFS; } nla_nest_end(msg, nl_page); @@ -347,6 +362,7 @@ nl802154_put_capabilities(struct sk_buff *msg, { const struct wpan_phy_supported *caps = &rdev->wpan_phy.supported; struct nlattr *nl_caps, *nl_channels; + u32 chans; int i; nl_caps = nla_nest_start_noflag(msg, NL802154_ATTR_WPAN_PHY_CAPS); @@ -358,10 +374,12 @@ nl802154_put_capabilities(struct sk_buff *msg, return -ENOBUFS; for (i = 0; i <= IEEE802154_MAX_PAGE; i++) { - if (caps->channels[i]) { - if (nl802154_put_flags(msg, i, caps->channels[i])) - return -ENOBUFS; - } + chans = cfg802154_get_supported_chans(&rdev->wpan_phy, i); + if (!chans) + continue; + + if (nl802154_put_flags(msg, i, chans)) + return -ENOBUFS; } nla_nest_end(msg, nl_channels); @@ -965,7 +983,7 @@ static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) /* check 802.15.4 constraints */ if (page > IEEE802154_MAX_PAGE || channel > IEEE802154_MAX_CHANNEL || - !(rdev->wpan_phy.supported.channels[page] & BIT(channel))) + !(cfg802154_get_supported_chans(&rdev->wpan_phy, page) & BIT(channel))) return -EINVAL; return rdev_set_channel(rdev, page, channel); From patchwork Wed Jan 12 17:32:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711670 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6F147C433F5 for ; Wed, 12 Jan 2022 17:33:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355647AbiALRdb (ORCPT ); Wed, 12 Jan 2022 12:33:31 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:41119 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355612AbiALRdZ (ORCPT ); Wed, 12 Jan 2022 12:33:25 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id ED8D22000E; Wed, 12 Jan 2022 17:33:21 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 04/27] net: ieee802154: Give more details to the core about the channel configurations Date: Wed, 12 Jan 2022 18:32:49 +0100 Message-Id: <20220112173312.764660-5-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org In order to let the core derive eg. the symbol duration for a given channel, it needs to know which protocol is being used, on which band, and eventually more details such as the mean PRF in the case of UWB. Create the necessary enumerations to declare all of that. Include them in the currently-almost-empty phy_channels structure which until now only declared the supported channels as bitfields. The PRF is declared in a union as this clearly is a parameter that does not apply to most of the protocols. It is very likely that other parameters will get added in the future to further define specific protocols and the union will likely be a good location for them. Signed-off-by: Miquel Raynal --- drivers/net/ieee802154/ca8210.c | 3 ++ drivers/net/ieee802154/mac802154_hwsim.c | 33 +++++++++++++++++++ drivers/net/ieee802154/mcr20a.c | 3 ++ include/net/cfg802154.h | 41 ++++++++++++++++++++++++ 4 files changed, 80 insertions(+) diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c index 1a667fceb8ba..f42a0b719a33 100644 --- a/drivers/net/ieee802154/ca8210.c +++ b/drivers/net/ieee802154/ca8210.c @@ -2963,7 +2963,10 @@ static void ca8210_hw_setup(struct ieee802154_hw *ca8210_hw) { /* Support channels 11-26 */ ca8210_hw->phy->supported.page[0].nchunks = 1; + /* 2.4 GHz O-QPSK */ ca8210_hw->phy->supported.page[0].chunk[0].channels = CA8210_VALID_CHANNELS; + ca8210_hw->phy->supported.page[0].chunk[0].protocol = IEEE802154_OQPSK_PHY; + ca8210_hw->phy->supported.page[0].chunk[0].band = IEEE802154_2400_MHZ_BAND; ca8210_hw->phy->supported.tx_powers_size = CA8210_MAX_TX_POWERS; ca8210_hw->phy->supported.tx_powers = ca8210_tx_powers; ca8210_hw->phy->supported.cca_ed_levels_size = CA8210_MAX_ED_LEVELS; diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c index 3a491e755022..a2827c0acabe 100644 --- a/drivers/net/ieee802154/mac802154_hwsim.c +++ b/drivers/net/ieee802154/mac802154_hwsim.c @@ -748,46 +748,79 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev, hw->phy->supported.page[0].nchunks = 3; /* 868 MHz BPSK 802.15.4-2003 */ hw->phy->supported.page[0].chunk[0].channels |= 1; + hw->phy->supported.page[0].chunk[0].protocol = IEEE802154_BPSK_PHY; + hw->phy->supported.page[0].chunk[0].band = IEEE802154_868_MHZ_BAND; /* 915 MHz BPSK 802.15.4-2003 */ hw->phy->supported.page[0].chunk[1].channels |= 0x7fe; + hw->phy->supported.page[0].chunk[1].protocol = IEEE802154_BPSK_PHY; + hw->phy->supported.page[0].chunk[1].band = IEEE802154_915_MHZ_BAND; /* 2.4 GHz O-QPSK 802.15.4-2003 */ hw->phy->supported.page[0].chunk[2].channels |= 0x7FFF800; + hw->phy->supported.page[0].chunk[2].protocol = IEEE802154_OQPSK_PHY; + hw->phy->supported.page[0].chunk[2].band = IEEE802154_2400_MHZ_BAND; hw->phy->supported.page[1].nchunks = 2; /* 868 MHz ASK 802.15.4-2006 */ hw->phy->supported.page[1].chunk[0].channels |= 1; + hw->phy->supported.page[1].chunk[0].protocol = IEEE802154_ASK_PHY; + hw->phy->supported.page[1].chunk[0].band = IEEE802154_868_MHZ_BAND; /* 915 MHz ASK 802.15.4-2006 */ hw->phy->supported.page[1].chunk[1].channels |= 0x7fe; + hw->phy->supported.page[1].chunk[1].protocol = IEEE802154_ASK_PHY; + hw->phy->supported.page[1].chunk[1].band = IEEE802154_915_MHZ_BAND; hw->phy->supported.page[2].nchunks = 2; /* 868 MHz O-QPSK 802.15.4-2006 */ hw->phy->supported.page[2].chunk[0].channels |= 1; + hw->phy->supported.page[2].chunk[0].protocol = IEEE802154_OQPSK_PHY; + hw->phy->supported.page[2].chunk[0].band = IEEE802154_868_MHZ_BAND; /* 915 MHz O-QPSK 802.15.4-2006 */ hw->phy->supported.page[2].chunk[1].channels |= 0x7fe; + hw->phy->supported.page[2].chunk[1].protocol = IEEE802154_OQPSK_PHY; + hw->phy->supported.page[2].chunk[1].band = IEEE802154_915_MHZ_BAND; hw->phy->supported.page[3].nchunks = 1; /* 2.4 GHz CSS 802.15.4a-2007 */ hw->phy->supported.page[3].chunk[0].channels |= 0x3fff; + hw->phy->supported.page[3].chunk[0].protocol = IEEE802154_CSS_PHY; + hw->phy->supported.page[3].chunk[0].band = IEEE802154_2400_MHZ_BAND; hw->phy->supported.page[4].nchunks = 3; /* UWB Sub-gigahertz 802.15.4a-2007 */ hw->phy->supported.page[4].chunk[0].channels |= 1; + hw->phy->supported.page[4].chunk[0].protocol = IEEE802154_HRP_UWB_PHY; + hw->phy->supported.page[4].chunk[0].band = IEEE802154_250_750_MHZ_BAND; + hw->phy->supported.page[4].chunk[0].prf = IEEE802154_62890KHZ_MEAN_PRF; /* UWB Low band 802.15.4a-2007 */ hw->phy->supported.page[4].chunk[1].channels |= 0x1e; + hw->phy->supported.page[4].chunk[1].protocol = IEEE802154_HRP_UWB_PHY; + hw->phy->supported.page[4].chunk[1].band = IEEE802154_3100_4800_MHZ_BAND; + hw->phy->supported.page[4].chunk[1].prf = IEEE802154_62890KHZ_MEAN_PRF; /* UWB High band 802.15.4a-2007 */ hw->phy->supported.page[4].chunk[2].channels |= 0xffe0; + hw->phy->supported.page[4].chunk[2].protocol = IEEE802154_HRP_UWB_PHY; + hw->phy->supported.page[4].chunk[2].band = IEEE802154_6000_10600_MHZ_BAND; + hw->phy->supported.page[4].chunk[2].prf = IEEE802154_62890KHZ_MEAN_PRF; hw->phy->supported.page[5].nchunks = 2; /* 750 MHz O-QPSK 802.15.4c-2009 */ hw->phy->supported.page[5].chunk[0].channels |= 0xf; + hw->phy->supported.page[5].chunk[0].protocol = IEEE802154_OQPSK_PHY; + hw->phy->supported.page[5].chunk[0].band = IEEE802154_750_MHZ_BAND; /* 750 MHz MPSK 802.15.4c-2009 */ hw->phy->supported.page[5].chunk[1].channels |= 0xf0; + hw->phy->supported.page[5].chunk[1].protocol = IEEE802154_MQPSK_PHY; + hw->phy->supported.page[5].chunk[1].band = IEEE802154_750_MHZ_BAND; hw->phy->supported.page[6].nchunks = 2; /* 950 MHz BPSK 802.15.4d-2009 */ hw->phy->supported.page[6].chunk[0].channels |= 0x3ff; + hw->phy->supported.page[6].chunk[0].protocol = IEEE802154_BPSK_PHY; + hw->phy->supported.page[6].chunk[0].band = IEEE802154_950_MHZ_BAND; /* 950 MHz GFSK 802.15.4d-2009 */ hw->phy->supported.page[6].chunk[1].channels |= 0x3ffc00; + hw->phy->supported.page[6].chunk[1].protocol = IEEE802154_GFSK_PHY; + hw->phy->supported.page[6].chunk[1].band = IEEE802154_950_MHZ_BAND; ieee802154_random_extended_addr(&hw->phy->perm_extended_addr); diff --git a/drivers/net/ieee802154/mcr20a.c b/drivers/net/ieee802154/mcr20a.c index 5190c4d4f505..f0eb2d3b1c4e 100644 --- a/drivers/net/ieee802154/mcr20a.c +++ b/drivers/net/ieee802154/mcr20a.c @@ -1003,7 +1003,10 @@ static void mcr20a_hw_setup(struct mcr20a_local *lp) phy->cca.mode = NL802154_CCA_ENERGY; phy->supported.page[0].nchunks = 1; + /* 2.4 GHz O-QPSK */ phy->supported.page[0].chunk[0].channels = MCR20A_VALID_CHANNELS; + phy->supported.page[0].chunk[0].protocol = IEEE802154_OQPSK_PHY; + phy->supported.page[0].chunk[0].band = IEEE802154_2400_MHZ_BAND; phy->current_page = 0; /* MCR20A default reset value */ phy->current_channel = 20; diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index ef49a23801c6..03c8008217fb 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -131,8 +131,49 @@ wpan_phy_supported_bool(bool b, enum nl802154_supported_bool_states st) return false; } +enum ieee802154_phy_protocols { + IEEE802154_UNKNOWN_PHY, + IEEE802154_BPSK_PHY, + IEEE802154_OQPSK_PHY, + IEEE802154_MQPSK_PHY, + IEEE802154_GFSK_PHY, + IEEE802154_ASK_PHY, + IEEE802154_CSS_PHY, + IEEE802154_HRP_UWB_PHY, + + IEEE802154_MAX_PHY, +}; + +enum ieee802154_phy_bands { + IEEE802154_UNKNOWN_BAND, + IEEE802154_750_MHZ_BAND, + IEEE802154_868_MHZ_BAND, + IEEE802154_915_MHZ_BAND, + IEEE802154_950_MHZ_BAND, + IEEE802154_2400_MHZ_BAND, + IEEE802154_250_750_MHZ_BAND, + IEEE802154_3100_4800_MHZ_BAND, + IEEE802154_6000_10600_MHZ_BAND, + + IEEE802154_MAX_BAND, +}; + +enum ieee802154_phy_mean_prfs { + IEEE802154_UNKNOWN_MEAN_PRF, + IEEE802154_16100KHZ_MEAN_PRF, + IEEE802154_4030KHZ_MEAN_PRF, + IEEE802154_62890KHZ_MEAN_PRF, + + IEEE802154_MAX_PRF, +}; + struct phy_channels { u32 channels; + enum ieee802154_phy_protocols protocol; + enum ieee802154_phy_bands band; + union { + enum ieee802154_phy_mean_prfs prf; + }; }; struct phy_page { From patchwork Wed Jan 12 17:32:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711671 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 988E0C4332F for ; Wed, 12 Jan 2022 17:33:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355657AbiALRdd (ORCPT ); Wed, 12 Jan 2022 12:33:33 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:33093 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355632AbiALRd3 (ORCPT ); Wed, 12 Jan 2022 12:33:29 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id E985D2000B; Wed, 12 Jan 2022 17:33:23 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 05/27] net: mac802154: Convert the symbol duration into nanoseconds Date: Wed, 12 Jan 2022 18:32:50 +0100 Message-Id: <20220112173312.764660-6-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Tdsym is often given in the spec as pretty small numbers in microseconds and hence was reflected in the code as symbol_duration and was stored as a u8. Actually, for UWB PHYs, the symbol duration is given in nanoseconds and are as precise as picoseconds. In order to handle better these PHYs, change the type of symbol_duration to u32 and store this value in nanoseconds. All the users of this variable are updated in a mechanical change. Signed-off-by: Miquel Raynal --- drivers/net/ieee802154/at86rf230.c | 22 +++++++++++----------- drivers/net/ieee802154/atusb.c | 22 +++++++++++----------- drivers/net/ieee802154/ca8210.c | 2 +- drivers/net/ieee802154/mcr20a.c | 4 ++-- include/net/cfg802154.h | 4 ++-- net/mac802154/main.c | 8 ++++---- 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index cdf5d2a4f763..47dafefedf79 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1066,24 +1066,24 @@ at86rf212_set_channel(struct at86rf230_local *lp, u8 page, u8 channel) if (channel == 0) { if (page == 0) { /* SUB:0 and BPSK:0 -> BPSK-20 */ - lp->hw->phy->symbol_duration = 50; + lp->hw->phy->symbol_duration = 50 * 1000; } else { /* SUB:1 and BPSK:0 -> BPSK-40 */ - lp->hw->phy->symbol_duration = 25; + lp->hw->phy->symbol_duration = 25 * 1000; } } else { if (page == 0) /* SUB:0 and BPSK:1 -> OQPSK-100/200/400 */ - lp->hw->phy->symbol_duration = 40; + lp->hw->phy->symbol_duration = 40 * 1000; else /* SUB:1 and BPSK:1 -> OQPSK-250/500/1000 */ - lp->hw->phy->symbol_duration = 16; + lp->hw->phy->symbol_duration = 16 * 1000; } - lp->hw->phy->lifs_period = IEEE802154_LIFS_PERIOD * - lp->hw->phy->symbol_duration; - lp->hw->phy->sifs_period = IEEE802154_SIFS_PERIOD * - lp->hw->phy->symbol_duration; + lp->hw->phy->lifs_period = + (IEEE802154_LIFS_PERIOD * lp->hw->phy->symbol_duration) / 1000; + lp->hw->phy->sifs_period = + (IEEE802154_SIFS_PERIOD * lp->hw->phy->symbol_duration) / 1000; return at86rf230_write_subreg(lp, SR_CHANNEL, channel); } @@ -1561,7 +1561,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) lp->hw->phy->supported.page[0].nchunks = 1; lp->hw->phy->supported.page[0].chunk[0].channels = 0x7FFF800; lp->hw->phy->current_channel = 11; - lp->hw->phy->symbol_duration = 16; + lp->hw->phy->symbol_duration = 16 * 1000; lp->hw->phy->supported.tx_powers = at86rf231_powers; lp->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf231_powers); lp->hw->phy->supported.cca_ed_levels = at86rf231_ed_levels; @@ -1576,7 +1576,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) lp->hw->phy->supported.page[2].nchunks = 1; lp->hw->phy->supported.page[2].chunk[0].channels = 0x00007FF; lp->hw->phy->current_channel = 5; - lp->hw->phy->symbol_duration = 25; + lp->hw->phy->symbol_duration = 25 * 1000; lp->hw->phy->supported.lbt = NL802154_SUPPORTED_BOOL_BOTH; lp->hw->phy->supported.tx_powers = at86rf212_powers; lp->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf212_powers); @@ -1589,7 +1589,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) lp->hw->phy->supported.page[0].nchunks = 1; lp->hw->phy->supported.page[0].chunk[0].channels = 0x7FFF800; lp->hw->phy->current_channel = 13; - lp->hw->phy->symbol_duration = 16; + lp->hw->phy->symbol_duration = 16 * 1000; lp->hw->phy->supported.tx_powers = at86rf233_powers; lp->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf233_powers); lp->hw->phy->supported.cca_ed_levels = at86rf233_ed_levels; diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c index 38ebfacf2698..099113bd4a26 100644 --- a/drivers/net/ieee802154/atusb.c +++ b/drivers/net/ieee802154/atusb.c @@ -678,24 +678,24 @@ static int hulusb_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel) if (channel == 0) { if (page == 0) { /* SUB:0 and BPSK:0 -> BPSK-20 */ - lp->hw->phy->symbol_duration = 50; + lp->hw->phy->symbol_duration = 50 * 1000; } else { /* SUB:1 and BPSK:0 -> BPSK-40 */ - lp->hw->phy->symbol_duration = 25; + lp->hw->phy->symbol_duration = 25 * 1000; } } else { if (page == 0) /* SUB:0 and BPSK:1 -> OQPSK-100/200/400 */ - lp->hw->phy->symbol_duration = 40; + lp->hw->phy->symbol_duration = 40 * 1000; else /* SUB:1 and BPSK:1 -> OQPSK-250/500/1000 */ - lp->hw->phy->symbol_duration = 16; + lp->hw->phy->symbol_duration = 16 * 1000; } - lp->hw->phy->lifs_period = IEEE802154_LIFS_PERIOD * - lp->hw->phy->symbol_duration; - lp->hw->phy->sifs_period = IEEE802154_SIFS_PERIOD * - lp->hw->phy->symbol_duration; + lp->hw->phy->lifs_period = + (IEEE802154_LIFS_PERIOD * lp->hw->phy->symbol_duration) / 1000; + lp->hw->phy->sifs_period = + (IEEE802154_SIFS_PERIOD * lp->hw->phy->symbol_duration) / 1000; return atusb_write_subreg(lp, SR_CHANNEL, channel); } @@ -917,7 +917,7 @@ static int atusb_get_and_conf_chip(struct atusb *atusb) atusb->hw->phy->supported.page[0].nchunks = 1; atusb->hw->phy->supported.page[0].chunk[0].channels = 0x7FFF800; atusb->hw->phy->current_channel = 11; /* reset default */ - atusb->hw->phy->symbol_duration = 16; + atusb->hw->phy->symbol_duration = 16 * 1000; atusb->hw->phy->supported.tx_powers = atusb_powers; atusb->hw->phy->supported.tx_powers_size = ARRAY_SIZE(atusb_powers); hw->phy->supported.cca_ed_levels = atusb_ed_levels; @@ -928,7 +928,7 @@ static int atusb_get_and_conf_chip(struct atusb *atusb) atusb->hw->phy->supported.page[0].nchunks = 1; atusb->hw->phy->supported.page[0].chunk[0].channels = 0x7FFF800; atusb->hw->phy->current_channel = 11; /* reset default */ - atusb->hw->phy->symbol_duration = 16; + atusb->hw->phy->symbol_duration = 16 * 1000; atusb->hw->phy->supported.tx_powers = atusb_powers; atusb->hw->phy->supported.tx_powers_size = ARRAY_SIZE(atusb_powers); hw->phy->supported.cca_ed_levels = atusb_ed_levels; @@ -942,7 +942,7 @@ static int atusb_get_and_conf_chip(struct atusb *atusb) atusb->hw->phy->supported.page[2].nchunks = 1; atusb->hw->phy->supported.page[2].chunk[0].channels = 0x00007FF; atusb->hw->phy->current_channel = 5; - atusb->hw->phy->symbol_duration = 25; + atusb->hw->phy->symbol_duration = 25 * 1000; atusb->hw->phy->supported.lbt = NL802154_SUPPORTED_BOOL_BOTH; atusb->hw->phy->supported.tx_powers = at86rf212_powers; atusb->hw->phy->supported.tx_powers_size = ARRAY_SIZE(at86rf212_powers); diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c index f42a0b719a33..82b2a173bdbd 100644 --- a/drivers/net/ieee802154/ca8210.c +++ b/drivers/net/ieee802154/ca8210.c @@ -2977,7 +2977,7 @@ static void ca8210_hw_setup(struct ieee802154_hw *ca8210_hw) ca8210_hw->phy->cca.mode = NL802154_CCA_ENERGY_CARRIER; ca8210_hw->phy->cca.opt = NL802154_CCA_OPT_ENERGY_CARRIER_AND; ca8210_hw->phy->cca_ed_level = -9800; - ca8210_hw->phy->symbol_duration = 16; + ca8210_hw->phy->symbol_duration = 16 * 1000; ca8210_hw->phy->lifs_period = 40; ca8210_hw->phy->sifs_period = 12; ca8210_hw->flags = diff --git a/drivers/net/ieee802154/mcr20a.c b/drivers/net/ieee802154/mcr20a.c index f0eb2d3b1c4e..8aa87e9bf92e 100644 --- a/drivers/net/ieee802154/mcr20a.c +++ b/drivers/net/ieee802154/mcr20a.c @@ -975,7 +975,7 @@ static void mcr20a_hw_setup(struct mcr20a_local *lp) dev_dbg(printdev(lp), "%s\n", __func__); - phy->symbol_duration = 16; + phy->symbol_duration = 16 * 1000; phy->lifs_period = 40; phy->sifs_period = 12; @@ -1010,7 +1010,7 @@ static void mcr20a_hw_setup(struct mcr20a_local *lp) phy->current_page = 0; /* MCR20A default reset value */ phy->current_channel = 20; - phy->symbol_duration = 16; + phy->symbol_duration = 16 * 1000; phy->supported.tx_powers = mcr20a_powers; phy->supported.tx_powers_size = ARRAY_SIZE(mcr20a_powers); phy->cca_ed_level = phy->supported.cca_ed_levels[75]; diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 03c8008217fb..286709a9dd0b 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -253,8 +253,8 @@ struct wpan_phy { /* PHY depended MAC PIB values */ - /* 802.15.4 acronym: Tdsym in usec */ - u8 symbol_duration; + /* 802.15.4 acronym: Tdsym in nsec */ + u32 symbol_duration; /* lifs and sifs periods timing */ u16 lifs_period; u16 sifs_period; diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 12ab1545e871..77a4943f345f 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -131,10 +131,10 @@ static void ieee802154_setup_wpan_phy_pib(struct wpan_phy *wpan_phy) * Should be done when all drivers sets this value. */ - wpan_phy->lifs_period = IEEE802154_LIFS_PERIOD * - wpan_phy->symbol_duration; - wpan_phy->sifs_period = IEEE802154_SIFS_PERIOD * - wpan_phy->symbol_duration; + wpan_phy->lifs_period = + (IEEE802154_LIFS_PERIOD * wpan_phy->symbol_duration) / 1000; + wpan_phy->sifs_period = + (IEEE802154_SIFS_PERIOD * wpan_phy->symbol_duration) / 1000; } int ieee802154_register_hw(struct ieee802154_hw *hw) From patchwork Wed Jan 12 17:32:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711674 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4057FC433FE for ; Wed, 12 Jan 2022 17:33:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355695AbiALRdh (ORCPT ); Wed, 12 Jan 2022 12:33:37 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:37001 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355639AbiALRdb (ORCPT ); Wed, 12 Jan 2022 12:33:31 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id E578320002; Wed, 12 Jan 2022 17:33:25 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 06/27] net: mac802154: Set the symbol duration automatically Date: Wed, 12 Jan 2022 18:32:51 +0100 Message-Id: <20220112173312.764660-7-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Now that we have access to all the basic information to know which symbol duration should be applied, let's set the symbol duration automatically. The two locations that must call for the symbol duration to be set are: - when manually requesting a channel change though the netlink interface - at PHY creation, ieee802154_alloc_hw() already calls ieee802154_change_channel() which will now update the symbol duration accordingly. If an information is missing, the symbol duration is not touched, a debug message is eventually printed. This keeps the compatibility with the unconverted drivers for which it was too complicated for me to find their precise information. If they initially provided a symbol duration, it would be kept. If they don't, the symbol duration value is left untouched. Signed-off-by: Miquel Raynal --- include/net/cfg802154.h | 2 + net/mac802154/cfg.c | 1 + net/mac802154/main.c | 93 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 286709a9dd0b..52eefc4b5b4d 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -455,4 +455,6 @@ static inline const char *wpan_phy_name(struct wpan_phy *phy) return dev_name(&phy->dev); } +void ieee802154_set_symbol_duration(struct wpan_phy *phy); + #endif /* __NET_CFG802154_H */ diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 6969f1330ccd..ba57da07c08e 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -113,6 +113,7 @@ int ieee802154_change_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) if (!ret) { wpan_phy->current_page = page; wpan_phy->current_channel = channel; + ieee802154_set_symbol_duration(wpan_phy); } return ret; diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 77a4943f345f..88826c5aa4ba 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -113,6 +113,99 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops) } EXPORT_SYMBOL(ieee802154_alloc_hw); +void ieee802154_set_symbol_duration(struct wpan_phy *phy) +{ + struct phy_page *page = &phy->supported.page[phy->current_page]; + struct phy_channels *chan; + unsigned int chunk; + u32 duration = 0; + + for (chunk = 0; chunk < page->nchunks; chunk++) { + if (page->chunk[chunk].channels & phy->current_channel) + break; + } + + if (chunk == page->nchunks) + goto set_duration; + + chan = &page->chunk[chunk]; + switch (chan->protocol) { + case IEEE802154_BPSK_PHY: + switch (chan->band) { + case IEEE802154_868_MHZ_BAND: + /* 868 MHz BPSK 802.15.4-2003: 20 ksym/s */ + duration = 50 * 1000; + break; + case IEEE802154_915_MHZ_BAND: + /* 915 MHz BPSK 802.15.4-2003: 40 ksym/s */ + duration = 25 * 1000; + break; + default: + break; + } + break; + case IEEE802154_OQPSK_PHY: + switch (chan->band) { + case IEEE802154_868_MHZ_BAND: + /* 868 MHz O-QPSK 802.15.4-2006: 25 ksym/s */ + duration = 40 * 1000; + break; + case IEEE802154_915_MHZ_BAND: + case IEEE802154_2400_MHZ_BAND: + /* 915/2400 MHz O-QPSK 802.15.4-2006: 62.5 ksym/s */ + duration = 16 * 1000; + break; + default: + break; + } + break; + case IEEE802154_CSS_PHY: + switch (chan->band) { + case IEEE802154_2400_MHZ_BAND: + /* 2.4 GHz CSS 802.15.4a-2007: 1/6 Msym/s */ + duration = 6 * 1000; + break; + default: + break; + } + break; + case IEEE802154_HRP_UWB_PHY: + switch (chan->band) { + case IEEE802154_250_750_MHZ_BAND: + case IEEE802154_3100_4800_MHZ_BAND: + case IEEE802154_6000_10600_MHZ_BAND: + break; + default: + goto set_duration; + } + + /* UWB 802.15.4a-2007: 993.6 or 1017.6 or 3974.4 ns */ + switch (chan->prf) { + case IEEE802154_16100KHZ_MEAN_PRF: + duration = 994; + break; + case IEEE802154_4030KHZ_MEAN_PRF: + duration = 3974; + break; + case IEEE802154_62890KHZ_MEAN_PRF: + duration = 1018; + break; + default: + break; + } + break; + default: + break; + } + +set_duration: + if (!duration) + pr_debug("Unknown PHY symbol duration, the driver should be fixed\n"); + else + phy->symbol_duration = duration; +} +EXPORT_SYMBOL(ieee802154_set_symbol_duration); + void ieee802154_free_hw(struct ieee802154_hw *hw) { struct ieee802154_local *local = hw_to_local(hw); From patchwork Wed Jan 12 17:32:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711673 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7AB2FC28CF5 for ; Wed, 12 Jan 2022 17:33:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355668AbiALRde (ORCPT ); Wed, 12 Jan 2022 12:33:34 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:41583 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242291AbiALRdb (ORCPT ); Wed, 12 Jan 2022 12:33:31 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 8084E2000C; Wed, 12 Jan 2022 17:33:28 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 07/27] net: ieee802154: hwsim: Ensure frame checksum are valid Date: Wed, 12 Jan 2022 18:32:52 +0100 Message-Id: <20220112173312.764660-8-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org There is no point in accepting frames with a wrong or missing checksum, at least not outside of a promiscuous setting. Set the right flag by default in the hwsim driver to ensure checksums are not ignored. Signed-off-by: Miquel Raynal --- drivers/net/ieee802154/mac802154_hwsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c index a2827c0acabe..8f87f2b8129d 100644 --- a/drivers/net/ieee802154/mac802154_hwsim.c +++ b/drivers/net/ieee802154/mac802154_hwsim.c @@ -836,7 +836,7 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev, phy->idx = idx; INIT_LIST_HEAD(&phy->edges); - hw->flags = IEEE802154_HW_PROMISCUOUS; + hw->flags = IEEE802154_HW_PROMISCUOUS | IEEE802154_HW_RX_DROP_BAD_CKSUM; hw->parent = dev; err = ieee802154_register_hw(hw); From patchwork Wed Jan 12 17:32:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711675 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2B899C433FE for ; Wed, 12 Jan 2022 17:33:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355738AbiALRdu (ORCPT ); Wed, 12 Jan 2022 12:33:50 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:55691 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355676AbiALRdf (ORCPT ); Wed, 12 Jan 2022 12:33:35 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 7B14A20009; Wed, 12 Jan 2022 17:33:30 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 08/27] net: ieee802154: Drop symbol duration settings when the core does it already Date: Wed, 12 Jan 2022 18:32:53 +0100 Message-Id: <20220112173312.764660-9-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org The core now knows how to set the symbol duration in a few cases, when drivers correctly advertise the protocols used on each channel. For these drivers, there is no more need to bother with symbol duration, so just drop the duplicated code. Signed-off-by: Miquel Raynal --- drivers/net/ieee802154/ca8210.c | 1 - drivers/net/ieee802154/mcr20a.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c index 82b2a173bdbd..d3a9e4fe05f4 100644 --- a/drivers/net/ieee802154/ca8210.c +++ b/drivers/net/ieee802154/ca8210.c @@ -2977,7 +2977,6 @@ static void ca8210_hw_setup(struct ieee802154_hw *ca8210_hw) ca8210_hw->phy->cca.mode = NL802154_CCA_ENERGY_CARRIER; ca8210_hw->phy->cca.opt = NL802154_CCA_OPT_ENERGY_CARRIER_AND; ca8210_hw->phy->cca_ed_level = -9800; - ca8210_hw->phy->symbol_duration = 16 * 1000; ca8210_hw->phy->lifs_period = 40; ca8210_hw->phy->sifs_period = 12; ca8210_hw->flags = diff --git a/drivers/net/ieee802154/mcr20a.c b/drivers/net/ieee802154/mcr20a.c index 8aa87e9bf92e..da2ab19cb5ee 100644 --- a/drivers/net/ieee802154/mcr20a.c +++ b/drivers/net/ieee802154/mcr20a.c @@ -975,7 +975,6 @@ static void mcr20a_hw_setup(struct mcr20a_local *lp) dev_dbg(printdev(lp), "%s\n", __func__); - phy->symbol_duration = 16 * 1000; phy->lifs_period = 40; phy->sifs_period = 12; @@ -1010,7 +1009,6 @@ static void mcr20a_hw_setup(struct mcr20a_local *lp) phy->current_page = 0; /* MCR20A default reset value */ phy->current_channel = 20; - phy->symbol_duration = 16 * 1000; phy->supported.tx_powers = mcr20a_powers; phy->supported.tx_powers_size = ARRAY_SIZE(mcr20a_powers); phy->cca_ed_level = phy->supported.cca_ed_levels[75]; From patchwork Wed Jan 12 17:32:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711678 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 98174C433FE for ; Wed, 12 Jan 2022 17:33:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355704AbiALRdx (ORCPT ); Wed, 12 Jan 2022 12:33:53 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:55207 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355694AbiALRdh (ORCPT ); Wed, 12 Jan 2022 12:33:37 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 6E9F52000E; Wed, 12 Jan 2022 17:33:32 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 09/27] net: ieee802154: Move IEEE 802.15.4 Kconfig main entry Date: Wed, 12 Jan 2022 18:32:54 +0100 Message-Id: <20220112173312.764660-10-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@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 Jan 12 17:32:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711677 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3D05AC4167D for ; Wed, 12 Jan 2022 17:33:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355700AbiALRdx (ORCPT ); Wed, 12 Jan 2022 12:33:53 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:55687 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355692AbiALRdh (ORCPT ); Wed, 12 Jan 2022 12:33:37 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 65A9620008; Wed, 12 Jan 2022 17:33:34 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 10/27] net: mac802154: Include the softMAC stack inside the IEEE 802.15.4 menu Date: Wed, 12 Jan 2022 18:32:55 +0100 Message-Id: <20220112173312.764660-11-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@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 Jan 12 17:32:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711676 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6D0ACC43219 for ; Wed, 12 Jan 2022 17:33:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355688AbiALRdw (ORCPT ); Wed, 12 Jan 2022 12:33:52 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:57193 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355700AbiALRdj (ORCPT ); Wed, 12 Jan 2022 12:33:39 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 831962000A; Wed, 12 Jan 2022 17:33:36 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 11/27] net: ieee802154: Move the address structure earlier Date: Wed, 12 Jan 2022 18:32:56 +0100 Message-Id: <20220112173312.764660-12-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@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 52eefc4b5b4d..f8ea3d519865 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, @@ -277,15 +286,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 Jan 12 17:32:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711679 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05B0FC433F5 for ; Wed, 12 Jan 2022 17:33:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355742AbiALRdz (ORCPT ); Wed, 12 Jan 2022 12:33:55 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:48601 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355716AbiALRdo (ORCPT ); Wed, 12 Jan 2022 12:33:44 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id F06A820014; Wed, 12 Jan 2022 17:33:38 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 12/27] net: ieee802154: Add a kernel doc header to the ieee802154_addr structure Date: Wed, 12 Jan 2022 18:32:57 +0100 Message-Id: <20220112173312.764660-13-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@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 f8ea3d519865..9295615ed019 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 Jan 12 17:32:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711680 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B91B3C433F5 for ; Wed, 12 Jan 2022 17:34:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350086AbiALReC (ORCPT ); Wed, 12 Jan 2022 12:34:02 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:57331 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355723AbiALRdq (ORCPT ); Wed, 12 Jan 2022 12:33:46 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id DE6D120013; Wed, 12 Jan 2022 17:33:40 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 13/27] net: ieee802154: Return meaningful error codes from the netlink helpers Date: Wed, 12 Jan 2022 18:32:58 +0100 Message-Id: <20220112173312.764660-14-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@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 45e2c9b0505a..bd1015611a7e 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -1459,7 +1459,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; @@ -1652,7 +1652,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; @@ -1830,7 +1830,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; @@ -2006,7 +2006,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 Jan 12 17:32:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711681 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 44750C433F5 for ; Wed, 12 Jan 2022 17:34:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355729AbiALReS (ORCPT ); Wed, 12 Jan 2022 12:34:18 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:56083 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355727AbiALRds (ORCPT ); Wed, 12 Jan 2022 12:33:48 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id DE6612000B; Wed, 12 Jan 2022 17:33:42 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 14/27] net: ieee802154: Add support for internal PAN management Date: Wed, 12 Jan 2022 18:32:59 +0100 Message-Id: <20220112173312.764660-15-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@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 | 26 +++++ net/ieee802154/pan.c | 231 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 net/ieee802154/pan.c diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 9295615ed019..9c79feac25bf 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, @@ -467,4 +485,17 @@ static inline const char *wpan_phy_name(struct wpan_phy *phy) void ieee802154_set_symbol_duration(struct wpan_phy *phy); +/** + * 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 a0cf6feffc6a..0d08d2f79ab9 100644 --- a/net/ieee802154/core.h +++ b/net/ieee802154/core.h @@ -22,6 +22,14 @@ 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; + unsigned int max_pan_entries; + unsigned int pan_expiration; + unsigned int pan_entries; + unsigned 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 +47,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 */ @@ -49,4 +68,11 @@ struct wpan_phy *wpan_phy_idx_to_wpan_phy(int wpan_phy_idx); u32 cfg802154_get_supported_chans(struct wpan_phy *phy, unsigned int page); +void cfg802154_set_max_pan_entries(struct cfg802154_registered_device *rdev, + unsigned int max); +void cfg802154_set_pans_expiration(struct cfg802154_registered_device *rdev, + unsigned int exp_time_s); +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..1ea15ea1b3bd --- /dev/null +++ b/net/ieee802154/pan.c @@ -0,0 +1,231 @@ +// 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" + +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_set_max_pan_entries(struct cfg802154_registered_device *rdev, + unsigned int max) +{ + lockdep_assert_held(&rdev->pan_lock); + + rdev->max_pan_entries = max; +} +EXPORT_SYMBOL(cfg802154_set_max_pan_entries); + +static bool +cfg802154_need_to_expire_pans(struct cfg802154_registered_device *rdev) +{ + if (!rdev->max_pan_entries) + return false; + + if (rdev->pan_entries > rdev->max_pan_entries) + return true; + + return false; +} + +void cfg802154_set_pans_expiration(struct cfg802154_registered_device *rdev, + unsigned int exp_time_s) +{ + lockdep_assert_held(&rdev->pan_lock); + + rdev->pan_expiration = exp_time_s * HZ; +} +EXPORT_SYMBOL(cfg802154_set_pans_expiration); + +void cfg802154_expire_pans(struct cfg802154_registered_device *rdev) +{ + struct cfg802154_internal_pan *pan, *tmp; + unsigned long expiration_time; + + lockdep_assert_held(&rdev->pan_lock); + + if (!rdev->pan_expiration) + return; + + expiration_time = jiffies - rdev->pan_expiration; + 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(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(cfg802154_need_to_expire_pans(rdev))) + 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 Jan 12 17:33:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711682 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B908C433EF for ; Wed, 12 Jan 2022 17:34:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355674AbiALReT (ORCPT ); Wed, 12 Jan 2022 12:34:19 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:37941 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355660AbiALRdu (ORCPT ); Wed, 12 Jan 2022 12:33:50 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id D19B520016; Wed, 12 Jan 2022 17:33:44 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 15/27] net: ieee802154: Define a beacon frame header Date: Wed, 12 Jan 2022 18:33:00 +0100 Message-Id: <20220112173312.764660-16-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@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..fb6ac354a7b6 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -22,6 +22,42 @@ #include +struct ieee802154_beacon_hdr { +#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 Jan 12 17:33:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711684 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 93F60C4321E for ; Wed, 12 Jan 2022 17:34:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350056AbiALRe0 (ORCPT ); Wed, 12 Jan 2022 12:34:26 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:47521 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355639AbiALRdw (ORCPT ); Wed, 12 Jan 2022 12:33:52 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 1896320019; Wed, 12 Jan 2022 17:33:47 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 16/27] net: ieee802154: Define frame types Date: Wed, 12 Jan 2022 18:33:01 +0100 Message-Id: <20220112173312.764660-17-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@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 fb6ac354a7b6..45dff5d11bc8 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 Jan 12 17:33:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711683 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 12AF6C433FE for ; Wed, 12 Jan 2022 17:34:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355812AbiALReZ (ORCPT ); Wed, 12 Jan 2022 12:34:25 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:56305 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355686AbiALRdw (ORCPT ); Wed, 12 Jan 2022 12:33:52 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 457D22001B; Wed, 12 Jan 2022 17:33:49 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 17/27] net: ieee802154: Add support for scanning requests Date: Wed, 12 Jan 2022 18:33:02 +0100 Message-Id: <20220112173312.764660-18-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@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 | 3 + 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, 387 insertions(+) diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h index 95c831162212..41178c87c43c 100644 --- a/include/linux/ieee802154.h +++ b/include/linux/ieee802154.h @@ -44,6 +44,9 @@ #define IEEE802154_SHORT_ADDR_LEN 2 #define IEEE802154_PAN_ID_LEN 2 +/* Duration in superframe order */ +#define IEEE802154_MAX_SCAN_DURATION 14 +#define IEEE802154_ACTIVE_SCAN_DURATION 15 #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 9c79feac25bf..2118bfc02d7c 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 0d08d2f79ab9..9aa8f88b6920 100644 --- a/net/ieee802154/core.h +++ b/net/ieee802154/core.h @@ -30,6 +30,9 @@ struct cfg802154_registered_device { unsigned int pan_entries; unsigned 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 bd1015611a7e..99cbad1f1381 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, }, @@ -1299,6 +1307,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 = cfg802154_get_supported_chans(wpan_phy, + 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("Duration is out of range\n"); + 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 }, @@ -2387,6 +2605,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 Jan 12 17:33:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711702 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 86BA8C433FE for ; Wed, 12 Jan 2022 17:36:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355907AbiALRgl (ORCPT ); Wed, 12 Jan 2022 12:36:41 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:53147 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355708AbiALRdy (ORCPT ); Wed, 12 Jan 2022 12:33:54 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 6244F2001E; Wed, 12 Jan 2022 17:33:51 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 18/27] net: mac802154: Handle scan requests Date: Wed, 12 Jan 2022 18:33:03 +0100 Message-Id: <20220112173312.764660-19-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@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. As transceiver enter in a promiscuous mode during scans, they might stop checking frame validity so we ensure this gets done at mac level. 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 | 22 +++ net/mac802154/main.c | 2 + net/mac802154/rx.c | 21 ++- net/mac802154/scan.c | 255 +++++++++++++++++++++++++++++++++++ net/mac802154/tx.c | 3 + net/mac802154/util.c | 26 ++++ 10 files changed, 382 insertions(+), 6 deletions(-) create mode 100644 net/mac802154/scan.c diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h index 41178c87c43c..57bf5317338e 100644 --- a/include/linux/ieee802154.h +++ b/include/linux/ieee802154.h @@ -47,6 +47,10 @@ /* Duration in superframe order */ #define IEEE802154_MAX_SCAN_DURATION 14 #define IEEE802154_ACTIVE_SCAN_DURATION 15 +/* 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 ba57da07c08e..c1e7bbea3058 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -109,6 +109,10 @@ int ieee802154_change_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) ASSERT_RTNL(); + /* Refuse to change channels during a scanning operation */ + if (mac802154_scan_is_ongoing(local)) + return -EBUSY; + ret = drv_set_channel(local, page, channel); if (!ret) { wpan_phy->current_page = page; @@ -268,6 +272,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, @@ -475,6 +512,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 8a7f4c83c5b6..5cc3ac8fd4a1 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; + atomic_t 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; @@ -167,6 +176,19 @@ 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_process_beacon(struct ieee802154_local *local, + struct sk_buff *skb); + +static inline bool mac802154_scan_is_ongoing(struct ieee802154_local *local) +{ + return atomic_read(&local->scanning); +} + /* 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 88826c5aa4ba..09e2fc6848cb 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..f2f3eca9bc20 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -94,10 +94,15 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, switch (mac_cb(skb)->type) { case IEEE802154_FC_TYPE_BEACON: - case IEEE802154_FC_TYPE_ACK: + if (mac802154_scan_is_ongoing(sdata->local)) { + rc = mac802154_scan_process_beacon(sdata->local, skb); + if (!rc) + goto success; + } + goto fail; case IEEE802154_FC_TYPE_MAC_CMD: + case IEEE802154_FC_TYPE_ACK: goto fail; - case IEEE802154_FC_TYPE_DATA: return ieee802154_deliver_skb(skb); default: @@ -109,6 +114,10 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, fail: kfree_skb(skb); return NET_RX_DROP; + +success: + kfree_skb(skb); + return NET_RX_SUCCESS; } static void @@ -268,10 +277,12 @@ void ieee802154_rx(struct ieee802154_local *local, struct sk_buff *skb) ieee802154_monitors_rx(local, skb); - /* Check if transceiver doesn't validate the checksum. - * If not we validate the checksum here. + /* Check if the transceiver doesn't validate the checksum, or if the + * check might have been disabled like during a scan. In these cases, + * we validate the checksum here. */ - if (local->hw.flags & IEEE802154_HW_RX_DROP_BAD_CKSUM) { + if (local->hw.flags & IEEE802154_HW_RX_DROP_BAD_CKSUM || + mac802154_scan_is_ongoing(local)) { crc = crc_ccitt(0, skb->data, skb->len); if (crc) { rcu_read_unlock(); diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c new file mode 100644 index 000000000000..7be63d73caa9 --- /dev/null +++ b/net/mac802154/scan.c @@ -0,0 +1,255 @@ +// 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); + ieee802154_set_symbol_duration(local->phy); + atomic_set(&local->scanning, 0); + mac802154_set_promiscuous_mode(local, false); + ieee802154_wake_queue(&local->hw); + + return mac802154_send_scan_done(local); +} + +int mac802154_abort_scan_locked(struct ieee802154_local *local) +{ + lockdep_assert_held(&local->scan_lock); + + if (!mac802154_scan_is_ongoing(local)) + 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 (!mac802154_scan_is_ongoing(local)) + 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; + ieee802154_set_symbol_duration(local->phy); + } 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 (mac802154_scan_is_ongoing(local)) + 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; + atomic_set(&local->scanning, 1); + + /* Software scanning requires to set promiscuous mode, so we need to + * pause the Tx queue + */ + ieee802154_stop_queue(&local->hw); + 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_process_beacon(struct ieee802154_local *local, + struct sk_buff *skb) +{ + struct ieee802154_beacon_hdr *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/tx.c b/net/mac802154/tx.c index c829e4a75325..40656728c624 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -54,6 +54,9 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) struct net_device *dev = skb->dev; int ret; + if (unlikely(mac802154_scan_is_ongoing(local))) + return NETDEV_TX_BUSY; + if (!(local->hw.flags & IEEE802154_HW_TX_OMIT_CKSUM)) { struct sk_buff *nskb; u16 crc; 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 Jan 12 17:33:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711691 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2B2B4C4332F for ; Wed, 12 Jan 2022 17:34:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355693AbiALRev (ORCPT ); Wed, 12 Jan 2022 12:34:51 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:53077 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355719AbiALRd5 (ORCPT ); Wed, 12 Jan 2022 12:33:57 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 73D3E20010; Wed, 12 Jan 2022 17:33:53 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 19/27] net: ieee802154: Full PAN management Date: Wed, 12 Jan 2022 18:33:04 +0100 Message-Id: <20220112173312.764660-20-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@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. The maximum number of PANs to list and their delay before expiration can be configured. By default there is no limit. When these parameters are set, PANs are automatically dropped from the list. Co-developed-by: David Girault Signed-off-by: David Girault Signed-off-by: Miquel Raynal --- include/net/nl802154.h | 47 +++++++++ net/ieee802154/nl802154.c | 195 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 242 insertions(+) diff --git a/include/net/nl802154.h b/include/net/nl802154.h index 51eca3a2b14e..22af514dd339 100644 --- a/include/net/nl802154.h +++ b/include/net/nl802154.h @@ -61,6 +61,10 @@ enum nl802154_commands { NL802154_CMD_TRIGGER_SCAN, NL802154_CMD_ABORT_SCAN, NL802154_CMD_SCAN_DONE, + NL802154_CMD_DUMP_PANS, + NL802154_CMD_FLUSH_PANS, + NL802154_CMD_SET_MAX_PAN_ENTRIES, + NL802154_CMD_SET_PANS_EXPIRATION, /* add new commands above here */ @@ -141,6 +145,9 @@ enum nl802154_attrs { NL802154_ATTR_SCAN_FLAGS, NL802154_ATTR_SCAN_CHANNELS, NL802154_ATTR_SCAN_DURATION, + NL802154_ATTR_PAN, + NL802154_ATTR_MAX_PAN_ENTRIES, + NL802154_ATTR_PANS_EXPIRATION, /* add attributes here, update the policy in nl802154.c */ @@ -267,6 +274,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 99cbad1f1381..62591ba7ed44 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -223,6 +223,9 @@ 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 }, + [NL802154_ATTR_MAX_PAN_ENTRIES] = { .type = NLA_U32 }, + [NL802154_ATTR_PANS_EXPIRATION] = { .type = NLA_U32 }, #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL [NL802154_ATTR_SEC_ENABLED] = { .type = NLA_U8, }, @@ -1517,6 +1520,172 @@ 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; +} + +static int nl802154_set_max_pan_entries(struct sk_buff *skb, + struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + unsigned int max_entries; + + if (!info->attrs[NL802154_ATTR_MAX_PAN_ENTRIES]) + return -EINVAL; + + max_entries = nla_get_u32(info->attrs[NL802154_ATTR_MAX_PAN_ENTRIES]); + + spin_lock_bh(&rdev->pan_lock); + cfg802154_set_max_pan_entries(rdev, max_entries); + spin_unlock_bh(&rdev->pan_lock); + + return 0; +} + +static int nl802154_set_pans_expiration(struct sk_buff *skb, + struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + unsigned int exp_time_s; + + if (!info->attrs[NL802154_ATTR_PANS_EXPIRATION]) + return -EINVAL; + + exp_time_s = nla_get_u32(info->attrs[NL802154_ATTR_PANS_EXPIRATION]); + + spin_lock_bh(&rdev->pan_lock); + cfg802154_set_pans_expiration(rdev, exp_time_s); + 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 }, @@ -2621,6 +2790,32 @@ 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, + }, + { + .cmd = NL802154_CMD_SET_MAX_PAN_ENTRIES, + .doit = nl802154_set_max_pan_entries, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_NETDEV | + NL802154_FLAG_NEED_RTNL, + }, + { + .cmd = NL802154_CMD_SET_PANS_EXPIRATION, + .doit = nl802154_set_pans_expiration, + .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 Jan 12 17:33:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711692 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 28A27C4167E for ; Wed, 12 Jan 2022 17:34:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355678AbiALReu (ORCPT ); Wed, 12 Jan 2022 12:34:50 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:51011 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355716AbiALReC (ORCPT ); Wed, 12 Jan 2022 12:34:02 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 99EBF20002; Wed, 12 Jan 2022 17:33:55 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 20/27] net: ieee802154: Add support for beacon requests Date: Wed, 12 Jan 2022 18:33:05 +0100 Message-Id: <20220112173312.764660-21-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@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 2118bfc02d7c..ab4d4b7461e6 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 22af514dd339..20c46f15cef4 100644 --- a/include/net/nl802154.h +++ b/include/net/nl802154.h @@ -65,6 +65,8 @@ enum nl802154_commands { NL802154_CMD_FLUSH_PANS, NL802154_CMD_SET_MAX_PAN_ENTRIES, NL802154_CMD_SET_PANS_EXPIRATION, + NL802154_CMD_SEND_BEACONS, + NL802154_CMD_STOP_BEACONS, /* add new commands above here */ @@ -148,6 +150,7 @@ enum nl802154_attrs { NL802154_ATTR_PAN, NL802154_ATTR_MAX_PAN_ENTRIES, NL802154_ATTR_PANS_EXPIRATION, + 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 62591ba7ed44..a5dcc69f0899 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -226,6 +226,7 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = { [NL802154_ATTR_PAN] = { .type = NLA_NESTED }, [NL802154_ATTR_MAX_PAN_ENTRIES] = { .type = NLA_U32 }, [NL802154_ATTR_PANS_EXPIRATION] = { .type = NLA_U32 }, + [NL802154_ATTR_BEACON_INTERVAL] = { .type = NLA_U8 }, #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL [NL802154_ATTR_SEC_ENABLED] = { .type = NLA_U8, }, @@ -1686,6 +1687,70 @@ static int nl802154_set_pans_expiration(struct sk_buff *skb, 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_ACTIVE_SCAN_DURATION) { + pr_err("Interval is out of range\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 }, @@ -2816,6 +2881,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 Jan 12 17:33:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711686 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 995FBC433F5 for ; Wed, 12 Jan 2022 17:34:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355744AbiALRe2 (ORCPT ); Wed, 12 Jan 2022 12:34:28 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:55733 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355720AbiALReC (ORCPT ); Wed, 12 Jan 2022 12:34:02 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 152B420004; Wed, 12 Jan 2022 17:33:58 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 21/27] net: mac802154: Handle beacons requests Date: Wed, 12 Jan 2022 18:33:06 +0100 Message-Id: <20220112173312.764660-22-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@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 | 119 ++++++++++++++++++++++++++++++++ 6 files changed, 226 insertions(+), 2 deletions(-) diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index 45dff5d11bc8..f7716aeec93b 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_beacon_hdr 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..bab710aa36f9 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_beacon_hdr *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 c1e7bbea3058..afba02c31850 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -109,8 +109,10 @@ int ieee802154_change_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) ASSERT_RTNL(); - /* Refuse to change channels during a scanning operation */ - if (mac802154_scan_is_ongoing(local)) + /* Refuse to change channels during a scanning operation or when a + * beacons request is ongoing. + */ + if (mac802154_scan_is_ongoing(local) || local->ongoing_beacons_request) return -EBUSY; ret = drv_set_channel(local, page, channel); @@ -305,6 +307,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, @@ -514,6 +549,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 5cc3ac8fd4a1..4feb9181ff4f 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; @@ -189,6 +197,11 @@ static inline bool mac802154_scan_is_ongoing(struct ieee802154_local *local) return atomic_read(&local->scanning); } +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 09e2fc6848cb..f342c7c5165e 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 7be63d73caa9..091cf6fdff41 100644 --- a/net/mac802154/scan.c +++ b/net/mac802154/scan.c @@ -17,6 +17,13 @@ #include "driver-ops.h" #include "../ieee802154/nl802154.h" +#define IEEE802154_BEACON_MHR_SZ 13 +#define IEEE802154_BEACON_PL_SZ 4 +#define IEEE802154_CRC_SZ 2 +#define IEEE802154_BEACON_SKB_SZ (IEEE802154_BEACON_MHR_SZ + \ + IEEE802154_BEACON_PL_SZ + \ + IEEE802154_CRC_SZ) + static bool mac802154_check_promiscuous(struct ieee802154_local *local) { struct ieee802154_sub_if_data *sdata; @@ -104,6 +111,86 @@ 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; + + lockdep_assert_held(&local->beacons_lock); + + if (local->ongoing_beacons_request) + return -EBUSY; + + local->ongoing_beacons_request = true; + + 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 = cpu_to_le16(request->wpan_dev->pan_id); + local->beacon.mhr.source.extended_addr = cpu_to_le64(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); + + /* Start the beacon work */ + local->beacons_interval = + mac802154_scan_get_channel_time(request->interval, + request->wpan_phy->symbol_duration); + 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; +} + +static int mac802154_scan_send_beacon_locked(struct ieee802154_local *local, + struct wpan_dev *wpan_dev) +{ + struct sk_buff *skb; + int ret; + + lockdep_assert_held(&local->beacons_lock); + + /* Update the sequence number */ + local->beacon.mhr.seq = atomic_inc_return(&wpan_dev->bsn); + + skb = alloc_skb(IEEE802154_BEACON_SKB_SZ, GFP_KERNEL); + if (!skb) + return -ENOBUFS; + + ret = ieee802154_beacon_push(skb, &local->beacon); + if (ret) { + kfree_skb(skb); + return ret; + } + + return drv_xmit_async(local, skb); +} + void mac802154_scan_work(struct work_struct *work) { struct ieee802154_local *local = @@ -205,6 +292,38 @@ 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; + 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; + + ret = mac802154_scan_send_beacon_locked(local, wpan_dev); + 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_process_beacon(struct ieee802154_local *local, struct sk_buff *skb) { From patchwork Wed Jan 12 17:33:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711685 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D0EC9C433EF for ; Wed, 12 Jan 2022 17:34:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355723AbiALRe3 (ORCPT ); Wed, 12 Jan 2022 12:34:29 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:44151 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355756AbiALReF (ORCPT ); Wed, 12 Jan 2022 12:34:05 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 0BEAB20013; Wed, 12 Jan 2022 17:33:59 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 22/27] net: ieee802154: Trace the registration of new PANs Date: Wed, 12 Jan 2022 18:33:07 +0100 Message-Id: <20220112173312.764660-23-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@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 1ea15ea1b3bd..5afc0aa38a43 100644 --- a/net/ieee802154/pan.c +++ b/net/ieee802154/pan.c @@ -18,6 +18,7 @@ #include "ieee802154.h" #include "core.h" +#include "trace.h" static struct cfg802154_internal_pan * cfg802154_alloc_pan(struct ieee802154_pan_desc *desc) @@ -205,6 +206,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(cfg802154_need_to_expire_pans(rdev))) 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), From patchwork Wed Jan 12 17:33:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711687 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4FCD7C433EF for ; Wed, 12 Jan 2022 17:34:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355760AbiALRea (ORCPT ); Wed, 12 Jan 2022 12:34:30 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:58677 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350095AbiALReF (ORCPT ); Wed, 12 Jan 2022 12:34:05 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 53A692001A; Wed, 12 Jan 2022 17:34:02 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 23/27] net: mac802154: Add support for active scans Date: Wed, 12 Jan 2022 18:33:08 +0100 Message-Id: <20220112173312.764660-24-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Active scan support is based on the current passive scan support, cheered up with beacon requests sent after every channel change. Co-developed-by: David Girault Signed-off-by: David Girault Signed-off-by: Miquel Raynal --- include/net/ieee802154_netdev.h | 14 ++++++++- net/ieee802154/header_ops.c | 25 +++++++++++++++++ net/mac802154/ieee802154_i.h | 1 + net/mac802154/scan.c | 50 +++++++++++++++++++++++++++++++-- 4 files changed, 87 insertions(+), 3 deletions(-) diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index f7716aeec93b..1bf1a4e508a2 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -58,6 +58,11 @@ struct ieee802154_beacon_hdr { #endif } __packed; +struct ieee802154_mac_cmd_pl { + u8 cmd_id; + /* TODO: content depending on the cmd_id */ +} __packed; + struct ieee802154_sechdr { #if defined(__LITTLE_ENDIAN_BITFIELD) u8 level:3, @@ -139,6 +144,11 @@ struct ieee802154_hdr { struct ieee802154_sechdr sec; }; +struct ieee802154_beacon_req_frame { + struct ieee802154_hdr mhr; + struct ieee802154_mac_cmd_pl mac_pl; +}; + struct ieee802154_beacon_frame { struct ieee802154_hdr mhr; struct ieee802154_beacon_hdr mac_pl; @@ -169,7 +179,9 @@ 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 */ +/* pushes a beacon_req or a beacon frame into an skb */ +int ieee802154_beacon_req_push(struct sk_buff *skb, + struct ieee802154_beacon_req_frame *breq); int ieee802154_beacon_push(struct sk_buff *skb, struct ieee802154_beacon_frame *beacon); diff --git a/net/ieee802154/header_ops.c b/net/ieee802154/header_ops.c index bab710aa36f9..c31a9e429a14 100644 --- a/net/ieee802154/header_ops.c +++ b/net/ieee802154/header_ops.c @@ -121,6 +121,31 @@ ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr) } EXPORT_SYMBOL_GPL(ieee802154_hdr_push); +int ieee802154_beacon_req_push(struct sk_buff *skb, + struct ieee802154_beacon_req_frame *breq) +{ + struct ieee802154_mac_cmd_pl *mac_pl = &breq->mac_pl; + struct ieee802154_hdr *mhr = &breq->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)); + + crc = crc_ccitt(0, skb->data, skb->len); + put_unaligned_le16(crc, skb_put(skb, 2)); + + return 0; +} +EXPORT_SYMBOL_GPL(ieee802154_beacon_req_push); + int ieee802154_beacon_push(struct sk_buff *skb, struct ieee802154_beacon_frame *beacon) { diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 4feb9181ff4f..19c840500bd8 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -56,6 +56,7 @@ struct ieee802154_local { struct cfg802154_scan_request __rcu *scan_req; struct ieee802154_sub_if_data __rcu *scan_sdata; struct delayed_work scan_work; + struct ieee802154_beacon_req_frame beacon_req; /* Beacons handling */ bool ongoing_beacons_request; diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c index 091cf6fdff41..a3ff65d5bb7a 100644 --- a/net/mac802154/scan.c +++ b/net/mac802154/scan.c @@ -19,10 +19,15 @@ #define IEEE802154_BEACON_MHR_SZ 13 #define IEEE802154_BEACON_PL_SZ 4 +#define IEEE802154_BEACON_REQ_MHR_SZ 7 +#define IEEE802154_BEACON_REQ_PL_SZ 1 #define IEEE802154_CRC_SZ 2 #define IEEE802154_BEACON_SKB_SZ (IEEE802154_BEACON_MHR_SZ + \ IEEE802154_BEACON_PL_SZ + \ IEEE802154_CRC_SZ) +#define IEEE802154_BEACON_REQ_SKB_SZ (IEEE802154_BEACON_REQ_MHR_SZ + \ + IEEE802154_BEACON_REQ_PL_SZ + \ + IEEE802154_CRC_SZ) static bool mac802154_check_promiscuous(struct ieee802154_local *local) { @@ -167,6 +172,41 @@ int mac802154_stop_beacons_locked(struct ieee802154_local *local) return 0; } +static int mac802154_scan_prepare_beacon_req(struct ieee802154_local *local) +{ + memset(&local->beacon_req, 0, sizeof(local->beacon_req)); + local->beacon_req.mhr.fc.type = IEEE802154_FC_TYPE_MAC_CMD; + local->beacon_req.mhr.fc.dest_addr_mode = IEEE802154_SHORT_ADDRESSING; + local->beacon_req.mhr.fc.version = IEEE802154_2003_STD; + local->beacon_req.mhr.fc.source_addr_mode = IEEE802154_NO_ADDRESSING; + local->beacon_req.mhr.dest.mode = IEEE802154_ADDR_SHORT; + local->beacon_req.mhr.dest.pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); + local->beacon_req.mhr.dest.short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); + local->beacon_req.mac_pl.cmd_id = IEEE802154_CMD_BEACON_REQ; + + return 0; +} + +static int mac802154_scan_send_beacon_req_locked(struct ieee802154_local *local) +{ + struct sk_buff *skb; + int ret; + + lockdep_assert_held(&local->scan_lock); + + skb = alloc_skb(IEEE802154_BEACON_REQ_SKB_SZ, GFP_KERNEL); + if (!skb) + return -ENOBUFS; + + ret = ieee802154_beacon_req_push(skb, &local->beacon_req); + if (ret) { + kfree_skb(skb); + return ret; + } + + return drv_xmit_async(local, skb); +} + static int mac802154_scan_send_beacon_locked(struct ieee802154_local *local, struct wpan_dev *wpan_dev) { @@ -236,6 +276,9 @@ void mac802154_scan_work(struct work_struct *work) ieee802154_set_symbol_duration(local->phy); } while (ret); + if (scan_req->type == NL802154_SCAN_ACTIVE) + mac802154_scan_send_beacon_req_locked(local); + queue_work: scan_duration = mac802154_scan_get_channel_time(scan_req->duration, local->phy->symbol_duration); @@ -262,8 +305,8 @@ int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata, if (mac802154_scan_is_ongoing(local)) return -EBUSY; - /* TODO: support other scanning type */ - if (request->type != NL802154_SCAN_PASSIVE) + if (request->type != NL802154_SCAN_PASSIVE && + request->type != NL802154_SCAN_ACTIVE) return -EOPNOTSUPP; /* Store scanning parameters */ @@ -276,6 +319,9 @@ 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)); + if (request->type == NL802154_SCAN_ACTIVE) + mac802154_scan_prepare_beacon_req(local); + local->scan_channel_idx = -1; atomic_set(&local->scanning, 1); From patchwork Wed Jan 12 17:33:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711689 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7FA55C43219 for ; Wed, 12 Jan 2022 17:34:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355821AbiALRef (ORCPT ); Wed, 12 Jan 2022 12:34:35 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:55579 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355763AbiALReK (ORCPT ); Wed, 12 Jan 2022 12:34:10 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id BEAEF2000A; Wed, 12 Jan 2022 17:34:04 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 24/27] net: mac802154: Add support for processing beacon requests Date: Wed, 12 Jan 2022 18:33:09 +0100 Message-Id: <20220112173312.764660-25-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org When performing an active scan, coordinators emit beacon requests which must be answered by other PANs receiving the request. Answering a beacon request is considered a duty whenever the user performs a "send beacons" command with an interval of 15. As in the softMAC we save the interval in micro-seconds, we use a negative value to discriminate between a passive beacons command and the task to answer received beacon requests. Signed-off-by: Miquel Raynal --- include/net/ieee802154_netdev.h | 4 +++- net/ieee802154/header_ops.c | 13 +++++++++++++ net/mac802154/ieee802154_i.h | 17 ++++++++++++++++- net/mac802154/rx.c | 13 +++++++++++++ net/mac802154/scan.c | 17 +++++++++++++---- 5 files changed, 58 insertions(+), 6 deletions(-) diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index 1bf1a4e508a2..a2dba4442c57 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -179,9 +179,11 @@ 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_req or a beacon frame into an skb */ +/* pushes/pulls a beacon_req or a beacon frame into/from an skb */ int ieee802154_beacon_req_push(struct sk_buff *skb, struct ieee802154_beacon_req_frame *breq); +int ieee802154_beacon_req_pl_pull(struct sk_buff *skb, + struct ieee802154_mac_cmd_pl *mac_pl); int ieee802154_beacon_push(struct sk_buff *skb, struct ieee802154_beacon_frame *beacon); diff --git a/net/ieee802154/header_ops.c b/net/ieee802154/header_ops.c index c31a9e429a14..771dbcf6e0b8 100644 --- a/net/ieee802154/header_ops.c +++ b/net/ieee802154/header_ops.c @@ -314,6 +314,19 @@ ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr) } EXPORT_SYMBOL_GPL(ieee802154_hdr_pull); +int ieee802154_beacon_req_pl_pull(struct sk_buff *skb, + struct ieee802154_mac_cmd_pl *mac_pl) +{ + if (!pskb_may_pull(skb, sizeof(*mac_pl))) + return -EINVAL; + + memcpy(mac_pl, skb->data, sizeof(*mac_pl)); + skb_pull(skb, sizeof(*mac_pl)); + + return 0; +} +EXPORT_SYMBOL_GPL(ieee802154_beacon_req_pl_pull); + int ieee802154_hdr_peek_addrs(const struct sk_buff *skb, struct ieee802154_hdr *hdr) { diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 19c840500bd8..3d79c6ecbdf1 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -61,7 +61,7 @@ struct ieee802154_local { /* Beacons handling */ bool ongoing_beacons_request; struct mutex beacons_lock; - unsigned int beacons_interval; + int beacons_interval; struct delayed_work beacons_work; struct ieee802154_sub_if_data __rcu *beacons_sdata; struct ieee802154_beacon_frame beacon; @@ -136,6 +136,21 @@ ieee802154_sdata_running(struct ieee802154_sub_if_data *sdata) return test_bit(SDATA_STATE_RUNNING, &sdata->state); } +static inline bool ieee802154_frame_is_beacon_req(struct sk_buff *skb) +{ + struct ieee802154_mac_cmd_pl mac_pl; + int ret; + + if (mac_cb(skb)->type != IEEE802154_FC_TYPE_MAC_CMD) + return false; + + ret = ieee802154_beacon_req_pl_pull(skb, &mac_pl); + if (ret) + return false; + + return mac_pl.cmd_id == IEEE802154_CMD_BEACON_REQ; +} + extern struct ieee802154_mlme_ops mac802154_mlme_wpan; void ieee802154_rx(struct ieee802154_local *local, struct sk_buff *skb); diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index f2f3eca9bc20..1aba23d007cf 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -29,6 +29,11 @@ static int ieee802154_deliver_skb(struct sk_buff *skb) return netif_receive_skb(skb); } +static bool mac802154_should_answer_beacon_req(struct ieee802154_local *local) +{ + return local->ongoing_beacons_request && local->beacons_interval < 0; +} + static int ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb, const struct ieee802154_hdr *hdr) @@ -101,6 +106,14 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, } goto fail; case IEEE802154_FC_TYPE_MAC_CMD: + if (ieee802154_frame_is_beacon_req(skb) && + mac802154_should_answer_beacon_req(sdata->local)) { + ieee802154_queue_delayed_work(&sdata->local->hw, + &sdata->local->beacons_work, + 0); + goto success; + } + goto fail; case IEEE802154_FC_TYPE_ACK: goto fail; case IEEE802154_FC_TYPE_DATA: diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c index a3ff65d5bb7a..c9412dfaeb66 100644 --- a/net/mac802154/scan.c +++ b/net/mac802154/scan.c @@ -142,7 +142,8 @@ int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata, local->beacon.mhr.source.pan_id = cpu_to_le16(request->wpan_dev->pan_id); local->beacon.mhr.source.extended_addr = cpu_to_le64(request->wpan_dev->extended_addr); local->beacon.mac_pl.beacon_order = request->interval; - local->beacon.mac_pl.superframe_order = request->interval; + if (request->interval <= IEEE802154_MAX_SCAN_DURATION) + 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; @@ -150,6 +151,11 @@ int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata, rcu_assign_pointer(local->beacons_sdata, sdata); + if (request->interval == IEEE802154_ACTIVE_SCAN_DURATION) { + local->beacons_interval = -1; + return 0; + } + /* Start the beacon work */ local->beacons_interval = mac802154_scan_get_channel_time(request->interval, @@ -167,7 +173,9 @@ int mac802154_stop_beacons_locked(struct ieee802154_local *local) return -ESRCH; local->ongoing_beacons_request = false; - cancel_delayed_work(&local->beacons_work); + + if (local->beacons_interval >= 0) + cancel_delayed_work(&local->beacons_work); return 0; } @@ -363,8 +371,9 @@ void mac802154_beacons_work(struct work_struct *work) pr_err("Error when transmitting beacon (%d)\n", ret); queue_work: - ieee802154_queue_delayed_work(&local->hw, &local->beacons_work, - local->beacons_interval); + if (local->beacons_interval >= 0) + ieee802154_queue_delayed_work(&local->hw, &local->beacons_work, + local->beacons_interval); unlock_mutex: mutex_unlock(&local->beacons_lock); From patchwork Wed Jan 12 17:33:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711688 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 414A2C433FE for ; Wed, 12 Jan 2022 17:34:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355815AbiALRed (ORCPT ); Wed, 12 Jan 2022 12:34:33 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:42287 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349894AbiALReK (ORCPT ); Wed, 12 Jan 2022 12:34:10 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 89A162000C; Wed, 12 Jan 2022 17:34:07 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 25/27] net: mac802154: Inform device drivers about scans Date: Wed, 12 Jan 2022 18:33:10 +0100 Message-Id: <20220112173312.764660-26-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Let's create a couple of driver hooks in order to tell the device drivers that a scan is ongoing, allowing them to eventually apply any needed configuration, or in the worst case to refuse the operation if it is not supported. These hooks are optional and not implementing them does not prevent the scan operation to happen. Returning an error from these implementations will however shut down the scan entirely. Co-developed-by: David Girault Signed-off-by: David Girault Signed-off-by: Miquel Raynal --- include/net/mac802154.h | 12 ++++++++++++ net/mac802154/driver-ops.h | 29 +++++++++++++++++++++++++++++ net/mac802154/scan.c | 7 +++++++ net/mac802154/trace.h | 28 ++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+) diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 19bfbf591ea1..9b852c02db88 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -204,6 +204,15 @@ 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. */ struct ieee802154_ops { struct module *owner; @@ -230,6 +239,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); + void (*exit_scan_mode)(struct ieee802154_hw *hw); }; /** diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h index d23f0db98015..9da2325d8346 100644 --- a/net/mac802154/driver-ops.h +++ b/net/mac802154/driver-ops.h @@ -282,4 +282,33 @@ 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 void drv_exit_scan_mode(struct ieee802154_local *local) +{ + might_sleep(); + + if (!local->ops->enter_scan_mode || !local->ops->exit_scan_mode) + return; + + trace_802154_drv_exit_scan_mode(local); + local->ops->exit_scan_mode(&local->hw); + trace_802154_drv_return_void(local); +} + #endif /* __MAC802154_DRIVER_OPS */ diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c index c9412dfaeb66..a639c53fa3ba 100644 --- a/net/mac802154/scan.c +++ b/net/mac802154/scan.c @@ -103,6 +103,8 @@ int mac802154_abort_scan_locked(struct ieee802154_local *local) cancel_delayed_work(&local->scan_work); + drv_exit_scan_mode(local); + return mac802154_end_of_scan(local); } @@ -327,6 +329,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)); + /* Let the drivers know about the starting scanning operation */ + ret = drv_enter_scan_mode(local, request); + if (ret) + return ret; + if (request->type == NL802154_SCAN_ACTIVE) mac802154_scan_prepare_beacon_req(local); 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 Jan 12 17:33:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711690 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D325CC4321E for ; Wed, 12 Jan 2022 17:34:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343677AbiALRet (ORCPT ); Wed, 12 Jan 2022 12:34:49 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:51829 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355728AbiALReO (ORCPT ); Wed, 12 Jan 2022 12:34:14 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 7163220003; Wed, 12 Jan 2022 17:34:09 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 26/27] net: mac802154: Inform device drivers about beacon operations Date: Wed, 12 Jan 2022 18:33:11 +0100 Message-Id: <20220112173312.764660-27-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Let's create a couple of driver hooks in order to tell the device drivers that beacons are being sent, allowing them to eventually apply any needed configuration, or in the worst case to refuse the operation if it is not supported. These hooks are optional and not implementing them does not prevent the beacons operation to happen. Returning an error from these implementations will however shut down the beacons configuration entirely. Co-developed-by: David Girault Signed-off-by: David Girault Signed-off-by: Miquel Raynal --- include/net/mac802154.h | 14 ++++++++++++++ net/mac802154/driver-ops.h | 29 +++++++++++++++++++++++++++++ net/mac802154/scan.c | 10 ++++++++++ net/mac802154/trace.h | 21 +++++++++++++++++++++ 4 files changed, 74 insertions(+) diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 9b852c02db88..f73b4f4f1025 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -213,6 +213,17 @@ enum ieee802154_hw_flags { * exit_scan_mode * Exits the scan mode and returns to a fully functioning state. * Should only be provided if ->enter_scan_mode() is populated. + * + * enter_beacons_mode + * Enters the beacons mode, the stack will either send beacons at a fixed + * rate or upon request depending on the configuration. + * Can be NULL, if the driver has no internal configuration to do. + * Returns either zero, or negative errno. + * + * exit_beacons_mode + * Exits the beacons mode and returns to a fully functioning state. + * Should only be provided if ->enter_beacons_mode() is populated. + * Returns either zero, or negative errno. */ struct ieee802154_ops { struct module *owner; @@ -242,6 +253,9 @@ struct ieee802154_ops { int (*enter_scan_mode)(struct ieee802154_hw *hw, struct cfg802154_scan_request *request); void (*exit_scan_mode)(struct ieee802154_hw *hw); + int (*enter_beacons_mode)(struct ieee802154_hw *hw, + struct cfg802154_beacons_request *request); + void (*exit_beacons_mode)(struct ieee802154_hw *hw); }; /** diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h index 9da2325d8346..fa874088a284 100644 --- a/net/mac802154/driver-ops.h +++ b/net/mac802154/driver-ops.h @@ -311,4 +311,33 @@ static inline void drv_exit_scan_mode(struct ieee802154_local *local) trace_802154_drv_return_void(local); } +static inline int drv_enter_beacons_mode(struct ieee802154_local *local, + struct cfg802154_beacons_request *request) +{ + int ret; + + might_sleep(); + + if (!local->ops->enter_beacons_mode || !local->ops->exit_beacons_mode) + return 0; + + trace_802154_drv_enter_beacons_mode(local, request); + ret = local->ops->enter_beacons_mode(&local->hw, request); + trace_802154_drv_return_int(local, ret); + + return ret; +} + +static inline void drv_exit_beacons_mode(struct ieee802154_local *local) +{ + might_sleep(); + + if (!local->ops->enter_beacons_mode || !local->ops->exit_beacons_mode) + return; + + trace_802154_drv_exit_beacons_mode(local); + local->ops->exit_beacons_mode(&local->hw); + trace_802154_drv_return_void(local); +} + #endif /* __MAC802154_DRIVER_OPS */ diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c index a639c53fa3ba..bda13448e294 100644 --- a/net/mac802154/scan.c +++ b/net/mac802154/scan.c @@ -122,6 +122,7 @@ int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata, struct cfg802154_beacons_request *request) { struct ieee802154_local *local = sdata->local; + int ret; lockdep_assert_held(&local->beacons_lock); @@ -130,6 +131,13 @@ 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_enter_beacons_mode(local, request); + if (ret) { + local->ongoing_beacons_request = false; + return ret; + } + memset(&local->beacon, 0, sizeof(local->beacon)); local->beacon.mhr.fc.type = IEEE802154_BEACON_FRAME; local->beacon.mhr.fc.security_enabled = 0; @@ -179,6 +187,8 @@ int mac802154_stop_beacons_locked(struct ieee802154_local *local) if (local->beacons_interval >= 0) cancel_delayed_work(&local->beacons_work); + drv_exit_beacons_mode(local); + return 0; } diff --git a/net/mac802154/trace.h b/net/mac802154/trace.h index 9c0a4f07ced1..93519181045a 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_enter_beacons_mode, + 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_exit_beacons_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 Jan 12 17:33:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 12711701 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D6ADC433F5 for ; Wed, 12 Jan 2022 17:36:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355784AbiALRgh (ORCPT ); Wed, 12 Jan 2022 12:36:37 -0500 Received: from relay7-d.mail.gandi.net ([217.70.183.200]:42183 "EHLO relay7-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355771AbiALReO (ORCPT ); Wed, 12 Jan 2022 12:34:14 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 766432000D; Wed, 12 Jan 2022 17:34:11 +0000 (UTC) From: Miquel Raynal To: Alexander Aring , Stefan Schmidt , linux-wpan@vger.kernel.org, "David S. Miller" , Jakub Kicinski , netdev@vger.kernel.org Cc: Michael Hennerich , Harry Morris , Varka Bhadram , Xue Liu , Alan Ott , David Girault , Romuald Despres , Frederic Blain , Nicolas Schodet , Thomas Petazzoni , linux-wireless@vger.kernel.org, Miquel Raynal Subject: [wpan-next v2 27/27] net: ieee802154: ca8210: Refuse most of the scan operations Date: Wed, 12 Jan 2022 18:33:12 +0100 Message-Id: <20220112173312.764660-28-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220112173312.764660-1-miquel.raynal@bootlin.com> References: <20220112173312.764660-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org The Cascada 8210 hardware transceiver is kind of a hardMAC which interfaces with the softMAC and in practice does not support sending anything else than dataframes. This means we cannot send any BEACON_REQ during active scans nor any BEACON in general. Refuse these operations officially so that the user is aware of the limitation. Signed-off-by: Miquel Raynal --- drivers/net/ieee802154/ca8210.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c index d3a9e4fe05f4..49c274280e3c 100644 --- a/drivers/net/ieee802154/ca8210.c +++ b/drivers/net/ieee802154/ca8210.c @@ -2385,6 +2385,25 @@ static int ca8210_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on) return link_to_linux_err(status); } +static int ca8210_enter_scan_mode(struct ieee802154_hw *hw, + struct cfg802154_scan_request *request) +{ + /* This xceiver can only send dataframes */ + if (request->type != NL802154_SCAN_PASSIVE) + return -EOPNOTSUPP; + + return 0; +} + +static int ca8210_enter_beacons_mode(struct ieee802154_hw *hw, + struct cfg802154_beacons_request *request) +{ + /* This xceiver can only send dataframes */ + return -EOPNOTSUPP; +} + +static void ca8210_exit_scan_beacons_mode(struct ieee802154_hw *hw) { } + static const struct ieee802154_ops ca8210_phy_ops = { .start = ca8210_start, .stop = ca8210_stop, @@ -2397,7 +2416,11 @@ static const struct ieee802154_ops ca8210_phy_ops = { .set_cca_ed_level = ca8210_set_cca_ed_level, .set_csma_params = ca8210_set_csma_params, .set_frame_retries = ca8210_set_frame_retries, - .set_promiscuous_mode = ca8210_set_promiscuous_mode + .set_promiscuous_mode = ca8210_set_promiscuous_mode, + .enter_scan_mode = ca8210_enter_scan_mode, + .exit_scan_mode = ca8210_exit_scan_beacons_mode, + .enter_beacons_mode = ca8210_enter_beacons_mode, + .exit_beacons_mode = ca8210_exit_scan_beacons_mode, }; /* Test/EVBME Interface */