/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <stdint.h>

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

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

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

#include "pdu.h"

#include "lll.h"
#include "lll_vendor.h"
#include "lll_clock.h"
#include "lll_chan.h"
#include "lll_df_types.h"
#include "lll_scan.h"
#include "lll_sync.h"

#include "lll_internal.h"
#include "lll_tim_internal.h"
#include "lll_prof_internal.h"
#include "lll_scan_internal.h"

#include "lll_df.h"
#include "lll_df_internal.h"

#include "ll_feat.h"

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

static int init_reset(void);
static void prepare(void *param);
static int create_prepare_cb(struct lll_prepare_param *p);
static int prepare_cb(struct lll_prepare_param *p);
static int prepare_cb_common(struct lll_prepare_param *p, uint8_t chan_idx);
static int is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb);
static void abort_cb(struct lll_prepare_param *prepare_param, void *param);
static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t crc_ok,
		  uint8_t phy_flags_rx, uint8_t cte_ready, uint8_t rssi_ready,
		  enum sync_status status);
static void isr_rx_adv_sync_estab(void *param);
static void isr_rx_adv_sync(void *param);
static void isr_rx_aux_chain(void *param);
static void isr_rx_done_cleanup(struct lll_sync *lll, uint8_t crc_ok, bool sync_term);
static void isr_done(void *param);
#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
static int create_iq_report(struct lll_sync *lll, uint8_t rssi_ready,
			    uint8_t packet_status);
static bool is_max_cte_reached(uint8_t max_cte_count, uint8_t cte_count);
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
static uint8_t data_channel_calc(struct lll_sync *lll);
static enum sync_status sync_filtrate_by_cte_type(uint8_t cte_type_mask, uint8_t filter_policy);

static uint8_t trx_cnt;

int lll_sync_init(void)
{
	int err;

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

	return 0;
}

int lll_sync_reset(void)
{
	int err;

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

	return 0;
}

void lll_sync_create_prepare(void *param)
{
	int err;

	prepare(param);

	/* Invoke common pipeline handling of prepare */
	err = lll_prepare(is_abort_cb, abort_cb, create_prepare_cb, 0, param);
	LL_ASSERT(!err || err == -EINPROGRESS);
}

void lll_sync_prepare(void *param)
{
	int err;

	prepare(param);

	/* Invoke common pipeline handling of prepare */
	err = lll_prepare(is_abort_cb, abort_cb, prepare_cb, 0, param);
	LL_ASSERT(!err || err == -EINPROGRESS);
}

static void prepare(void *param)
{
	struct lll_prepare_param *p;
	struct lll_sync *lll;
	int err;

	/* Request to start HF Clock */
	err = lll_hfclock_on();
	LL_ASSERT(err >= 0);

	p = param;

	lll = p->param;

	/* Accumulate window widening */
	lll->window_widening_prepare_us += lll->window_widening_periodic_us *
					   (p->lazy + 1);
	if (lll->window_widening_prepare_us > lll->window_widening_max_us) {
		lll->window_widening_prepare_us = lll->window_widening_max_us;
	}
}

void lll_sync_aux_prepare_cb(struct lll_sync *lll,
			     struct lll_scan_aux *lll_aux)
{
	struct node_rx_pdu *node_rx;

	/* Initialize Trx count */
	trx_cnt = 0U;

	/* Start setting up Radio h/w */
	radio_reset();

	radio_phy_set(lll_aux->phy, PHY_FLAGS_S8);
	radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, LL_EXT_OCTETS_RX_MAX,
			    RADIO_PKT_CONF_PHY(lll_aux->phy));

	node_rx = ull_pdu_rx_alloc_peek(1);
	LL_ASSERT(node_rx);

	radio_pkt_rx_set(node_rx->pdu);

	/* Set access address for sync */
	radio_aa_set(lll->access_addr);
	radio_crc_configure(PDU_CRC_POLYNOMIAL,
				sys_get_le24(lll->crc_init));

	lll_chan_set(lll_aux->chan);

	radio_isr_set(isr_rx_aux_chain, lll);

#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
	struct lll_df_sync_cfg *cfg;

	cfg = lll_df_sync_cfg_latest_get(&lll->df_cfg, NULL);

	if (cfg->is_enabled) {
		lll_df_conf_cte_rx_enable(cfg->slot_durations, cfg->ant_sw_len, cfg->ant_ids,
					  lll_aux->chan, CTE_INFO_IN_PAYLOAD, lll_aux->phy);
		cfg->cte_count = 0;
	}
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
	radio_switch_complete_and_disable();
}

#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING)
enum sync_status lll_sync_cte_is_allowed(uint8_t cte_type_mask, uint8_t filter_policy,
					 uint8_t rx_cte_time, uint8_t rx_cte_type)
{
	bool cte_ok;

	if (cte_type_mask == BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_FILTERING) {
		return SYNC_STAT_ALLOWED;
	}

	if (rx_cte_time > 0) {
		if ((cte_type_mask & BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_CTE) != 0) {
			cte_ok = false;
		} else {
			switch (rx_cte_type) {
			case BT_HCI_LE_AOA_CTE:
				cte_ok = !(cte_type_mask &
					   BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOA);
				break;
			case BT_HCI_LE_AOD_CTE_1US:
				cte_ok = !(cte_type_mask &
					   BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_1US);
				break;
			case BT_HCI_LE_AOD_CTE_2US:
				cte_ok = !(cte_type_mask &
					   BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_2US);
				break;
			default:
				/* Unknown or forbidden CTE type */
				cte_ok = false;
			}
		}
	} else {
		/* If there is no CTEInfo in advertising PDU, Radio will not parse the S0 byte and
		 * CTESTATUS register will hold zeros only.
		 * Zero value in CTETime field of CTESTATUS may be used to distinguish between PDU
		 * that includes CTEInfo or not. Allowed range for CTETime is 2-20.
		 */
		if ((cte_type_mask & BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_ONLY_CTE) != 0) {
			cte_ok = false;
		} else {
			cte_ok = true;
		}
	}

	if (!cte_ok) {
		return filter_policy ? SYNC_STAT_CONT_SCAN : SYNC_STAT_TERM;
	}

	return SYNC_STAT_ALLOWED;
}
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */

static int init_reset(void)
{
	return 0;
}

static int create_prepare_cb(struct lll_prepare_param *p)
{
	uint16_t event_counter;
	struct lll_sync *lll;
	uint8_t chan_idx;
	int err;

	DEBUG_RADIO_START_O(1);

	lll = p->param;

	/* Calculate the current event latency */
	lll->skip_event = lll->skip_prepare + p->lazy;

	/* Calculate the current event counter value */
	event_counter = lll->event_counter + lll->skip_event;

	/* Reset accumulated latencies */
	lll->skip_prepare = 0;

	chan_idx = data_channel_calc(lll);

	/* Update event counter to next value */
	lll->event_counter = (event_counter + 1);

	err = prepare_cb_common(p, chan_idx);
	if (err) {
		DEBUG_RADIO_START_O(1);

		return 0;
	}

#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
	struct lll_df_sync_cfg *cfg;

	cfg = lll_df_sync_cfg_latest_get(&lll->df_cfg, NULL);
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */

	if (false) {
#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
	} else if (cfg->is_enabled) {

		lll_df_conf_cte_rx_enable(cfg->slot_durations, cfg->ant_sw_len, cfg->ant_ids,
					  chan_idx, CTE_INFO_IN_PAYLOAD, lll->phy);
		cfg->cte_count = 0;
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
	} else if (IS_ENABLED(CONFIG_BT_CTLR_DF_SUPPORT)) {
		radio_df_cte_inline_set_enabled(false);
	}

	radio_switch_complete_and_disable();

	/* RSSI enable must be called after radio_switch_XXX function because it clears
	 * RADIO->SHORTS register, thus disables all other shortcuts.
	 */
	radio_rssi_measure();

	radio_isr_set(isr_rx_adv_sync_estab, lll);

	DEBUG_RADIO_START_O(1);

	return 0;
}

static int prepare_cb(struct lll_prepare_param *p)
{
	uint16_t event_counter;
	struct lll_sync *lll;
	uint8_t chan_idx;
	int err;

	DEBUG_RADIO_START_O(1);

	lll = p->param;

	/* Calculate the current event latency */
	lll->skip_event = lll->skip_prepare + p->lazy;

	/* Calculate the current event counter value */
	event_counter = lll->event_counter + lll->skip_event;

	/* Reset accumulated latencies */
	lll->skip_prepare = 0;

	chan_idx = data_channel_calc(lll);

	/* Update event counter to next value */
	lll->event_counter = (event_counter + 1);

	err = prepare_cb_common(p, chan_idx);
	if (err) {
		DEBUG_RADIO_START_O(1);
		return 0;
	}

#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
	struct lll_df_sync_cfg *cfg;

	cfg = lll_df_sync_cfg_latest_get(&lll->df_cfg, NULL);

	if (cfg->is_enabled) {
		lll_df_conf_cte_rx_enable(cfg->slot_durations, cfg->ant_sw_len, cfg->ant_ids,
					  chan_idx, CTE_INFO_IN_PAYLOAD, lll->phy);
		cfg->cte_count = 0;
	}
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */

	radio_switch_complete_and_disable();

	/* RSSI enable must be called after radio_switch_XXX function because it clears
	 * RADIO->SHORTS register, thus disables all other shortcuts.
	 */
	radio_rssi_measure();

	radio_isr_set(isr_rx_adv_sync, lll);

	DEBUG_RADIO_START_O(1);

	return 0;
}

static int prepare_cb_common(struct lll_prepare_param *p, uint8_t chan_idx)
{
	struct node_rx_pdu *node_rx;
	uint32_t ticks_at_event;
	uint32_t ticks_at_start;
	uint32_t remainder_us;
	struct lll_sync *lll;
	struct ull_hdr *ull;
	uint32_t remainder;
	uint32_t hcto;

	lll = p->param;

	/* Current window widening */
	lll->window_widening_event_us += lll->window_widening_prepare_us;
	lll->window_widening_prepare_us = 0;
	if (lll->window_widening_event_us > lll->window_widening_max_us) {
		lll->window_widening_event_us =	lll->window_widening_max_us;
	}

	/* Reset chain PDU being scheduled by lll_sync context */
	lll->is_aux_sched = 0U;

	/* Initialize Trx count */
	trx_cnt = 0U;

	/* Start setting up Radio h/w */
	radio_reset();

	radio_phy_set(lll->phy, PHY_FLAGS_S8);
	radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, LL_EXT_OCTETS_RX_MAX,
			    RADIO_PKT_CONF_PHY(lll->phy));
	radio_aa_set(lll->access_addr);
	radio_crc_configure(PDU_CRC_POLYNOMIAL,
					sys_get_le24(lll->crc_init));

	lll_chan_set(chan_idx);

	node_rx = ull_pdu_rx_alloc_peek(1);
	LL_ASSERT(node_rx);

	radio_pkt_rx_set(node_rx->pdu);

	ticks_at_event = p->ticks_at_expire;
	ull = HDR_LLL2ULL(lll);
	ticks_at_event += lll_event_offset_get(ull);

	ticks_at_start = ticks_at_event;
	ticks_at_start += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);

	remainder = p->remainder;
	remainder_us = radio_tmr_start(0, ticks_at_start, remainder);

	radio_tmr_aa_capture();

	hcto = remainder_us +
	       ((EVENT_JITTER_US + EVENT_TICKER_RES_MARGIN_US + lll->window_widening_event_us)
		<< 1) +
	       lll->window_size_event_us;
	hcto += radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8);
	hcto += addr_us_get(lll->phy);
	hcto += radio_rx_chain_delay_get(lll->phy, PHY_FLAGS_S8);
	radio_tmr_hcto_configure(hcto);

	radio_tmr_end_capture();

#if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
	radio_gpio_lna_setup();

	radio_gpio_pa_lna_enable(remainder_us +
				 radio_rx_ready_delay_get(lll->phy,
							  PHY_FLAGS_S8) -
				 HAL_RADIO_GPIO_LNA_OFFSET);
#endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */

#if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
	(EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
	/* check if preempt to start has changed */
	if (lll_preempt_calc(ull, (TICKER_ID_SCAN_SYNC_BASE +
				   ull_sync_lll_handle_get(lll)),
			     ticks_at_event)) {
		radio_isr_set(isr_done, lll);
		radio_disable();

		return -ECANCELED;
	} else
#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
	{
		uint32_t ret;

		ret = lll_prepare_done(lll);
		LL_ASSERT(!ret);
	}

	DEBUG_RADIO_START_O(1);

	return 0;
}

static int is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb)
{
	/* Sync context shall not resume when being preempted, i.e. they
	 * shall not use -EAGAIN as return value.
	 */
	ARG_UNUSED(resume_cb);

	/* Different radio event overlap */
	if (next != curr) {
		struct lll_scan *lll;

		lll = ull_scan_lll_is_valid_get(next);
		if (!lll) {
			/* Abort current event as next event is not a scan
			 * event.
			 */
			return -ECANCELED;
		}
	}

	/* Do not abort if current periodic sync event overlaps next interval
	 * or next event is a scan event.
	 */
	return 0;
}

static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
{
	struct lll_sync *lll;
	int err;

	/* NOTE: This is not a prepare being cancelled */
	if (!prepare_param) {
		/* Perform event abort here.
		 * After event has been cleanly aborted, clean up resources
		 * and dispatch event done.
		 */
		radio_isr_set(isr_done, param);
		radio_disable();

		return;
	}

	/* NOTE: Else clean the top half preparations of the aborted event
	 * currently in preparation pipeline.
	 */
	err = lll_hfclock_off();
	LL_ASSERT(err >= 0);

	/* Accumulate the latency as event is aborted while being in pipeline */
	lll = prepare_param->param;
	lll->skip_prepare += (prepare_param->lazy + 1);

	lll_done(param);
}

static void isr_aux_setup(void *param)
{
	struct pdu_adv_aux_ptr *aux_ptr;
	struct node_rx_pdu *node_rx;
	uint32_t window_widening_us;
	uint32_t window_size_us;
	struct node_rx_ftr *ftr;
	uint32_t aux_offset_us;
	uint32_t aux_start_us;
	struct lll_sync *lll;
	uint8_t phy_aux;
	uint32_t hcto;

	lll_isr_status_reset();

	node_rx = param;
	ftr = &node_rx->hdr.rx_ftr;
	aux_ptr = ftr->aux_ptr;
	phy_aux = BIT(aux_ptr->phy);
	ftr->aux_phy = phy_aux;

	lll = ftr->param;

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

	/* Calculate the aux offset from start of the scan window */
	aux_offset_us = (uint32_t) aux_ptr->offs * window_size_us;

	/* Calculate the window widening that needs to be deducted */
	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);
	}

	/* Setup radio for auxiliary PDU scan */
	radio_phy_set(phy_aux, PHY_FLAGS_S8);
	radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, LL_EXT_OCTETS_RX_MAX,
			    RADIO_PKT_CONF_PHY(phy_aux));

	lll_chan_set(aux_ptr->chan_idx);

	radio_pkt_rx_set(node_rx->pdu);

	radio_isr_set(isr_rx_aux_chain, lll);

#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
	struct lll_df_sync_cfg *cfg;

	cfg = lll_df_sync_cfg_latest_get(&lll->df_cfg, NULL);

	if (cfg->is_enabled && is_max_cte_reached(cfg->max_cte_count, cfg->cte_count)) {
		lll_df_conf_cte_rx_enable(cfg->slot_durations, cfg->ant_sw_len, cfg->ant_ids,
					  aux_ptr->chan_idx, CTE_INFO_IN_PAYLOAD, aux_ptr->phy);
	}
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
	radio_switch_complete_and_disable();

	/* Setup radio rx on micro second offset. Note that radio_end_us stores
	 * PDU start time in this case.
	 */
	aux_start_us = ftr->radio_end_us + aux_offset_us;
	aux_start_us -= lll_radio_rx_ready_delay_get(phy_aux, PHY_FLAGS_S8);
	aux_start_us -= window_widening_us;
	aux_start_us -= EVENT_JITTER_US;
	radio_tmr_start_us(0, aux_start_us);

	/* Setup header complete timeout */
	hcto = ftr->radio_end_us + aux_offset_us;
	hcto += window_size_us;
	hcto += window_widening_us;
	hcto += EVENT_JITTER_US;
	hcto += radio_rx_chain_delay_get(phy_aux, PHY_FLAGS_S8);
	hcto += addr_us_get(phy_aux);
	radio_tmr_hcto_configure(hcto);

	/* capture end of Rx-ed PDU, extended scan to schedule auxiliary
	 * channel chaining, create connection or to create periodic sync.
	 */
	radio_tmr_end_capture();

	/* scanner always measures RSSI */
	radio_rssi_measure();

#if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
	radio_gpio_lna_setup();

	radio_gpio_pa_lna_enable(aux_start_us +
				 radio_rx_ready_delay_get(phy_aux,
							  PHY_FLAGS_S8) -
				 HAL_RADIO_GPIO_LNA_OFFSET);
#endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
}

/**
 * @brief Common part of ISR responsible for handling PDU receive.
 *
 * @param lll          Pointer to LLL sync object.
 * @param node_type    Type of a receive node to be set for handling by ULL.
 * @param crc_ok       Informs if received PDU has correct CRC.
 * @param phy_flags_rx Received Coded PHY coding scheme (0 - S1, 1 - S8).
 * @param cte_ready    Informs if received PDU has CTEInfo present and IQ samples were collected.
 * @param rssi_ready   Informs if RSSI for received PDU is ready.
 * @param status       Informs about periodic advertisement synchronization status.
 *
 * @return Zero in case of there is no chained PDU or there is a chained PDUs but spaced long enough
 *         to schedule its reception by ULL.
 * @return -EBUSY in case there is a chained PDU scheduled by LLL due to short spacing.
 */
static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t crc_ok,
		  uint8_t phy_flags_rx, uint8_t cte_ready, uint8_t rssi_ready,
		  enum sync_status status)
{
	bool sched = false;
	int err;

	/* Check CRC and generate Periodic Advertising Report */
	if (crc_ok) {
		struct node_rx_pdu *node_rx;

		/* Verify if there are free RX buffers for:
		 * - reporting just received PDU
		 * - allocating an extra node_rx for periodic report incomplete
		 * - a buffer for receiving data in a connection
		 * - a buffer for receiving empty PDU
		 */
		node_rx = ull_pdu_rx_alloc_peek(4);
		if (node_rx) {
			struct node_rx_ftr *ftr;
			struct pdu_adv *pdu;

			ull_pdu_rx_alloc();

			node_rx->hdr.type = node_type;

			ftr = &(node_rx->hdr.rx_ftr);
			ftr->param = lll;
			ftr->aux_failed = 0U;
			ftr->rssi = (rssi_ready) ? radio_rssi_get() :
						   BT_HCI_LE_RSSI_NOT_AVAILABLE;
			ftr->ticks_anchor = radio_tmr_start_get();
			ftr->radio_end_us = radio_tmr_end_get() -
					    radio_rx_chain_delay_get(lll->phy,
								     phy_flags_rx);
			ftr->phy_flags = phy_flags_rx;
			ftr->sync_status = status;
			ftr->sync_rx_enabled = lll->is_rx_enabled;

			if (node_type != NODE_RX_TYPE_EXT_AUX_REPORT) {
				ftr->extra = ull_pdu_rx_alloc();
			}

			pdu = (void *)node_rx->pdu;

			ftr->aux_lll_sched = lll_scan_aux_setup(pdu, lll->phy,
								phy_flags_rx,
								isr_aux_setup,
								lll);
			if (ftr->aux_lll_sched) {
				if (node_type != NODE_RX_TYPE_EXT_AUX_REPORT) {
					lll->is_aux_sched = 1U;
				}

				err = -EBUSY;
			} else {
				err = 0;
			}

			ull_rx_put(node_rx->hdr.link, node_rx);

			sched = true;
		} else if (node_type == NODE_RX_TYPE_EXT_AUX_REPORT) {
			err = -ENOMEM;
		} else {
			err = 0;
		}

#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
		if (cte_ready) {
			/* Retunred value is not checked because it does not matter if there
			 * is a IQ report to be send towards ULL. There is always periodic sync
			 * report to be send.
			 */
			(void)create_iq_report(lll, rssi_ready, BT_HCI_LE_CTE_CRC_OK);
			sched = true;
		}
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */

	} else {
#if defined(CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC)
		if (cte_ready) {
			err = create_iq_report(lll, rssi_ready,
					       BT_HCI_LE_CTE_CRC_ERR_CTE_BASED_TIME);
			if (!err) {
				sched = true;
			}
		}
#endif /* CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC */

		err = 0;
	}

	if (sched) {
		ull_rx_sched();
	}

	return err;
}

static void isr_rx_adv_sync_estab(void *param)
{
	enum sync_status sync_ok;
	struct lll_sync *lll;
	uint8_t phy_flags_rx;
	uint8_t rssi_ready;
	uint8_t cte_ready;
	uint8_t trx_done;
	uint8_t crc_ok;
	int err;

	lll = param;

	/* Read radio status and events */
	trx_done = radio_is_done();
	if (trx_done) {
		crc_ok = radio_crc_is_valid();
		rssi_ready = radio_rssi_is_ready();
		phy_flags_rx = radio_phy_flags_rx_get();
		sync_ok = sync_filtrate_by_cte_type(lll->cte_type, lll->filter_policy);
		trx_cnt = 1U;

		if (IS_ENABLED(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)) {
			cte_ready = radio_df_cte_ready();
		} else {
			cte_ready = 0U;
		}
	} else {
		crc_ok = phy_flags_rx = rssi_ready = cte_ready = 0U;
		/* Initiated as allowed, crc_ok takes precended during handling of PDU
		 * reception in the situation.
		 */
		sync_ok = SYNC_STAT_ALLOWED;
	}

	/* Clear radio rx status and events */
	lll_isr_rx_status_reset();

	/* No Rx */
	if (!trx_done) {
		/* TODO: Combine the early exit with above if-then-else block
		 */
		goto isr_rx_done;
	}

	/* Save radio ready and address capture timestamp for later use for
	 * drift compensation.
	 */
	radio_tmr_aa_save(radio_tmr_aa_get());
	radio_tmr_ready_save(radio_tmr_ready_get());

	/* Handle regular PDU reception if CTE type is acceptable */
	if (sync_ok == SYNC_STAT_ALLOWED) {
		err = isr_rx(lll, NODE_RX_TYPE_SYNC, crc_ok, phy_flags_rx,
			     cte_ready, rssi_ready, SYNC_STAT_ALLOWED);
		if (err == -EBUSY) {
			return;
		}
	} else if (sync_ok == SYNC_STAT_TERM) {
		struct node_rx_pdu *node_rx;

		/* Verify if there are free RX buffers for:
		 * - reporting just received PDU
		 * - a buffer for receiving data in a connection
		 * - a buffer for receiving empty PDU
		 */
		node_rx = ull_pdu_rx_alloc_peek(3);
		if (node_rx) {
			struct node_rx_ftr *ftr;

			ull_pdu_rx_alloc();

			node_rx->hdr.type = NODE_RX_TYPE_SYNC;

			ftr = &node_rx->hdr.rx_ftr;
			ftr->param = lll;
			ftr->sync_status = SYNC_STAT_TERM;

			ull_rx_put(node_rx->hdr.link, node_rx);
			ull_rx_sched();
		}
	}

isr_rx_done:
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) && \
	defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
	isr_rx_done_cleanup(lll, crc_ok, sync_ok != SYNC_STAT_ALLOWED);
#else
	isr_rx_done_cleanup(lll, crc_ok, false);
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING && CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
}

static void isr_rx_adv_sync(void *param)
{
	struct lll_sync *lll;
	uint8_t phy_flags_rx;
	uint8_t rssi_ready;
	uint8_t cte_ready;
	uint8_t trx_done;
	uint8_t crc_ok;
	int err;

	lll = param;

	/* Read radio status and events */
	trx_done = radio_is_done();
	if (trx_done) {
		crc_ok = radio_crc_is_valid();
		rssi_ready = radio_rssi_is_ready();
		phy_flags_rx = radio_phy_flags_rx_get();
		trx_cnt = 1U;

		if (IS_ENABLED(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)) {
			cte_ready = radio_df_cte_ready();
		} else {
			cte_ready = 0U;
		}
	} else {
		crc_ok = phy_flags_rx = rssi_ready = cte_ready = 0U;
	}

	/* Clear radio rx status and events */
	lll_isr_rx_status_reset();

	/* No Rx */
	if (!trx_done) {
		/* TODO: Combine the early exit with above if-then-else block
		 */
		goto isr_rx_done;
	}

	/* Save radio ready and address capture timestamp for later use for
	 * drift compensation.
	 */
	radio_tmr_aa_save(radio_tmr_aa_get());
	radio_tmr_ready_save(radio_tmr_ready_get());

	/* When periodic advertisement is synchronized, the CTEType may change. It should not
	 * affect synchronization even when new CTE type is not allowed by sync parameters.
	 * Hence the SYNC_STAT_READY is set.
	 */
	err = isr_rx(lll, NODE_RX_TYPE_SYNC_REPORT, crc_ok, phy_flags_rx, cte_ready, rssi_ready,
		     SYNC_STAT_READY);
	if (err == -EBUSY) {
		return;
	}

isr_rx_done:
	isr_rx_done_cleanup(lll, crc_ok, false);
}

static void isr_rx_aux_chain(void *param)
{
	struct lll_scan_aux *lll_aux;
	struct lll_sync *lll;
	uint8_t phy_flags_rx;
	uint8_t rssi_ready;
	uint8_t cte_ready;
	uint8_t trx_done;
	uint8_t crc_ok;
	int err;

	lll = param;
	lll_aux = lll->lll_aux;
	if (!lll_aux) {
		/* auxiliary context not assigned (yet) in ULL execution
		 * context, drop current reception and abort further chain PDU
		 * receptions, if any.
		 */
		lll_isr_status_reset();

		crc_ok =  0U;
		err = 0;

		goto isr_rx_aux_chain_done;
	}

	/* Read radio status and events */
	trx_done = radio_is_done();
	if (trx_done) {
		crc_ok = radio_crc_is_valid();
		phy_flags_rx = radio_phy_flags_rx_get();
		rssi_ready = radio_rssi_is_ready();

		if (IS_ENABLED(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)) {
			cte_ready = radio_df_cte_ready();
		} else {
			cte_ready = 0U;
		}
	} else {
		crc_ok = phy_flags_rx = rssi_ready = cte_ready = 0U;
	}

	/* Clear radio rx status and events */
	lll_isr_rx_status_reset();

	/* No Rx */
	if (!trx_done) {
		/* TODO: Combine the early exit with above if-then-else block
		 */

		err = 0;

		goto isr_rx_aux_chain_done;
	}

	/* When periodic advertisement is synchronized, the CTEType may change. It should not
	 * affect synchronization even when new CTE type is not allowed by sync parameters.
	 * Hence the SYNC_STAT_READY is set.
	 */
	err = isr_rx(lll, NODE_RX_TYPE_EXT_AUX_REPORT, crc_ok, phy_flags_rx, cte_ready, rssi_ready,
		     SYNC_STAT_READY);

	if (err == -EBUSY) {
		return;
	}

isr_rx_aux_chain_done:
	if (!crc_ok || err) {
		struct node_rx_pdu *node_rx;

		/* Generate message to release aux context and flag the report
		 * generated thereafter by HCI as incomplete.
		 */
		node_rx = ull_pdu_rx_alloc();
		LL_ASSERT(node_rx);

		node_rx->hdr.type = NODE_RX_TYPE_EXT_AUX_RELEASE;

		node_rx->hdr.rx_ftr.param = lll;
		node_rx->hdr.rx_ftr.aux_failed = 1U;

		ull_rx_put(node_rx->hdr.link, node_rx);
		ull_rx_sched();
	}

	if (lll->is_aux_sched) {
		lll->is_aux_sched = 0U;

		isr_rx_done_cleanup(lll, 1U, false);
	} else {
		lll_isr_cleanup(lll_aux);
	}
}

static void isr_rx_done_cleanup(struct lll_sync *lll, uint8_t crc_ok, bool sync_term)
{
	struct event_done_extra *e;

	/* Calculate and place the drift information in done event */
	e = ull_event_done_extra_get();
	LL_ASSERT(e);

	e->type = EVENT_DONE_EXTRA_TYPE_SYNC;
	e->trx_cnt = trx_cnt;
	e->crc_valid = crc_ok;
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) && \
	defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
	e->sync_term = sync_term;
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING && CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
	if (trx_cnt) {
		e->drift.preamble_to_addr_us = addr_us_get(lll->phy);
		e->drift.start_to_address_actual_us =
			radio_tmr_aa_restore() - radio_tmr_ready_restore();
		e->drift.window_widening_event_us = lll->window_widening_event_us;

		/* Reset window widening, as anchor point sync-ed */
		lll->window_widening_event_us = 0U;
		lll->window_size_event_us = 0U;
	}

	lll_isr_cleanup(lll);
}

static void isr_done(void *param)
{
	struct lll_sync *lll;

	lll_isr_status_reset();

	/* Generate incomplete data status and release aux context when
	 * sync event is using LLL scheduling.
	 */
	lll = param;

	/* LLL scheduling used for chain PDU reception is aborted/preempted */
	if (lll->is_aux_sched) {
		struct node_rx_pdu *node_rx;

		lll->is_aux_sched = 0U;

		/* Generate message to release aux context and flag the report
		 * generated thereafter by HCI as incomplete.
		 */
		node_rx = ull_pdu_rx_alloc();
		LL_ASSERT(node_rx);

		node_rx->hdr.type = NODE_RX_TYPE_EXT_AUX_RELEASE;

		node_rx->hdr.rx_ftr.param = lll;
		node_rx->hdr.rx_ftr.aux_failed = 1U;

		ull_rx_put(node_rx->hdr.link, node_rx);
		ull_rx_sched();
	}

	isr_rx_done_cleanup(param, ((trx_cnt) ? 1U : 0U), false);
}

#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
static inline int create_iq_report(struct lll_sync *lll, uint8_t rssi_ready,
				   uint8_t packet_status)
{
	struct node_rx_iq_report *iq_report;
	struct lll_df_sync_cfg *cfg;
	struct node_rx_ftr *ftr;
	uint8_t cte_info;
	uint8_t ant;

	cfg = lll_df_sync_cfg_curr_get(&lll->df_cfg);

	if (cfg->is_enabled) {
		if (is_max_cte_reached(cfg->max_cte_count, cfg->cte_count)) {
			cte_info = radio_df_cte_status_get();
			ant = radio_df_pdu_antenna_switch_pattern_get();
			iq_report = ull_df_iq_report_alloc();
			LL_ASSERT(iq_report);

			iq_report->hdr.type = NODE_RX_TYPE_SYNC_IQ_SAMPLE_REPORT;
			iq_report->sample_count = radio_df_iq_samples_amount_get();
			iq_report->packet_status = packet_status;
			iq_report->rssi_ant_id = ant;
			iq_report->cte_info = *(struct pdu_cte_info *)&cte_info;
			iq_report->local_slot_durations = cfg->slot_durations;
			/* Event counter is updated to next value during event preparation, hence
			 * it has to be subtracted to store actual event counter value.
			 */
			iq_report->event_counter = lll->event_counter - 1;

			ftr = &iq_report->hdr.rx_ftr;
			ftr->param = lll;
			ftr->rssi =
				((rssi_ready) ? radio_rssi_get() : BT_HCI_LE_RSSI_NOT_AVAILABLE);

			cfg->cte_count += 1U;

			ull_rx_put(iq_report->hdr.link, iq_report);

			return 0;
		}
	}

	return -ENODATA;
}

static bool is_max_cte_reached(uint8_t max_cte_count, uint8_t cte_count)
{
	return max_cte_count == BT_HCI_LE_SAMPLE_CTE_ALL || cte_count < max_cte_count;
}
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */

static uint8_t data_channel_calc(struct lll_sync *lll)
{
	uint8_t data_chan_count;
	uint8_t *data_chan_map;

	/* Process channel map update, if any */
	if (lll->chm_first != lll->chm_last) {
		uint16_t instant_latency;

		instant_latency = (lll->event_counter + lll->skip_event - lll->chm_instant) &
				  EVENT_INSTANT_MAX;
		if (instant_latency <= EVENT_INSTANT_LATENCY_MAX) {
			/* At or past the instant, use channelMapNew */
			lll->chm_first = lll->chm_last;
		}
	}

	/* Calculate the radio channel to use */
	data_chan_map = lll->chm[lll->chm_first].data_chan_map;
	data_chan_count = lll->chm[lll->chm_first].data_chan_count;
	return lll_chan_sel_2(lll->event_counter + lll->skip_event, lll->data_chan_id,
			      data_chan_map, data_chan_count);
}

static enum sync_status sync_filtrate_by_cte_type(uint8_t cte_type_mask, uint8_t filter_policy)
{
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) && \
	defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
	uint8_t rx_cte_time;
	uint8_t rx_cte_type;

	rx_cte_time = nrf_radio_cte_time_get(NRF_RADIO);
	rx_cte_type = nrf_radio_cte_type_get(NRF_RADIO);

	return lll_sync_cte_is_allowed(cte_type_mask, filter_policy, rx_cte_time, rx_cte_type);

#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING && CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
	return SYNC_STAT_ALLOWED;
}
