1 /*
2  * Copyright (c) 2021 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <errno.h>
8 #include <zephyr/types.h>
9 #include <zephyr/device.h>
10 
11 #include "util/mem.h"
12 #include "util/memq.h"
13 
14 #include "lll.h"
15 
16 #include "hal/debug.h"
17 
18 /**
19  * @brief Common entry point for LLL event prepare invocations from ULL.
20  *
21  * This function will resolve the event priority and invoke the LLL
22  * lll_prepare_resolve, which decides if event should be programmed in
23  * the radio via the prepare callback function, or queued in the prepare
24  * pipeline.
25  *
26  * @param is_abort_cb   Callback for checking if event is aborted
27  * @param abort_cb      Callback for aborting event
28  * @param prepare_cb    Callback for event prepare
29  * @param event_prio    Priority of event [-128..127]
30  * @param prepare_param Prepare data
31  *
32  * @return 0: Prepare was successfully completed
33  *	   1: TICKER_STATUS_FAILURE: Preemption ticker stop error
34  *	   2: TICKER_STATUS_BUSY: Preemption ticker stop error
35  *	   -EINPROGRESS: Event already in progress and prepare was queued
36  */
lll_prepare(lll_is_abort_cb_t is_abort_cb,lll_abort_cb_t abort_cb,lll_prepare_cb_t prepare_cb,int8_t event_prio,struct lll_prepare_param * prepare_param)37 int lll_prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
38 		lll_prepare_cb_t prepare_cb, int8_t event_prio,
39 		struct lll_prepare_param *prepare_param)
40 {
41 	int err;
42 
43 #if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
44 	int prio = event_prio;
45 	struct lll_hdr *hdr = prepare_param->param;
46 
47 	/* Establish priority based on:
48 	 * 1. Event priority passed to function
49 	 * 2. Force flag => priority = -127
50 	 * 3. Score (events terminated- and too late)
51 	 * 4. Latency (skipped- and programmed latency)
52 	 * 5. Critical priority is immutable (-128)
53 	 */
54 	if (prio > -128) {
55 		if (prepare_param->force) {
56 			prio = -127;
57 		} else {
58 			prio = MAX(-127, prio - hdr->score - hdr->latency);
59 		}
60 	}
61 
62 	prepare_param->prio = prio;
63 #endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
64 
65 	err = lll_prepare_resolve(is_abort_cb, abort_cb, prepare_cb, prepare_param, 0U, 0U);
66 
67 	return err;
68 }
69 
lll_resume(void * param)70 void lll_resume(void *param)
71 {
72 	struct lll_event *next;
73 	int err;
74 
75 	next = param;
76 	err = lll_prepare_resolve(next->is_abort_cb, next->abort_cb, next->prepare_cb,
77 				  &next->prepare_param, next->is_resume, 1U);
78 	LL_ASSERT(!err || err == -EINPROGRESS);
79 }
80 
81 #if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
lll_done_score(void * param,uint8_t result)82 void lll_done_score(void *param, uint8_t result)
83 {
84 	struct lll_hdr *hdr = param;
85 
86 	if (!hdr) {
87 		return;
88 	}
89 
90 	if (result == DONE_COMPLETED) {
91 		hdr->score  = 0;
92 		hdr->latency = 0;
93 	} else {
94 		hdr->score++;
95 	}
96 }
97 #endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
98