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: 531774 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: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: 531773 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: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: 531772 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: 531771 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: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: 531770 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: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: 531769 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: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: 531768 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: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: 531767 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: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: 531763 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: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: 531766 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: 531765 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: 531764 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: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: 531758 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 */