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 c2fc629dd2
("Bluetooth: controller:
255 byte AD payload support").
Fixes #29967.
Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
05ca10001e
commit
ef2ece82c0
3 changed files with 322 additions and 45 deletions
|
@ -18,7 +18,9 @@
|
|||
#include "hal/ticker.h"
|
||||
|
||||
#include "util/util.h"
|
||||
#include "util/mem.h"
|
||||
#include "util/memq.h"
|
||||
#include "util/mfifo.h"
|
||||
|
||||
#include "ticker/ticker.h"
|
||||
|
||||
|
@ -75,6 +77,46 @@ static inline bool isr_rx_ci_tgta_check(struct lll_adv *lll,
|
|||
static inline bool isr_rx_ci_adva_check(struct pdu_adv *adv,
|
||||
struct pdu_adv *ci);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
#define PAYLOAD_FRAG_COUNT ((CONFIG_BT_CTLR_ADV_DATA_LEN_MAX + \
|
||||
PDU_AC_PAYLOAD_SIZE_MAX - 1) / \
|
||||
PDU_AC_PAYLOAD_SIZE_MAX)
|
||||
#define BT_CTLR_ADV_AUX_SET CONFIG_BT_CTLR_ADV_AUX_SET
|
||||
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
|
||||
#define BT_CTLR_ADV_SYNC_SET CONFIG_BT_CTLR_ADV_SYNC_SET
|
||||
#else /* !CONFIG_BT_CTLR_ADV_PERIODIC */
|
||||
#define BT_CTLR_ADV_SYNC_SET 0
|
||||
#endif /* !CONFIG_BT_CTLR_ADV_PERIODIC */
|
||||
#else
|
||||
#define PAYLOAD_FRAG_COUNT 1
|
||||
#define BT_CTLR_ADV_AUX_SET 0
|
||||
#define BT_CTLR_ADV_SYNC_SET 0
|
||||
#endif
|
||||
|
||||
#define PDU_MEM_SIZE MROUND(PDU_AC_LL_HEADER_SIZE + \
|
||||
PDU_AC_PAYLOAD_SIZE_MAX)
|
||||
#define PDU_MEM_COUNT_MIN (BT_CTLR_ADV_SET + \
|
||||
(BT_CTLR_ADV_SET * PAYLOAD_FRAG_COUNT) + \
|
||||
(BT_CTLR_ADV_AUX_SET * PAYLOAD_FRAG_COUNT) + \
|
||||
(BT_CTLR_ADV_SYNC_SET * PAYLOAD_FRAG_COUNT))
|
||||
#define PDU_MEM_FIFO_COUNT ((BT_CTLR_ADV_SET * PAYLOAD_FRAG_COUNT * 2) + \
|
||||
(CONFIG_BT_CTLR_ADV_DATA_BUF_MAX * \
|
||||
PAYLOAD_FRAG_COUNT))
|
||||
#define PDU_MEM_COUNT (PDU_MEM_COUNT_MIN + PDU_MEM_FIFO_COUNT)
|
||||
#define PDU_POOL_SIZE (PDU_MEM_SIZE * PDU_MEM_COUNT)
|
||||
|
||||
/* Free AD data PDU buffer pool */
|
||||
static struct {
|
||||
void *free;
|
||||
uint8_t pool[PDU_POOL_SIZE];
|
||||
} mem_pdu;
|
||||
|
||||
/* FIFO to return stale AD data PDU buffers from LLL to thread context */
|
||||
static MFIFO_DEFINE(pdu_free, sizeof(void *), PDU_MEM_FIFO_COUNT);
|
||||
|
||||
/* Semaphore to wakeup thread waiting for free AD data PDU buffers */
|
||||
static struct k_sem sem_pdu_free;
|
||||
|
||||
int lll_adv_init(void)
|
||||
{
|
||||
int err;
|
||||
|
@ -99,6 +141,166 @@ int lll_adv_reset(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int lll_adv_data_init(struct lll_adv_pdu *pdu)
|
||||
{
|
||||
struct pdu_adv *p;
|
||||
|
||||
p = mem_acquire(&mem_pdu.free);
|
||||
if (!p) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pdu->pdu[0] = (void *)p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lll_adv_data_reset(struct lll_adv_pdu *pdu)
|
||||
{
|
||||
/* NOTE: this function is used on HCI reset to mem-zero the structure
|
||||
* members that otherwise was zero-ed by the architecture
|
||||
* startup code that zero-ed the .bss section.
|
||||
* pdu[0] element in the array is not initialized as subsequent
|
||||
* call to lll_adv_data_init will allocate a PDU buffer and
|
||||
* assign that.
|
||||
*/
|
||||
|
||||
pdu->first = 0U;
|
||||
pdu->last = 0U;
|
||||
pdu->pdu[1] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lll_adv_data_release(struct lll_adv_pdu *pdu)
|
||||
{
|
||||
uint8_t last;
|
||||
void *p;
|
||||
|
||||
last = pdu->last;
|
||||
p = pdu->pdu[last];
|
||||
pdu->pdu[last] = NULL;
|
||||
mem_release(p, &mem_pdu.free);
|
||||
|
||||
last++;
|
||||
if (last == DOUBLE_BUFFER_SIZE) {
|
||||
last = 0U;
|
||||
}
|
||||
p = pdu->pdu[last];
|
||||
if (p) {
|
||||
pdu->pdu[last] = NULL;
|
||||
mem_release(p, &mem_pdu.free);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct pdu_adv *lll_adv_pdu_alloc(struct lll_adv_pdu *pdu, uint8_t *idx)
|
||||
{
|
||||
uint8_t first, last;
|
||||
struct pdu_adv *p;
|
||||
int err;
|
||||
|
||||
first = pdu->first;
|
||||
last = pdu->last;
|
||||
if (first == last) {
|
||||
last++;
|
||||
if (last == DOUBLE_BUFFER_SIZE) {
|
||||
last = 0U;
|
||||
}
|
||||
} else {
|
||||
uint8_t first_latest;
|
||||
|
||||
pdu->last = first;
|
||||
/* FIXME: Ensure that data is synchronized so that an ISR
|
||||
* vectored, after pdu->last has been updated, does
|
||||
* access the latest value. __DSB() is used in ARM
|
||||
* Cortex M4 architectures. Use appropriate
|
||||
* instructions on other platforms.
|
||||
*
|
||||
* cpu_dsb();
|
||||
*/
|
||||
first_latest = pdu->first;
|
||||
if (first_latest != first) {
|
||||
last++;
|
||||
if (last == DOUBLE_BUFFER_SIZE) {
|
||||
last = 0U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*idx = last;
|
||||
|
||||
p = (void *)pdu->pdu[last];
|
||||
if (p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
p = MFIFO_DEQUEUE_PEEK(pdu_free);
|
||||
if (p) {
|
||||
err = k_sem_take(&sem_pdu_free, K_NO_WAIT);
|
||||
LL_ASSERT(!err);
|
||||
|
||||
MFIFO_DEQUEUE(pdu_free);
|
||||
pdu->pdu[last] = (void *)p;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
p = mem_acquire(&mem_pdu.free);
|
||||
if (p) {
|
||||
pdu->pdu[last] = (void *)p;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
err = k_sem_take(&sem_pdu_free, K_FOREVER);
|
||||
LL_ASSERT(!err);
|
||||
|
||||
p = MFIFO_DEQUEUE(pdu_free);
|
||||
LL_ASSERT(p);
|
||||
|
||||
pdu->pdu[last] = (void *)p;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
struct pdu_adv *lll_adv_pdu_latest_get(struct lll_adv_pdu *pdu,
|
||||
uint8_t *is_modified)
|
||||
{
|
||||
uint8_t first;
|
||||
|
||||
first = pdu->first;
|
||||
if (first != pdu->last) {
|
||||
uint8_t free_idx;
|
||||
uint8_t pdu_idx;
|
||||
void *p;
|
||||
|
||||
if (!MFIFO_ENQUEUE_IDX_GET(pdu_free, &free_idx)) {
|
||||
LL_ASSERT(false);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pdu_idx = first;
|
||||
|
||||
first += 1U;
|
||||
if (first == DOUBLE_BUFFER_SIZE) {
|
||||
first = 0U;
|
||||
}
|
||||
pdu->first = first;
|
||||
*is_modified = 1U;
|
||||
|
||||
p = pdu->pdu[pdu_idx];
|
||||
pdu->pdu[pdu_idx] = NULL;
|
||||
|
||||
MFIFO_BY_IDX_ENQUEUE(pdu_free, free_idx, p);
|
||||
k_sem_give(&sem_pdu_free);
|
||||
}
|
||||
|
||||
return (void *)pdu->pdu[first];
|
||||
}
|
||||
|
||||
void lll_adv_prepare(void *param)
|
||||
{
|
||||
struct lll_prepare_param *p = param;
|
||||
|
|
|
@ -4,13 +4,61 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_SET)
|
||||
#define BT_CTLR_ADV_SET CONFIG_BT_CTLR_ADV_SET
|
||||
#else /* CONFIG_BT_CTLR_ADV_SET */
|
||||
#define BT_CTLR_ADV_SET 1
|
||||
#endif /* CONFIG_BT_CTLR_ADV_SET */
|
||||
|
||||
/* Structure used to double buffer pointers of AD Data PDU buffer.
|
||||
* The first and last members are used to make modification to AD data to be
|
||||
* context safe. Thread always appends or updates the buffer pointed to
|
||||
* the array element indexed by the member last.
|
||||
* LLL in the ISR context, checks, traverses to the valid pointer indexed
|
||||
* by the member first, such that the buffer is the latest committed by
|
||||
* the thread context.
|
||||
*/
|
||||
struct lll_adv_pdu {
|
||||
uint8_t first;
|
||||
uint8_t last;
|
||||
/* TODO: use,
|
||||
* struct pdu_adv *pdu[DOUBLE_BUFFER_SIZE];
|
||||
*/
|
||||
uint8_t pdu[DOUBLE_BUFFER_SIZE][PDU_AC_LL_SIZE_MAX];
|
||||
uint8_t volatile first;
|
||||
uint8_t last;
|
||||
uint8_t *pdu[DOUBLE_BUFFER_SIZE];
|
||||
};
|
||||
|
||||
struct lll_adv_aux {
|
||||
struct lll_hdr hdr;
|
||||
struct lll_adv *adv;
|
||||
|
||||
uint32_t ticks_offset;
|
||||
|
||||
struct lll_adv_pdu data;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
|
||||
int8_t tx_pwr_lvl;
|
||||
#endif /* CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */
|
||||
};
|
||||
|
||||
struct lll_adv_sync {
|
||||
struct lll_hdr hdr;
|
||||
struct lll_adv *adv;
|
||||
|
||||
uint8_t access_addr[4];
|
||||
uint8_t crc_init[3];
|
||||
|
||||
uint16_t latency_prepare;
|
||||
uint16_t latency_event;
|
||||
uint16_t event_counter;
|
||||
|
||||
uint8_t data_chan_map[5];
|
||||
uint8_t data_chan_count:6;
|
||||
uint16_t data_chan_id;
|
||||
|
||||
uint32_t ticks_offset;
|
||||
|
||||
struct lll_adv_pdu data;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
|
||||
int8_t tx_pwr_lvl;
|
||||
#endif /* CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */
|
||||
};
|
||||
|
||||
struct lll_adv {
|
||||
|
@ -28,7 +76,12 @@ struct lll_adv {
|
|||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
uint8_t phy_p:3;
|
||||
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
|
||||
uint8_t phy_s:3;
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY)
|
||||
uint8_t scan_req_notify:1;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_HCI_MESH_EXT)
|
||||
uint8_t is_mesh:1;
|
||||
|
@ -40,32 +93,32 @@ struct lll_adv {
|
|||
|
||||
struct lll_adv_pdu adv_data;
|
||||
struct lll_adv_pdu scan_rsp;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
struct lll_adv_aux *aux;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
|
||||
struct lll_adv_sync *sync;
|
||||
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
|
||||
int8_t tx_pwr_lvl;
|
||||
#endif /* CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
struct node_rx_hdr *node_rx_adv_term;
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
};
|
||||
|
||||
int lll_adv_init(void);
|
||||
int lll_adv_reset(void);
|
||||
|
||||
int lll_adv_data_init(struct lll_adv_pdu *pdu);
|
||||
int lll_adv_data_reset(struct lll_adv_pdu *pdu);
|
||||
int lll_adv_data_release(struct lll_adv_pdu *pdu);
|
||||
struct pdu_adv *lll_adv_pdu_alloc(struct lll_adv_pdu *pdu, uint8_t *idx);
|
||||
void lll_adv_prepare(void *param);
|
||||
|
||||
static inline struct pdu_adv *lll_adv_pdu_alloc(struct lll_adv_pdu *pdu,
|
||||
uint8_t *idx)
|
||||
{
|
||||
uint8_t last;
|
||||
|
||||
if (pdu->first == pdu->last) {
|
||||
last = pdu->last + 1;
|
||||
if (last == DOUBLE_BUFFER_SIZE) {
|
||||
last = 0U;
|
||||
}
|
||||
} else {
|
||||
last = pdu->last;
|
||||
}
|
||||
|
||||
*idx = last;
|
||||
|
||||
return (void *)pdu->pdu[last];
|
||||
}
|
||||
|
||||
static inline void lll_adv_pdu_enqueue(struct lll_adv_pdu *pdu, uint8_t idx)
|
||||
{
|
||||
pdu->last = idx;
|
||||
|
@ -102,4 +155,42 @@ static inline struct pdu_adv *lll_adv_scan_rsp_peek(struct lll_adv *lll)
|
|||
return (void *)lll->scan_rsp.pdu[lll->scan_rsp.last];
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
static inline struct pdu_adv *lll_adv_aux_data_alloc(struct lll_adv_aux *lll,
|
||||
uint8_t *idx)
|
||||
{
|
||||
return lll_adv_pdu_alloc(&lll->data, idx);
|
||||
}
|
||||
|
||||
static inline void lll_adv_aux_data_enqueue(struct lll_adv_aux *lll,
|
||||
uint8_t idx)
|
||||
{
|
||||
lll_adv_pdu_enqueue(&lll->data, idx);
|
||||
}
|
||||
|
||||
static inline struct pdu_adv *lll_adv_aux_data_peek(struct lll_adv_aux *lll)
|
||||
{
|
||||
return (void *)lll->data.pdu[lll->data.last];
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
|
||||
static inline struct pdu_adv *lll_adv_sync_data_alloc(struct lll_adv_sync *lll,
|
||||
uint8_t *idx)
|
||||
{
|
||||
return lll_adv_pdu_alloc(&lll->data, idx);
|
||||
}
|
||||
|
||||
static inline void lll_adv_sync_data_enqueue(struct lll_adv_sync *lll,
|
||||
uint8_t idx)
|
||||
{
|
||||
lll_adv_pdu_enqueue(&lll->data, idx);
|
||||
}
|
||||
|
||||
static inline struct pdu_adv *lll_adv_sync_data_peek(struct lll_adv_sync *lll)
|
||||
{
|
||||
return (void *)lll->data.pdu[lll->data.last];
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
||||
extern uint16_t ull_adv_lll_handle_get(struct lll_adv *lll);
|
||||
|
|
|
@ -4,24 +4,8 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
static inline struct pdu_adv *lll_adv_pdu_latest_get(struct lll_adv_pdu *pdu,
|
||||
uint8_t *is_modified)
|
||||
{
|
||||
uint8_t first;
|
||||
|
||||
first = pdu->first;
|
||||
if (first != pdu->last) {
|
||||
first += 1U;
|
||||
if (first == DOUBLE_BUFFER_SIZE) {
|
||||
first = 0U;
|
||||
}
|
||||
pdu->first = first;
|
||||
*is_modified = 1U;
|
||||
}
|
||||
|
||||
return (void *)pdu->pdu[first];
|
||||
}
|
||||
|
||||
struct pdu_adv *lll_adv_pdu_latest_get(struct lll_adv_pdu *pdu,
|
||||
uint8_t *is_modified);
|
||||
static inline struct pdu_adv *lll_adv_data_latest_get(struct lll_adv *lll,
|
||||
uint8_t *is_modified)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue