Skip to content

Commit ef2ece8

Browse files
cvinayakcarlescufi
authored andcommitted
Bluetooth: controller: openisa: Fix sanitycheck failures
Fix sanitycheck failures when building samples/bluetooth/peripheral_hr for rv32m1_vega_ri5cy platform. Updates from nRF platform related to 255 byte AD data support have been directly copied into openisa port to fix build failures. Relates to commit c2fc629 ("Bluetooth: controller: 255 byte AD payload support"). Fixes #29967. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
1 parent 05ca100 commit ef2ece8

File tree

3 files changed

+322
-45
lines changed

3 files changed

+322
-45
lines changed

subsys/bluetooth/controller/ll_sw/openisa/lll/lll_adv.c

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
#include "hal/ticker.h"
1919

2020
#include "util/util.h"
21+
#include "util/mem.h"
2122
#include "util/memq.h"
23+
#include "util/mfifo.h"
2224

2325
#include "ticker/ticker.h"
2426

@@ -75,6 +77,46 @@ static inline bool isr_rx_ci_tgta_check(struct lll_adv *lll,
7577
static inline bool isr_rx_ci_adva_check(struct pdu_adv *adv,
7678
struct pdu_adv *ci);
7779

80+
#if defined(CONFIG_BT_CTLR_ADV_EXT)
81+
#define PAYLOAD_FRAG_COUNT ((CONFIG_BT_CTLR_ADV_DATA_LEN_MAX + \
82+
PDU_AC_PAYLOAD_SIZE_MAX - 1) / \
83+
PDU_AC_PAYLOAD_SIZE_MAX)
84+
#define BT_CTLR_ADV_AUX_SET CONFIG_BT_CTLR_ADV_AUX_SET
85+
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
86+
#define BT_CTLR_ADV_SYNC_SET CONFIG_BT_CTLR_ADV_SYNC_SET
87+
#else /* !CONFIG_BT_CTLR_ADV_PERIODIC */
88+
#define BT_CTLR_ADV_SYNC_SET 0
89+
#endif /* !CONFIG_BT_CTLR_ADV_PERIODIC */
90+
#else
91+
#define PAYLOAD_FRAG_COUNT 1
92+
#define BT_CTLR_ADV_AUX_SET 0
93+
#define BT_CTLR_ADV_SYNC_SET 0
94+
#endif
95+
96+
#define PDU_MEM_SIZE MROUND(PDU_AC_LL_HEADER_SIZE + \
97+
PDU_AC_PAYLOAD_SIZE_MAX)
98+
#define PDU_MEM_COUNT_MIN (BT_CTLR_ADV_SET + \
99+
(BT_CTLR_ADV_SET * PAYLOAD_FRAG_COUNT) + \
100+
(BT_CTLR_ADV_AUX_SET * PAYLOAD_FRAG_COUNT) + \
101+
(BT_CTLR_ADV_SYNC_SET * PAYLOAD_FRAG_COUNT))
102+
#define PDU_MEM_FIFO_COUNT ((BT_CTLR_ADV_SET * PAYLOAD_FRAG_COUNT * 2) + \
103+
(CONFIG_BT_CTLR_ADV_DATA_BUF_MAX * \
104+
PAYLOAD_FRAG_COUNT))
105+
#define PDU_MEM_COUNT (PDU_MEM_COUNT_MIN + PDU_MEM_FIFO_COUNT)
106+
#define PDU_POOL_SIZE (PDU_MEM_SIZE * PDU_MEM_COUNT)
107+
108+
/* Free AD data PDU buffer pool */
109+
static struct {
110+
void *free;
111+
uint8_t pool[PDU_POOL_SIZE];
112+
} mem_pdu;
113+
114+
/* FIFO to return stale AD data PDU buffers from LLL to thread context */
115+
static MFIFO_DEFINE(pdu_free, sizeof(void *), PDU_MEM_FIFO_COUNT);
116+
117+
/* Semaphore to wakeup thread waiting for free AD data PDU buffers */
118+
static struct k_sem sem_pdu_free;
119+
78120
int lll_adv_init(void)
79121
{
80122
int err;
@@ -99,6 +141,166 @@ int lll_adv_reset(void)
99141
return 0;
100142
}
101143

144+
int lll_adv_data_init(struct lll_adv_pdu *pdu)
145+
{
146+
struct pdu_adv *p;
147+
148+
p = mem_acquire(&mem_pdu.free);
149+
if (!p) {
150+
return -ENOMEM;
151+
}
152+
153+
pdu->pdu[0] = (void *)p;
154+
155+
return 0;
156+
}
157+
158+
int lll_adv_data_reset(struct lll_adv_pdu *pdu)
159+
{
160+
/* NOTE: this function is used on HCI reset to mem-zero the structure
161+
* members that otherwise was zero-ed by the architecture
162+
* startup code that zero-ed the .bss section.
163+
* pdu[0] element in the array is not initialized as subsequent
164+
* call to lll_adv_data_init will allocate a PDU buffer and
165+
* assign that.
166+
*/
167+
168+
pdu->first = 0U;
169+
pdu->last = 0U;
170+
pdu->pdu[1] = NULL;
171+
172+
return 0;
173+
}
174+
175+
int lll_adv_data_release(struct lll_adv_pdu *pdu)
176+
{
177+
uint8_t last;
178+
void *p;
179+
180+
last = pdu->last;
181+
p = pdu->pdu[last];
182+
pdu->pdu[last] = NULL;
183+
mem_release(p, &mem_pdu.free);
184+
185+
last++;
186+
if (last == DOUBLE_BUFFER_SIZE) {
187+
last = 0U;
188+
}
189+
p = pdu->pdu[last];
190+
if (p) {
191+
pdu->pdu[last] = NULL;
192+
mem_release(p, &mem_pdu.free);
193+
}
194+
195+
return 0;
196+
}
197+
198+
struct pdu_adv *lll_adv_pdu_alloc(struct lll_adv_pdu *pdu, uint8_t *idx)
199+
{
200+
uint8_t first, last;
201+
struct pdu_adv *p;
202+
int err;
203+
204+
first = pdu->first;
205+
last = pdu->last;
206+
if (first == last) {
207+
last++;
208+
if (last == DOUBLE_BUFFER_SIZE) {
209+
last = 0U;
210+
}
211+
} else {
212+
uint8_t first_latest;
213+
214+
pdu->last = first;
215+
/* FIXME: Ensure that data is synchronized so that an ISR
216+
* vectored, after pdu->last has been updated, does
217+
* access the latest value. __DSB() is used in ARM
218+
* Cortex M4 architectures. Use appropriate
219+
* instructions on other platforms.
220+
*
221+
* cpu_dsb();
222+
*/
223+
first_latest = pdu->first;
224+
if (first_latest != first) {
225+
last++;
226+
if (last == DOUBLE_BUFFER_SIZE) {
227+
last = 0U;
228+
}
229+
}
230+
}
231+
232+
*idx = last;
233+
234+
p = (void *)pdu->pdu[last];
235+
if (p) {
236+
return p;
237+
}
238+
239+
p = MFIFO_DEQUEUE_PEEK(pdu_free);
240+
if (p) {
241+
err = k_sem_take(&sem_pdu_free, K_NO_WAIT);
242+
LL_ASSERT(!err);
243+
244+
MFIFO_DEQUEUE(pdu_free);
245+
pdu->pdu[last] = (void *)p;
246+
247+
return p;
248+
}
249+
250+
p = mem_acquire(&mem_pdu.free);
251+
if (p) {
252+
pdu->pdu[last] = (void *)p;
253+
254+
return p;
255+
}
256+
257+
err = k_sem_take(&sem_pdu_free, K_FOREVER);
258+
LL_ASSERT(!err);
259+
260+
p = MFIFO_DEQUEUE(pdu_free);
261+
LL_ASSERT(p);
262+
263+
pdu->pdu[last] = (void *)p;
264+
265+
return p;
266+
}
267+
268+
struct pdu_adv *lll_adv_pdu_latest_get(struct lll_adv_pdu *pdu,
269+
uint8_t *is_modified)
270+
{
271+
uint8_t first;
272+
273+
first = pdu->first;
274+
if (first != pdu->last) {
275+
uint8_t free_idx;
276+
uint8_t pdu_idx;
277+
void *p;
278+
279+
if (!MFIFO_ENQUEUE_IDX_GET(pdu_free, &free_idx)) {
280+
LL_ASSERT(false);
281+
282+
return NULL;
283+
}
284+
285+
pdu_idx = first;
286+
287+
first += 1U;
288+
if (first == DOUBLE_BUFFER_SIZE) {
289+
first = 0U;
290+
}
291+
pdu->first = first;
292+
*is_modified = 1U;
293+
294+
p = pdu->pdu[pdu_idx];
295+
pdu->pdu[pdu_idx] = NULL;
296+
297+
MFIFO_BY_IDX_ENQUEUE(pdu_free, free_idx, p);
298+
k_sem_give(&sem_pdu_free);
299+
}
300+
301+
return (void *)pdu->pdu[first];
302+
}
303+
102304
void lll_adv_prepare(void *param)
103305
{
104306
struct lll_prepare_param *p = param;

0 commit comments

Comments
 (0)