From c409b74f0dcd9659fe85bfb2b81f42d8bece6f8a Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Mon, 2 Aug 2021 06:05:34 +0530 Subject: [PATCH] Bluetooth: Controller: Add lll_prof_reserve profiling function Add the lll_prof_reserve and lll_prof_reserve_send profiling functions to use when profiling active scanning and initiator. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/lll/lll_adv.c | 4 +- .../controller/ll_sw/nordic/lll/lll_adv_aux.c | 7 +- .../controller/ll_sw/nordic/lll/lll_prof.c | 102 +++++++++++++----- .../ll_sw/nordic/lll/lll_prof_internal.h | 2 + 4 files changed, 82 insertions(+), 33 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c index 994b8491138..7e3751ca2a0 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c @@ -1049,6 +1049,7 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param) static void isr_tx(void *param) { uint32_t hcto; + struct node_rx_pdu *node_rx_prof; #if defined(CONFIG_BT_CTLR_ADV_EXT) struct lll_adv *lll = param; uint8_t phy_p = lll->phy_p; @@ -1060,6 +1061,7 @@ static void isr_tx(void *param) if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) { lll_prof_latency_capture(); + node_rx_prof = lll_prof_reserve(); } /* Clear radio tx status and events */ @@ -1122,7 +1124,7 @@ static void isr_tx(void *param) /* NOTE: as scratch packet is used to receive, it is safe to * generate profile event using rx nodes. */ - lll_prof_send(); + lll_prof_reserve_send(node_rx_prof); } } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c index 0e50233559f..14e21ff8130 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_aux.c @@ -362,12 +362,14 @@ static void isr_done(void *param) static void isr_tx(void *param) { + struct node_rx_pdu *node_rx_prof; struct lll_adv_aux *lll_aux; struct lll_adv *lll; uint32_t hcto; if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) { lll_prof_latency_capture(); + node_rx_prof = lll_prof_reserve(); } /* Clear radio tx status and events */ @@ -430,10 +432,7 @@ static void isr_tx(void *param) #endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */ if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) { - /* NOTE: as scratch packet is used to receive, it is safe to - * generate profile event using rx nodes. - */ - lll_prof_send(); + lll_prof_reserve_send(node_rx_prof); } } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof.c index 984cccd83bd..2f9ab7ccff3 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof.c @@ -6,6 +6,7 @@ #include #include +#include #include @@ -18,6 +19,7 @@ #include "lll.h" +static int send(struct node_rx_pdu *rx); static inline void sample(uint32_t *timestamp); static inline void delta(uint32_t timestamp, uint8_t *cputime); @@ -111,8 +113,50 @@ void lll_prof_cputime_capture(void) } void lll_prof_send(void) +{ + struct node_rx_pdu *rx; + + /* Generate only if spare node rx is available */ + rx = ull_pdu_rx_alloc_peek(3); + if (rx) { + (void)send(NULL); + } +} + +struct node_rx_pdu *lll_prof_reserve(void) +{ + struct node_rx_pdu *rx; + + rx = ull_pdu_rx_alloc_peek(3); + if (!rx) { + return NULL; + } + + ull_pdu_rx_alloc(); + + return rx; +} + +void lll_prof_reserve_send(struct node_rx_pdu *rx) +{ + if (rx) { + int err; + + err = send(rx); + if (err) { + rx->hdr.type = NODE_RX_TYPE_PROFILE; + + ull_rx_put(rx->hdr.link, rx); + ull_rx_sched(); + } + } +} + +static int send(struct node_rx_pdu *rx) { uint8_t latency, cputime, prev; + struct pdu_data *pdu; + struct profile *p; uint8_t chg = 0U; /* calculate the elapsed time in us since on-air radio packet end @@ -163,37 +207,39 @@ void lll_prof_send(void) } /* generate event if any change */ - if (chg) { - struct node_rx_pdu *rx; + if (!chg) { + return -ENODATA; + } - /* NOTE: enqueue only if rx buffer available, else ignore */ - rx = ull_pdu_rx_alloc_peek(3); - if (rx) { - struct pdu_data *pdu; - struct profile *p; - - ull_pdu_rx_alloc(); - - rx->hdr.type = NODE_RX_TYPE_PROFILE; - rx->hdr.handle = 0xFFFF; - - pdu = (void *)rx->pdu; - p = &pdu->profile; - p->lcur = latency; - p->lmin = latency_min; - p->lmax = latency_max; - p->cur = cputime; - p->min = cputime_min; - p->max = cputime_max; - p->radio = cputime_radio; - p->lll = cputime_lll; - p->ull_high = cputime_ull_high; - p->ull_low = cputime_ull_low; - - ull_rx_put(rx->hdr.link, rx); - ull_rx_sched(); + /* Allocate if not already allocated */ + if (!rx) { + rx = ull_pdu_rx_alloc(); + if (!rx) { + return -ENOMEM; } } + + /* Generate event with the allocated node rx */ + rx->hdr.type = NODE_RX_TYPE_PROFILE; + rx->hdr.handle = NODE_RX_HANDLE_INVALID; + + pdu = (void *)rx->pdu; + p = &pdu->profile; + p->lcur = latency; + p->lmin = latency_min; + p->lmax = latency_max; + p->cur = cputime; + p->min = cputime_min; + p->max = cputime_max; + p->radio = cputime_radio; + p->lll = cputime_lll; + p->ull_high = cputime_ull_high; + p->ull_low = cputime_ull_low; + + ull_rx_put(rx->hdr.link, rx); + ull_rx_sched(); + + return 0; } static inline void sample(uint32_t *timestamp) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof_internal.h b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof_internal.h index 8a318a9a601..603f3cf6b69 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof_internal.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_prof_internal.h @@ -28,3 +28,5 @@ void lll_prof_latency_capture(void); void lll_prof_radio_end_backup(void); void lll_prof_cputime_capture(void); void lll_prof_send(void); +struct node_rx_pdu *lll_prof_reserve(void); +void lll_prof_reserve_send(struct node_rx_pdu *rx);