Bluetooth: controller: split: Fix data pause on Enc Req enqueue
Fix the controller implementation to handle data packet enqueue being pause on Encryption Request be done early in the ULL when enqueueing packets towards LLL. Fixes #18645. Signed-off-by: Vinayak Kariappa Chettimada <vinayak.chettimada@gmail.com>
This commit is contained in:
parent
3320b51644
commit
385b82dcef
1 changed files with 52 additions and 3 deletions
|
@ -90,6 +90,8 @@ static inline void event_phy_upd_ind_prep(struct ll_conn *conn,
|
|||
u16_t event_counter);
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
|
||||
static inline void ctrl_tx_pre_ack(struct ll_conn *conn,
|
||||
struct pdu_data *pdu_tx);
|
||||
static inline void ctrl_tx_ack(struct ll_conn *conn, struct node_tx **tx,
|
||||
struct pdu_data *pdu_tx);
|
||||
static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
|
||||
|
@ -1213,6 +1215,7 @@ void ull_conn_tx_lll_enqueue(struct ll_conn *conn, u8_t count)
|
|||
#endif /* CONFIG_BT_CTLR_LE_ENC */
|
||||
1) ||
|
||||
(!pause_tx && (conn->tx_head == conn->tx_ctrl))) && count--) {
|
||||
struct pdu_data *pdu_tx;
|
||||
struct node_tx *tx_lll;
|
||||
memq_link_t *link;
|
||||
|
||||
|
@ -1239,6 +1242,11 @@ void ull_conn_tx_lll_enqueue(struct ll_conn *conn, u8_t count)
|
|||
tx_lll->next = NULL;
|
||||
}
|
||||
|
||||
pdu_tx = (void *)tx_lll->pdu;
|
||||
if (pdu_tx->ll_id == PDU_DATA_LLID_CTRL) {
|
||||
ctrl_tx_pre_ack(conn, pdu_tx);
|
||||
}
|
||||
|
||||
link = mem_acquire(&mem_link_tx.free);
|
||||
LL_ASSERT(link);
|
||||
|
||||
|
@ -2193,6 +2201,8 @@ static inline void event_enc_prep(struct ll_conn *conn)
|
|||
|
||||
/* send enc start resp */
|
||||
start_enc_rsp_send(conn, pdu_ctrl_tx);
|
||||
|
||||
ctrl_tx_enqueue(conn, tx);
|
||||
}
|
||||
|
||||
/* slave send reject ind or start enc req at control priority */
|
||||
|
@ -2206,6 +2216,8 @@ static inline void event_enc_prep(struct ll_conn *conn)
|
|||
/* place the reject ind packet as next in tx queue */
|
||||
if (conn->llcp.encryption.error_code) {
|
||||
event_enc_reject_prep(conn, pdu_ctrl_tx);
|
||||
|
||||
ctrl_tx_enqueue(conn, tx);
|
||||
}
|
||||
/* place the start enc req packet as next in tx queue */
|
||||
else {
|
||||
|
@ -2262,21 +2274,22 @@ static inline void event_enc_prep(struct ll_conn *conn)
|
|||
sizeof(struct pdu_data_llctrl_start_enc_req);
|
||||
pdu_ctrl_tx->llctrl.opcode =
|
||||
PDU_DATA_LLCTRL_TYPE_START_ENC_REQ;
|
||||
|
||||
ctrl_tx_enqueue(conn, tx);
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_BT_CTLR_FAST_ENC)
|
||||
} else {
|
||||
start_enc_rsp_send(conn, pdu_ctrl_tx);
|
||||
|
||||
ctrl_tx_enqueue(conn, tx);
|
||||
|
||||
/* resume data packet rx and tx */
|
||||
conn->llcp_enc.pause_rx = 0U;
|
||||
conn->llcp_enc.pause_tx = 0U;
|
||||
#endif /* !CONFIG_BT_CTLR_FAST_ENC */
|
||||
|
||||
}
|
||||
|
||||
ctrl_tx_enqueue(conn, tx);
|
||||
|
||||
/* procedure request acked */
|
||||
conn->llcp_ack = conn->llcp_req;
|
||||
}
|
||||
|
@ -4240,6 +4253,42 @@ static inline u8_t phy_upd_ind_recv(struct ll_conn *conn, memq_link_t *link,
|
|||
}
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
|
||||
static inline void ctrl_tx_pre_ack(struct ll_conn *conn,
|
||||
struct pdu_data *pdu_tx)
|
||||
{
|
||||
switch (pdu_tx->llctrl.opcode) {
|
||||
#if defined(CONFIG_BT_CTLR_LE_ENC)
|
||||
case PDU_DATA_LLCTRL_TYPE_PAUSE_ENC_RSP:
|
||||
if (!conn->lll.role) {
|
||||
break;
|
||||
}
|
||||
/* Pass Through */
|
||||
|
||||
case PDU_DATA_LLCTRL_TYPE_ENC_REQ:
|
||||
case PDU_DATA_LLCTRL_TYPE_ENC_RSP:
|
||||
case PDU_DATA_LLCTRL_TYPE_PAUSE_ENC_REQ:
|
||||
/* pause data packet tx */
|
||||
conn->llcp_enc.pause_tx = 1U;
|
||||
break;
|
||||
|
||||
#endif /* CONFIG_BT_CTLR_LE_ENC */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
|
||||
case PDU_DATA_LLCTRL_TYPE_LENGTH_REQ:
|
||||
if ((conn->llcp_length.req != conn->llcp_length.ack) &&
|
||||
(conn->llcp_length.state == LLCP_LENGTH_STATE_ACK_WAIT)) {
|
||||
/* pause data packet tx */
|
||||
conn->llcp_length.pause_tx = 1U;
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
|
||||
default:
|
||||
/* Do nothing for other ctrl packet ack */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ctrl_tx_ack(struct ll_conn *conn, struct node_tx **tx,
|
||||
struct pdu_data *pdu_tx)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue