You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by an...@apache.org on 2022/02/12 11:13:01 UTC
[mynewt-nimble] 02/02: nimble/phy/cmac: Fix race on rx-tx
This is an automated email from the ASF dual-hosted git repository.
andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
commit dbed9d46d551847f7580c22a1e56f088dfb47941
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Wed Feb 2 10:49:17 2022 +0100
nimble/phy/cmac: Fix race on rx-tx
On rx-tx transition we disable Frame and Field interrupts so they do
not mess up tx setup process - they are reenabled in ble_phy_tx.
However, after recent optimizations we are sometimes too fast and
ble_phy_tx can be called before interrupts are disabled. This means
there's nothing to enable interrupts again and this will trigger a
CMAC error since we are not processing interrupts on time.
To fix this we add flag to check whether ble_phy_tx already finished
setup so there's no need to disable interrupts on transition.
---
nimble/drivers/dialog_cmac/src/ble_phy.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c
index e36a31c..9c9d878 100644
--- a/nimble/drivers/dialog_cmac/src/ble_phy.c
+++ b/nimble/drivers/dialog_cmac/src/ble_phy.c
@@ -262,6 +262,7 @@ struct ble_phy_data {
struct ble_mbuf_hdr rxhdr;
ble_phy_tx_end_func txend_cb;
void *txend_arg;
+ uint8_t phy_tx_set;
};
static struct ble_phy_data g_ble_phy_data;
@@ -647,6 +648,8 @@ ble_phy_irq_frame_tx_exc_bs_stop(void)
CMAC_CM_EV_LINKUP_REG_LU_FRAME_START_2_NONE_Msk;
}
+ g_ble_phy_data.phy_tx_set = 0;
+
if (g_ble_phy_data.txend_cb) {
ble_phy_sw_mac_handover(SW_MAC_EXC_TXEND_CB);
return;
@@ -897,13 +900,16 @@ ble_phy_irq_frame_rx_exc_phy_to_idle_4this(void)
#endif
rf_chan = g_ble_phy_chan_to_rf[g_ble_phy_data.channel];
ble_rf_setup_tx(rf_chan, g_ble_phy_data.phy_mode_tx);
+
g_ble_phy_data.phy_state = BLE_PHY_STATE_TX;
/* We do not want FIELD/FRAME interrupts until ble_phy_tx() has pushed all
* fields.
*/
- NVIC_DisableIRQ(FRAME_IRQn);
- NVIC_DisableIRQ(FIELD_IRQn);
+ if (!g_ble_phy_data.phy_tx_set) {
+ NVIC_DisableIRQ(FRAME_IRQn);
+ NVIC_DisableIRQ(FIELD_IRQn);
+ }
}
static void
@@ -1278,6 +1284,7 @@ ble_phy_disable(void)
NVIC_EnableIRQ(FIELD_IRQn);
g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE;
+ g_ble_phy_data.phy_tx_set = 0;
}
static void
@@ -1460,6 +1467,8 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans)
rc = BLE_ERR_SUCCESS;
}
+ g_ble_phy_data.phy_tx_set = 1;
+
/* Now we can handle BS_CTRL */
NVIC_EnableIRQ(FRAME_IRQn);
NVIC_EnableIRQ(FIELD_IRQn);