1 /*
2 * Copyright (c) 2017-2019 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * User CPR Interval
9 */
10 #if !defined(CONFIG_BT_CTLR_USER_CPR_INTERVAL_MIN)
11 /* Bluetooth defined CPR Interval Minimum (7.5ms) */
12 #define CONN_INTERVAL_MIN(x) (6)
13 #else /* CONFIG_BT_CTLR_USER_CPR_INTERVAL_MIN */
14 /* Proprietary user defined CPR Interval Minimum */
15 #define CONN_INTERVAL_MIN(x) (MAX(ull_conn_interval_min_get(x), 1))
16 #endif /* CONFIG_BT_CTLR_USER_CPR_INTERVAL_MIN */
17
18 /**
19 * User deferance of CPR Anchor Point Move
20 */
21 #if !defined(CONFIG_BT_CTLR_USER_CPR_ANCHOR_POINT_MOVE)
22 #define DEFER_APM_CHECK(x, y, z) (false)
23 #else
24 /* Proprietary handling of peripheral CPR Anchor Point Movement Response
25 *
26 * When returning TRUE the LLCP system changes to a
27 * USER_WAIT state and an EXTERNAL trigger must kick the LLCP system
28 * to continue to either accept (with possibly changed offsets) or reject CPR
29 *
30 * When returning FALSE the LLCP system will automatically
31 * continue and thus respond immediately
32 *
33 * Possibly modified LLCP internal status/error state will determine the type of 'response'
34 * 0U - Accept CPR (possibly with changed offsets)
35 * BT_HCI_ERR_UNSUPP_LL_PARAM_VAL - Reject CPR
36 */
37 struct ll_conn;
38 extern bool ull_handle_cpr_anchor_point_move(struct ll_conn *conn, uint16_t *offsets,
39 uint8_t *status);
40 #define DEFER_APM_CHECK(x, y, z) (ull_handle_cpr_anchor_point_move(x, y, z))
41 #endif /* CONFIG_BT_CTLR_USER_CPR_ANCHOR_POINT_MOVE */
42 /* Macro to convert time in us to connection interval units */
43 #define RADIO_CONN_EVENTS(x, y) ((uint16_t)DIV_ROUND_UP(x, y))
44
45 /* Macro to convert time in us to periodic advertising interval units */
46 #define RADIO_SYNC_EVENTS(x, y) ((uint16_t)DIV_ROUND_UP(x, y))
47
ull_ref_get(struct ull_hdr * hdr)48 static inline uint8_t ull_ref_get(struct ull_hdr *hdr)
49 {
50 return hdr->ref;
51 }
52
ull_ref_inc(struct ull_hdr * hdr)53 static inline uint8_t ull_ref_inc(struct ull_hdr *hdr)
54 {
55 return ++hdr->ref;
56 }
57
ull_ref_dec(struct ull_hdr * hdr)58 static inline uint8_t ull_ref_dec(struct ull_hdr *hdr)
59 {
60 return hdr->ref--;
61 }
62
ull_hdr_init(struct ull_hdr * hdr)63 static inline void ull_hdr_init(struct ull_hdr *hdr)
64 {
65 hdr->ref = 0U;
66 hdr->disabled_cb = hdr->disabled_param = NULL;
67 }
68
69 void *ll_rx_link_alloc(void);
70 void ll_rx_link_release(memq_link_t *link);
71 void *ll_rx_alloc(void);
72 void ll_rx_release(void *node_rx);
73 void *ll_pdu_rx_alloc_peek(uint8_t count);
74 void *ll_pdu_rx_alloc(void);
75 void ll_rx_put_sched(memq_link_t *link, void *rx);
76 void ll_rx_put(memq_link_t *link, void *rx);
77 void ll_rx_sched(void);
78 void ull_ticker_status_give(uint32_t status, void *param);
79 uint32_t ull_ticker_status_take(uint32_t ret, uint32_t volatile *ret_cb);
80 void *ull_disable_mark(void *param);
81 void *ull_disable_unmark(void *param);
82 void *ull_disable_mark_get(void);
83 int ull_ticker_stop_with_mark(uint8_t ticker_handle, void *param,
84 void *lll_disable);
85 void *ull_update_mark(void *param);
86 void *ull_update_unmark(void *param);
87 void *ull_update_mark_get(void);
88 int ull_disable(void *param);
89 void ull_drift_ticks_get(struct node_rx_event_done *done,
90 uint32_t *ticks_drift_plus,
91 uint32_t *ticks_drift_minus);
92
93 /**
94 * @brief RX FIFO macro frontend
95 * @details The RXFIFO data composite consists of an MFIFO with pointers to
96 * data elements backed by a memory pool and memq link elements.
97 * Link memq elements have a separate pool of (_count + _extra_links)
98 * elements. Extra links may be used for initializing one or more
99 * external memq instances. The following data structures are created
100 * with RXFIFO_DEFINE():
101 * - mfifo_<_name>: FIFO with pointers to RX node elements.
102 * - mem_<_name>: Backing data pool of <_count> RX node elements
103 * of size <_size>.
104 * - mem_link_<_name>: Pool of <_count + _extra_links> memq_link_t
105 * elements.
106 */
107 #define RXFIFO_DEFINE(_name, _size, _count, _extra_links) \
108 MFIFO_DEFINE(_name, sizeof(void *), _count); \
109 \
110 static struct { \
111 void *free; \
112 uint16_t size; \
113 uint8_t count; \
114 uint8_t extra_links; \
115 uint8_t pool[MROUND(_size) * (_count)]; \
116 } mem_##_name = { .size = MROUND(_size), .count = _count, \
117 .extra_links = _extra_links }; \
118 \
119 static struct { \
120 void *free; \
121 uint8_t pool[sizeof(memq_link_t) * \
122 (_count + _extra_links)]; \
123 } mem_link_##_name
124
125 /**
126 * @brief Initializes MFIFO and pools
127 * @details This makes the MFIFO empty and will subsequently need
128 * RXFIFO_ALLOC. Memory pools are initialized.
129 */
130 #define RXFIFO_INIT(_name) \
131 MFIFO_INIT(_name); \
132 mem_init(mem_##_name.pool, mem_##_name.size, \
133 mem_##_name.count, &mem_##_name.free); \
134 \
135 mem_init(mem_link_##_name.pool, sizeof(memq_link_t), mem_##_name.count + \
136 mem_##_name.extra_links, &mem_link_##_name.free)
137
138 /**
139 * @brief Allocate FIFO elements with backing
140 * @details This function allocates up to <_count> number of MFIFO elements by
141 * enqueuing pointers to memory elements with associated memq links.
142 */
143 #define RXFIFO_ALLOC(_name, _count) \
144 ull_rxfifo_alloc(mfifo_##_name.s, mfifo_##_name.n, mfifo_##_name.f, \
145 &mfifo_##_name.l, mfifo_##_name.m, &mem_##_name.free, \
146 &mem_link_##_name.free, _count)
147
148 /**
149 * @brief Initialize and allocate MFIFO and pools
150 */
151 #define RXFIFO_INIT_ALLOC(_name) \
152 RXFIFO_INIT(_name); \
153 RXFIFO_ALLOC(_name, mem_##_name.count)
154
155 /**
156 * @brief Release RX node
157 * @details Enqueues an RX node back into the FIFO.
158 */
159 #define RXFIFO_RELEASE(_name, _link, _rx) \
160 ull_rxfifo_release(mfifo_##_name.s, mfifo_##_name.n, mfifo_##_name.f, \
161 &mfifo_##_name.l, mfifo_##_name.m, _link, \
162 (struct node_rx_hdr *)_rx)
163
164 void ull_rxfifo_alloc(uint8_t s, uint8_t n, uint8_t f, uint8_t *l, uint8_t *m,
165 void *mem_free, void *link_free, uint8_t max);
166 void *ull_rxfifo_release(uint8_t s, uint8_t n, uint8_t f, uint8_t *l, uint8_t *m,
167 memq_link_t *link, struct node_rx_hdr *rx);
168