Bluetooth: Controller: Fix Data Length Update node Rx reservations

Reserve a minimum node rx of 2 that can happen when local
central initiated PHY Update reserves 2 node rx, one for PHY
Update complete and another for Data Length Update complete
notification. Otherwise, a peripheral only needs 1
additional node rx to generate Data Length Update complete
when PHY Update completes.

Relates to #36381.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2021-06-24 15:17:50 +05:30 committed by Anas Nashif
commit d3c27aeb8f
2 changed files with 40 additions and 12 deletions

View file

@ -323,11 +323,20 @@ static struct {
* Increasing this by times the max. simultaneous connection count will permit * Increasing this by times the max. simultaneous connection count will permit
* simultaneous parallel PHY update or Connection Update procedures amongst * simultaneous parallel PHY update or Connection Update procedures amongst
* active connections. * active connections.
* Minimum node rx of 2 that can be reserved happens when local central
* initiated PHY Update reserves 2 node rx, one for PHY update complete and
* another for Data Length Update complete notification. Otherwise, a
* peripheral only needs 1 additional node rx to generate Data Length Update
* complete when PHY Update completes; node rx for PHY update complete is
* reserved as the received PHY Update Ind PDU.
*/ */
#if defined(CONFIG_BT_CTLR_PHY) && defined(CONFIG_BT_CTLR_DATA_LENGTH) #if defined(CONFIG_BT_CENTRAL) && defined(CONFIG_BT_CTLR_PHY) && \
#define LL_PDU_RX_CNT 3 defined(CONFIG_BT_CTLR_DATA_LENGTH)
#define LL_PDU_RX_CNT (2 * (CONFIG_BT_CTLR_LLCP_CONN))
#elif defined(CONFIG_BT_CONN)
#define LL_PDU_RX_CNT (CONFIG_BT_CTLR_LLCP_CONN)
#else #else
#define LL_PDU_RX_CNT 2 #define LL_PDU_RX_CNT 0
#endif #endif
/* No. of node rx for LLL to ULL. /* No. of node rx for LLL to ULL.

View file

@ -4086,6 +4086,21 @@ static inline void event_phy_upd_ind_prep(struct ll_conn *conn,
struct node_rx_pdu *rx; struct node_rx_pdu *rx;
uint8_t old_tx, old_rx; uint8_t old_tx, old_rx;
/* Acquire additional rx node for Data length notification as
* a peripheral.
*/
if (IS_ENABLED(CONFIG_BT_PERIPHERAL) &&
IS_ENABLED(CONFIG_BT_CTLR_DATA_LENGTH) &&
conn->lll.role) {
rx = ll_pdu_rx_alloc();
if (!rx) {
return;
}
rx->hdr.link->mem = conn->llcp_rx;
conn->llcp_rx = rx;
}
#if defined(CONFIG_BT_PERIPHERAL) && defined(CONFIG_BT_CTLR_LE_ENC) #if defined(CONFIG_BT_PERIPHERAL) && defined(CONFIG_BT_CTLR_LE_ENC)
if (conn->lll.role && (conn->slave.llcp_type != LLCP_NONE)) { if (conn->lll.role && (conn->slave.llcp_type != LLCP_NONE)) {
/* Local peripheral initiated PHY update completed while /* Local peripheral initiated PHY update completed while
@ -5496,23 +5511,27 @@ static inline uint8_t phy_upd_ind_recv(struct ll_conn *conn, memq_link_t *link,
conn->llcp.phy_upd_ind.instant = instant; conn->llcp.phy_upd_ind.instant = instant;
conn->llcp.phy_upd_ind.initiate = 0U; conn->llcp.phy_upd_ind.initiate = 0U;
/* Reserve the Rx-ed PHY Update Indication PDU in the connection
* context, by appending to the LLCP node rx list. We do not mark it
* for release in ULL, i.e., by returning *rx as NULL.
* PHY Update notification to HCI layer will use node rx from this
* list when at the instant.
* If data length update is supported in the Controller, then, at the
* instant we attempt to acquire an additional free node rx for Data
* Length Update notification.
*/
link->mem = conn->llcp_rx; link->mem = conn->llcp_rx;
(*rx)->hdr.link = link; (*rx)->hdr.link = link;
conn->llcp_rx = *rx; conn->llcp_rx = *rx;
*rx = NULL; *rx = NULL;
#if defined(CONFIG_BT_CTLR_DATA_LENGTH) /* Transition to PHY Update Ind received state and wait for the
/* reserve rx node for DLE event generation */ * instant.
struct node_rx_pdu *rx_dle = ll_pdu_rx_alloc(); */
LL_ASSERT(rx_dle);
rx_dle->hdr.link->mem = conn->llcp_rx;
conn->llcp_rx = rx_dle;
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
conn->llcp_type = LLCP_PHY_UPD; conn->llcp_type = LLCP_PHY_UPD;
conn->llcp_ack -= 2U; conn->llcp_ack -= 2U;
/* Enforce packet timing restrictions until the instant */
if (conn->llcp.phy_upd_ind.tx) { if (conn->llcp.phy_upd_ind.tx) {
conn->lll.phy_tx_time = conn->llcp.phy_upd_ind.tx; conn->lll.phy_tx_time = conn->llcp.phy_upd_ind.tx;
} }