Bluetooth: controller: llcp: serialize phy update notifications

The PHY update procedure may trigger a DLE update in certain
situations
When a limited number of rx buffers is available there may not be
enough for doing the phy update and dle update notifications
at once.

Fixes #41788

Signed-off-by: Andries Kruithof <Andries.Kruithof@nordicsemi.no>
This commit is contained in:
Andries Kruithof 2022-02-03 08:52:11 +01:00 committed by Carles Cufí
commit b909647d0a
4 changed files with 52 additions and 4 deletions

View file

@ -260,10 +260,10 @@ static uint8_t pu_update_eff_times(struct ll_conn *conn, struct proc_ctx *ctx)
(eff_rx_time != lll->dle.eff.max_rx_time)) {
lll->dle.eff.max_tx_time = eff_tx_time;
lll->dle.eff.max_rx_time = eff_rx_time;
return 1;
return 1U;
}
return 0;
return 0U;
}
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
@ -366,6 +366,7 @@ static void pu_ntf(struct ll_conn *conn, struct proc_ctx *ctx)
/* Enqueue notification towards LL */
ll_rx_put(ntf->hdr.link, ntf);
ll_rx_sched();
ctx->data.pu.ntf_pu = 0;
}
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
@ -397,17 +398,33 @@ static void lp_pu_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t e
#else
#define NTF_DLE 0
#endif
const uint8_t ntf_count = ctx->data.pu.ntf_pu + NTF_DLE;
uint8_t ntf_count = ctx->data.pu.ntf_pu + NTF_DLE;
/* when complete reset timing restrictions - idempotent
* (so no problem if we need to wait for NTF buffer)
*/
pu_reset_timing_restrict(conn);
/* if we need to send both PHY and DLE notification, but we
* do not have 2 buffers available we serialize the sending
* of notifications
*/
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
if ((ntf_count > 1) && !llcp_ntf_alloc_num_available(ntf_count)) {
ntf_count = 1;
}
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
if (ntf_count && !llcp_ntf_alloc_num_available(ntf_count)) {
ctx->state = LP_PU_STATE_WAIT_NTF;
} else {
if (ctx->data.pu.ntf_pu) {
pu_ntf(conn, ctx);
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
if (ntf_count == 1 && NTF_DLE == 1) {
ctx->state = LP_PU_STATE_WAIT_NTF;
return;
}
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
}
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
if (ctx->data.pu.ntf_dle) {
@ -796,17 +813,32 @@ static void rp_pu_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t e
#else
#define NTF_DLE 0
#endif
const uint8_t ntf_count = ctx->data.pu.ntf_pu + NTF_DLE;
uint8_t ntf_count = ctx->data.pu.ntf_pu + NTF_DLE;
/* when complete reset timing restrictions - idempotent
* (so no problem if we need to wait for NTF buffer)
*/
pu_reset_timing_restrict(conn);
/* if we need to send both PHY and DLE notification, but we
* do not have 2 buffers available we serialize the sending
* of notifications
*/
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
if ((ntf_count > 1) && !llcp_ntf_alloc_num_available(ntf_count)) {
ntf_count = 1;
}
#endif /* CONFIG_BT_CTLR_DATA_LENGTH) */
if ((ntf_count > 0) && !llcp_ntf_alloc_num_available(ntf_count)) {
ctx->state = RP_PU_STATE_WAIT_NTF;
} else {
if (ctx->data.pu.ntf_pu) {
pu_ntf(conn, ctx);
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
if (ntf_count == 1 && NTF_DLE == 1) {
ctx->state = RP_PU_STATE_WAIT_NTF;
return;
}
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
}
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
if (ctx->data.pu.ntf_dle) {

View file

@ -0,0 +1,11 @@
/*
* Copyright (c) 2021 Demant
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef CONFIG_BT_CTLR_LLCP_CONN
#undef CONFIG_BT_CTLR_LLCP_CONN
#define CONFIG_BT_CTLR_LLCP_CONN 2
#endif

View file

@ -3,3 +3,6 @@ common:
tests:
bluetooth.controller.ctrl_phy_update.test:
type: unit
bluetooth.controller.ctrl_phy_update.test_reduced_buf:
type: unit
extra_args: KCONFIG_OVERRIDE_FILE="kconfig_override_rx_cnt.h"

View file

@ -79,7 +79,9 @@
#define CONFIG_BT_CTLR_XTAL_ADVANCED y
#endif
#ifndef CONFIG_BT_CTLR_LLCP_CONN
#define CONFIG_BT_CTLR_LLCP_CONN 4
#endif
#ifndef CONFIG_BT_CTLR_LLCP_TX_PER_CONN_TX_CTRL_BUF_NUM_MAX
#define CONFIG_BT_CTLR_LLCP_TX_PER_CONN_TX_CTRL_BUF_NUM_MAX (4)