diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c index 5b4a6194c15..46c32e7ae9e 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_cc.c @@ -190,9 +190,9 @@ static void llcp_rp_cc_tx_reject(struct ll_conn *conn, struct proc_ctx *ctx, uin struct pdu_data *pdu; /* Allocate tx node */ - tx = ctx->node_ref.tx_ack; + tx = ctx->node_ref.tx; LL_ASSERT(tx); - ctx->node_ref.tx_ack = NULL; + ctx->node_ref.tx = NULL; pdu = (struct pdu_data *)tx->pdu; @@ -252,7 +252,7 @@ static void rp_cc_send_reject_ind(struct ll_conn *conn, struct proc_ctx *ctx, ui ctx->state = RP_CC_STATE_WAIT_TX_REJECT_IND; } else { /* Allocate TX node to use, store in case we need to wait for NTF node */ - ctx->node_ref.tx_ack = llcp_tx_alloc(conn, ctx); + ctx->node_ref.tx = llcp_tx_alloc(conn, ctx); if (ctx->data.cis_create.error == BT_HCI_ERR_CONN_ACCEPT_TIMEOUT) { /* We complete with error, so we must generate NTF, thus we must make sure * we have a node to use for NTF before TX'ing diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_common.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_common.c index 2a3cd99b159..ff72f45b23f 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_common.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_common.c @@ -150,11 +150,6 @@ static void lp_comm_tx(struct ll_conn *conn, struct proc_ctx *ctx) pdu = (struct pdu_data *)tx->pdu; - /* Clear tx_ack/rx node reference due to dual/union functionality - * rx node might be !=NULL and thus tx_ack !=NULL - */ - ctx->node_ref.tx_ack = NULL; - /* Encode LL Control PDU */ switch (ctx->proc) { #if defined(CONFIG_BT_CTLR_LE_PING) @@ -1042,9 +1037,6 @@ static void rp_comm_tx(struct ll_conn *conn, struct proc_ctx *ctx) pdu = (struct pdu_data *)tx->pdu; - /* Clear tx_ack/rx node reference */ - ctx->node_ref.tx_ack = NULL; - /* Encode LL Control PDU */ switch (ctx->proc) { #if defined(CONFIG_BT_CTLR_LE_PING) @@ -1346,7 +1338,6 @@ static void rp_comm_st_wait_tx_ack(struct ll_conn *conn, struct proc_ctx *ctx, u /* Apply changes in data lengths/times */ uint8_t dle_changed = ull_dle_update_eff_tx(conn); - ctx->node_ref.tx_ack = NULL; dle_changed |= ctx->data.dle.ntf_dle; llcp_tx_resume_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_DATA_LENGTH); @@ -1359,7 +1350,6 @@ static void rp_comm_st_wait_tx_ack(struct ll_conn *conn, struct proc_ctx *ctx, u #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP) case PROC_CTE_REQ: { /* add PHY update pause = false here */ - ctx->node_ref.tx_ack = NULL; llcp_rr_set_paused_cmd(conn, PROC_NONE); llcp_rr_complete(conn); ctx->state = RP_COMMON_STATE_IDLE; @@ -1367,7 +1357,6 @@ static void rp_comm_st_wait_tx_ack(struct ll_conn *conn, struct proc_ctx *ctx, u #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */ #if defined(CONFIG_BT_CTLR_SCA_UPDATE) case PROC_SCA_UPDATE: { - ctx->node_ref.tx_ack = NULL; #if defined(CONFIG_BT_PERIPHERAL) if (conn->lll.role == BT_HCI_ROLE_PERIPHERAL) { conn->periph.sca = ctx->data.sca_update.sca; diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c index 1f5de4b3494..3c1639bc52a 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c @@ -277,9 +277,8 @@ static void lp_cu_tx(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t opcode) struct pdu_data *pdu; /* Get pre-allocated tx node */ - tx = ctx->node_ref.tx_ack; - /* Clear to not trigger tx-ack*/ - ctx->node_ref.tx_ack = NULL; + tx = ctx->node_ref.tx; + ctx->node_ref.tx = NULL; if (!tx) { /* Allocate tx node if non pre-alloc'ed */ @@ -426,7 +425,7 @@ static void lp_cu_send_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ct ctx->state = LP_CU_STATE_WAIT_TX_CONN_UPDATE_IND; } else { /* ensure alloc of TX node, before possibly waiting for NTF node */ - ctx->node_ref.tx_ack = llcp_tx_alloc(conn, ctx); + ctx->node_ref.tx = llcp_tx_alloc(conn, ctx); if (ctx->node_ref.rx == NULL && !llcp_ntf_alloc_is_available()) { /* No RX node piggy, and no NTF avail, so go wait for one, before TX'ing */ ctx->state = LP_CU_STATE_WAIT_NTF_AVAIL; @@ -747,8 +746,8 @@ static void rp_cu_tx(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t opcode) struct pdu_data *pdu; /* Get pre-allocated tx node */ - tx = ctx->node_ref.tx_ack; - ctx->node_ref.tx_ack = NULL; + tx = ctx->node_ref.tx; + ctx->node_ref.tx = NULL; if (!tx) { /* Allocate tx node if non pre-alloc'ed */ @@ -861,7 +860,7 @@ static void rp_cu_send_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ct ctx->state = RP_CU_STATE_WAIT_TX_CONN_UPDATE_IND; } else { /* ensure alloc of TX node, before possibly waiting for NTF node */ - ctx->node_ref.tx_ack = llcp_tx_alloc(conn, ctx); + ctx->node_ref.tx = llcp_tx_alloc(conn, ctx); if (!llcp_ntf_alloc_is_available()) { /* No RX node piggy, and no NTF avail, so go wait for one, before TX'ing */ ctx->state = RP_CU_STATE_WAIT_NTF_AVAIL; diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_internal.h b/subsys/bluetooth/controller/ll_sw/ull_llcp_internal.h index 280001f4aba..cb7ea659171 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_internal.h @@ -163,6 +163,8 @@ struct proc_ctx { struct node_tx *tx_ack; /* most recent RX node */ struct node_rx_pdu *rx; + /* pre-allocated TX node */ + struct node_tx *tx; } node_ref; /* * This flag is set to 1 when we are finished with the control diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_phy.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_phy.c index ef59aef9e5e..dc3ea686d05 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_phy.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_phy.c @@ -377,13 +377,9 @@ static void lp_pu_tx(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, vo struct node_tx *tx; struct pdu_data *pdu; - /* Allocate tx node, but only do it if not already done */ - if (ctx->node_ref.tx_ack == NULL) { - ctx->node_ref.tx_ack = llcp_tx_alloc(conn, ctx); - LL_ASSERT(ctx->node_ref.tx_ack); - } + LL_ASSERT(ctx->node_ref.tx); -#if defined(CONFIG_BT_CENTRAL) +#if defined(CONFIG_BT_CTLR_DATA_LENGTH) if (!((ctx->tx_opcode == PDU_DATA_LLCTRL_TYPE_PHY_REQ) && (conn->lll.role == BT_HCI_ROLE_CENTRAL))) { if (!llcp_ntf_alloc_is_available()) { @@ -391,14 +387,14 @@ static void lp_pu_tx(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, vo ctx->state = LP_PU_STATE_WAIT_NTF_AVAIL; return; } -#if defined(CONFIG_BT_CTLR_DATA_LENGTH) ctx->data.pu.ntf_dle_node = llcp_ntf_alloc(); LL_ASSERT(ctx->data.pu.ntf_dle_node); -#endif /* CONFIG_BT_CTLR_DATA_LENGTH */ } -#endif +#endif /* CONFIG_BT_CTLR_DATA_LENGTH */ - tx = ctx->node_ref.tx_ack; + tx = ctx->node_ref.tx; + ctx->node_ref.tx = NULL; + ctx->node_ref.tx_ack = tx; pdu = (struct pdu_data *)tx->pdu; /* Encode LL Control PDU */ @@ -526,12 +522,6 @@ static void lp_pu_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t e * Instead postpone completion/NTF to the beginning of RX handling */ ctx->state = LP_PU_STATE_WAIT_INSTANT_ON_AIR; - - if (ctx->node_ref.rx) { - /* Mark RX node to NOT release */ - llcp_rx_node_retain(ctx); - } - } static void lp_pu_send_phy_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param) @@ -544,6 +534,9 @@ static void lp_pu_send_phy_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8 llcp_rr_set_incompat(conn, INCOMPAT_RESOLVABLE); llcp_rr_set_paused_cmd(conn, PROC_CTE_REQ); ctx->tx_opcode = PDU_DATA_LLCTRL_TYPE_PHY_REQ; + + /* Allocate TX node */ + ctx->node_ref.tx = llcp_tx_alloc(conn, ctx); lp_pu_tx(conn, ctx, evt, param); } } @@ -556,6 +549,9 @@ static void lp_pu_send_phy_update_ind(struct ll_conn *conn, struct proc_ctx *ctx ctx->state = LP_PU_STATE_WAIT_TX_PHY_UPDATE_IND; } else { ctx->tx_opcode = PDU_DATA_LLCTRL_TYPE_PHY_UPD_IND; + + /* Allocate TX node */ + ctx->node_ref.tx = llcp_tx_alloc(conn, ctx); lp_pu_tx(conn, ctx, evt, param); } } @@ -749,28 +745,18 @@ static void lp_pu_st_wait_rx_phy_update_ind(struct ll_conn *conn, struct proc_ct llcp_tx_resume_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_PHY_UPDATE); break; case LP_PU_EVT_REJECT: - llcp_rr_set_incompat(conn, INCOMPAT_NO_COLLISION); - llcp_pdu_decode_reject_ext_ind(ctx, (struct pdu_data *) param); - - /* Mark RX node to NOT release */ - llcp_rx_node_retain(ctx); - + llcp_pdu_decode_reject_ext_ind(ctx, (struct pdu_data *)param); ctx->data.pu.error = ctx->reject_ext_ind.error_code; - ctx->data.pu.ntf_pu = 1; - lp_pu_complete(conn, ctx, evt, param); - llcp_tx_resume_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_PHY_UPDATE); - break; + /* Fallthrough */ case LP_PU_EVT_UNKNOWN: llcp_rr_set_incompat(conn, INCOMPAT_NO_COLLISION); - /* Unsupported in peer, so disable locally for this connection - * Peer does not accept PHY UPDATE, so disable non 1M phys on current connection - */ - feature_unmask_features(conn, LL_FEAT_BIT_PHY_2M | LL_FEAT_BIT_PHY_CODED); - + if (evt == LP_PU_EVT_UNKNOWN) { + feature_unmask_features(conn, LL_FEAT_BIT_PHY_2M | LL_FEAT_BIT_PHY_CODED); + ctx->data.pu.error = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE; + } /* Mark RX node to NOT release */ llcp_rx_node_retain(ctx); - ctx->data.pu.error = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE; ctx->data.pu.ntf_pu = 1; lp_pu_complete(conn, ctx, evt, param); llcp_tx_resume_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_PHY_UPDATE); @@ -825,6 +811,7 @@ static void lp_pu_st_wait_instant_on_air(struct ll_conn *conn, struct proc_ctx * } } +#if defined(CONFIG_BT_CTLR_DATA_LENGTH) static void lp_pu_st_wait_ntf_avail(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param) { @@ -837,6 +824,7 @@ static void lp_pu_st_wait_ntf_avail(struct ll_conn *conn, struct proc_ctx *ctx, break; } } +#endif /* CONFIG_BT_CTLR_DATA_LENGTH */ static void lp_pu_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param) { @@ -872,9 +860,11 @@ static void lp_pu_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8_ case LP_PU_STATE_WAIT_INSTANT_ON_AIR: lp_pu_st_wait_instant_on_air(conn, ctx, evt, param); break; +#if defined(CONFIG_BT_CTLR_DATA_LENGTH) case LP_PU_STATE_WAIT_NTF_AVAIL: lp_pu_st_wait_ntf_avail(conn, ctx, evt, param); break; +#endif /* CONFIG_BT_CTLR_DATA_LENGTH */ default: /* Unknown state */ LL_ASSERT(0); @@ -945,25 +935,23 @@ static void rp_pu_tx(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, vo struct node_tx *tx; struct pdu_data *pdu; - /* (pre)allocate tx node, but only do it if not already done */ - if (ctx->node_ref.tx_ack == NULL) { - ctx->node_ref.tx_ack = llcp_tx_alloc(conn, ctx); - LL_ASSERT(ctx->node_ref.tx_ack); - } + LL_ASSERT(ctx->node_ref.tx); +#if defined(CONFIG_BT_CTLR_DATA_LENGTH) if (!llcp_ntf_alloc_is_available()) { /* No NTF nodes avail, so we need to hold off TX */ ctx->state = RP_PU_STATE_WAIT_NTF_AVAIL; return; } -#if defined(CONFIG_BT_CTLR_DATA_LENGTH) ctx->data.pu.ntf_dle_node = llcp_ntf_alloc(); LL_ASSERT(ctx->data.pu.ntf_dle_node); #endif /* CONFIG_BT_CTLR_DATA_LENGTH */ - tx = ctx->node_ref.tx_ack; + tx = ctx->node_ref.tx; + ctx->node_ref.tx = NULL; pdu = (struct pdu_data *)tx->pdu; + ctx->node_ref.tx_ack = tx; /* Encode LL Control PDU */ switch (ctx->tx_opcode) { @@ -1032,6 +1020,7 @@ static void rp_pu_send_phy_update_ind(struct ll_conn *conn, struct proc_ctx *ctx } else { llcp_rr_set_paused_cmd(conn, PROC_CTE_REQ); ctx->tx_opcode = PDU_DATA_LLCTRL_TYPE_PHY_UPD_IND; + ctx->node_ref.tx = llcp_tx_alloc(conn, ctx); rp_pu_tx(conn, ctx, evt, param); } @@ -1047,6 +1036,7 @@ static void rp_pu_send_phy_rsp(struct ll_conn *conn, struct proc_ctx *ctx, uint8 } else { llcp_rr_set_paused_cmd(conn, PROC_CTE_REQ); ctx->tx_opcode = PDU_DATA_LLCTRL_TYPE_PHY_RSP; + ctx->node_ref.tx = llcp_tx_alloc(conn, ctx); rp_pu_tx(conn, ctx, evt, param); } } @@ -1247,6 +1237,7 @@ static void rp_pu_st_wait_instant_on_air(struct ll_conn *conn, struct proc_ctx * } } +#if defined(CONFIG_BT_CTLR_DATA_LENGTH) static void rp_pu_st_wait_ntf_avail(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param) { @@ -1259,6 +1250,7 @@ static void rp_pu_st_wait_ntf_avail(struct ll_conn *conn, struct proc_ctx *ctx, break; } } +#endif /* CONFIG_BT_CTLR_DATA_LENGTH */ static void rp_pu_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param) { @@ -1294,9 +1286,11 @@ static void rp_pu_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8_ case RP_PU_STATE_WAIT_INSTANT_ON_AIR: rp_pu_st_wait_instant_on_air(conn, ctx, evt, param); break; +#if defined(CONFIG_BT_CTLR_DATA_LENGTH) case RP_PU_STATE_WAIT_NTF_AVAIL: rp_pu_st_wait_ntf_avail(conn, ctx, evt, param); break; +#endif /* CONFIG_BT_CTLR_DATA_LENGTH */ default: /* Unknown state */ LL_ASSERT(0);