/*
 * Copyright (c) 2016-2019 Nordic Semiconductor ASA
 * Copyright (c) 2016 Vinayak Kariappa Chettimada
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <soc.h>
#include <zephyr/bluetooth/hci.h>

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

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

#include "ticker/ticker.h"

#include "pdu.h"

#include "lll.h"
#include "lll/lll_vendor.h"
#include "lll/lll_adv_types.h"
#include "lll_adv.h"
#include "lll/lll_adv_pdu.h"
#include "lll_scan.h"
#include "lll/lll_df_types.h"
#include "lll_conn.h"
#include "lll_filter.h"

#if !defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
#include "ull_tx_queue.h"
#endif /* CONFIG_BT_LL_SW_LLCP_LEGACY */


#include "ull_adv_types.h"
#include "ull_filter.h"

#include "ull_conn_types.h"
#include "ull_internal.h"
#include "ull_adv_internal.h"
#include "ull_scan_types.h"
#include "ull_scan_internal.h"
#include "ull_sched_internal.h"

#include "ll.h"

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
#define LOG_MODULE_NAME bt_ctlr_ull_scan
#include "common/log.h"
#include "hal/debug.h"

static int init_reset(void);
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 uint8_t disable(uint8_t handle);

#if defined(CONFIG_BT_CTLR_ADV_EXT)
#define IS_PHY_ENABLED(scan_ctx, scan_phy) ((scan_ctx)->lll.phy & (scan_phy))

static uint8_t is_scan_update(uint8_t handle, uint16_t duration,
			      uint16_t period, struct ll_scan_set **scan,
			      struct node_rx_pdu **node_rx_scan_term);
static uint8_t duration_period_setup(struct ll_scan_set *scan,
				     uint16_t duration, uint16_t period,
				     struct node_rx_pdu **node_rx_scan_term);
static uint8_t duration_period_update(struct ll_scan_set *scan,
				      uint8_t is_update);
static void ticker_stop_ext_op_cb(uint32_t status, void *param);
static void ext_disable(void *param);
static void ext_disabled_cb(void *param);
#endif /* CONFIG_BT_CTLR_ADV_EXT */

static struct ll_scan_set ll_scan[BT_CTLR_SCAN_SET];

uint8_t ll_scan_params_set(uint8_t type, uint16_t interval, uint16_t window,
			uint8_t own_addr_type, uint8_t filter_policy)
{
	struct ll_scan_set *scan;
	struct lll_scan *lll;

	scan = ull_scan_is_disabled_get(SCAN_HANDLE_1M);
	if (!scan) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

#if defined(CONFIG_BT_CTLR_ADV_EXT)
	uint8_t phy;

	phy  = type >> 1;
	if (phy & BT_HCI_LE_EXT_SCAN_PHY_CODED) {
		struct ll_scan_set *scan_coded;

		if (!IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED)) {
			return BT_HCI_ERR_CMD_DISALLOWED;
		}

		scan_coded = ull_scan_is_disabled_get(SCAN_HANDLE_PHY_CODED);
		if (!scan_coded) {
			return BT_HCI_ERR_CMD_DISALLOWED;
		}

		scan = scan_coded;
	}

	lll = &scan->lll;

	/* NOTE: Pass invalid interval value to not start scanning using this
	 *       scan instance.
	 */
	if (!interval) {
		/* Set PHY to 0 to not start scanning on this instance */
		lll->phy = 0U;

		return 0;
	}

	/* If phy assigned is PHY_1M or PHY_CODED, then scanning on that
	 * PHY is enabled.
	 */
	lll->phy = phy;

#else /* !CONFIG_BT_CTLR_ADV_EXT */
	lll = &scan->lll;
#endif /* !CONFIG_BT_CTLR_ADV_EXT */

	scan->own_addr_type = own_addr_type;

	ull_scan_params_set(lll, type, interval, window, filter_policy);

	return 0;
}

#if defined(CONFIG_BT_CTLR_ADV_EXT)
uint8_t ll_scan_enable(uint8_t enable, uint16_t duration, uint16_t period)
{
	struct node_rx_pdu *node_rx_scan_term = NULL;
	uint8_t is_update_coded = 0U;
	uint8_t is_update_1m = 0U;
#else /* !CONFIG_BT_CTLR_ADV_EXT */
uint8_t ll_scan_enable(uint8_t enable)
{
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
	struct ll_scan_set *scan_coded = NULL;
	uint8_t own_addr_type = 0U;
	uint8_t is_coded_phy = 0U;
	struct ll_scan_set *scan;
	uint8_t err;

	if (!enable) {
		err = disable(SCAN_HANDLE_1M);

		if (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT) &&
		    IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED)) {
			uint8_t err_coded;

			err_coded = disable(SCAN_HANDLE_PHY_CODED);
			if (!err_coded) {
				err = 0U;
			}
		}

		return err;
	}

	scan = ull_scan_is_disabled_get(SCAN_HANDLE_1M);
	if (!scan) {
#if defined(CONFIG_BT_CTLR_ADV_EXT)
		is_update_1m = is_scan_update(SCAN_HANDLE_1M, duration, period,
					      &scan, &node_rx_scan_term);
		if (!is_update_1m)
#endif /* CONFIG_BT_CTLR_ADV_EXT */
		{
			return BT_HCI_ERR_CMD_DISALLOWED;
		}
	}

#if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_CTLR_PHY_CODED)
	scan_coded = ull_scan_is_disabled_get(SCAN_HANDLE_PHY_CODED);
	if (!scan_coded) {
		is_update_coded = is_scan_update(SCAN_HANDLE_PHY_CODED,
						 duration, period, &scan_coded,
						 &node_rx_scan_term);
		if (!is_update_coded) {
			return BT_HCI_ERR_CMD_DISALLOWED;
		}
	}

	own_addr_type = scan_coded->own_addr_type;
	is_coded_phy = (scan_coded->lll.phy &
			BT_HCI_LE_EXT_SCAN_PHY_CODED);
#endif /* CONFIG_BT_CTLR_ADV_EXT && CONFIG_BT_CTLR_PHY_CODED */

	if ((is_coded_phy && (own_addr_type & 0x1)) ||
	    (!is_coded_phy && (scan->own_addr_type & 0x1))) {
		if (!mem_nz(ll_addr_get(BT_ADDR_LE_RANDOM), BDADDR_SIZE)) {
			return BT_HCI_ERR_INVALID_PARAM;
		}
	}

#if defined(CONFIG_BT_CTLR_ADV_EXT)
#if defined(CONFIG_BT_CTLR_PHY_CODED)
	if (!is_coded_phy || IS_PHY_ENABLED(scan, PHY_1M))
#endif /* CONFIG_BT_CTLR_PHY_CODED */
	{
		err = duration_period_setup(scan, duration, period,
					    &node_rx_scan_term);
		if (err) {
			return err;
		}
	}

	if (IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED) &&
	    is_coded_phy) {
		err = duration_period_setup(scan_coded, duration, period,
					    &node_rx_scan_term);
		if (err) {
			return err;
		}
	}
#endif /* CONFIG_BT_CTLR_ADV_EXT */

#if defined(CONFIG_BT_CTLR_PRIVACY)
	struct lll_scan *lll;

	if (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT) && is_coded_phy) {
		lll = &scan_coded->lll;

		/* TODO: Privacy support in Advertising Extensions */
	} else {
		lll = &scan->lll;
		own_addr_type = scan->own_addr_type;
	}

	ull_filter_scan_update(lll->filter_policy);

	lll->rl_idx = FILTER_IDX_NONE;
	lll->rpa_gen = 0;

	if ((lll->type & 0x1) &&
	    (own_addr_type == BT_ADDR_LE_PUBLIC_ID ||
	     own_addr_type == BT_ADDR_LE_RANDOM_ID)) {
		/* Generate RPAs if required */
		ull_filter_rpa_update(false);
		lll->rpa_gen = 1;
	}
#endif /* CONFIG_BT_CTLR_PRIVACY */

#if defined(CONFIG_BT_CTLR_ADV_EXT)
#if defined(CONFIG_BT_CTLR_PHY_CODED)
	if (!is_coded_phy || IS_PHY_ENABLED(scan, PHY_1M))
#endif /* CONFIG_BT_CTLR_PHY_CODED */
	{
		err = duration_period_update(scan, is_update_1m);
		if (err) {
			return err;
		} else if (is_update_1m) {
			return 0;
		}
	}

	if (IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED) &&
	    is_coded_phy) {
		err = duration_period_update(scan_coded, is_update_coded);
		if (err) {
			return err;
		} else if (is_update_coded) {
			return 0;
		}
	}

#if defined(CONFIG_BT_CTLR_PHY_CODED)
	if (!is_coded_phy || IS_PHY_ENABLED(scan, PHY_1M))
#endif /* CONFIG_BT_CTLR_PHY_CODED */
#endif /* CONFIG_BT_CTLR_ADV_EXT */
	{
		err = ull_scan_enable(scan);
		if (err) {
			return err;
		}
	}

	if (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT) &&
	    IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED) &&
	    is_coded_phy) {
		err = ull_scan_enable(scan_coded);
		if (err) {
			return err;
		}
	}

	return 0;
}

int ull_scan_init(void)
{
	int err;

	if (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT)) {
		err = ull_scan_aux_init();
		if (err) {
			return err;
		}
	}

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

	return 0;
}

int ull_scan_reset(void)
{
	uint8_t handle;
	int err;

	for (handle = 0U; handle < BT_CTLR_SCAN_SET; handle++) {
		(void)disable(handle);

#if defined(CONFIG_BT_CTLR_ADV_EXT)
		/* Initialize PHY value to 0 to not start scanning on the scan
		 * instance if an explicit ll_scan_params_set() has not been
		 * invoked from HCI to enable scanning on that PHY.
		 */
		ll_scan[handle].lll.phy = 0U;
#endif /* CONFIG_BT_CTLR_ADV_EXT */
	}

	if (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT)) {
		err = ull_scan_aux_reset();
		if (err) {
			return err;
		}
	}

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

	return 0;
}

void ull_scan_params_set(struct lll_scan *lll, uint8_t type, uint16_t interval,
			 uint16_t window, uint8_t filter_policy)
{
	/* type value:
	 * 0000b - legacy 1M passive
	 * 0001b - legacy 1M active
	 * 0010b - Ext. 1M passive
	 * 0011b - Ext. 1M active
	 * 0100b - invalid
	 * 0101b - invalid
	 * 0110b - invalid
	 * 0111b - invalid
	 * 1000b - Ext. Coded passive
	 * 1001b - Ext. Coded active
	 */
	lll->type = type;
	lll->filter_policy = filter_policy;
	lll->interval = interval;
	lll->ticks_window = HAL_TICKER_US_TO_TICKS((uint64_t)window *
						   SCAN_INT_UNIT_US);
}

uint8_t ull_scan_enable(struct ll_scan_set *scan)
{
	uint32_t ticks_slot_overhead;
	uint32_t volatile ret_cb;
	uint32_t ticks_interval;
	uint32_t ticks_anchor;
	uint32_t ticks_offset;
	struct lll_scan *lll;
	uint8_t handle;
	uint32_t ret;

#if defined(CONFIG_BT_CTLR_ADV_EXT)
	/* Initialize extend scan stop request */
	scan->is_stop = 0U;
#endif /* CONFIG_BT_CTLR_ADV_EXT */

	/* Initialize LLL scan context */
	lll = &scan->lll;
	lll->init_addr_type = scan->own_addr_type;
	(void)ll_addr_read(lll->init_addr_type, lll->init_addr);
	lll->chan = 0U;
	lll->is_stop = 0U;

	ull_hdr_init(&scan->ull);
	lll_hdr_init(lll, scan);

	ticks_interval = HAL_TICKER_US_TO_TICKS((uint64_t)lll->interval *
						SCAN_INT_UNIT_US);

	/* TODO: active_to_start feature port */
	scan->ull.ticks_active_to_start = 0U;
	scan->ull.ticks_prepare_to_start =
		HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US);
	scan->ull.ticks_preempt_to_start =
		HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US);

	if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) {
		ticks_slot_overhead = MAX(scan->ull.ticks_active_to_start,
					  scan->ull.ticks_prepare_to_start);
	} else {
		ticks_slot_overhead = 0U;
	}

	if ((lll->ticks_window +
	     HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US)) <
	    (ticks_interval - ticks_slot_overhead)) {
		scan->ull.ticks_slot =
			(lll->ticks_window +
			 HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US));
	} else {
		if (IS_ENABLED(CONFIG_BT_CTLR_SCAN_UNRESERVED)) {
			scan->ull.ticks_slot = 0U;
		} else {
			scan->ull.ticks_slot = ticks_interval -
					       ticks_slot_overhead;
		}

		lll->ticks_window = 0U;
	}

	handle = ull_scan_handle_get(scan);

	if (false) {

#if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_CTLR_PHY_CODED)
	} else if (handle == SCAN_HANDLE_1M) {
		const struct ll_scan_set *scan_coded;

		scan_coded = ull_scan_set_get(SCAN_HANDLE_PHY_CODED);
		if (IS_PHY_ENABLED(scan_coded, PHY_CODED) &&
		    (lll->ticks_window != 0U)) {
			const struct lll_scan *lll_coded;
			uint32_t ticks_interval_coded;
			uint32_t ticks_window_sum_min;
			uint32_t ticks_window_sum_max;

			lll_coded = &scan_coded->lll;
			ticks_interval_coded = HAL_TICKER_US_TO_TICKS(
						(uint64_t)lll_coded->interval *
						SCAN_INT_UNIT_US);
			ticks_window_sum_min = lll->ticks_window +
					       lll_coded->ticks_window;
			ticks_window_sum_max = ticks_window_sum_min +
				HAL_TICKER_US_TO_TICKS(EVENT_TICKER_RES_MARGIN_US << 1);
			/* Check if 1M and Coded PHY scanning use same interval
			 * and the sum of the scan window duration equals their
			 * interval then use continuous scanning and avoid time
			 * reservation from overlapping.
			 */
			if ((ticks_interval == ticks_interval_coded) &&
			    IN_RANGE(ticks_interval, ticks_window_sum_min,
				     ticks_window_sum_max)) {
				if (IS_ENABLED(CONFIG_BT_CTLR_SCAN_UNRESERVED)) {
					scan->ull.ticks_slot = 0U;
				} else {
					scan->ull.ticks_slot =
						lll->ticks_window -
						ticks_slot_overhead -
						HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US) -
						HAL_TICKER_US_TO_TICKS(EVENT_TICKER_RES_MARGIN_US);
				}

				/* Continuous scanning, no scan window stop
				 * ticker to be started but we will zero the
				 * ticks_window value when coded PHY scan is
				 * enabled (the next following else clause).
				 * Due to this the first scan window will have
				 * the stop ticker started but consecutive
				 * scan window will not have the stop ticker
				 * started once coded PHY scan window has been
				 * enabled.
				 */
			}
		}

		/* 1M scan window starts without any offset */
		ticks_offset = 0U;

	} else if (handle == SCAN_HANDLE_PHY_CODED) {
		struct ll_scan_set *scan_1m;

		scan_1m = ull_scan_set_get(SCAN_HANDLE_1M);
		if (IS_PHY_ENABLED(scan_1m, PHY_1M) &&
		    (lll->ticks_window != 0U)) {
			uint32_t ticks_window_sum_min;
			uint32_t ticks_window_sum_max;
			uint32_t ticks_interval_1m;
			struct lll_scan *lll_1m;

			lll_1m = &scan_1m->lll;
			ticks_interval_1m = HAL_TICKER_US_TO_TICKS(
						(uint64_t)lll_1m->interval *
						SCAN_INT_UNIT_US);
			ticks_window_sum_min = lll->ticks_window +
					       lll_1m->ticks_window;
			ticks_window_sum_max = ticks_window_sum_min +
				HAL_TICKER_US_TO_TICKS(EVENT_TICKER_RES_MARGIN_US << 1);
			/* Check if 1M and Coded PHY scanning use same interval
			 * and the sum of the scan window duration equals their
			 * interval then use continuous scanning and avoid time
			 * reservation from overlapping.
			 */
			if ((ticks_interval == ticks_interval_1m) &&
			    IN_RANGE(ticks_interval, ticks_window_sum_min,
				     ticks_window_sum_max)) {
				if (IS_ENABLED(CONFIG_BT_CTLR_SCAN_UNRESERVED)) {
					scan->ull.ticks_slot = 0U;
				} else {
					scan->ull.ticks_slot =
						lll->ticks_window -
						ticks_slot_overhead -
						HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US) -
						HAL_TICKER_US_TO_TICKS(EVENT_TICKER_RES_MARGIN_US);
				}
				/* Offset the coded PHY scan window, place
				 * after 1M scan window.
				 * Have some margin for jitter due to ticker
				 * resolution.
				 */
				ticks_offset = lll_1m->ticks_window;
				ticks_offset += HAL_TICKER_US_TO_TICKS(
					EVENT_TICKER_RES_MARGIN_US << 1);

				/* Continuous scanning, no scan window stop
				 * ticker started for both 1M and coded PHY.
				 */
				lll->ticks_window = 0U;
				lll_1m->ticks_window = 0U;

			} else {
				ticks_offset = 0U;
			}
		} else {
			ticks_offset = 0U;
		}
#endif /* CONFIG_BT_CTLR_ADV_EXT && CONFIG_BT_CTLR_PHY_CODED */

	} else {
		ticks_offset = 0U;
	}

	ticks_anchor = ticker_ticks_now_get();

#if defined(CONFIG_BT_CENTRAL) && defined(CONFIG_BT_CTLR_SCHED_ADVANCED)
	if (!lll->conn) {
		uint32_t ticks_ref = 0U;
		uint32_t offset_us = 0U;
		int err;

		err = ull_sched_after_cen_slot_get(TICKER_USER_ID_THREAD,
						   (scan->ull.ticks_slot +
						    ticks_slot_overhead),
						   &ticks_ref, &offset_us);

		/* Use the ticks_ref as scanner's anchor if a free time space
		 * after any central role is available (indicated by a non-zero
		 * offset_us value).
		 */
		if (!err) {
			ticks_anchor = ticks_ref +
				       HAL_TICKER_US_TO_TICKS(offset_us);
		}
	}
#endif /* CONFIG_BT_CENTRAL && CONFIG_BT_CTLR_SCHED_ADVANCED */

	ret_cb = TICKER_STATUS_BUSY;
	ret = ticker_start(TICKER_INSTANCE_ID_CTLR,
			   TICKER_USER_ID_THREAD, TICKER_ID_SCAN_BASE + handle,
			   (ticks_anchor + ticks_offset), 0, ticks_interval,
			   HAL_TICKER_REMAINDER((uint64_t)lll->interval *
						SCAN_INT_UNIT_US),
			   TICKER_NULL_LAZY,
			   (scan->ull.ticks_slot + ticks_slot_overhead),
			   ticker_cb, scan,
			   ull_ticker_status_give, (void *)&ret_cb);
	ret = ull_ticker_status_take(ret, &ret_cb);
	if (ret != TICKER_STATUS_SUCCESS) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	scan->is_enabled = 1U;

#if defined(CONFIG_BT_CTLR_PRIVACY)
#if defined(CONFIG_BT_BROADCASTER)
	if (!ull_adv_is_enabled_get(0))
#endif
	{
		ull_filter_adv_scan_state_cb(BIT(1));
	}
#endif

	return 0;
}

uint8_t ull_scan_disable(uint8_t handle, struct ll_scan_set *scan)
{
	int err;

#if defined(CONFIG_BT_CTLR_ADV_EXT)
	/* Request Extended Scan stop */
	scan->is_stop = 1U;
	cpu_dmb();
#endif /* CONFIG_BT_CTLR_ADV_EXT */

	err = ull_ticker_stop_with_mark(TICKER_ID_SCAN_BASE + handle,
					scan, &scan->lll);
	LL_ASSERT(err == 0 || err == -EALREADY);
	if (err) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

#if defined(CONFIG_BT_CTLR_ADV_EXT)
	/* Find and stop associated auxiliary scan contexts */
	for (uint8_t aux_handle = 0; aux_handle < CONFIG_BT_CTLR_SCAN_AUX_SET;
	     aux_handle++) {
		struct lll_scan_aux *aux_scan_lll;
		struct ll_scan_set *aux_scan;
		struct ll_scan_aux_set *aux;

		aux = ull_scan_aux_set_get(aux_handle);
		aux_scan_lll = aux->parent;
		if (!aux_scan_lll) {
			continue;
		}

		aux_scan = HDR_LLL2ULL(aux_scan_lll);
		if (aux_scan == scan) {
			void *parent;

			err = ull_scan_aux_stop(aux);
			if (err && (err != -EALREADY)) {
				return BT_HCI_ERR_CMD_DISALLOWED;
			}

			/* Use a local variable to assert on auxiliary context's
			 * release.
			 * Under race condition a released aux context can be
			 * allocated for reception of chain PDU of a periodic
			 * sync role.
			 */
			parent = aux->parent;
			LL_ASSERT(!parent || (parent != aux_scan_lll));
		}
	}
#endif /* CONFIG_BT_CTLR_ADV_EXT */

	return 0;
}

#if defined(CONFIG_BT_CTLR_ADV_EXT)
void ull_scan_done(struct node_rx_event_done *done)
{
	struct node_rx_hdr *rx_hdr;
	struct ll_scan_set *scan;
	struct lll_scan *lll;
	uint8_t handle;
	uint32_t ret;

	/* Get reference to ULL context */
	scan = CONTAINER_OF(done->param, struct ll_scan_set, ull);
	lll = &scan->lll;

	if (likely(scan->duration_lazy || !lll->duration_reload ||
		   lll->duration_expire)) {
		return;
	}

	/* Prevent duplicate terminate event generation */
	lll->duration_reload = 0U;

	handle = ull_scan_handle_get(scan);
	LL_ASSERT(handle < BT_CTLR_SCAN_SET);

#if defined(CONFIG_BT_CTLR_PHY_CODED)
	/* Prevent duplicate terminate event if ull_scan_done get called by
	 * the other scan instance.
	 */
	struct ll_scan_set *scan_other;

	if (handle == SCAN_HANDLE_1M) {
		scan_other = ull_scan_set_get(SCAN_HANDLE_PHY_CODED);
	} else {
		scan_other = ull_scan_set_get(SCAN_HANDLE_1M);
	}
	scan_other->lll.duration_reload = 0U;
#endif /* CONFIG_BT_CTLR_PHY_CODED */

	rx_hdr = (void *)scan->node_rx_scan_term;
	rx_hdr->type = NODE_RX_TYPE_EXT_SCAN_TERMINATE;
	rx_hdr->handle = handle;

	ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
			  (TICKER_ID_SCAN_BASE + handle), ticker_stop_ext_op_cb,
			  scan);

	LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
		  (ret == TICKER_STATUS_BUSY));
}

void ull_scan_term_dequeue(uint8_t handle)
{
	struct ll_scan_set *scan;

	scan = ull_scan_set_get(handle);
	LL_ASSERT(scan);

	scan->is_enabled = 0U;

#if defined(CONFIG_BT_CTLR_PHY_CODED)
	if (handle == SCAN_HANDLE_1M) {
		struct ll_scan_set *scan_coded;

		scan_coded = ull_scan_set_get(SCAN_HANDLE_PHY_CODED);
		if (IS_PHY_ENABLED(scan_coded, PHY_CODED)) {
			uint8_t err;

			err = disable(SCAN_HANDLE_PHY_CODED);
			LL_ASSERT(!err);
		}
	} else {
		struct ll_scan_set *scan_1m;

		scan_1m = ull_scan_set_get(SCAN_HANDLE_1M);
		if (IS_PHY_ENABLED(scan_1m, PHY_1M)) {
			uint8_t err;

			err = disable(SCAN_HANDLE_1M);
			LL_ASSERT(!err);
		}
	}
#endif /* CONFIG_BT_CTLR_PHY_CODED */
}
#endif /* CONFIG_BT_CTLR_ADV_EXT */

struct ll_scan_set *ull_scan_set_get(uint8_t handle)
{
	if (handle >= BT_CTLR_SCAN_SET) {
		return NULL;
	}

	return &ll_scan[handle];
}

uint8_t ull_scan_handle_get(struct ll_scan_set *scan)
{
	return ((uint8_t *)scan - (uint8_t *)ll_scan) / sizeof(*scan);
}

uint8_t ull_scan_lll_handle_get(struct lll_scan *lll)
{
	return ull_scan_handle_get((void *)lll->hdr.parent);
}

struct ll_scan_set *ull_scan_is_valid_get(struct ll_scan_set *scan)
{
	if (((uint8_t *)scan < (uint8_t *)ll_scan) ||
	    ((uint8_t *)scan > ((uint8_t *)ll_scan +
				(sizeof(struct ll_scan_set) *
				 (BT_CTLR_SCAN_SET - 1))))) {
		return NULL;
	}

	return scan;
}

struct lll_scan *ull_scan_lll_is_valid_get(struct lll_scan *lll)
{
	struct ll_scan_set *scan;

	scan = HDR_LLL2ULL(lll);
	scan = ull_scan_is_valid_get(scan);
	if (scan) {
		return &scan->lll;
	}

	return NULL;
}

struct ll_scan_set *ull_scan_is_enabled_get(uint8_t handle)
{
	struct ll_scan_set *scan;

	scan = ull_scan_set_get(handle);
	if (!scan || !scan->is_enabled) {
		return NULL;
	}

	return scan;
}

struct ll_scan_set *ull_scan_is_disabled_get(uint8_t handle)
{
	struct ll_scan_set *scan;

	scan = ull_scan_set_get(handle);
	if (!scan || scan->is_enabled) {
		return NULL;
	}

	return scan;
}

uint32_t ull_scan_is_enabled(uint8_t handle)
{
	struct ll_scan_set *scan;

	scan = ull_scan_is_enabled_get(handle);
	if (!scan) {
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
		scan = ull_scan_set_get(handle);

		return scan->periodic.sync ? ULL_SCAN_IS_SYNC : 0U;
#else
		return 0U;
#endif
	}

	return (((uint32_t)scan->is_enabled << scan->lll.type) |
#if defined(CONFIG_BT_CENTRAL)
		(scan->lll.conn ? ULL_SCAN_IS_INITIATOR : 0U) |
#endif
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
		(scan->periodic.sync ? ULL_SCAN_IS_SYNC : 0U) |
#endif
		0U);
}

uint32_t ull_scan_filter_pol_get(uint8_t handle)
{
	struct ll_scan_set *scan;

	scan = ull_scan_is_enabled_get(handle);
	if (!scan) {
		return 0;
	}

	return scan->lll.filter_policy;
}

static int init_reset(void)
{
#if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) && \
	!defined(CONFIG_BT_CTLR_ADV_EXT)
	ll_scan[0].lll.tx_pwr_lvl = RADIO_TXP_DEFAULT;
#endif /* CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL && !CONFIG_BT_CTLR_ADV_EXT */

	return 0;
}

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_prepare};
	static struct lll_prepare_param p;
	struct ll_scan_set *scan;
	struct lll_scan *lll;
	uint32_t ret;
	uint8_t ref;

	DEBUG_RADIO_PREPARE_O(1);

	scan = param;
	lll = &scan->lll;

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

	/* Append timing parameters */
	p.ticks_at_expire = ticks_at_expire;
	p.remainder = remainder;
	p.lazy = lazy;
	p.param = lll;
	p.force = force;
	mfy.param = &p;

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

#if defined(CONFIG_BT_CTLR_ADV_EXT)
	if (lll->duration_expire) {
		uint16_t elapsed;

		elapsed = lazy + 1;
		if (lll->duration_expire > elapsed) {
			lll->duration_expire -= elapsed;
		} else {
			if (scan->duration_lazy) {
				uint8_t handle;
				uint16_t duration_lazy;

				duration_lazy = lll->duration_expire +
						scan->duration_lazy - elapsed;

				handle = ull_scan_handle_get(scan);
				LL_ASSERT(handle < BT_CTLR_SCAN_SET);

				ret = ticker_update(TICKER_INSTANCE_ID_CTLR,
						    TICKER_USER_ID_ULL_HIGH,
						    (TICKER_ID_SCAN_BASE +
						     handle), 0, 0, 0, 0,
						    duration_lazy, 0,
						    NULL, NULL);
				LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
					  (ret == TICKER_STATUS_BUSY));
			}

			lll->duration_expire = 0U;
		}
	} else if (lll->duration_reload && lazy) {
		uint8_t handle;

		handle = ull_scan_handle_get(scan);
		LL_ASSERT(handle < BT_CTLR_SCAN_SET);

		lll->duration_expire = lll->duration_reload;
		ret = ticker_update(TICKER_INSTANCE_ID_CTLR,
				    TICKER_USER_ID_ULL_HIGH,
				    (TICKER_ID_SCAN_BASE + handle),
				    0, 0, 0, 0, 1, 1, NULL, NULL);
		LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
			  (ret == TICKER_STATUS_BUSY));
	}
#endif /* CONFIG_BT_CTLR_ADV_EXT */

	DEBUG_RADIO_PREPARE_O(1);
}

#if defined(CONFIG_BT_CTLR_ADV_EXT)
static uint8_t is_scan_update(uint8_t handle, uint16_t duration,
			      uint16_t period, struct ll_scan_set **scan,
			      struct node_rx_pdu **node_rx_scan_term)
{
	*scan = ull_scan_set_get(handle);
	*node_rx_scan_term = (void *)(*scan)->node_rx_scan_term;
	return duration && period && (*scan)->lll.duration_reload &&
	       (*scan)->duration_lazy;
}

static uint8_t duration_period_setup(struct ll_scan_set *scan,
				     uint16_t duration, uint16_t period,
				     struct node_rx_pdu **node_rx_scan_term)
{
	struct lll_scan *lll;

	lll = &scan->lll;
	if (duration) {
		lll->duration_reload =
			ULL_SCAN_DURATION_TO_EVENTS(duration,
						    scan->lll.interval);
		if (period) {
			if (IS_ENABLED(CONFIG_BT_CTLR_PARAM_CHECK) &&
			    (duration >= ULL_SCAN_PERIOD_TO_DURATION(period))) {
				return BT_HCI_ERR_INVALID_PARAM;
			}

			scan->duration_lazy =
				ULL_SCAN_PERIOD_TO_EVENTS(period,
							  scan->lll.interval);
			scan->duration_lazy -= lll->duration_reload;
			scan->node_rx_scan_term = NULL;
		} else {
			struct node_rx_pdu *node_rx;
			void *link_scan_term;

			scan->duration_lazy = 0U;

			if (*node_rx_scan_term) {
				scan->node_rx_scan_term =
					(void *)*node_rx_scan_term;

				return 0;
			}

			/* The alloc here used for ext scan termination event */
			link_scan_term = ll_rx_link_alloc();
			if (!link_scan_term) {
				return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
			}

			node_rx = ll_rx_alloc();
			if (!node_rx) {
				ll_rx_link_release(link_scan_term);

				return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
			}

			node_rx->hdr.link = (void *)link_scan_term;
			scan->node_rx_scan_term = (void *)node_rx;
			*node_rx_scan_term = node_rx;
		}
	} else {
		lll->duration_reload = 0U;
		scan->duration_lazy = 0U;
		scan->node_rx_scan_term = NULL;
	}

	return 0;
}

static uint8_t duration_period_update(struct ll_scan_set *scan,
				      uint8_t is_update)
{
	if (is_update) {
		uint32_t volatile ret_cb;
		uint32_t ret;

		scan->lll.duration_expire = 0U;

		ret_cb = TICKER_STATUS_BUSY;
		ret = ticker_update(TICKER_INSTANCE_ID_CTLR,
				    TICKER_USER_ID_THREAD,
				    (TICKER_ID_SCAN_BASE +
				     ull_scan_handle_get(scan)),
				    0, 0, 0, 0, 1, 1,
				    ull_ticker_status_give, (void *)&ret_cb);
		ret = ull_ticker_status_take(ret, &ret_cb);
		if (ret != TICKER_STATUS_SUCCESS) {
			return BT_HCI_ERR_CMD_DISALLOWED;
		}

		return 0;
	} else {
		scan->lll.duration_expire = scan->lll.duration_reload;
	}

	return 0;
}

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

	/* Ignore if race between thread and ULL */
	if (status != TICKER_STATUS_SUCCESS) {
		/* TODO: detect race */

		return;
	}

	/* Check if any pending LLL events that need to be aborted */
	mfy.param = param;
	ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW,
			     TICKER_USER_ID_ULL_HIGH, 0, &mfy);
	LL_ASSERT(!ret);
}

static void ext_disable(void *param)
{
	struct ll_scan_set *scan;
	struct ull_hdr *hdr;

	/* Check ref count to determine if any pending LLL events in pipeline */
	scan = param;
	hdr = &scan->ull;
	if (ull_ref_get(hdr)) {
		static memq_link_t link;
		static struct mayfly mfy = {0, 0, &link, NULL, lll_disable};
		uint32_t ret;

		mfy.param = &scan->lll;

		/* Setup disabled callback to be called when ref count
		 * returns to zero.
		 */
		LL_ASSERT(!hdr->disabled_cb);
		hdr->disabled_param = mfy.param;
		hdr->disabled_cb = ext_disabled_cb;

		/* Trigger LLL disable */
		ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH,
				     TICKER_USER_ID_LLL, 0, &mfy);
		LL_ASSERT(!ret);
	} else {
		/* No pending LLL events */
		ext_disabled_cb(&scan->lll);
	}
}

static void ext_disabled_cb(void *param)
{
	struct node_rx_hdr *rx_hdr;
	struct ll_scan_set *scan;
	struct lll_scan *lll;

	/* Under race condition, if a connection has been established then
	 * node_rx is already utilized to send terminate event on connection
	 */
	lll = (void *)param;
	scan = HDR_LLL2ULL(lll);
	rx_hdr = (void *)scan->node_rx_scan_term;
	if (!rx_hdr) {
		return;
	}

	/* NOTE: parameters are already populated on disable,
	 * just enqueue here
	 */
	ll_rx_put(rx_hdr->link, rx_hdr);
	ll_rx_sched();
}
#endif /* CONFIG_BT_CTLR_ADV_EXT */

static uint8_t disable(uint8_t handle)
{
	struct ll_scan_set *scan;
	uint8_t ret;

	scan = ull_scan_is_enabled_get(handle);
	if (!scan) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

#if defined(CONFIG_BT_CENTRAL)
	if (scan->lll.conn) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}
#endif

	ret = ull_scan_disable(handle, scan);
	if (ret) {
		return ret;
	}

	scan->is_enabled = 0U;

#if defined(CONFIG_BT_CTLR_ADV_EXT)
	if (scan->node_rx_scan_term) {
		struct node_rx_pdu *node_rx_scan_term =
			(void *)scan->node_rx_scan_term;

		scan->node_rx_scan_term = NULL;

		ll_rx_link_release(node_rx_scan_term->hdr.link);
		ll_rx_release(node_rx_scan_term);
	}
#endif /* CONFIG_BT_CTLR_ADV_EXT */

#if defined(CONFIG_BT_CTLR_PRIVACY)
#if defined(CONFIG_BT_BROADCASTER)
	if (!ull_adv_is_enabled_get(0))
#endif
	{
		ull_filter_adv_scan_state_cb(0);
	}
#endif

	return 0;
}
