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 <[email protected]> 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);
