Bluetooth: controller: llcp: fixing tx buffer queue handling
Misc. fixups to get the tx buffer alloc mechanism to work as intended Signed-off-by: Erik Brockhoff <erbr@oticon.com>
This commit is contained in:
parent
be19051248
commit
1ff458ec87
7 changed files with 66 additions and 26 deletions
|
@ -2014,7 +2014,7 @@ void ull_conn_tx_ack(uint16_t handle, memq_link_t *link, struct node_tx *tx)
|
|||
#if defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
|
||||
mem_release(tx, &mem_conn_tx_ctrl.free);
|
||||
#else /* CONFIG_BT_LL_SW_LLCP_LEGACY */
|
||||
struct ll_conn *conn = ll_conn_get(handle);
|
||||
struct ll_conn *conn = ll_connected_get(handle);
|
||||
|
||||
ull_cp_release_tx(conn, tx);
|
||||
#endif /* CONFIG_BT_LL_SW_LLCP_LEGACY */
|
||||
|
@ -2492,6 +2492,11 @@ static void conn_cleanup_finalize(struct ll_conn *conn)
|
|||
#else /* CONFIG_BT_LL_SW_LLCP_LEGACY */
|
||||
ARG_UNUSED(rx);
|
||||
ull_cp_state_set(conn, ULL_CP_DISCONNECTED);
|
||||
|
||||
/* Update tx buffer queue handling */
|
||||
#if defined(LLCP_TX_CTRL_BUF_QUEUE_ENABLE)
|
||||
ull_cp_update_tx_buffer_queue(conn);
|
||||
#endif /* LLCP_TX_CTRL_BUF_QUEUE_ENABLE */
|
||||
#endif /* CONFIG_BT_LL_SW_LLCP_LEGACY */
|
||||
|
||||
/* flush demux-ed Tx buffer still in ULL context */
|
||||
|
|
|
@ -462,12 +462,7 @@ struct llcp_struct {
|
|||
} cte_rsp;
|
||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
||||
|
||||
#if (CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM > 0) &&\
|
||||
(CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM <\
|
||||
CONFIG_BT_CTLR_LLCP_TX_PER_CONN_TX_CTRL_BUF_NUM_MAX)
|
||||
|
||||
uint8_t tx_buffer_alloc;
|
||||
#endif /* (CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM > 0) */
|
||||
uint8_t tx_q_pause_data_mask;
|
||||
|
||||
}; /* struct llcp_struct */
|
||||
|
|
|
@ -92,6 +92,18 @@ void llcp_proc_ctx_release(struct proc_ctx *ctx)
|
|||
}
|
||||
|
||||
#if defined(LLCP_TX_CTRL_BUF_QUEUE_ENABLE)
|
||||
/*
|
||||
* @brief Update 'global' tx buffer allowance
|
||||
*/
|
||||
void ull_cp_update_tx_buffer_queue(struct ll_conn *conn)
|
||||
{
|
||||
if (conn->llcp.tx_buffer_alloc > CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM) {
|
||||
common_tx_buffer_alloc -= (conn->llcp.tx_buffer_alloc -
|
||||
CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @brief Check for per conn pre-allocated tx buffer allowance
|
||||
* @return true if buffer is available
|
||||
|
@ -159,8 +171,8 @@ void llcp_tx_alloc_unpeek(struct proc_ctx *ctx)
|
|||
*/
|
||||
struct node_tx *llcp_tx_alloc(struct ll_conn *conn, struct proc_ctx *ctx)
|
||||
{
|
||||
#if (CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM > 0)
|
||||
conn->llcp.tx_buffer_alloc++;
|
||||
#if (CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM > 0)
|
||||
if (conn->llcp.tx_buffer_alloc > CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM) {
|
||||
common_tx_buffer_alloc++;
|
||||
/* global buffer allocated, so we're at the head and should just pop head */
|
||||
|
@ -494,9 +506,7 @@ void ull_llcp_init(struct ll_conn *conn)
|
|||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
||||
|
||||
#if defined(LLCP_TX_CTRL_BUF_QUEUE_ENABLE)
|
||||
#if (CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM > 0)
|
||||
conn->llcp.tx_buffer_alloc = 0;
|
||||
#endif /* (CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM > 0) */
|
||||
#endif /* LLCP_TX_CTRL_BUF_QUEUE_ENABLE */
|
||||
|
||||
conn->llcp.tx_q_pause_data_mask = 0;
|
||||
|
@ -506,15 +516,13 @@ void ull_llcp_init(struct ll_conn *conn)
|
|||
void ull_cp_release_tx(struct ll_conn *conn, struct node_tx *tx)
|
||||
{
|
||||
#if defined(LLCP_TX_CTRL_BUF_QUEUE_ENABLE)
|
||||
#if (CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM > 0)
|
||||
if (conn->llcp.tx_buffer_alloc > CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM) {
|
||||
common_tx_buffer_alloc--;
|
||||
if (conn) {
|
||||
LL_ASSERT(conn->llcp.tx_buffer_alloc > 0);
|
||||
if (conn->llcp.tx_buffer_alloc > CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM) {
|
||||
common_tx_buffer_alloc--;
|
||||
}
|
||||
conn->llcp.tx_buffer_alloc--;
|
||||
}
|
||||
conn->llcp.tx_buffer_alloc--;
|
||||
#else /* CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM > 0 */
|
||||
ARG_UNUSED(conn);
|
||||
common_tx_buffer_alloc--;
|
||||
#endif /* CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM > 0 */
|
||||
#else /* LLCP_TX_CTRL_BUF_QUEUE_ENABLE */
|
||||
ARG_UNUSED(conn);
|
||||
#endif /* LLCP_TX_CTRL_BUF_QUEUE_ENABLE */
|
||||
|
@ -1616,6 +1624,13 @@ uint16_t ctx_buffers_free(void)
|
|||
return local_ctx_buffers_free() + remote_ctx_buffers_free();
|
||||
}
|
||||
|
||||
#if defined(LLCP_TX_CTRL_BUF_QUEUE_ENABLE)
|
||||
uint8_t common_tx_buffer_alloc_count(void)
|
||||
{
|
||||
return common_tx_buffer_alloc;
|
||||
}
|
||||
#endif /* LLCP_TX_CTRL_BUF_QUEUE_ENABLE */
|
||||
|
||||
void test_int_mem_proc_ctx(void)
|
||||
{
|
||||
struct proc_ctx *ctx1;
|
||||
|
|
|
@ -25,6 +25,11 @@ void ull_llcp_init(struct ll_conn *conn);
|
|||
*/
|
||||
void ull_cp_state_set(struct ll_conn *conn, uint8_t state);
|
||||
|
||||
/*
|
||||
* @brief Update 'global' tx buffer allowance
|
||||
*/
|
||||
void ull_cp_update_tx_buffer_queue(struct ll_conn *conn);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -643,4 +643,5 @@ bool lr_is_idle(struct ll_conn *conn);
|
|||
bool rr_is_disconnected(struct ll_conn *conn);
|
||||
bool rr_is_idle(struct ll_conn *conn);
|
||||
uint16_t ctx_buffers_free(void);
|
||||
uint8_t common_tx_buffer_alloc_count(void);
|
||||
#endif
|
||||
|
|
|
@ -1090,9 +1090,6 @@ void test_conn_update_central_loc_unsupp_w_feat_exch(void)
|
|||
pdu = (struct pdu_data *)tx->pdu;
|
||||
instant = sys_le16_to_cpu(pdu->llctrl.conn_update_ind.instant);
|
||||
|
||||
/* Release Tx */
|
||||
ull_cp_release_tx(&conn, tx);
|
||||
|
||||
/* */
|
||||
while (!is_instant_reached(&conn, instant)) {
|
||||
/* Prepare */
|
||||
|
@ -2491,7 +2488,7 @@ void test_conn_update_periph_loc_collision_reject_2nd_cpr(void)
|
|||
struct ll_conn conn_2nd;
|
||||
struct ll_conn conn_3rd;
|
||||
uint8_t err;
|
||||
struct node_tx *tx;
|
||||
struct node_tx *tx, *tx1;
|
||||
struct node_rx_pdu *ntf;
|
||||
uint16_t instant;
|
||||
|
||||
|
@ -2532,7 +2529,7 @@ void test_conn_update_periph_loc_collision_reject_2nd_cpr(void)
|
|||
event_prepare(&conn);
|
||||
|
||||
/* (A) Tx Queue should have one LL Control PDU */
|
||||
lt_rx(LL_CONNECTION_PARAM_REQ, &conn, &tx, &conn_param_req);
|
||||
lt_rx(LL_CONNECTION_PARAM_REQ, &conn, &tx1, &conn_param_req);
|
||||
lt_rx_q_is_empty(&conn);
|
||||
|
||||
/* (B) Rx */
|
||||
|
@ -2611,7 +2608,7 @@ void test_conn_update_periph_loc_collision_reject_2nd_cpr(void)
|
|||
|
||||
|
||||
/* Release Tx */
|
||||
ull_cp_release_tx(&conn, tx);
|
||||
ull_cp_release_tx(&conn, tx1);
|
||||
|
||||
/*******************/
|
||||
|
||||
|
@ -3668,9 +3665,6 @@ void test_conn_update_central_loc_accept_no_param_req(void)
|
|||
pdu = (struct pdu_data *)tx->pdu;
|
||||
instant = sys_le16_to_cpu(pdu->llctrl.conn_update_ind.instant);
|
||||
|
||||
/* Release Tx */
|
||||
ull_cp_release_tx(&conn, tx);
|
||||
|
||||
/* */
|
||||
while (!is_instant_reached(&conn, instant)) {
|
||||
/* Prepare */
|
||||
|
|
|
@ -59,17 +59,26 @@ void test_tx_buffer_alloc(void)
|
|||
ctxs[ctx_idx] = llcp_create_local_procedure(PROC_VERSION_EXCHANGE);
|
||||
}
|
||||
|
||||
/* Init per conn tx_buffer_alloc count */
|
||||
for (int j = 1; j < CONFIG_BT_CTLR_LLCP_CONN; j++) {
|
||||
conn[j].llcp.tx_buffer_alloc = 0;
|
||||
}
|
||||
#if defined(LLCP_TX_CTRL_BUF_QUEUE_ENABLE)
|
||||
/* Check alloc flow */
|
||||
for (i = 0; i < CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM; i++) {
|
||||
zassert_true(llcp_tx_alloc_peek(&conn[0], ctxs[0]), NULL);
|
||||
tx[tx_alloc_idx] = llcp_tx_alloc(&conn[0], ctxs[0]);
|
||||
zassert_equal(conn[0].llcp.tx_buffer_alloc, i + 1, NULL);
|
||||
zassert_equal(common_tx_buffer_alloc_count(), 0, NULL);
|
||||
zassert_not_null(tx[tx_alloc_idx], NULL);
|
||||
tx_alloc_idx++;
|
||||
}
|
||||
for (i = 0; i < CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM; i++) {
|
||||
zassert_true(llcp_tx_alloc_peek(&conn[0], ctxs[0]), NULL);
|
||||
tx[tx_alloc_idx] = llcp_tx_alloc(&conn[0], ctxs[0]);
|
||||
zassert_equal(conn[0].llcp.tx_buffer_alloc,
|
||||
CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM + i + 1, NULL);
|
||||
zassert_equal(common_tx_buffer_alloc_count(), i+1, NULL);
|
||||
zassert_not_null(tx[tx_alloc_idx], NULL);
|
||||
tx_alloc_idx++;
|
||||
}
|
||||
|
@ -82,6 +91,9 @@ void test_tx_buffer_alloc(void)
|
|||
zassert_true(llcp_tx_alloc_peek(&conn[j], ctxs[j]), NULL);
|
||||
tx[tx_alloc_idx] = llcp_tx_alloc(&conn[j], ctxs[j]);
|
||||
zassert_not_null(tx[tx_alloc_idx], NULL);
|
||||
zassert_equal(common_tx_buffer_alloc_count(),
|
||||
CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM, NULL);
|
||||
zassert_equal(conn[j].llcp.tx_buffer_alloc, i + 1, NULL);
|
||||
tx_alloc_idx++;
|
||||
}
|
||||
|
||||
|
@ -90,6 +102,10 @@ void test_tx_buffer_alloc(void)
|
|||
}
|
||||
|
||||
ull_cp_release_tx(&conn[0], tx[1]);
|
||||
zassert_equal(common_tx_buffer_alloc_count(),
|
||||
CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM - 1, NULL);
|
||||
zassert_equal(conn[0].llcp.tx_buffer_alloc, CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM +
|
||||
CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM - 1, NULL);
|
||||
|
||||
/* global pool is now 'open' again, but ctxs[1] is NOT next in line */
|
||||
zassert_false(llcp_tx_alloc_peek(&conn[1], ctxs[1]), NULL);
|
||||
|
@ -97,9 +113,18 @@ void test_tx_buffer_alloc(void)
|
|||
/* ... ctxs[0] is */
|
||||
zassert_true(llcp_tx_alloc_peek(&conn[0], ctxs[0]), NULL);
|
||||
tx[tx_alloc_idx] = llcp_tx_alloc(&conn[0], ctxs[0]);
|
||||
zassert_equal(common_tx_buffer_alloc_count(), CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM,
|
||||
NULL);
|
||||
zassert_equal(conn[0].llcp.tx_buffer_alloc, CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM +
|
||||
CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM, NULL);
|
||||
|
||||
zassert_not_null(tx[tx_alloc_idx], NULL);
|
||||
tx_alloc_idx++;
|
||||
ull_cp_release_tx(&conn[0], tx[tx_alloc_idx - 1]);
|
||||
zassert_equal(common_tx_buffer_alloc_count(),
|
||||
CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM - 1, NULL);
|
||||
zassert_equal(conn[0].llcp.tx_buffer_alloc, CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM +
|
||||
CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM - 1, NULL);
|
||||
|
||||
/* global pool does not allow as ctxs[2] is NOT next up */
|
||||
zassert_false(llcp_tx_alloc_peek(&conn[2], ctxs[2]), NULL);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue