Bluetooth: controller: Add extra data storage for ext. adv. configuration

The storage for extra data is required for implementation of
CTE transmission with periodic advertising.

Data required to transmit CTE correctly are compound of two parts:
- PDU field CTEInfo
- radio configuration to transmit actual constant tone at the end
  of PDU.

Extra data is a storage required for radio configuration data.
Nevertheless it must be in compliance with content of CTEInfo field.
Because of that extra data is stored as part of lll_adv_pdu and
is double buffered like PDU memory.

Bluetooth 5.1 spec. allows to enable or disable CTE TX
and change CTE TX parameters when periodic advertising is
enabled. Besides that CTE TX settings may be set before periodic
advertising parameters are set. In such situation ll_adv_sync_set
may be not yet created.
To overcome these constraints ULL should store CTE TX
settings and forward them to LLL only when CTE TX is enabled.
Because of above reasons ULL stores CTE TX settings in ll_adv_set.

Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
This commit is contained in:
Piotr Pryga 2021-01-09 03:58:52 -08:00 committed by Anas Nashif
commit b56a2d1384
9 changed files with 376 additions and 51 deletions

View file

@ -100,6 +100,7 @@ config BT_CTLR_DF_CONN_CTE_RSP
config BT_CTLR_DF_ADV_CTE_TX
bool "Enable Connectionless CTE Transmitter feature"
depends on BT_CTLR_DF_CTE_TX && BT_CTLR_ADV_PERIODIC
select BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY
default y
help
Enable support for Bluetooth v5.1 Connectionless CTE Transmitter

View file

@ -175,6 +175,20 @@ config BT_CTLR_ADV_DATA_BUF_MAX
Maximum number of buffered Advertising Data payload across enabled
advertising sets.
config BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY
bool
depends on BT_CTLR_ADV_EXT
help
Add additional memory to advertising PDU storage. The memory is a
general purpose storage for data that should be send from ULL to LLL.
The data stored in the memory are in synchoronization with content
of PDU memory.
For example, the extra data memory is used for storage for parameters
to configure Radio peripheral to transmit CTE. The configuration data
must be synchronized with CTEInfo field in extended advertising header
that is part of PDU data.
config BT_CTRL_ADV_ADI_IN_SCAN_RSP
bool "Include ADI in AUX_SCAN_RSP PDU"
depends on BT_BROADCASTER && BT_CTLR_ADV_EXT

View file

@ -39,6 +39,7 @@
#include "lll_tim_internal.h"
#include "lll_adv_internal.h"
#include "lll_prof_internal.h"
#include "lll_df_internal.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
#define LOG_MODULE_NAME bt_ctlr_lll_adv
@ -110,6 +111,34 @@ 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;
#if IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
#if IS_ENABLED(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
#define EXTRA_DATA_MEM_SIZE MROUND(sizeof(struct lll_df_adv_cfg))
#else
#define EXTRA_DATA_MEM_SIZE 0
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
/* ToDo check if number of fragments is not smaller than number of CTE
* to be transmitted. Pay attention it would depend on the chain PDU storage
*
* Currently we can send only single CTE with AUX_SYNC_IND.
* Number is equal to allowed adv sync sets * 2 (double buffering).
*/
#define EXTRA_DATA_MEM_COUNT (BT_CTLR_ADV_SYNC_SET * PAYLOAD_FRAG_COUNT + 1)
#define EXTRA_DATA_MEM_FIFO_COUNT (EXTRA_DATA_MEM_COUNT * 2)
#define EXTRA_DATA_POOL_SIZE (EXTRA_DATA_MEM_SIZE * EXTRA_DATA_MEM_COUNT * 2)
/* Free extra data buffer pool */
static struct {
void *free;
uint8_t pool[EXTRA_DATA_POOL_SIZE];
} mem_extra_data;
/* FIFO to return stale extra data buffers from LLL to thread context. */
static MFIFO_DEFINE(extra_data_free, sizeof(void *), EXTRA_DATA_MEM_FIFO_COUNT);
static struct k_sem sem_extra_data_free;
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
int lll_adv_init(void)
{
int err;
@ -181,6 +210,13 @@ int lll_adv_data_reset(struct lll_adv_pdu *pdu)
pdu->last = 0U;
pdu->pdu[1] = NULL;
#if IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
/* Both slots are NULL because the extra_memory is allocated only
* on request. Not every advertising PDU includes extra_data.
*/
pdu->extra_data[0] = NULL;
pdu->extra_data[1] = NULL;
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
return 0;
}
@ -207,35 +243,12 @@ int lll_adv_data_release(struct lll_adv_pdu *pdu)
return 0;
}
struct pdu_adv *lll_adv_pdu_alloc(struct lll_adv_pdu *pdu, uint8_t *idx)
static inline struct pdu_adv *adv_pdu_allocate(struct lll_adv_pdu *pdu,
uint8_t last)
{
uint8_t first, last;
struct pdu_adv *p;
void *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;
cpu_dmb();
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;
@ -270,6 +283,36 @@ struct pdu_adv *lll_adv_pdu_alloc(struct lll_adv_pdu *pdu, uint8_t *idx)
return p;
}
struct pdu_adv *lll_adv_pdu_alloc(struct lll_adv_pdu *pdu, uint8_t *idx)
{
uint8_t first, last;
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;
cpu_dmb();
first_latest = pdu->first;
if (first_latest != first) {
last++;
if (last == DOUBLE_BUFFER_SIZE) {
last = 0U;
}
}
}
*idx = last;
return adv_pdu_allocate(pdu, last);
}
struct pdu_adv *lll_adv_pdu_latest_get(struct lll_adv_pdu *pdu,
uint8_t *is_modified)
{
@ -306,6 +349,209 @@ struct pdu_adv *lll_adv_pdu_latest_get(struct lll_adv_pdu *pdu,
return (void *)pdu->pdu[first];
}
#if IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
int lll_adv_and_extra_data_init(struct lll_adv_pdu *pdu)
{
struct pdu_adv *p;
void *extra_data;
p = mem_acquire(&mem_pdu.free);
if (!p) {
return -ENOMEM;
}
pdu->pdu[0] = (void *)p;
extra_data = mem_acquire(&mem_extra_data.free);
if (!extra_data) {
return -ENOMEM;
}
pdu->extra_data[0] = extra_data;
return 0;
}
static inline void adv_extra_data_release(struct lll_adv_pdu *pdu, int idx)
{
void *extra_data;
extra_data = pdu->extra_data[idx];
if (extra_data) {
pdu->extra_data[idx] = NULL;
mem_release(extra_data, &mem_extra_data.free);
}
}
int lll_adv_and_extra_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);
adv_extra_data_release(pdu, last);
last++;
if (last == DOUBLE_BUFFER_SIZE) {
last = 0U;
}
p = pdu->pdu[last];
if (p) {
pdu->pdu[last] = NULL;
mem_release(p, &mem_pdu.free);
}
adv_extra_data_release(pdu, last);
return 0;
}
static inline void *adv_extra_data_allocate(struct lll_adv_pdu *pdu,
uint8_t last)
{
void *extra_data;
int err;
extra_data = pdu->extra_data[last];
if (extra_data) {
return extra_data;
}
extra_data = MFIFO_DEQUEUE_PEEK(extra_data_free);
if (extra_data) {
err = k_sem_take(&sem_extra_data_free, K_NO_WAIT);
LL_ASSERT(!err);
MFIFO_DEQUEUE(extra_data_free);
pdu->extra_data[last] = extra_data;
return extra_data;
}
extra_data = mem_acquire(&mem_extra_data.free);
if (extra_data) {
pdu->extra_data[last] = extra_data;
return extra_data;
}
err = k_sem_take(&sem_extra_data_free, K_FOREVER);
LL_ASSERT(!err);
extra_data = MFIFO_DEQUEUE(extra_data_free);
LL_ASSERT(extra_data);
pdu->extra_data[last] = (void *)extra_data;
return extra_data;
}
struct pdu_adv *lll_adv_pdu_and_extra_data_alloc(struct lll_adv_pdu *pdu,
void **extra_data,
uint8_t *idx)
{
uint8_t first, last;
struct pdu_adv *p;
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;
cpu_dsb();
first_latest = pdu->first;
if (first_latest != first) {
last++;
if (last == DOUBLE_BUFFER_SIZE) {
last = 0U;
}
}
}
*idx = last;
p = adv_pdu_allocate(pdu, last);
if (extra_data) {
*extra_data = adv_extra_data_allocate(pdu, last);
} else {
pdu->extra_data[last] = NULL;
}
return p;
}
struct pdu_adv *lll_adv_pdu_and_extra_data_latest_get(struct lll_adv_pdu *pdu,
void **extra_data,
uint8_t *is_modified)
{
uint8_t first;
first = pdu->first;
if (first != pdu->last) {
uint8_t pdu_free_idx;
uint8_t ed_free_idx;
void *ed;
uint8_t pdu_idx;
void *p;
if (!MFIFO_ENQUEUE_IDX_GET(pdu_free, &pdu_free_idx)) {
LL_ASSERT(false);
return NULL;
}
pdu_idx = first;
ed = pdu->extra_data[pdu_idx];
if (ed && (!MFIFO_ENQUEUE_IDX_GET(extra_data_free,
&ed_free_idx))) {
LL_ASSERT(false);
/* ToDo what if enqueue fails and assert does not fire?
* pdu_free_idx should be released before return.
*/
return NULL;
}
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, pdu_free_idx, p);
k_sem_give(&sem_pdu_free);
if (ed) {
pdu->extra_data[pdu_idx] = NULL;
MFIFO_BY_IDX_ENQUEUE(extra_data_free, ed_free_idx, ed);
k_sem_give(&sem_extra_data_free);
}
}
if (extra_data) {
*extra_data = pdu->extra_data[first];
}
return (void *)pdu->pdu[first];
}
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
void lll_adv_prepare(void *param)
{
int err;
@ -419,6 +665,17 @@ static int init_reset(void)
/* Initialize AC PDU free buffer return queue */
MFIFO_INIT(pdu_free);
#if IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
/* Initialize extra data pool */
mem_init(mem_extra_data.pool, EXTRA_DATA_MEM_SIZE,
(sizeof(mem_extra_data.pool) / EXTRA_DATA_MEM_SIZE), &mem_extra_data.free);
/* Initialize extra data free buffer return queue */
MFIFO_INIT(extra_data_free);
k_sem_init(&sem_extra_data_free, 0, EXTRA_DATA_MEM_FIFO_COUNT);
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
/* Initialize semaphore for ticker API blocking wait */
k_sem_init(&sem_pdu_free, 0, PDU_MEM_FIFO_COUNT);

View file

@ -22,6 +22,15 @@ struct lll_adv_pdu {
uint8_t volatile first;
uint8_t last;
uint8_t *pdu[DOUBLE_BUFFER_SIZE];
#if IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
/* This is a storage for LLL configuration that may be
* changed while LLL advertising role is started.
* Also it makes the configuration data to be in sync
* with extended advertising PDU e.g. CTE TX configuration
* and CTEInfo field.
*/
void *extra_data[DOUBLE_BUFFER_SIZE];
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
};
struct lll_adv_aux {
@ -37,10 +46,6 @@ struct lll_adv_aux {
#endif /* CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */
};
#if IS_ENABLED(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
struct lll_df_adv_cfg;
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
struct lll_adv_iso {
struct lll_hdr hdr;
};
@ -72,7 +77,10 @@ struct lll_adv_sync {
#endif /* CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */
#if IS_ENABLED(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
struct lll_df_adv_cfg *df_cfg;
/* This flag is used only by LLL. It holds information if CTE
* transmission was started by LLL.
*/
uint8_t cte_started:1;
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
};
@ -134,6 +142,17 @@ 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);
#if IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
int lll_adv_and_extra_data_init(struct lll_adv_pdu *pdu);
int lll_adv_and_extra_data_release(struct lll_adv_pdu *pdu);
struct pdu_adv *lll_adv_pdu_and_extra_data_alloc(struct lll_adv_pdu *pdu,
void **extra_data,
uint8_t *idx);
struct pdu_adv *lll_adv_pdu_and_extra_data_latest_get(struct lll_adv_pdu *pdu,
void **extra_data,
uint8_t *is_modified);
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
static inline void lll_adv_pdu_enqueue(struct lll_adv_pdu *pdu, uint8_t idx)
{
pdu->last = idx;
@ -190,9 +209,14 @@ static inline struct pdu_adv *lll_adv_aux_data_peek(struct lll_adv_aux *lll)
#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)
void **extra_data,
uint8_t *idx)
{
#if IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
return lll_adv_pdu_and_extra_data_alloc(&lll->data, extra_data, idx);
#else
return lll_adv_pdu_alloc(&lll->data, idx);
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
}
static inline void lll_adv_sync_data_enqueue(struct lll_adv_sync *lll,
@ -201,9 +225,18 @@ static inline void lll_adv_sync_data_enqueue(struct lll_adv_sync *lll,
lll_adv_pdu_enqueue(&lll->data, idx);
}
static inline struct pdu_adv *lll_adv_sync_data_peek(struct lll_adv_sync *lll)
static inline struct pdu_adv *lll_adv_sync_data_peek(struct lll_adv_sync *lll,
void **extra_data)
{
return (void *)lll->data.pdu[lll->data.last];
uint8_t last = lll->data.last;
#if IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
if (extra_data) {
*extra_data = lll->data.extra_data[last];
}
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
return (void *)lll->data.pdu[last];
}
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
#endif /* CONFIG_BT_CTLR_ADV_EXT */

View file

@ -7,6 +7,12 @@
struct pdu_adv *lll_adv_pdu_latest_get(struct lll_adv_pdu *pdu,
uint8_t *is_modified);
#if IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
struct pdu_adv *lll_adv_pdu_and_extra_data_latest_get(struct lll_adv_pdu *pdu,
void **extra_data,
uint8_t *is_modified);
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
static inline struct pdu_adv *lll_adv_data_latest_get(struct lll_adv *lll,
uint8_t *is_modified)
{
@ -43,15 +49,27 @@ static inline struct pdu_adv *lll_adv_aux_data_curr_get(struct lll_adv_aux *lll)
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
static inline struct pdu_adv *
lll_adv_sync_data_latest_get(struct lll_adv_sync *lll, uint8_t *is_modified)
lll_adv_sync_data_latest_get(struct lll_adv_sync *lll, void **extra_data,
uint8_t *is_modified)
{
#if IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
return lll_adv_pdu_and_extra_data_latest_get(&lll->data, extra_data,
is_modified);
#else
return lll_adv_pdu_latest_get(&lll->data, is_modified);
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
}
static inline struct pdu_adv *
lll_adv_sync_data_curr_get(struct lll_adv_sync *lll)
lll_adv_sync_data_curr_get(struct lll_adv_sync *lll, void **extra_data)
{
return (void *)lll->data.pdu[lll->data.first];
uint8_t first = lll->data.first;
#if IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
if (extra_data) {
*extra_data = lll->data.extra_data[first];
}
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
return (void *)lll->data.pdu[first];
}
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
#endif /* CONFIG_BT_CTLR_ADV_EXT */

View file

@ -146,7 +146,7 @@ static int prepare_cb(struct lll_prepare_param *p)
((uint32_t)lll->crc_init[0])));
lll_chan_set(data_chan_use);
pdu = lll_adv_sync_data_latest_get(lll, &upd);
pdu = lll_adv_sync_data_latest_get(lll, NULL, &upd);
radio_pkt_tx_set(pdu);
/* TODO: chaining */

View file

@ -117,7 +117,7 @@ uint8_t ll_adv_sync_param_set(uint8_t handle, uint16_t interval, uint16_t flags)
sync->interval = interval;
ter_pdu = lll_adv_sync_data_peek(lll_sync);
ter_pdu = lll_adv_sync_data_peek(lll_sync, NULL);
ter_pdu->type = PDU_ADV_TYPE_AUX_SYNC_IND;
ter_pdu->rfu = 0U;
ter_pdu->chan_sel = 0U;
@ -187,14 +187,14 @@ uint8_t ll_adv_sync_ad_data_set(uint8_t handle, uint8_t op, uint8_t len,
}
/* Get reference to previous tertiary PDU data */
ter_pdu_prev = lll_adv_sync_data_peek(lll_sync);
ter_pdu_prev = lll_adv_sync_data_peek(lll_sync, NULL);
ter_com_hdr_prev = (void *)&ter_pdu_prev->adv_ext_ind;
ter_hdr = (void *)ter_com_hdr_prev->ext_hdr_adv_data;
ter_hdr_prev = *ter_hdr;
ter_dptr_prev = ter_hdr->data;
/* Get reference to new tertiary PDU data buffer */
ter_pdu = lll_adv_sync_data_alloc(lll_sync, &ter_idx);
ter_pdu = lll_adv_sync_data_alloc(lll_sync, NULL, &ter_idx);
ter_pdu->type = ter_pdu_prev->type;
ter_pdu->rfu = 0U;
ter_pdu->chan_sel = 0U;

View file

@ -4,6 +4,10 @@
* SPDX-License-Identifier: Apache-2.0
*/
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
struct lll_df_adv_cfg;
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
struct ll_adv_set {
struct evt_hdr evt;
struct ull_hdr ull;
@ -36,6 +40,10 @@ struct ll_adv_set {
uint8_t id_addr_type:1;
uint8_t id_addr[BDADDR_SIZE];
#endif /* CONFIG_BT_CTLR_PRIVACY */
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
struct lll_df_adv_cfg *df_cfg;
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
};
#if defined(CONFIG_BT_CTLR_ADV_EXT)

View file

@ -119,7 +119,6 @@ uint8_t ll_df_set_cl_cte_tx_params(uint8_t adv_handle, uint8_t cte_len,
uint8_t num_ant_ids, uint8_t *ant_ids)
{
struct ll_adv_set *adv;
struct lll_adv_sync *sync;
struct lll_df_adv_cfg *cfg;
/* Get the advertising set instance */
@ -128,11 +127,6 @@ uint8_t ll_df_set_cl_cte_tx_params(uint8_t adv_handle, uint8_t cte_len,
return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
}
sync = adv->lll.sync;
if (!sync) {
return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
}
if (cte_len < BT_HCI_LE_CTE_LEN_MIN ||
cte_len > BT_HCI_LE_CTE_LEN_MAX) {
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
@ -163,11 +157,11 @@ uint8_t ll_df_set_cl_cte_tx_params(uint8_t adv_handle, uint8_t cte_len,
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
}
if (!sync->df_cfg) {
sync->df_cfg = ull_df_adv_cfg_acquire();
if (!adv->df_cfg) {
adv->df_cfg = ull_df_adv_cfg_acquire();
}
cfg = sync->df_cfg;
cfg = adv->df_cfg;
if (cfg->is_enabled) {
return BT_HCI_ERR_CMD_DISALLOWED;
@ -283,7 +277,7 @@ static struct lll_df_adv_cfg *ull_df_adv_cfg_acquire(void)
return NULL;
}
df_adv_cfg->is_enabled = false;
df_adv_cfg->is_enabled = 0U;
return df_adv_cfg;
}