From 270266987308a0736af115b1874fbcd5788e74f8 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Wed, 16 Oct 2024 11:08:41 +0200 Subject: [PATCH 1/3] drivers: ieee802154: add Kconfig IEEE802154_SELECTIVE_TXCHANNEL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Kconfig `IEEE802154_SELECTIVE_TXCHANNEL` is added along with the new capability `IEEE802154_HW_SELECTIVE_TXCHANNEL`. The new capability of the ieee802154 drivers allows to schedule CSL transmissions as stated in IEEE 802.15.4-2020 chapter 6.12.2.7 CSL over multiple channels. The benefit of the new API is that additional call to `ieee802154_radio_api::set_channel()` is not required. The drivers will switch to the new channel as late as possible for CSL transmissions thus will not interrupt any reception that might be in progress until the very late moment when the transmission actually starts. This improves reception performance when CSL transmissions are used. Signed-off-by: Damian Krolik Signed-off-by: Andrzej Kuroś --- drivers/ieee802154/Kconfig | 8 +++++ include/zephyr/net/ieee802154_pkt.h | 22 ++++++++++++ include/zephyr/net/ieee802154_radio.h | 36 ++++++++++++++++++- .../zephyr/net/ieee802154_radio_openthread.h | 3 ++ 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig index 916cc1a9ddba3..a4e4e6d307dbe 100644 --- a/drivers/ieee802154/Kconfig +++ b/drivers/ieee802154/Kconfig @@ -92,6 +92,14 @@ config IEEE802154_CSL_DEBUG help Enable support for CSL debugging by avoiding sleep state in favor of receive state. +config IEEE802154_SELECTIVE_TXCHANNEL + bool "Support for selective TX channel setting" + help + Enable support for selectively setting TX channel for every timed transmission request. + The drivers MAY have the capability IEEE802154_HW_SELECTIVE_TXCHANNEL only if + this Kconfig option is enabled. If the Kconfig option is disabled the drivers + MUST NOT have the capability. + module = IEEE802154_DRIVER module-str = IEEE 802.15.4 driver module-help = Sets log level for IEEE 802.15.4 Device Drivers. diff --git a/include/zephyr/net/ieee802154_pkt.h b/include/zephyr/net/ieee802154_pkt.h index 3270f9942483d..b51db139c60b4 100644 --- a/include/zephyr/net/ieee802154_pkt.h +++ b/include/zephyr/net/ieee802154_pkt.h @@ -59,6 +59,16 @@ struct net_pkt_cb_ieee802154 { */ uint8_t rssi; }; + struct { +#if defined(CONFIG_IEEE802154_SELECTIVE_TXCHANNEL) + /* The channel used for timed transmissions. + * + * Please refer to `ieee802154_radio_api::tx` documentation for + * details. + */ + uint8_t txchannel; +#endif /* CONFIG_IEEE802154_SELECTIVE_TXCHANNEL */ + }; }; /* Flags */ @@ -179,6 +189,18 @@ static inline void net_pkt_set_ieee802154_rssi_dbm(struct net_pkt *pkt, int16_t CODE_UNREACHABLE; } +#if defined(CONFIG_IEEE802154_SELECTIVE_TXCHANNEL) +static inline uint8_t net_pkt_ieee802154_txchannel(struct net_pkt *pkt) +{ + return net_pkt_cb_ieee802154(pkt)->txchannel; +} + +static inline void net_pkt_set_ieee802154_txchannel(struct net_pkt *pkt, uint8_t channel) +{ + net_pkt_cb_ieee802154(pkt)->txchannel = channel; +} +#endif /* CONFIG_IEEE802154_SELECTIVE_TXCHANNEL */ + static inline bool net_pkt_ieee802154_ack_fpb(struct net_pkt *pkt) { return net_pkt_cb_ieee802154(pkt)->ack_fpb; diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index 10a1922f6fa87..f9a557beba0db 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -520,13 +520,26 @@ enum ieee802154_hw_caps { /** RxOnWhenIdle handling supported */ IEEE802154_RX_ON_WHEN_IDLE = BIT(12), + /** Support for timed transmissions on selective channel. + * + * This capability informs that transmissions with modes + * @ref IEEE802154_TX_MODE_TXTIME and @ref IEEE802154_TX_MODE_TXTIME_CCA support + * scheduling of timed transmissions on selective tx channel. + * The driver MAY have this capability only if the Kconfig option + * `CONFIG_IEEE802154_SELECTIVE_TXCHANNEL` is set, otherwise the driver MUST + * NOT have this capability. + * + * Please refer to the `ieee802154_radio_api::tx` documentation for details. + */ + IEEE802154_HW_SELECTIVE_TXCHANNEL = BIT(13), + /* Note: Update also IEEE802154_HW_CAPS_BITS_COMMON_COUNT when changing * the ieee802154_hw_caps type. */ }; /** @brief Number of bits used by ieee802154_hw_caps type. */ -#define IEEE802154_HW_CAPS_BITS_COMMON_COUNT (13) +#define IEEE802154_HW_CAPS_BITS_COMMON_COUNT (14) /** @brief This and higher values are specific to the protocol- or driver-specific extensions. */ #define IEEE802154_HW_CAPS_BITS_PRIV_START IEEE802154_HW_CAPS_BITS_COMMON_COUNT @@ -625,6 +638,8 @@ enum ieee802154_tx_mode { * Transmit packet in the future, at the specified time, no CCA. * * @note requires IEEE802154_HW_TXTIME capability. + * + * @note capability IEEE802154_HW_SELECTIVE_TXCHANNEL may apply. */ IEEE802154_TX_MODE_TXTIME, @@ -635,6 +650,8 @@ enum ieee802154_tx_mode { * * @note Required for Thread 1.2 Coordinated Sampled Listening feature * (see Thread specification 1.2.0, ch. 3.2.6.3). + * + * @note capability IEEE802154_HW_SELECTIVE_TXCHANNEL may apply. */ IEEE802154_TX_MODE_TXTIME_CCA, @@ -1657,6 +1674,23 @@ struct ieee802154_radio_api { * considerable idle waiting time. SHALL return `-ENETDOWN` unless the * interface is "UP". * + * @note The transmission occurs on the radio channel set by the call to + * `set_channel()`. However, if the `CONFIG_IEEE802154_SELECTIVE_TXCHANNEL` + * is set and the driver has the capability `IEEE802154_HW_SELECTIVE_TXCHANNEL` + * then the transmissions requested with `mode` IEEE802154_TX_MODE_TXTIME + * or `IEEE802154_TX_MODE_TXTIME_CCA` SHALL use the radio channel + * returned by `net_pkt_ieee802154_txchannel()` to transmit the packet + * and receive an ACK on that channel if the frame requested it. After + * the operation the driver should return to the channel set previously by + * `set_channel()` call. + * It is responsibility of an upper layer to set the required radio channel + * for the packet by a call to `net_pkt_set_ieee802154_txchannel()`. + * This feature allows CSL transmissions as stated in IEEE 802.15.4-2020 + * chapter 6.12.2.7 CSL over multiple channels. This feature allows to perform + * a switch of the radio channel as late as possible before transmission without + * interrupting possible reception that could occur if separate `set_channel()` + * was called. + * * @param dev pointer to IEEE 802.15.4 driver device * @param mode the transmission mode, some of which require specific * offloading capabilities. diff --git a/include/zephyr/net/ieee802154_radio_openthread.h b/include/zephyr/net/ieee802154_radio_openthread.h index e45bbc6b85b4c..3606c7a2b78be 100644 --- a/include/zephyr/net/ieee802154_radio_openthread.h +++ b/include/zephyr/net/ieee802154_radio_openthread.h @@ -64,6 +64,9 @@ enum ieee802154_openthread_tx_mode { * section 11.3, table 11-2). * * Requires IEEE802154_OPENTHREAD_HW_MULTIPLE_CCA capability. + * + * @note Capability @ref IEEE802154_HW_SELECTIVE_TXCHANNEL applies as for + * @ref IEEE802154_TX_MODE_TXTIME_CCA. */ IEEE802154_OPENTHREAD_TX_MODE_TXTIME_MULTIPLE_CCA = IEEE802154_TX_MODE_PRIV_START }; From aee48034374f76cd97e4b90a8cdbe437b3b7c559 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Wed, 16 Oct 2024 11:38:40 +0200 Subject: [PATCH 2/3] drivers: ieee802154_nrf5: support IEEE802154_SELECTIVE_TXCHANNEL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ieee802154_nrf5 supports the IEEE802154_SELECTIVE_TXCHANNEL Kconfig option and advertises the IEEE802154_HW_SELECTIVE_TXCHANNEL capability. The ieee802154_nrf5 driver now allows to schedule timed transmission requests with selective tx channel, that is set at the latest possible moment. This improves reception performance when the timed transmissions are requested. Signed-off-by: Damian Krolik Signed-off-by: Andrzej Kuroś --- drivers/ieee802154/ieee802154_nrf5.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 613c913868bfd..8b9c9368e6df7 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -255,6 +255,9 @@ static void nrf5_get_capabilities_at_boot(void) ((caps & NRF_802154_CAPABILITY_SECURITY) ? IEEE802154_HW_TX_SEC : 0UL) #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) | IEEE802154_OPENTHREAD_HW_MULTIPLE_CCA +#endif +#if defined(CONFIG_IEEE802154_SELECTIVE_TXCHANNEL) + | IEEE802154_HW_SELECTIVE_TXCHANNEL #endif ; } @@ -540,7 +543,11 @@ static bool nrf5_tx_at(struct nrf5_802154_data *nrf5_radio, struct net_pkt *pkt, .dynamic_data_is_set = net_pkt_ieee802154_mac_hdr_rdy(pkt), }, .cca = cca, +#if defined(CONFIG_IEEE802154_SELECTIVE_TXCHANNEL) + .channel = net_pkt_ieee802154_txchannel(pkt), +#else .channel = nrf_802154_channel_get(), +#endif .tx_power = { .use_metadata_value = true, .power = nrf5_data.txpwr, From 2ea27d9d59892a9235b86cab64b587fbb3da2684 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Wed, 16 Oct 2024 12:28:52 +0200 Subject: [PATCH 3/3] net: openthread: support Kconfig IEEE802154_SELECTIVE_TXCHANNEL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For transmit_message if the transmission is timed and underlying driver supports `IEEE802154_HW_SELECTIVE_TXCHANNEL` then use the selective txchannel feature for transmission. This does not change the current `channel` at the moment of call, the driver will transmit the message on the channel selected through `net_pkt_set_ieee802154_txchannel` then (after receiving an ACK if requested) it will return to the original channel. When Kconfig option IEEE802154_SELECTIVE_TXCHANNEL is turned on, the timed transmissions scheduled some time ahead on different channel will not abort ongoing reception until the exact moment of transmission comes. Signed-off-by: Andrzej Kuroś --- modules/openthread/platform/radio.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 7e2943e734f80..4f9a52de20d2f 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -379,12 +379,20 @@ void platformRadioInit(void) radio_api->configure(radio_dev, IEEE802154_CONFIG_EVENT_HANDLER, &cfg); } +static void radio_set_channel(uint16_t ch) +{ + channel = ch; + radio_api->set_channel(radio_dev, ch); +} + void transmit_message(struct k_work *tx_job) { int tx_err; ARG_UNUSED(tx_job); + enum ieee802154_hw_caps radio_caps = radio_api->get_capabilities(radio_dev); + /* * The payload is already in tx_payload->data, * but we need to set the length field @@ -394,10 +402,7 @@ void transmit_message(struct k_work *tx_job) */ tx_payload->len = sTransmitFrame.mLength - FCS_SIZE; - channel = sTransmitFrame.mChannel; - - radio_api->set_channel(radio_dev, channel); - radio_api->set_txpower(radio_dev, get_transmit_power_for_channel(channel)); + radio_api->set_txpower(radio_dev, get_transmit_power_for_channel(sTransmitFrame.mChannel)); #if defined(CONFIG_OPENTHREAD_TIME_SYNC) if (sTransmitFrame.mInfo.mTxInfo.mIeInfo->mTimeIeOffset != 0) { @@ -415,17 +420,27 @@ void transmit_message(struct k_work *tx_job) sTransmitFrame.mInfo.mTxInfo.mIsSecurityProcessed); net_pkt_set_ieee802154_mac_hdr_rdy(tx_pkt, sTransmitFrame.mInfo.mTxInfo.mIsHeaderUpdated); - if ((radio_api->get_capabilities(radio_dev) & IEEE802154_HW_TXTIME) && + if ((radio_caps & IEEE802154_HW_TXTIME) && (sTransmitFrame.mInfo.mTxInfo.mTxDelay != 0)) { #if defined(CONFIG_NET_PKT_TXTIME) uint32_t tx_at = sTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime + sTransmitFrame.mInfo.mTxInfo.mTxDelay; net_pkt_set_timestamp_ns(tx_pkt, convert_32bit_us_wrapped_to_64bit_ns(tx_at)); +#endif +#if defined(CONFIG_IEEE802154_SELECTIVE_TXCHANNEL) + if (radio_caps & IEEE802154_HW_SELECTIVE_TXCHANNEL) { + net_pkt_set_ieee802154_txchannel(tx_pkt, sTransmitFrame.mChannel); + } else { + radio_set_channel(sTransmitFrame.mChannel); + } +#else + radio_set_channel(sTransmitFrame.mChannel); #endif tx_err = radio_api->tx(radio_dev, IEEE802154_TX_MODE_TXTIME_CCA, tx_pkt, tx_payload); } else if (sTransmitFrame.mInfo.mTxInfo.mCsmaCaEnabled) { - if (radio_api->get_capabilities(radio_dev) & IEEE802154_HW_CSMA) { + radio_set_channel(sTransmitFrame.mChannel); + if (radio_caps & IEEE802154_HW_CSMA) { tx_err = radio_api->tx(radio_dev, IEEE802154_TX_MODE_CSMA_CA, tx_pkt, tx_payload); } else { @@ -436,6 +451,7 @@ void transmit_message(struct k_work *tx_job) } } } else { + radio_set_channel(sTransmitFrame.mChannel); tx_err = radio_api->tx(radio_dev, IEEE802154_TX_MODE_DIRECT, tx_pkt, tx_payload); }