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>
diff --git a/subsys/bluetooth/controller/Kconfig.df b/subsys/bluetooth/controller/Kconfig.df
index 434f934..e34e9c8 100644
--- a/subsys/bluetooth/controller/Kconfig.df
+++ b/subsys/bluetooth/controller/Kconfig.df
@@ -100,6 +100,7 @@
 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
diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split
index d73177f..21dd489 100644
--- a/subsys/bluetooth/controller/Kconfig.ll_sw_split
+++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split
@@ -175,6 +175,20 @@
 	  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
diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c
index 4e21e78..f8bada5 100644
--- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c
+++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c
@@ -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 @@
 /* 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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	/* 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);
 
diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.h b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.h
index 957be25..d70a0ac 100644
--- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.h
+++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.h
@@ -22,6 +22,15 @@
 	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 @@
 #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 @@
 #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 @@
 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 @@
 
 #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 @@
 	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 */
diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_internal.h b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_internal.h
index 9d2c765..11a569f 100644
--- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_internal.h
+++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_internal.h
@@ -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 @@
 
 #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 */
diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c
index c2a17dd..612c838 100644
--- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c
+++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c
@@ -146,7 +146,7 @@
 			     ((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 */
diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c b/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c
index d25fa43..8e43c9a 100644
--- a/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c
+++ b/subsys/bluetooth/controller/ll_sw/ull_adv_sync.c
@@ -117,7 +117,7 @@
 
 	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 @@
 	}
 
 	/* 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;
diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_types.h b/subsys/bluetooth/controller/ll_sw/ull_adv_types.h
index ba6a5a9..8ebea5c 100644
--- a/subsys/bluetooth/controller/ll_sw/ull_adv_types.h
+++ b/subsys/bluetooth/controller/ll_sw/ull_adv_types.h
@@ -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 @@
 	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)
diff --git a/subsys/bluetooth/controller/ll_sw/ull_df.c b/subsys/bluetooth/controller/ll_sw/ull_df.c
index 33c33a6..e260927 100644
--- a/subsys/bluetooth/controller/ll_sw/ull_df.c
+++ b/subsys/bluetooth/controller/ll_sw/ull_df.c
@@ -119,7 +119,6 @@
 				   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 @@
 		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 @@
 		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 @@
 		return NULL;
 	}
 
-	df_adv_cfg->is_enabled = false;
+	df_adv_cfg->is_enabled = 0U;
 
 	return df_adv_cfg;
 }