From 3724f460517a71e67cf759bdc9ea34c7fd4467d5 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Thu, 6 Jul 2023 18:24:29 +0200 Subject: [PATCH] net: l2: ieee802154: simplify/fix ACK procedure Removes redundant ACK state from `struct ieee802154_context` and simplifies the ACK procedure. Signed-off-by: Florian Grandel --- include/zephyr/net/ieee802154.h | 3 +-- subsys/net/l2/ieee802154/ieee802154.c | 24 ++++++++++++--------- subsys/net/l2/ieee802154/ieee802154_frame.c | 4 ++-- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/include/zephyr/net/ieee802154.h b/include/zephyr/net/ieee802154.h index 93766f212b195db..e69179863e1ee72 100644 --- a/include/zephyr/net/ieee802154.h +++ b/include/zephyr/net/ieee802154.h @@ -156,9 +156,8 @@ struct ieee802154_context { */ uint8_t sequence; - uint8_t _unused : 6; + uint8_t _unused : 7; - uint8_t ack_received : 1; /* guarded by ack_lock */ uint8_t ack_requested : 1; /* guarded by ack_lock */ uint8_t ack_seq; /* guarded by ack_lock */ struct k_sem ack_lock; diff --git a/subsys/net/l2/ieee802154/ieee802154.c b/subsys/net/l2/ieee802154/ieee802154.c index 50e11fb479fbccd..543c4a4d43bc7a6 100644 --- a/subsys/net/l2/ieee802154/ieee802154.c +++ b/subsys/net/l2/ieee802154/ieee802154.c @@ -110,8 +110,9 @@ inline bool ieee802154_prepare_for_ack(struct net_if *iface, struct net_pkt *pkt struct ieee802154_context *ctx = net_if_l2_data(iface); ctx->ack_seq = fs->sequence; - ctx->ack_received = false; - k_sem_init(&ctx->ack_lock, 0, K_SEM_MAX_LIMIT); + if (k_sem_count_get(&ctx->ack_lock) == 1U) { + k_sem_take(&ctx->ack_lock, K_NO_WAIT); + } return true; } @@ -139,7 +140,6 @@ enum net_verdict ieee802154_handle_ack(struct net_if *iface, struct net_pkt *pkt return NET_CONTINUE; } - ctx->ack_received = true; k_sem_give(&ctx->ack_lock); /* TODO: Release packet in L2 as we're taking ownership. */ @@ -152,6 +152,7 @@ enum net_verdict ieee802154_handle_ack(struct net_if *iface, struct net_pkt *pkt inline int ieee802154_wait_for_ack(struct net_if *iface, bool ack_required) { struct ieee802154_context *ctx = net_if_l2_data(iface); + int ret; if (!ack_required || (ieee802154_radio_get_hw_capabilities(iface) & IEEE802154_HW_TX_RX_ACK)) { @@ -159,16 +160,18 @@ inline int ieee802154_wait_for_ack(struct net_if *iface, bool ack_required) return 0; } - if (k_sem_take(&ctx->ack_lock, K_MSEC(10)) == 0) { - /* We reinit the semaphore in case ieee802154_handle_ack() - * got called multiple times. - */ - k_sem_init(&ctx->ack_lock, 0, K_SEM_MAX_LIMIT); + ret = k_sem_take(&ctx->ack_lock, K_MSEC(10)); + if (ret == 0) { + /* no-op */ + } else if (ret == -EAGAIN) { + ret = -ETIME; + } else { + NET_ERR("Error while waiting for ACK."); + ret = -EFAULT; } ctx->ack_seq = 0U; - - return ctx->ack_received ? 0 : -ETIME; + return ret; } int ieee802154_radio_send(struct net_if *iface, struct net_pkt *pkt, struct net_buf *frag) @@ -619,6 +622,7 @@ void ieee802154_init(struct net_if *iface) NET_DBG("Initializing IEEE 802.15.4 stack on iface %p", iface); k_sem_init(&ctx->ctx_lock, 1, 1); + k_sem_init(&ctx->ack_lock, 0, 1); /* no need to lock the context here as it has * not been published yet. diff --git a/subsys/net/l2/ieee802154/ieee802154_frame.c b/subsys/net/l2/ieee802154/ieee802154_frame.c index 36ba972ae05ee5e..5b203fa28bd6633 100644 --- a/subsys/net/l2/ieee802154/ieee802154_frame.c +++ b/subsys/net/l2/ieee802154/ieee802154_frame.c @@ -914,8 +914,8 @@ bool ieee802154_create_ack_frame(struct net_if *iface, struct net_pkt *pkt, uint fs = generate_fcf_grounds(&p_buf, false); - fs->fc.dst_addr_mode = 0U; - fs->fc.src_addr_mode = 0U; + fs->fc.dst_addr_mode = IEEE802154_ADDR_MODE_NONE; + fs->fc.src_addr_mode = IEEE802154_ADDR_MODE_NONE; fs->fc.frame_type = IEEE802154_FRAME_TYPE_ACK; fs->sequence = seq;