Bluetooth: controller: Added Force MD bit automatic feature
Added automatic runtime calculation of Forced MD bit count based on incoming Tx buffer throughput. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
3bbe2c0a07
commit
e4fe7435d7
4 changed files with 93 additions and 3 deletions
|
@ -391,8 +391,9 @@ config BT_CTLR_THROUGHPUT
|
|||
Measure incoming Tx throughput and log the results.
|
||||
|
||||
config BT_CTLR_FORCE_MD_COUNT
|
||||
int "Forced MD bit count"
|
||||
int "Forced MD bit count" if !BT_CTLR_FORCE_MD_AUTO
|
||||
range 0 255
|
||||
default 1 if BT_CTLR_FORCE_MD_AUTO
|
||||
default 0
|
||||
help
|
||||
No. of times to force MD bit to be set in Tx PDU after a successful
|
||||
|
@ -402,6 +403,14 @@ config BT_CTLR_FORCE_MD_COUNT
|
|||
where applications want to send data in same connection event but are
|
||||
slow in providing new Tx data.
|
||||
|
||||
config BT_CTLR_FORCE_MD_AUTO
|
||||
bool "Forced MD bit automatic calculation"
|
||||
select BT_CTLR_THROUGHPUT
|
||||
default y if BT_HCI_RAW
|
||||
help
|
||||
Force MD bit in transmitted PDU based on runtime incoming transmit
|
||||
data throughput.
|
||||
|
||||
config BT_CTLR_CONN_RSSI_EVENT
|
||||
bool "Connection RSSI event"
|
||||
depends on BT_CTLR_CONN_RSSI
|
||||
|
|
|
@ -122,10 +122,12 @@ struct lll_conn {
|
|||
|
||||
int lll_conn_init(void);
|
||||
int lll_conn_reset(void);
|
||||
void lll_conn_flush(uint16_t handle, struct lll_conn *lll);
|
||||
|
||||
uint8_t lll_conn_sca_local_get(void);
|
||||
uint32_t lll_conn_ppm_local_get(void);
|
||||
uint32_t lll_conn_ppm_get(uint8_t sca);
|
||||
|
||||
void lll_conn_prepare_reset(void);
|
||||
void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param);
|
||||
void lll_conn_isr_rx(void *param);
|
||||
|
@ -133,7 +135,7 @@ void lll_conn_isr_tx(void *param);
|
|||
void lll_conn_rx_pkt_set(struct lll_conn *lll);
|
||||
void lll_conn_tx_pkt_set(struct lll_conn *lll, struct pdu_data *pdu_data_tx);
|
||||
void lll_conn_pdu_tx_prep(struct lll_conn *lll, struct pdu_data **pdu_data_tx);
|
||||
void lll_conn_flush(uint16_t handle, struct lll_conn *lll);
|
||||
uint8_t lll_conn_force_md_cnt_set(uint8_t force_md_cnt);
|
||||
|
||||
extern void ull_conn_lll_ack_enqueue(uint16_t handle, struct node_tx *tx);
|
||||
extern uint16_t ull_conn_lll_max_tx_octets_get(struct lll_conn *lll);
|
||||
|
|
|
@ -53,6 +53,12 @@ static uint8_t mic_state;
|
|||
|
||||
#if defined(CONFIG_BT_CTLR_FORCE_MD_COUNT) && \
|
||||
(CONFIG_BT_CTLR_FORCE_MD_COUNT > 0)
|
||||
#if defined(CONFIG_BT_CTLR_FORCE_MD_AUTO)
|
||||
static uint8_t force_md_cnt_reload;
|
||||
#define BT_CTLR_FORCE_MD_COUNT force_md_cnt_reload
|
||||
#else
|
||||
#define BT_CTLR_FORCE_MD_COUNT CONFIG_BT_CTLR_FORCE_MD_COUNT
|
||||
#endif
|
||||
static uint8_t force_md_cnt;
|
||||
|
||||
#define FORCE_MD_CNT_INIT() \
|
||||
|
@ -73,7 +79,7 @@ static uint8_t force_md_cnt;
|
|||
do { \
|
||||
if (force_md_cnt || \
|
||||
(trx_cnt >= ((CONFIG_BT_CTLR_TX_BUFFERS) - 1))) { \
|
||||
force_md_cnt = CONFIG_BT_CTLR_FORCE_MD_COUNT; \
|
||||
force_md_cnt = BT_CTLR_FORCE_MD_COUNT; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
@ -593,6 +599,18 @@ void lll_conn_pdu_tx_prep(struct lll_conn *lll, struct pdu_data **pdu_data_tx)
|
|||
*pdu_data_tx = p;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_FORCE_MD_AUTO)
|
||||
uint8_t lll_conn_force_md_cnt_set(uint8_t force_md_cnt)
|
||||
{
|
||||
uint8_t previous;
|
||||
|
||||
previous = force_md_cnt_reload;
|
||||
force_md_cnt_reload = force_md_cnt;
|
||||
|
||||
return previous;
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_FORCE_MD_AUTO */
|
||||
|
||||
static int init_reset(void)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -116,6 +116,10 @@ static inline void ctrl_tx_ack(struct ll_conn *conn, struct node_tx **tx,
|
|||
static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
|
||||
struct pdu_data *pdu_rx, struct ll_conn *conn);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_FORCE_MD_AUTO)
|
||||
static uint8_t force_md_cnt_calc(struct lll_conn *lll_conn, uint32_t tx_rate);
|
||||
#endif /* CONFIG_BT_CTLR_FORCE_MD_AUTO */
|
||||
|
||||
#if !defined(BT_CTLR_USER_TX_BUFFER_OVERHEAD)
|
||||
#define BT_CTLR_USER_TX_BUFFER_OVERHEAD 0
|
||||
#endif /* BT_CTLR_USER_TX_BUFFER_OVERHEAD */
|
||||
|
@ -246,10 +250,28 @@ int ll_tx_mem_enqueue(uint16_t handle, void *tx)
|
|||
static memq_link_t link;
|
||||
static struct mayfly mfy = {0, 0, &link, NULL, tx_demux};
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_FORCE_MD_AUTO)
|
||||
if (tx_cnt >= CONFIG_BT_CTLR_TX_BUFFERS) {
|
||||
uint8_t previous, force_md_cnt;
|
||||
|
||||
force_md_cnt = force_md_cnt_calc(&conn->lll, tx_rate);
|
||||
previous = lll_conn_force_md_cnt_set(force_md_cnt);
|
||||
if (previous != force_md_cnt) {
|
||||
BT_INFO("force_md_cnt: old= %u, new= %u.",
|
||||
previous, force_md_cnt);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_FORCE_MD_AUTO */
|
||||
|
||||
mfy.param = conn;
|
||||
|
||||
mayfly_enqueue(TICKER_USER_ID_THREAD, TICKER_USER_ID_ULL_HIGH,
|
||||
0, &mfy);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_FORCE_MD_AUTO)
|
||||
} else {
|
||||
lll_conn_force_md_cnt_set(0U);
|
||||
#endif /* CONFIG_BT_CTLR_FORCE_MD_AUTO */
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_PERIPHERAL)
|
||||
|
@ -6291,3 +6313,42 @@ ull_conn_rx_unknown_rsp_send:
|
|||
|
||||
return nack;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_FORCE_MD_AUTO)
|
||||
static uint8_t force_md_cnt_calc(struct lll_conn *lll_conn, uint32_t tx_rate)
|
||||
{
|
||||
uint32_t time_incoming, time_outgoing;
|
||||
uint8_t force_md_cnt;
|
||||
uint8_t phy;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
phy = lll_conn->phy_tx;
|
||||
#else /* !CONFIG_BT_CTLR_PHY */
|
||||
phy = PHY_1M;
|
||||
#endif /* !CONFIG_BT_CTLR_PHY */
|
||||
|
||||
time_incoming = (CONFIG_BT_CTLR_DATA_LENGTH_MAX << 3) *
|
||||
1000000UL / tx_rate;
|
||||
time_outgoing = PKT_DC_US(CONFIG_BT_CTLR_DATA_LENGTH_MAX,
|
||||
(PDU_MIC_SIZE * lll_conn->enc_tx), phy) +
|
||||
PKT_DC_US(0U, 0U, phy) +
|
||||
(EVENT_IFS_US << 1);
|
||||
|
||||
force_md_cnt = 0U;
|
||||
if (time_incoming > time_outgoing) {
|
||||
uint32_t delta;
|
||||
uint32_t time_keep_alive;
|
||||
|
||||
delta = (time_incoming << 1) - time_outgoing;
|
||||
time_keep_alive = (PKT_DC_US(0U, 0U, phy) + EVENT_IFS_US) << 1;
|
||||
force_md_cnt = (delta + (time_keep_alive - 1)) /
|
||||
time_keep_alive;
|
||||
BT_DBG("Time: incoming= %u, expected outgoing= %u, delta= %u, "
|
||||
"keepalive= %u, force_md_cnt = %u.",
|
||||
time_incoming, time_outgoing, delta, time_keep_alive,
|
||||
force_md_cnt);
|
||||
}
|
||||
|
||||
return force_md_cnt;
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_FORCE_MD_AUTO */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue