Skip to content

Commit 51574c1

Browse files
cvinayakcarlescufi
authored andcommitted
Bluetooth: controller: Avoid retransmission of NACK-ed Tx PDU
Added implementation to avoid retransmitting NACK-ed Tx PDU, to save on current consumption in retrying to transmit in case peer device has no free buffer to receive the PDU. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent c0a6801 commit 51574c1

File tree

2 files changed

+46
-18
lines changed

2 files changed

+46
-18
lines changed

subsys/bluetooth/controller/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,19 @@ config BT_CTLR_FAST_ENC
452452
Maximum CPU time in Radio ISR will increase if this feature is
453453
selected.
454454

455+
config BT_CTLR_TX_RETRY_DISABLE
456+
bool "Disable Tx Retry"
457+
help
458+
Avoid retransmission of a PDU if peer device Nack-ed a transmission
459+
in the current connection event, close the connection event so as to
460+
save current consumption on retries (in case peer has no buffers to
461+
receive new PDUs).
462+
463+
Enabling this will lower power consumption, but increase transmission
464+
latencies by one connection interval as the next attempt to send a PDU
465+
would happen in the next connection event instead of repeated retries
466+
in the current connection event.
467+
455468
config BT_CTLR_CONN_RSSI
456469
bool "Connection RSSI"
457470
help

subsys/bluetooth/controller/ll_sw/ctrl.c

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,10 +1738,13 @@ static inline void isr_rx_conn_phy_tx_time_set(void)
17381738
}
17391739
#endif /* CONFIG_BT_CTLR_PHY */
17401740

1741-
static inline u8_t isr_rx_conn_pkt_ack(struct pdu_data *pdu_data_tx,
1741+
#define ERR_TERMINATE 1
1742+
#define ERR_TX_NACK 2
1743+
1744+
static inline u32_t isr_rx_conn_pkt_ack(struct pdu_data *pdu_data_tx,
17421745
struct radio_pdu_node_tx **node_tx)
17431746
{
1744-
u8_t terminate = 0;
1747+
u32_t ret = 0;
17451748

17461749
switch (pdu_data_tx->llctrl.opcode) {
17471750
case PDU_DATA_LLCTRL_TYPE_TERMINATE_IND:
@@ -1758,7 +1761,7 @@ static inline u8_t isr_rx_conn_pkt_ack(struct pdu_data *pdu_data_tx,
17581761
pdu_data_tx->llctrl.terminate_ind.error_code);
17591762

17601763
/* Ack received, hence terminate */
1761-
terminate = 1;
1764+
ret = ERR_TERMINATE;
17621765
break;
17631766

17641767
#if defined(CONFIG_BT_CTLR_LE_ENC)
@@ -1868,7 +1871,7 @@ static inline u8_t isr_rx_conn_pkt_ack(struct pdu_data *pdu_data_tx,
18681871
break;
18691872
}
18701873

1871-
return terminate;
1874+
return ret;
18721875
}
18731876

18741877
static inline struct radio_pdu_node_tx *
@@ -3338,8 +3341,7 @@ isr_rx_conn_pkt(struct radio_pdu_node_rx *node_rx,
33383341
{
33393342
struct pdu_data *pdu_data_rx;
33403343
struct pdu_data *pdu_data_tx;
3341-
u8_t terminate = 0;
3342-
u8_t nack = 0;
3344+
u32_t ret = 0;
33433345

33443346
/* Ack for transmitted data */
33453347
pdu_data_rx = (void *)node_rx->pdu_data;
@@ -3372,9 +3374,8 @@ isr_rx_conn_pkt(struct radio_pdu_node_rx *node_rx,
33723374

33733375
/* process ctrl packet on tx cmplt */
33743376
if (pdu_data_tx->ll_id == PDU_DATA_LLID_CTRL) {
3375-
terminate =
3376-
isr_rx_conn_pkt_ack(pdu_data_tx,
3377-
&node_tx);
3377+
ret = isr_rx_conn_pkt_ack(pdu_data_tx,
3378+
&node_tx);
33783379
}
33793380
}
33803381

@@ -3386,14 +3387,18 @@ isr_rx_conn_pkt(struct radio_pdu_node_rx *node_rx,
33863387
} else {
33873388
_radio.conn_curr->empty = 0;
33883389
}
3390+
#if defined(CONFIG_BT_CTLR_TX_RETRY_DISABLE)
3391+
} else if (_radio.packet_counter != 1) {
3392+
ret = ERR_TX_NACK;
3393+
#endif /* CONFIG_BT_CTLR_TX_RETRY_DISABLE */
33893394
}
33903395

33913396
/* local initiated disconnect procedure completed */
3392-
if (terminate) {
3397+
if (ret == ERR_TERMINATE) {
33933398
connection_release(_radio.conn_curr);
33943399
_radio.conn_curr = NULL;
33953400

3396-
return terminate;
3401+
return ret;
33973402
}
33983403

33993404
/* process received data */
@@ -3414,6 +3419,7 @@ isr_rx_conn_pkt(struct radio_pdu_node_rx *node_rx,
34143419
(_radio.fc_handle[_radio.fc_req - 1] ==
34153420
_radio.conn_curr->handle)))))) {
34163421
u8_t ccm_rx_increment = 0;
3422+
u8_t nack = 0;
34173423

34183424
if (pdu_data_rx->len != 0) {
34193425
/* If required, wait for CCM to finish
@@ -3507,7 +3513,7 @@ isr_rx_conn_pkt(struct radio_pdu_node_rx *node_rx,
35073513
}
35083514
}
35093515

3510-
return 0;
3516+
return ret;
35113517
}
35123518

35133519
static inline void isr_rx_conn(u8_t crc_ok, u8_t trx_done,
@@ -3520,6 +3526,7 @@ static inline void isr_rx_conn(u8_t crc_ok, u8_t trx_done,
35203526
struct pdu_data *pdu_data_tx;
35213527
u8_t rx_enqueue = 0;
35223528
u8_t crc_close = 0;
3529+
u32_t rx_ret = 0;
35233530

35243531
#if defined(CONFIG_BT_CTLR_PROFILE_ISR)
35253532
static u8_t s_lmin = (u8_t) -1;
@@ -3543,10 +3550,8 @@ static inline void isr_rx_conn(u8_t crc_ok, u8_t trx_done,
35433550
node_rx->hdr.type = NODE_RX_TYPE_DC_PDU;
35443551

35453552
if (crc_ok) {
3546-
u32_t terminate;
3547-
3548-
terminate = isr_rx_conn_pkt(node_rx, &tx_release, &rx_enqueue);
3549-
if (terminate) {
3553+
rx_ret = isr_rx_conn_pkt(node_rx, &tx_release, &rx_enqueue);
3554+
if (rx_ret == ERR_TERMINATE) {
35503555
goto isr_rx_conn_exit;
35513556
}
35523557

@@ -3609,13 +3614,23 @@ static inline void isr_rx_conn(u8_t crc_ok, u8_t trx_done,
36093614
pdu_data_rx = (void *)node_rx->pdu_data;
36103615
_radio.state = ((_radio.state == STATE_CLOSE) || (crc_close) ||
36113616
((crc_ok) && (pdu_data_rx->md == 0) &&
3612-
(pdu_data_tx->len == 0)) ||
3617+
((pdu_data_tx->len == 0) ||
3618+
#if defined(CONFIG_BT_CTLR_TX_RETRY_DISABLE)
3619+
(rx_ret == ERR_TX_NACK))) ||
3620+
#else /* !CONFIG_BT_CTLR_TX_RETRY_DISABLE */
3621+
(0))) ||
3622+
#endif /* !CONFIG_BT_CTLR_TX_RETRY_DISABLE */
36133623
_radio.conn_curr->llcp_terminate.reason_peer) ?
36143624
STATE_CLOSE : STATE_TX;
36153625

36163626
if (_radio.state == STATE_CLOSE) {
36173627
/* Event close for master */
3618-
if (_radio.role == ROLE_MASTER) {
3628+
if ((_radio.role == ROLE_MASTER) ||
3629+
#if defined(CONFIG_BT_CTLR_TX_RETRY_DISABLE)
3630+
(rx_ret == ERR_TX_NACK)) {
3631+
#else /* !CONFIG_BT_CTLR_TX_RETRY_DISABLE */
3632+
(0)) {
3633+
#endif /* !CONFIG_BT_CTLR_TX_RETRY_DISABLE */
36193634
_radio.conn_curr->empty = is_empty_pdu_tx_retry;
36203635

36213636
radio_disable();

0 commit comments

Comments
 (0)