/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/util.h>

#include "util/mem.h"
#include "util/memq.h"
#include "util/mayfly.h"
#include "util/util.h"
#include "util/dbuf.h"

#include "hal/ticker.h"
#include "hal/ccm.h"

#include "ticker/ticker.h"

#include "pdu.h"

#include "lll.h"
#include "lll/lll_vendor.h"
#include "lll_scan.h"
#include "lll_scan_aux.h"
#include "lll/lll_df_types.h"
#include "lll_conn.h"
#include "lll_sync.h"
#include "lll_sync_iso.h"

#include "ull_scan_types.h"
#include "ull_sync_types.h"

#include "ull_internal.h"
#include "ull_scan_internal.h"
#include "ull_sync_internal.h"
#include "ull_sync_iso_internal.h"

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
#define LOG_MODULE_NAME bt_ctlr_ull_scan_aux
#include "common/log.h"
#include <soc.h>
#include "hal/debug.h"

static int init_reset(void);
static inline struct ll_scan_aux_set *aux_acquire(void);
static inline void aux_release(struct ll_scan_aux_set *aux);
static inline uint8_t aux_handle_get(struct ll_scan_aux_set *aux);
static inline struct ll_sync_set *sync_create_get(struct ll_scan_set *scan);
static inline struct ll_sync_iso_set *
	sync_iso_create_get(struct ll_sync_set *sync);
static void done_disabled_cb(void *param);
static void flush_safe(void *param);
static void flush(void *param);
static void rx_release_put(struct node_rx_hdr *rx);
static void aux_sync_incomplete(void *param);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
		      uint32_t remainder, uint16_t lazy, uint8_t force,
		      void *param);
static void ticker_op_cb(uint32_t status, void *param);

/* Auxiliary context pool used for reception of PDUs at aux offsets, common for
 * both Extended Advertising and Periodic Advertising.
 * Increasing the count allows simultaneous reception of interleaved chain PDUs
 * from multiple advertisers.
 */
static struct ll_scan_aux_set ll_scan_aux_pool[CONFIG_BT_CTLR_SCAN_AUX_SET];
static void *scan_aux_free;

int ull_scan_aux_init(void)
{
	int err;

	err = init_reset();
	if (err) {
		return err;
	}

	return 0;
}

int ull_scan_aux_reset(void)
{
	int err;

	err = init_reset();
	if (err) {
		return err;
	}

	return 0;
}

void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx)
{
	struct node_rx_hdr *rx_incomplete;
	struct ll_sync_iso_set *sync_iso;
	struct pdu_adv_aux_ptr *aux_ptr;
	struct pdu_adv_com_ext_adv *p;
	uint32_t ticks_slot_overhead;
	struct lll_scan_aux *lll_aux;
	struct ll_scan_aux_set *aux;
	uint8_t ticker_yield_handle;
	uint32_t window_widening_us;
	uint32_t ticks_slot_offset;
	uint32_t ticks_aux_offset;
	struct pdu_adv_ext_hdr *h;
	struct lll_sync *sync_lll;
	struct ll_scan_set *scan;
	struct ll_sync_set *sync;
	struct pdu_adv_adi *adi;
	struct node_rx_ftr *ftr;
	uint32_t ready_delay_us;
	uint32_t aux_offset_us;
	uint32_t ticker_status;
	struct lll_scan *lll;
	struct pdu_adv *pdu;
	uint8_t hdr_buf_len;
	uint8_t aux_handle;
	bool is_scan_req;
	uint8_t acad_len;
	uint8_t data_len;
	uint8_t hdr_len;
	uint8_t *ptr;
	uint8_t phy;

	is_scan_req = false;
	ftr = &rx->rx_ftr;

	switch (rx->type) {
	case NODE_RX_TYPE_EXT_1M_REPORT:
		lll_aux = NULL;
		aux = NULL;
		sync_lll = NULL;
		sync_iso = NULL;
		rx_incomplete = NULL;

		lll = ftr->param;
		LL_ASSERT(!lll->lll_aux);

		scan = HDR_LLL2ULL(lll);
		sync = sync_create_get(scan);
		phy = BT_HCI_LE_EXT_SCAN_PHY_1M;

		ticker_yield_handle = TICKER_ID_SCAN_BASE +
				      ull_scan_handle_get(scan);
		break;

	case NODE_RX_TYPE_EXT_CODED_REPORT:
		lll_aux = NULL;
		aux = NULL;
		sync_lll = NULL;
		sync_iso = NULL;
		rx_incomplete = NULL;

		lll = ftr->param;
		LL_ASSERT(!lll->lll_aux);

		scan = HDR_LLL2ULL(lll);
		sync = sync_create_get(scan);
		phy = BT_HCI_LE_EXT_SCAN_PHY_CODED;

		ticker_yield_handle = TICKER_ID_SCAN_BASE +
				      ull_scan_handle_get(scan);
		break;

	case NODE_RX_TYPE_EXT_AUX_REPORT:
		sync_iso = NULL;
		rx_incomplete = NULL;
		if (ull_scan_aux_is_valid_get(HDR_LLL2ULL(ftr->param))) {
			sync_lll = NULL;

			/* Node has valid aux context so its scan was scheduled
			 * from ULL.
			 */
			lll_aux = ftr->param;
			aux = HDR_LLL2ULL(lll_aux);

			/* aux parent will be NULL for periodic sync */
			lll = aux->parent;
			LL_ASSERT(lll);

			ticker_yield_handle = TICKER_ID_SCAN_AUX_BASE +
					      aux_handle_get(aux);

		} else if (!IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) ||
			   ull_scan_is_valid_get(HDR_LLL2ULL(ftr->param))) {
			sync_lll = NULL;

			/* Node that does not have valid aux context but has
			 * valid scan set was scheduled from LLL. We can
			 * retrieve aux context from lll_scan as it was stored
			 * there when superior PDU was handled.
			 */
			lll = ftr->param;

			lll_aux = lll->lll_aux;
			LL_ASSERT(lll_aux);

			aux = HDR_LLL2ULL(lll_aux);
			LL_ASSERT(lll == aux->parent);

			ticker_yield_handle = TICKER_NULL;

		} else {
			lll = NULL;

			/* If none of the above, node is part of sync scanning
			 */
			sync_lll = ftr->param;

			lll_aux = sync_lll->lll_aux;
			LL_ASSERT(lll_aux);

			aux = HDR_LLL2ULL(lll_aux);
			LL_ASSERT(sync_lll == aux->parent);

			ticker_yield_handle = TICKER_NULL;
		}

		if (!IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) || lll) {
			scan = HDR_LLL2ULL(lll);
			sync = (void *)scan;
			scan = ull_scan_is_valid_get(scan);
			if (scan) {
				sync = NULL;
			}
		} else {
			scan = NULL;
			sync = HDR_LLL2ULL(sync_lll);
		}

		phy = lll_aux->phy;
		if (!IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) || scan) {
			/* Here we are scanner context */
			sync = sync_create_get(scan);

			/* Generate report based on PHY scanned */
			switch (phy) {
			case PHY_1M:
				rx->type = NODE_RX_TYPE_EXT_1M_REPORT;
				break;
			case PHY_2M:
				rx->type = NODE_RX_TYPE_EXT_2M_REPORT;
				break;
			case PHY_CODED:
				rx->type = NODE_RX_TYPE_EXT_CODED_REPORT;
				break;
			default:
				LL_ASSERT(0);
				return;
			}

			/* Backup scan requested flag as it is in union with
			 * `extra` struct member which will be set to NULL
			 * in subsequent code.
			 */
			is_scan_req = !!ftr->scan_req;

#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
		} else {
			/* Here we are periodic sync context */
			rx->type = NODE_RX_TYPE_SYNC_REPORT;
			rx->handle = ull_sync_handle_get(sync);

			/* Check if we need to create BIG sync */
			sync_iso = sync_iso_create_get(sync);

			/* lll_aux and aux are auxiliary channel context,
			 * reuse the existing aux context to scan the chain.
			 * hence lll_aux and aux are not released or set to NULL.
			 */
			sync = NULL;
		}
		break;

	case NODE_RX_TYPE_SYNC_REPORT:
		{
			struct ll_sync_set *ull_sync;

			/* set the sync handle corresponding to the LLL context
			 * passed in the node rx footer field.
			 */
			sync_lll = ftr->param;
			LL_ASSERT(!sync_lll->lll_aux);

			ull_sync = HDR_LLL2ULL(sync_lll);
			rx->handle = ull_sync_handle_get(ull_sync);

			/* Check if we need to create BIG sync */
			sync_iso = sync_iso_create_get(ull_sync);

			/* FIXME: we will need lll_scan if chain was scheduled
			 *        from LLL; should we store lll_scan_set in
			 *        sync_lll instead?
			 */
			lll = NULL;
			lll_aux = NULL;
			aux = NULL;
			scan = NULL;
			sync = NULL;
			phy =  sync_lll->phy;

			/* backup extra node_rx supplied for generating
			 * incomplete report
			 */
			rx_incomplete = ftr->extra;

			ticker_yield_handle = TICKER_ID_SCAN_SYNC_BASE +
					      ull_sync_handle_get(ull_sync);
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */

		}
		break;
	default:
		LL_ASSERT(0);
		return;
	}

	rx->link = link;
	ftr->extra = NULL;

	ftr->aux_sched = 0U;

	pdu = (void *)((struct node_rx_pdu *)rx)->pdu;
	p = (void *)&pdu->adv_ext_ind;
	if (!pdu->len || !p->ext_hdr_len) {
		if (pdu->len) {
			data_len = pdu->len - PDU_AC_EXT_HEADER_SIZE_MIN;
		} else {
			data_len = 0U;
		}

		if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && sync_lll) {
			struct ll_sync_set *sync;

			sync = HDR_LLL2ULL(sync_lll);
			ftr->aux_data_len = sync->data_len + data_len;
			sync->data_len = 0U;
		} else if (aux) {
			aux->data_len += data_len;
			ftr->aux_data_len = aux->data_len;
		} else {
			ftr->aux_data_len = data_len;
		}

		goto ull_scan_aux_rx_flush;
	}

	h = (void *)p->ext_hdr_adv_data;

	/* Regard PDU as invalid if a RFU field is set, we do not know the
	 * size of this future field, hence will cause incorrect calculation of
	 * offset to ACAD field.
	 */
	if (h->rfu) {
		goto ull_scan_aux_rx_flush;
	}

	ptr = h->data;

	if (h->adv_addr) {
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
		/* Check if Periodic Advertising Synchronization to be created
		 */
		if (sync && (scan->periodic.state != LL_SYNC_STATE_CREATED)) {
			/* Check address and update internal state */
#if defined(CONFIG_BT_CTLR_PRIVACY)
			ull_sync_setup_addr_check(scan, pdu->tx_addr, ptr,
						  ftr->rl_idx);
#else /* !CONFIG_BT_CTLR_PRIVACY */
			ull_sync_setup_addr_check(scan, pdu->tx_addr, ptr, 0U);
#endif /* !CONFIG_BT_CTLR_PRIVACY */

		}
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */

		ptr += BDADDR_SIZE;
	}

	if (h->tgt_addr) {
		ptr += BDADDR_SIZE;
	}

	if (h->cte_info) {
		ptr += sizeof(struct pdu_cte_info);
	}

	adi = NULL;
	if (h->adi) {
		adi = (void *)ptr;
		ptr += sizeof(*adi);
	}

	aux_ptr = NULL;
	if (h->aux_ptr) {
		aux_ptr = (void *)ptr;
		ptr += sizeof(*aux_ptr);
	}

	if (h->sync_info) {
		struct pdu_adv_sync_info *si;

		si = (void *)ptr;
		ptr += sizeof(*si);

		/* Check if Periodic Advertising Synchronization to be created.
		 * Setup synchronization if address and SID match in the
		 * Periodic Advertiser List or with the explicitly supplied.
		 */
		if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && sync && adi &&
		    ull_sync_setup_sid_match(scan, adi->sid)) {
			ull_sync_setup(scan, aux, rx, si);
		}
	}

	if (h->tx_pwr) {
		ptr++;
	}

	/* Calculate ACAD Len */
	hdr_len = ptr - (uint8_t *)p;
	hdr_buf_len = PDU_AC_EXT_HEADER_SIZE_MIN + p->ext_hdr_len;
	if (hdr_len > hdr_buf_len) {
		/* FIXME: Handle invalid header length */
		acad_len = 0U;
	} else {
		acad_len = hdr_buf_len - hdr_len;
		hdr_len += acad_len;
	}

	/* calculate total data length */
	if (hdr_len < pdu->len) {
		data_len = pdu->len - hdr_len;
	} else {
		data_len = 0U;
	}

	/* Periodic Advertising Channel Map Indication and/or Broadcast ISO
	 * synchronization
	 */
	if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) &&
	    (rx->type == NODE_RX_TYPE_SYNC_REPORT) &&
	    acad_len) {
		/* Periodic Advertising Channel Map Indication */
		ull_sync_chm_update(rx->handle, ptr, acad_len);

		/* Broadcast ISO synchronize */
		if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_ISO) && sync_iso) {
			ull_sync_iso_setup(sync_iso, rx, ptr, acad_len);
		}
	}

	/* Do not ULL schedule auxiliary PDU reception if no aux pointer
	 * or aux pointer is zero or scannable advertising has erroneous aux
	 * pointer being present or PHY in the aux pointer is invalid.
	 */
	if (!aux_ptr || !aux_ptr->offs || is_scan_req ||
	    (aux_ptr->phy > EXT_ADV_AUX_PHY_LE_CODED)) {
		if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && sync_lll) {
			struct ll_sync_set *sync;

			sync = HDR_LLL2ULL(sync_lll);
			ftr->aux_data_len = sync->data_len + data_len;
			sync->data_len = 0U;
		} else if (aux) {
			aux->data_len += data_len;
			ftr->aux_data_len = aux->data_len;
		} else {
			ftr->aux_data_len = data_len;
		}

		if (is_scan_req) {
			LL_ASSERT(aux && aux->rx_last);

			aux->rx_last->rx_ftr.extra = rx;
			aux->rx_last = rx;

			return;
		}

		goto ull_scan_aux_rx_flush;
	}

	if (!aux) {
		aux = aux_acquire();
		if (!aux) {
			/* As LLL scheduling has been used and will fail due to
			 * non-allocation of aux context, a sync report with
			 * aux_failed flag set will be generated. Let the
			 * current sync report be set as partial, and the
			 * sync report corresponding to ull_scan_aux_release
			 * have the incomplete data status.
			 */
			if (ftr->aux_lll_sched) {
				ftr->aux_sched = 1U;
			}

			if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) &&
			    sync_lll) {
				struct ll_sync_set *sync;

				sync = HDR_LLL2ULL(sync_lll);
				ftr->aux_data_len = sync->data_len + data_len;
				sync->data_len = 0U;

			}

			goto ull_scan_aux_rx_flush;
		}

		aux->rx_head = aux->rx_last = NULL;
		aux->data_len = data_len;
		lll_aux = &aux->lll;
		lll_aux->is_chain_sched = 0U;

		ull_hdr_init(&aux->ull);
		lll_hdr_init(lll_aux, aux);

		aux->parent = lll ? (void *)lll : (void *)sync_lll;

#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
		aux->rx_incomplete = rx_incomplete;
		rx_incomplete = NULL;
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */

	} else {
		aux->data_len += data_len;
	}

	/* In sync context we can dispatch rx immediately, in scan context we
	 * enqueue rx in aux context and will flush them after scan is complete.
	 */
	if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && sync_lll) {
		struct ll_sync_set *sync;

		sync = HDR_LLL2ULL(sync_lll);
		sync->data_len += data_len;
		ftr->aux_data_len = sync->data_len;
	} else {
		if (aux->rx_last) {
			aux->rx_last->rx_ftr.extra = rx;
		} else {
			aux->rx_head = rx;
		}
		aux->rx_last = rx;

		ftr->aux_data_len = aux->data_len;
	}

	/* Initialize the channel index and PHY for the Auxiliary PDU reception.
	 */
	lll_aux->chan = aux_ptr->chan_idx;
	lll_aux->phy = BIT(aux_ptr->phy);

	/* See if this was already scheduled from LLL. If so, store aux context
	 * in global scan struct so we can pick it when scanned node is received
	 * with a valid context.
	 */
	if (ftr->aux_lll_sched) {
		/* AUX_ADV_IND/AUX_CHAIN_IND PDU reception is being setup */
		ftr->aux_sched = 1U;

		if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && sync_lll) {
			sync_lll->lll_aux = lll_aux;

			/* In sync context, dispatch immediately */
			ll_rx_put(link, rx);
			ll_rx_sched();
		} else {
			lll->lll_aux = lll_aux;
		}

		/* Reset auxiliary channel PDU scan state which otherwise is
		 * done in the prepare_cb when ULL scheduling is used.
		 */
		lll_aux->state = 0U;

		return;
	}

	/* Switching to ULL scheduling to receive auxiliary PDUs */
	if (!IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) || lll) {
		/* Do not ULL schedule if scan disable requested */
		if (unlikely(scan->is_stop)) {
			goto ull_scan_aux_rx_flush;
		}

		/* Remove auxiliary context association with scan context so
		 * that LLL can differentiate it to being ULL scheduling.
		 */
		lll->lll_aux = NULL;
	} else {
		struct ll_sync_set *sync;

		LL_ASSERT(sync_lll &&
			  (!sync_lll->lll_aux || sync_lll->lll_aux == lll_aux));

		/* Do not ULL schedule if sync terminate requested */
		sync = HDR_LLL2ULL(sync_lll);
		if (unlikely(sync->is_stop)) {
			goto ull_scan_aux_rx_flush;
		}

		/* Associate the auxiliary context with sync context */
		sync_lll->lll_aux = lll_aux;

		/* Backup the node rx to be dispatch on successfully ULL
		 * scheduling setup.
		 */
		aux->rx_head = rx;
	}

	/* Determine the window size */
	if (aux_ptr->offs_units) {
		lll_aux->window_size_us = OFFS_UNIT_300_US;
	} else {
		lll_aux->window_size_us = OFFS_UNIT_30_US;
	}

	aux_offset_us = (uint32_t)aux_ptr->offs * lll_aux->window_size_us;

	/* CA field contains the clock accuracy of the advertiser;
	 * 0 - 51 ppm to 500 ppm
	 * 1 - 0 ppm to 50 ppm
	 */
	if (aux_ptr->ca) {
		window_widening_us = SCA_DRIFT_50_PPM_US(aux_offset_us);
	} else {
		window_widening_us = SCA_DRIFT_500_PPM_US(aux_offset_us);
	}

	lll_aux->window_size_us += (EVENT_TICKER_RES_MARGIN_US +
				    ((EVENT_JITTER_US + window_widening_us) << 1));

	ready_delay_us = lll_radio_rx_ready_delay_get(lll_aux->phy,
						      PHY_FLAGS_S8);

	/* Calculate the aux offset from start of the scan window */
	aux_offset_us += ftr->radio_end_us;
	aux_offset_us -= PDU_AC_US(pdu->len, phy, ftr->phy_flags);
	aux_offset_us -= EVENT_TICKER_RES_MARGIN_US;
	aux_offset_us -= EVENT_JITTER_US;
	aux_offset_us -= ready_delay_us;
	aux_offset_us -= window_widening_us;

	/* TODO: active_to_start feature port */
	aux->ull.ticks_active_to_start = 0;
	aux->ull.ticks_prepare_to_start =
		HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US);
	aux->ull.ticks_preempt_to_start =
		HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US);
	aux->ull.ticks_slot =
		HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US +
				       ready_delay_us +
				       PDU_AC_MAX_US(PDU_AC_EXT_PAYLOAD_SIZE_MAX,
						     lll_aux->phy) +
				       EVENT_OVERHEAD_END_US);

	ticks_slot_offset = MAX(aux->ull.ticks_active_to_start,
				aux->ull.ticks_prepare_to_start);
	if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) {
		ticks_slot_overhead = ticks_slot_offset;
	} else {
		ticks_slot_overhead = 0U;
	}
	ticks_slot_offset += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);

	ticks_aux_offset = HAL_TICKER_US_TO_TICKS(aux_offset_us);

	/* Yield the primary scan window or auxiliary or periodic sync event
	 * in ticker.
	 */
	if (ticker_yield_handle != TICKER_NULL) {
		ticker_status = ticker_yield_abs(TICKER_INSTANCE_ID_CTLR,
						 TICKER_USER_ID_ULL_HIGH,
						 ticker_yield_handle,
						 (ftr->ticks_anchor +
						  ticks_aux_offset -
						  ticks_slot_offset),
						 NULL, NULL);
		LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
			  (ticker_status == TICKER_STATUS_BUSY));
	}

	aux_handle = aux_handle_get(aux);
	ticker_status = ticker_start(TICKER_INSTANCE_ID_CTLR,
				     TICKER_USER_ID_ULL_HIGH,
				     TICKER_ID_SCAN_AUX_BASE + aux_handle,
				     ftr->ticks_anchor - ticks_slot_offset,
				     ticks_aux_offset,
				     TICKER_NULL_PERIOD,
				     TICKER_NULL_REMAINDER,
				     TICKER_NULL_LAZY,
				     (aux->ull.ticks_slot +
				      ticks_slot_overhead),
				     ticker_cb, aux, ticker_op_cb, aux);
	LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
		  (ticker_status == TICKER_STATUS_BUSY));

	return;

ull_scan_aux_rx_flush:
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
	if (sync && (scan->periodic.state != LL_SYNC_STATE_CREATED)) {
		scan->periodic.state = LL_SYNC_STATE_IDLE;
	}
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */

	if (aux) {
		/* Enqueue last rx in aux context if possible, otherwise send
		 * immediately since we are in sync context.
		 */
		if (!IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) || aux->rx_last) {
			/* If scan is being disabled, rx has already been
			 * enqueued before coming here, ull_scan_aux_rx_flush.
			 * Do not add it, to avoid duplicate report generation,
			 * release and probable infinite loop processing the
			 * list.
			 */
			if (unlikely(scan->is_stop)) {
				return;
			}

			aux->rx_last->rx_ftr.extra = rx;
			aux->rx_last = rx;
		} else {
			const struct ll_sync_set *sync;

			LL_ASSERT(sync_lll);

			ll_rx_put(link, rx);
			ll_rx_sched();

			sync = HDR_LLL2ULL(sync_lll);
			if (unlikely(sync->is_stop)) {
				return;
			}
		}

		LL_ASSERT(aux->parent);

		flush_safe(aux);

		return;
	}

	ll_rx_put(link, rx);

	if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && rx_incomplete) {
		rx_release_put(rx_incomplete);
	}

	ll_rx_sched();
}

void ull_scan_aux_done(struct node_rx_event_done *done)
{
	struct ll_scan_aux_set *aux;

	/* Get reference to ULL context */
	aux = CONTAINER_OF(done->param, struct ll_scan_aux_set, ull);

	if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) &&
	    !ull_scan_aux_is_valid_get(aux)) {
		struct ll_sync_set *sync;

		sync = CONTAINER_OF(done->param, struct ll_sync_set, ull);
		LL_ASSERT(ull_sync_is_valid_get(sync));

		/* Auxiliary context will be flushed by ull_scan_aux_stop() */
		if (unlikely(sync->is_stop) || !sync->lll.lll_aux) {
			return;
		}

		aux = HDR_LLL2ULL(sync->lll.lll_aux);
		LL_ASSERT(aux->parent);
	} else {
		struct ll_scan_set *scan;
		struct lll_scan *lll;

		lll = aux->parent;
		LL_ASSERT(lll);

		scan = HDR_LLL2ULL(lll);
		LL_ASSERT(ull_scan_is_valid_get(scan));

		/* Auxiliary context will be flushed by ull_scan_aux_stop() */
		if (unlikely(scan->is_stop)) {
			return;
		}
	}

	flush(aux);
}

struct ll_scan_aux_set *ull_scan_aux_set_get(uint8_t handle)
{
	if (handle >= CONFIG_BT_CTLR_SCAN_AUX_SET) {
		return NULL;
	}

	return &ll_scan_aux_pool[handle];
}

uint8_t ull_scan_aux_lll_handle_get(struct lll_scan_aux *lll)
{
	struct ll_scan_aux_set *aux;

	aux = HDR_LLL2ULL(lll);

	return aux_handle_get(aux);
}

void *ull_scan_aux_lll_parent_get(struct lll_scan_aux *lll,
				  uint8_t *is_lll_scan)
{
	struct ll_scan_aux_set *aux;

	aux = HDR_LLL2ULL(lll);

	if (is_lll_scan) {
		struct ll_scan_set *scan;
		struct lll_scan *lll;

		lll = aux->parent;
		LL_ASSERT(lll);

		scan = HDR_LLL2ULL(lll);
		*is_lll_scan = !!ull_scan_is_valid_get(scan);
	}

	return aux->parent;
}

struct ll_scan_aux_set *ull_scan_aux_is_valid_get(struct ll_scan_aux_set *aux)
{
	if (((uint8_t *)aux < (uint8_t *)ll_scan_aux_pool) ||
	    ((uint8_t *)aux > ((uint8_t *)ll_scan_aux_pool +
			       (sizeof(struct ll_scan_aux_set) *
				(CONFIG_BT_CTLR_SCAN_AUX_SET - 1))))) {
		return NULL;
	}

	return aux;
}

void ull_scan_aux_release(memq_link_t *link, struct node_rx_hdr *rx)
{
	struct lll_scan_aux *lll_aux;
	void *param_ull;

	param_ull = HDR_LLL2ULL(rx->rx_ftr.param);

	if (ull_scan_is_valid_get(param_ull)) {
		struct lll_scan *lll;

		/* Mark for buffer for release */
		rx->type = NODE_RX_TYPE_RELEASE;

		lll = rx->rx_ftr.param;
		lll_aux = lll->lll_aux;

	} else if (!IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) ||
		   ull_scan_aux_is_valid_get(param_ull)) {
		/* Mark for buffer for release */
		rx->type = NODE_RX_TYPE_RELEASE;

		lll_aux = rx->rx_ftr.param;

	} else if (ull_sync_is_valid_get(param_ull)) {
		struct ll_sync_set *sync;
		struct lll_sync *lll;

		sync = param_ull;

		/* reset data len total */
		sync->data_len = 0U;

		lll = rx->rx_ftr.param;
		lll_aux = lll->lll_aux;

		/* Change node type so HCI can dispatch report for truncated
		 * data properly.
		 */
		rx->type = NODE_RX_TYPE_SYNC_REPORT;
		rx->handle = ull_sync_handle_get(sync);

		/* Dequeue will try releasing list of node rx, set the extra
		 * pointer to NULL.
		 */
		rx->rx_ftr.extra = NULL;

	} else {
		LL_ASSERT(0);
		lll_aux = NULL;
	}

	if (lll_aux) {
		struct ll_scan_aux_set *aux;
		struct ll_scan_set *scan;
		struct lll_scan *lll;
		uint8_t is_stop;

		aux = HDR_LLL2ULL(lll_aux);
		lll = aux->parent;
		LL_ASSERT(lll);

		scan = HDR_LLL2ULL(lll);
		scan = ull_scan_is_valid_get(scan);
		if (scan) {
			is_stop = scan->is_stop;
		} else {
			struct lll_sync *sync_lll;
			struct ll_sync_set *sync;

			sync_lll = (void *)lll;
			sync = HDR_LLL2ULL(sync_lll);
			is_stop = sync->is_stop;
		}

		if (!is_stop) {
			LL_ASSERT(aux->parent);

			flush_safe(aux);

		} else if (!scan) {
			/* Sync terminate requested, enqueue node rx so that it
			 * be flushed by ull_scan_aux_stop().
			 */
			rx->link = link;
			if (aux->rx_last) {
				aux->rx_last->rx_ftr.extra = rx;
			} else {
				aux->rx_head = rx;
			}
			aux->rx_last = rx;

			return;
		}
	}

	ll_rx_put(link, rx);
	ll_rx_sched();
}

int ull_scan_aux_stop(struct ll_scan_aux_set *aux)
{
	static memq_link_t link;
	static struct mayfly mfy = {0, 0, &link, NULL, NULL};
	uint8_t aux_handle;
	uint32_t ret;
	int err;

	/* Stop any ULL scheduling of auxiliary PDU scan */
	aux_handle = aux_handle_get(aux);
	err = ull_ticker_stop_with_mark(TICKER_ID_SCAN_AUX_BASE + aux_handle,
					aux, &aux->lll);
	if (err && (err != -EALREADY)) {
		return err;
	}

	/* Abort LLL event if ULL scheduling not used or already in prepare */
	if (err == -EALREADY) {
		err = ull_disable(&aux->lll);
		if (err && (err != -EALREADY)) {
			return err;
		}

		mfy.fp = flush;

	} else if (!IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC)) {
		/* ULL scan auxiliary PDU reception scheduling stopped
		 * before prepare.
		 */
		mfy.fp = flush;

	} else {
		struct ll_scan_set *scan;
		struct lll_scan *lll;

		lll = aux->parent;
		LL_ASSERT(lll);

		scan = HDR_LLL2ULL(lll);
		scan = ull_scan_is_valid_get(scan);
		if (scan) {
			/* ULL scan auxiliary PDU reception scheduling stopped
			 * before prepare.
			 */
			mfy.fp = flush;
		} else {
			/* ULL sync chain reception scheduling stopped before
			 * prepare.
			 */
			mfy.fp = aux_sync_incomplete;
		}
	}

	/* Release auxiliary context in ULL execution context */
	mfy.param = aux;
	ret = mayfly_enqueue(TICKER_USER_ID_THREAD, TICKER_USER_ID_ULL_HIGH,
			     0, &mfy);
	LL_ASSERT(!ret);

	return 0;
}

static int init_reset(void)
{
	/* Initialize adv aux pool. */
	mem_init(ll_scan_aux_pool, sizeof(struct ll_scan_aux_set),
		 sizeof(ll_scan_aux_pool) / sizeof(struct ll_scan_aux_set),
		 &scan_aux_free);

	return 0;
}

static inline struct ll_scan_aux_set *aux_acquire(void)
{
	return mem_acquire(&scan_aux_free);
}

static inline void aux_release(struct ll_scan_aux_set *aux)
{
	/* Clear the parent so that when scan is being disabled then this
	 * auxiliary context shall not associate itself from being disable.
	 */
	LL_ASSERT(aux->parent);
	aux->parent = NULL;

	mem_release(aux, &scan_aux_free);
}

static inline uint8_t aux_handle_get(struct ll_scan_aux_set *aux)
{
	return mem_index_get(aux, ll_scan_aux_pool,
			     sizeof(struct ll_scan_aux_set));
}

static inline struct ll_sync_set *sync_create_get(struct ll_scan_set *scan)
{
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
	return (!scan->periodic.cancelled) ? scan->periodic.sync : NULL;
#else /* !CONFIG_BT_CTLR_SYNC_PERIODIC */
	return NULL;
#endif /* !CONFIG_BT_CTLR_SYNC_PERIODIC */
}

static inline struct ll_sync_iso_set *
	sync_iso_create_get(struct ll_sync_set *sync)
{
#if defined(CONFIG_BT_CTLR_SYNC_ISO)
	return sync->iso.sync_iso;
#else /* !CONFIG_BT_CTLR_SYNC_ISO */
	return NULL;
#endif /* !CONFIG_BT_CTLR_SYNC_ISO */
}

static void done_disabled_cb(void *param)
{
	struct ll_scan_aux_set *aux;

	aux = param;
	LL_ASSERT(aux->parent);

	flush(aux);
}

static void flush_safe(void *param)
{
	struct ll_scan_aux_set *aux;
	struct ull_hdr *hdr;
	uint8_t ref;

	aux = param;
	LL_ASSERT(aux->parent);

	/* ref == 0
	 * All PDUs were scheduled from LLL and there is no pending done
	 * event, we can flush here.
	 *
	 * ref == 1
	 * There is pending done event so we need to flush from disabled
	 * callback. Flushing here would release aux context and thus
	 * ull_hdr before done event was processed.
	 */
	hdr = &aux->ull;
	ref = ull_ref_get(hdr);
	if (ref == 0U) {
		flush(aux);
	} else {
		/* A specific single shot scheduled aux context
		 * cannot overlap, i.e. ULL reference count
		 * shall be less than 2.
		 */
		LL_ASSERT(ref < 2U);

		LL_ASSERT(!hdr->disabled_cb);
		hdr->disabled_param = aux;
		hdr->disabled_cb = done_disabled_cb;
	}
}

static void flush(void *param)
{
	struct ll_scan_aux_set *aux;
	struct ll_scan_set *scan;
	struct node_rx_hdr *rx;
	struct lll_scan *lll;
	bool sched = false;

	/* Debug check that parent was assigned when allocated for reception of
	 * auxiliary channel PDUs.
	 */
	aux = param;
	LL_ASSERT(aux->parent);

	rx = aux->rx_head;
	if (rx) {
		aux->rx_head = NULL;

		ll_rx_put(rx->link, rx);
		sched = true;
	}

#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
	rx = aux->rx_incomplete;
	if (rx) {
		aux->rx_incomplete = NULL;

		rx_release_put(rx);
		sched = true;
	}
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */

	if (sched) {
		ll_rx_sched();
	}

	lll = aux->parent;
	scan = HDR_LLL2ULL(lll);
	scan = ull_scan_is_valid_get(scan);
	if (!IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) || scan) {
		lll->lll_aux = NULL;
	} else {
		struct lll_sync *sync_lll;
		struct ll_sync_set *sync;

		sync_lll = aux->parent;
		sync = HDR_LLL2ULL(sync_lll);

		LL_ASSERT(sync->is_stop || sync_lll->lll_aux);
		sync_lll->lll_aux = NULL;
	}

	aux_release(aux);
}

static void rx_release_put(struct node_rx_hdr *rx)
{
	rx->type = NODE_RX_TYPE_RELEASE;

	ll_rx_put(rx->link, rx);
}

static void aux_sync_partial(void *param)
{
	struct ll_scan_aux_set *aux;
	struct node_rx_hdr *rx;

	aux = param;
	rx = aux->rx_head;
	aux->rx_head = NULL;

	LL_ASSERT(rx);
	rx->rx_ftr.aux_sched = 1U;

	ll_rx_put(rx->link, rx);
	ll_rx_sched();
}

static void aux_sync_incomplete(void *param)
{
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
	struct ll_scan_aux_set *aux;

	aux = param;
	LL_ASSERT(aux->parent);

	/* ULL scheduling succeeded hence no backup node rx present, use the
	 * extra node rx reserved for incomplete data status generation.
	 */
	if (!aux->rx_head) {
		struct ll_sync_set *sync;
		struct node_rx_hdr *rx;
		struct lll_sync *lll;

		/* get reference to sync context */
		lll = aux->parent;
		LL_ASSERT(lll);
		sync = HDR_LLL2ULL(lll);

		/* reset data len total */
		sync->data_len = 0U;

		/* pick extra node rx stored in aux context */
		rx = aux->rx_incomplete;
		LL_ASSERT(rx);
		aux->rx_incomplete = NULL;

		/* prepare sync report with failure */
		rx->type = NODE_RX_TYPE_SYNC_REPORT;
		rx->handle = ull_sync_handle_get(sync);
		rx->rx_ftr.param = lll;

		/* flag chain reception failure */
		rx->rx_ftr.aux_failed = 1U;

		/* Dequeue will try releasing list of node rx,
		 * set the extra pointer to NULL.
		 */
		rx->rx_ftr.extra = NULL;

		/* add to rx list, will be flushed */
		aux->rx_head = rx;
	}

	LL_ASSERT(!ull_ref_get(&aux->ull));

	flush(aux);
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
}

static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
		      uint32_t remainder, uint16_t lazy, uint8_t force,
		      void *param)
{
	static memq_link_t link;
	static struct mayfly mfy = {0, 0, &link, NULL, lll_scan_aux_prepare};
	struct ll_scan_aux_set *aux = param;
	static struct lll_prepare_param p;
	uint32_t ret;
	uint8_t ref;

	DEBUG_RADIO_PREPARE_O(1);

	/* Increment prepare reference count */
	ref = ull_ref_inc(&aux->ull);
	LL_ASSERT(ref);

	/* Append timing parameters */
	p.ticks_at_expire = ticks_at_expire;
	p.remainder = 0; /* FIXME: remainder; */
	p.lazy = lazy;
	p.force = force;
	p.param = &aux->lll;
	mfy.param = &p;

	/* Kick LLL prepare */
	ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_LLL,
			     0, &mfy);
	LL_ASSERT(!ret);

	DEBUG_RADIO_PREPARE_O(1);
}

static void ticker_op_cb(uint32_t status, void *param)
{
	static memq_link_t link;
	static struct mayfly mfy = {0, 0, &link, NULL, NULL};
	struct ll_sync_set *sync;
	uint32_t ret;

	if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC)) {
		struct ll_scan_aux_set *aux;
		struct lll_sync *sync_lll;

		aux = param;
		sync_lll = aux->parent;
		LL_ASSERT(sync_lll);

		sync = HDR_LLL2ULL(sync_lll);
		sync = ull_sync_is_valid_get(sync);
	} else {
		sync = NULL;
	}

	if (status == TICKER_STATUS_SUCCESS) {
		if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && sync) {
			mfy.fp = aux_sync_partial;
		} else {
			return;
		}
	} else {
		if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && sync) {
			mfy.fp = aux_sync_incomplete;
		} else {
			struct ll_scan_aux_set *aux;

			aux = param;
			LL_ASSERT(aux->parent);

			mfy.fp = flush_safe;
		}
	}

	mfy.param = param;

	ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, TICKER_USER_ID_ULL_HIGH,
			     0, &mfy);
	LL_ASSERT(!ret);
}
