Commit d452ef98 authored by Florian Grandel's avatar Florian Grandel Committed by Carles Cufi
Browse files

net: l2: ieee802154: correctly calculate macResponseWaitTime

Calculates macResponseWaitTime and applies it to the association
process.

As the timing calculation re-uses symbol period calculations and other
PHY timing constants previously introduced, these are now shared as
utility functions.

Signed-off-by: default avatarFlorian Grandel <fgrandel@code-for-humans.de>
parent 4edf46d8
Loading
Loading
Loading
Loading
+3 −3
Changes for include/zephyr/net/ieee802154_radio.h: 3 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ extern "C" {
 *       https://github.com/zephyrproject-rtos/zephyr/issues/50336#issuecomment-1251122582.
 *       For now we assume PHYs that current drivers actually implement.
 */
#define IEEE802154_PHY_SYMBOL_PERIOD(is_subg_phy)                                                  \
#define IEEE802154_PHY_SYMBOL_PERIOD_US(is_subg_phy)                                               \
	((is_subg_phy) ? IEEE802154_PHY_SUN_FSK_863MHZ_915MHZ_SYMBOL_PERIOD_US                     \
		       : IEEE802154_PHY_OQPSK_2450MHZ_SYMBOL_PERIOD_US)

@@ -69,8 +69,8 @@ extern "C" {
 *       For now we assume PHYs that current drivers actually implement.
 */
#define IEEE802154_PHY_A_TURNAROUND_TIME(is_subg_phy)                                              \
	((is_subg_phy)                                                                             \
		 ? IEEE802154_PHY_A_TURNAROUND_TIME_1MS(IEEE802154_PHY_SYMBOL_PERIOD(is_subg_phy)) \
	((is_subg_phy) ? IEEE802154_PHY_A_TURNAROUND_TIME_1MS(                                     \
				 IEEE802154_PHY_SYMBOL_PERIOD_US(is_subg_phy))                     \
		       : IEEE802154_PHY_A_TURNAROUND_TIME_DEFAULT)

/* PHY PIB attribute aCcaTime, in PHY symbols, all PHYs except for SUN O-QPSK,
+7 −5
Changes for subsys/net/l2/ieee802154/ieee802154_mgmt.c: 7 added lines, 5 removed lines.
Original line number Diff line number Diff line
@@ -394,15 +394,17 @@ static int ieee802154_associate(uint32_t mgmt_request, struct net_if *iface,
		goto out;
	}

	/* acquire the lock so that the next k_sem_take() blocks */
	/* Acquire the lock so that the next k_sem_take() blocks. */
	k_sem_take(&ctx->scan_ctx_lock, K_FOREVER);

	/* TODO: current timeout is arbitrary,
	 * see section 8.4.3.1, table 8-94, macResponseWaitTime
	/* Wait macResponseWaitTime PHY symbols for the association response, see
	 * ieee802154_handle_mac_command() and section 6.4.1.
	 */
	k_sem_take(&ctx->scan_ctx_lock, K_SECONDS(1));
	k_sem_take(&ctx->scan_ctx_lock, K_USEC(ieee802154_get_response_wait_time_us(iface)));

	/* release the lock */
	/* Release the scan lock in case an association response was not received
	 * within macResponseWaitTime and we got a timeout instead.
	 */
	k_sem_give(&ctx->scan_ctx_lock);

	k_sem_take(&ctx->ctx_lock, K_FOREVER);
+2 −7
Changes for subsys/net/l2/ieee802154/ieee802154_radio_csma_ca.c: 2 added lines, 7 removed lines.
Original line number Diff line number Diff line
@@ -28,14 +28,9 @@ BUILD_ASSERT(CONFIG_NET_L2_IEEE802154_RADIO_CSMA_CA_MIN_BE <=
/* See section 6.2.5.1. */
static inline int unslotted_csma_ca_channel_access(struct net_if *iface)
{
	uint32_t turnaround_time = ieee802154_radio_get_a_turnaround_time(iface);
	uint32_t symbol_period = ieee802154_radio_get_symbol_period_us(iface);
	uint8_t be = CONFIG_NET_L2_IEEE802154_RADIO_CSMA_CA_MIN_BE;
	uint32_t symbol_period, turnaround_time;
	bool is_subg_phy;

	is_subg_phy = ieee802154_radio_get_hw_capabilities(iface) & IEEE802154_HW_SUB_GHZ;
	/* TODO: Move symbol period calculation to radio driver. */
	symbol_period = IEEE802154_PHY_SYMBOL_PERIOD(is_subg_phy);
	turnaround_time = IEEE802154_PHY_A_TURNAROUND_TIME(is_subg_phy);

	for (uint8_t nb = 0U; nb <= CONFIG_NET_L2_IEEE802154_RADIO_CSMA_CA_MAX_BO; nb++) {
		int ret;
+139 −1
Changes for subsys/net/l2/ieee802154/ieee802154_utils.h: 139 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -6,13 +6,20 @@

/**
 * @file
 * @brief IEEE 802.15.4 Management
 * @brief IEEE 802.15.4 internal MAC and PHY Utils
 *
 * All references to the standard in this file cite IEEE 802.15.4-2020.
 */

#ifndef __IEEE802154_UTILS_H__
#define __IEEE802154_UTILS_H__

#include <zephyr/net/ieee802154_radio.h>
#include <zephyr/sys/util_macro.h>

/**
 * PHY utilities
 */

static inline enum ieee802154_hw_caps ieee802154_radio_get_hw_capabilities(struct net_if *iface)
{
@@ -238,6 +245,60 @@ static inline void ieee802154_radio_remove_src_short_addr(struct net_if *iface,
	}
}

/**
 * @brief Calculates the PHY's symbol period in microseconds.
 *
 * @details The PHY's symbol period depends on the interface's current PHY which
 * can be derived from the currently chosen channel page (phyCurrentPage).
 *
 * Examples:
 *  * SUN FSK: see section 19.1, table 19-1
 *  * O-QPSK:  see section 12.3.3
 *  * HRP UWB: derived from the preamble symbol period (T_psym), see section
 *             11.3, table 11-1 and section 15.2.5, table 15-4
 *
 * @note Currently the symbol period can only be calculated for SUN FSK and O-QPSK.
 *
 * @param iface The interface for which the symbol period should be calculated.
 *
 * @returns The symbol period for the given interface in microseconds.
 */
static inline uint32_t ieee802154_radio_get_symbol_period_us(struct net_if *iface)
{
	/* TODO: Move symbol period calculation to radio driver. */

	if (IS_ENABLED(CONFIG_NET_L2_IEEE802154_SUB_GHZ) &&
	    ieee802154_radio_get_hw_capabilities(iface) & IEEE802154_HW_SUB_GHZ) {
		return IEEE802154_PHY_SYMBOL_PERIOD_US(true);
	}

	return IEEE802154_PHY_SYMBOL_PERIOD_US(false);
}

/**
 * @brief Calculates the PHY's turnaround time (see section 11.3, table 11-1,
 * aTurnaroundTime) in PHY symbols.
 *
 * @details The PHY's turnaround time is used to calculate - among other
 * parameters - the TX-to-RX turnaround time (see section 10.2.2) and the
 * RX-to-TX turnaround time (see section 10.2.3).
 *
 * @note Currently the turnaround time can only be calculated for SUN FSK and O-QPSK.
 *
 * @param iface The interface for which the turnaround time should be calculated.
 *
 * @returns The turnaround time for the given interface.
 */
static inline uint32_t ieee802154_radio_get_a_turnaround_time(struct net_if *iface)
{
	if (IS_ENABLED(CONFIG_NET_L2_IEEE802154_SUB_GHZ) &&
	    ieee802154_radio_get_hw_capabilities(iface) & IEEE802154_HW_SUB_GHZ) {
		return IEEE802154_PHY_A_TURNAROUND_TIME(true);
	}

	return IEEE802154_PHY_A_TURNAROUND_TIME(false);
}

static inline bool ieee802154_radio_verify_channel(struct net_if *iface, uint16_t channel)
{
	if (channel == IEEE802154_NO_CHANNEL) {
@@ -264,4 +325,81 @@ static inline bool ieee802154_radio_verify_channel(struct net_if *iface, uint16_
	return true;
}


/**
 * MAC utilities
 *
 * Note: While MAC utilities may refer to PHY utilities,
 *       the inverse is not true.
 */

/**
 * The number of PHY symbols forming a superframe slot when the superframe order
 * is equal to zero, see sections 8.4.2, table 8-93, aBaseSlotDuration and 6.2.1.
 */
#define IEEE802154_MAC_A_BASE_SLOT_DURATION 60U

/**
 * The number of slots contained in any superframe, see section 8.4.2,
 * table 8-93, aNumSuperframeSlots.
 */
#define IEEE802154_MAC_A_NUM_SUPERFRAME_SLOTS 16U

/**
 * The number of PHY symbols forming a superframe when the superframe order is
 * equal to zero, see section 8.4.2, table 8-93, aBaseSuperframeDuration.
 */
#define IEEE802154_MAC_A_BASE_SUPERFRAME_DURATION                                                  \
	(IEEE802154_MAC_A_BASE_SLOT_DURATION * IEEE802154_MAC_A_NUM_SUPERFRAME_SLOTS)

/**
 * @brief Calculates the MAC's superframe duration (see section 8.4.2,
 * table 8-93, aBaseSuperframeDuration) in microseconds.
 *
 * @details The number of symbols forming a superframe when the superframe order
 * is equal to zero.
 *
 * @param iface The interface for which the base superframe duration should be
 *              calculated.
 *
 * @returns The base superframe duration for the given interface in microseconds.
 */
static inline uint32_t ieee802154_get_a_base_superframe_duration(struct net_if *iface)
{
	return IEEE802154_MAC_A_BASE_SUPERFRAME_DURATION *
	       ieee802154_radio_get_symbol_period_us(iface);
}

/**
 * Default macResponseWaitTime in multiples of aBaseSuperframeDuration as
 * defined in section 8.4.3.1, table 8-94.
 */
#define IEEE802154_MAC_RESONSE_WAIT_TIME_DEFAULT 32U

/**
 * @brief Retrieves macResponseWaitTime, see section 8.4.3.1, table 8-94,
 * converted to microseconds.
 *
 * @details The maximum time, in multiples of aBaseSuperframeDuration converted
 * to microseconds, a device shall wait for a response command to be available
 * following a request command.
 *
 * macResponseWaitTime is a network-topology-dependent parameter and may be set
 * to match the specific requirements of the network that a device is operating
 * on.
 *
 * @note Currently this parameter is read-only and uses the specified default of 32.
 *
 * @param iface The interface for which the response wait time should be calculated.
 *
 * @returns The response wait time for the given interface in microseconds.
 */
static inline uint32_t ieee802154_get_response_wait_time_us(struct net_if *iface)
{
	/* TODO: Make this parameter configurable. */
	return IEEE802154_MAC_RESONSE_WAIT_TIME_DEFAULT *
	       ieee802154_get_a_base_superframe_duration(iface);
}


#endif /* __IEEE802154_UTILS_H__ */