| /* |
| * Copyright (c) 2021 Nordic Semiconductor ASA |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <errno.h> |
| #include <zephyr/types.h> |
| #include <zephyr/device.h> |
| |
| #include "util/mem.h" |
| #include "util/memq.h" |
| |
| #include "lll.h" |
| |
| #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER) |
| #define LOG_MODULE_NAME bt_ctlr_lll_common |
| #include "common/log.h" |
| #include "hal/debug.h" |
| |
| /** |
| * @brief Common entry point for LLL event prepare invocations from ULL. |
| * |
| * This function will resolve the event priority and invoke the LLL |
| * lll_prepare_resolve, which decides if event should be programmed in |
| * the radio via the prepare callback function, or queued in the prepare |
| * pipeline. |
| * |
| * @param is_abort_cb Callback for checking if event is aborted |
| * @param abort_cb Callback for aborting event |
| * @param prepare_cb Callback for event prepare |
| * @param event_prio Priority of event [-128..127] |
| * @param prepare_param Prepare data |
| * |
| * @return 0: Prepare was successfully completed |
| * 1: TICKER_STATUS_FAILURE: Preemption ticker stop error |
| * 2: TICKER_STATUS_BUSY: Preemption ticker stop error |
| * -EINPROGRESS: Event already in progress and prepare was queued |
| */ |
| int 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) |
| { |
| #if defined(CONFIG_BT_CTLR_JIT_SCHEDULING) |
| int prio = event_prio; |
| struct lll_hdr *hdr = prepare_param->param; |
| |
| /* Establish priority based on: |
| * 1. Event priority passed to function |
| * 2. Force flag => priority = -127 |
| * 3. Score (events terminated- and too late) |
| * 4. Latency (skipped- and programmed latency) |
| * 5. Critical priority is immutable (-128) |
| */ |
| if (prio > -128) { |
| if (prepare_param->force) { |
| prio = -127; |
| } else { |
| prio = MAX(-127, prio - hdr->score - hdr->latency); |
| } |
| } |
| |
| prepare_param->prio = prio; |
| #endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */ |
| |
| return lll_prepare_resolve(is_abort_cb, abort_cb, prepare_cb, |
| prepare_param, 0, 0); |
| } |
| |
| void lll_resume(void *param) |
| { |
| struct lll_event *next; |
| int ret; |
| |
| next = param; |
| ret = lll_prepare_resolve(next->is_abort_cb, next->abort_cb, |
| next->prepare_cb, &next->prepare_param, |
| next->is_resume, 1); |
| LL_ASSERT(!ret || ret == -EINPROGRESS); |
| } |
| |
| #if defined(CONFIG_BT_CTLR_JIT_SCHEDULING) |
| void lll_done_score(void *param, uint8_t result) |
| { |
| struct lll_hdr *hdr = param; |
| |
| if (!hdr) { |
| return; |
| } |
| |
| if (result == DONE_COMPLETED) { |
| hdr->score = 0; |
| hdr->latency = 0; |
| } else { |
| hdr->score++; |
| } |
| } |
| #endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */ |