/* ieee802154_kw41z.c - NXP KW41Z driver */

/*
 * Copyright (c) 2017 Linaro Limited
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT nxp_kw41z_ieee802154

#define LOG_MODULE_NAME ieee802154_kw41z
#define LOG_LEVEL CONFIG_IEEE802154_DRIVER_LOG_LEVEL

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/irq.h>
#include <zephyr/net/ieee802154_radio.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/random/rand32.h>

#include "fsl_xcvr.h"

#if defined(CONFIG_NET_L2_OPENTHREAD)
#include <zephyr/net/openthread.h>
#endif


/*
 * For non-invasive tracing of IRQ events. Sometimes the print logs
 * will shift the timings around so this trace buffer can be used to
 * post inspect conditions to see what sequence of events occurred.
 */

#define KW41_DBG_TRACE_WTRM	0
#define KW41_DBG_TRACE_RX	1
#define KW41_DBG_TRACE_TX	2
#define KW41_DBG_TRACE_CCA	3
#define KW41_DBG_TRACE_TMR3	0xFF

#if defined(CONFIG_KW41_DBG_TRACE)

#define KW41_DBG_TRACE_SIZE 30

struct kw41_dbg_trace {
	uint8_t	type;
	uint32_t	time;
	uint32_t	irqsts;
	uint32_t	phy_ctrl;
	uint32_t	seq_state;
};

struct kw41_dbg_trace kw41_dbg[KW41_DBG_TRACE_SIZE];
int kw41_dbg_idx;

#define KW_DBG_TRACE(_type, _irqsts, _phy_ctrl, _seq_state) \
	do { \
		kw41_dbg[kw41_dbg_idx].type = (_type); \
		kw41_dbg[kw41_dbg_idx].time = \
			ZLL->EVENT_TMR >> ZLL_EVENT_TMR_EVENT_TMR_SHIFT; \
		kw41_dbg[kw41_dbg_idx].irqsts = (_irqsts); \
		kw41_dbg[kw41_dbg_idx].phy_ctrl = (_phy_ctrl); \
		kw41_dbg[kw41_dbg_idx].seq_state = (_seq_state); \
		if (++kw41_dbg_idx == KW41_DBG_TRACE_SIZE) { \
			kw41_dbg_idx = 0; \
		} \
	} while (false)

#else

#define KW_DBG_TRACE(_type, _irqsts, _phy_ctrl, _seq_state)

#endif

#define KW41Z_DEFAULT_CHANNEL		26
#define KW41Z_CCA_TIME			8
#define KW41Z_SHR_PHY_TIME		12
#define KW41Z_PER_BYTE_TIME		2
#define KW41Z_ACK_WAIT_TIME		54
#define KW41Z_PRE_RX_WAIT_TIME		1
#define KW40Z_POST_SEQ_WAIT_TIME	1

#define RADIO_0_IRQ_PRIO		0x0
#define KW41Z_FCS_LENGTH		2
#define KW41Z_PSDU_LENGTH		125
#define KW41Z_OUTPUT_POWER_MAX		4
#define KW41Z_OUTPUT_POWER_MIN		(-31)

#define IEEE802154_ACK_LENGTH		5

#define BM_ZLL_IRQSTS_TMRxMSK (ZLL_IRQSTS_TMR1MSK_MASK | \
				ZLL_IRQSTS_TMR2MSK_MASK | \
				ZLL_IRQSTS_TMR3MSK_MASK | \
				ZLL_IRQSTS_TMR4MSK_MASK)

/*
 * Clear channel assessment types. Note that there is an extra one when
 * bit 26 is included for "No CCA before transmit" if we are handling
 * ACK frames but we will let the hardware handle that automatically.
 */
enum {
	KW41Z_CCA_ED,       /* Energy detect */
	KW41Z_CCA_MODE1,    /* Energy above threshold   */
	KW41Z_CCA_MODE2,    /* Carrier sense only       */
	KW41Z_CCA_MODE3     /* Mode 1 + Mode 2          */
};

/*
 * KW41Z has a sequencer that can run in any of the following states.
 */
enum {
	KW41Z_STATE_IDLE,
	KW41Z_STATE_RX,
	KW41Z_STATE_TX,
	KW41Z_STATE_CCA,
	KW41Z_STATE_TXRX,
	KW41Z_STATE_CCCA
};

/* Lookup table for PA_PWR register */
static const uint8_t pa_pwr_lt[] = {
	1,                   /* -31.1 dBm: -31 */
	2, 2, 2, 2, 2, 2, 2, /* -25.0 dBm: -30, -29, -28, -27, -26, -25 */
	4, 4, 4, 4, 4,       /* -19.0 dBm: -24, -23, -22, -21, -20, -19 */
	6, 6, 6,             /* -15.6 dBm: -18, -17, -16 */
	8, 8,                /* -13.1 dBm: -15, -14 */
	10, 10,              /* -11.2 dBm: -13, -12 */
	12, 12,              /* - 9.6 dBm: -11, -10 */
	14,                  /* - 8.3 dBm: -9 */
	16,                  /* - 7.2 dBm: -8 */
	18,                  /* - 6.2 dBm: -7 */
	20,                  /* - 5.3 dBm: -6 */
	22,                  /* - 4.5 dBm: -5 */
	24,                  /* - 3.8 dBm: -4 */
	28,                  /* - 2.5 dBm: -3 */
	30,                  /* - 1.9 dBm: -2 */
	34,                  /* - 1.0 dBm: -1 */
	40,                  /* + 0.3 dBm:  0 */
	44,                  /* + 1.1 dBm: +1 */
	50,                  /* + 2.1 dBm: +2 */
	58,                  /* + 3.1 dBm: +3 */
	62                   /* + 3.5 dBm: +4 */
};

struct kw41z_context {
	struct net_if *iface;
	uint8_t mac_addr[8];

	struct k_sem seq_sync;
	atomic_t seq_retval;

	uint32_t rx_warmup_time;
	uint32_t tx_warmup_time;

	bool frame_pending; /* FP bit state from the most recent ACK frame. */
};

static struct kw41z_context kw41z_context_data;

static inline uint8_t kw41z_get_instant_state(void)
{
	return (ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK) >>
	       ZLL_SEQ_STATE_SEQ_STATE_SHIFT;
}

static inline uint8_t kw41z_get_seq_state(void)
{
	return (ZLL->PHY_CTRL & ZLL_PHY_CTRL_XCVSEQ_MASK) >>
	       ZLL_PHY_CTRL_XCVSEQ_SHIFT;
}

static inline void kw41z_set_seq_state(uint8_t state)
{
#if CONFIG_SOC_MKW40Z4
	/*
	 * KW40Z seems to require a small delay when switching to IDLE state
	 * after a programmed sequence is complete.
	 */
	if (state == KW41Z_STATE_IDLE) {
		k_busy_wait(KW40Z_POST_SEQ_WAIT_TIME);
	}
#endif

	ZLL->PHY_CTRL = (ZLL->PHY_CTRL & ~ZLL_PHY_CTRL_XCVSEQ_MASK) |
			ZLL_PHY_CTRL_XCVSEQ(state);
}

static inline void kw41z_wait_for_idle(void)
{
	uint8_t state = kw41z_get_instant_state();

	while (state != KW41Z_STATE_IDLE) {
		state = kw41z_get_instant_state();
	}

	if (state != KW41Z_STATE_IDLE) {
		LOG_ERR("Error waiting for idle state");
	}
}

static void kw41z_phy_abort(void)
{
	unsigned int key;

	key = irq_lock();

	/* Mask SEQ interrupt */
	ZLL->PHY_CTRL |= ZLL_PHY_CTRL_SEQMSK_MASK;
	/* Disable timer trigger (for scheduled XCVSEQ) */
	if (ZLL->PHY_CTRL & ZLL_PHY_CTRL_TMRTRIGEN_MASK) {
		ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TMRTRIGEN_MASK;
		/* give the FSM enough time to start if it was triggered */
		while ((XCVR_MISC->XCVR_CTRL &
			XCVR_CTRL_XCVR_STATUS_TSM_COUNT_MASK) == 0) {
		}
	}

	/* If XCVR is not idle, abort current SEQ */
	if (ZLL->PHY_CTRL & ZLL_PHY_CTRL_XCVSEQ_MASK) {
		ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_XCVSEQ_MASK;
		/* wait for Sequence Idle (if not already) */

		while (ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK) {
		}
	}

	/* Stop timers */
	ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_TMR1CMP_EN_MASK |
			ZLL_PHY_CTRL_TMR2CMP_EN_MASK |
			ZLL_PHY_CTRL_TMR3CMP_EN_MASK |
			ZLL_PHY_CTRL_TC3TMOUT_MASK);

	/*
	 * Clear all IRQ bits to avoid unexpected interrupts.
	 *
	 * For Coverity, this is a pointer to a register bank and the IRQSTS
	 * register bits get cleared when a 1 is written to them so doing a
	 * reg=reg may generate a warning but it is needed to clear the bits.
	 */
	ZLL->IRQSTS = ZLL->IRQSTS;

	irq_unlock(key);
}

static void kw41z_isr_timeout_cleanup(void)
{
	uint32_t irqsts;

	/*
	 * Set the PHY sequencer back to IDLE and disable TMR3 comparator
	 * and timeout
	 */
	ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_TMR3CMP_EN_MASK |
			ZLL_PHY_CTRL_TC3TMOUT_MASK   |
			ZLL_PHY_CTRL_XCVSEQ_MASK);

	/* Mask SEQ, RX, TX and CCA interrupts */
	ZLL->PHY_CTRL |= ZLL_PHY_CTRL_CCAMSK_MASK |
			ZLL_PHY_CTRL_RXMSK_MASK  |
			ZLL_PHY_CTRL_TXMSK_MASK  |
			ZLL_PHY_CTRL_SEQMSK_MASK;

	while (ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK) {
	}

	irqsts = ZLL->IRQSTS;
	/* Mask TMR3 interrupt */
	irqsts |= ZLL_IRQSTS_TMR3MSK_MASK;

	ZLL->IRQSTS = irqsts;
}

static void kw41z_isr_seq_cleanup(void)
{
	uint32_t irqsts;

	/* Set the PHY sequencer back to IDLE */
	ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_XCVSEQ_MASK;
	/* Mask SEQ, RX, TX and CCA interrupts */
	ZLL->PHY_CTRL |= ZLL_PHY_CTRL_CCAMSK_MASK |
			ZLL_PHY_CTRL_RXMSK_MASK  |
			ZLL_PHY_CTRL_TXMSK_MASK  |
			ZLL_PHY_CTRL_SEQMSK_MASK;

	while (ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK) {
	}

	irqsts = ZLL->IRQSTS;
	/* Mask TMR3 interrupt */
	irqsts |= ZLL_IRQSTS_TMR3MSK_MASK;

	/* Clear transceiver interrupts except TMRxIRQ */
	irqsts &= ~(ZLL_IRQSTS_TMR1IRQ_MASK |
		ZLL_IRQSTS_TMR2IRQ_MASK |
		ZLL_IRQSTS_TMR3IRQ_MASK |
		ZLL_IRQSTS_TMR4IRQ_MASK);
	ZLL->IRQSTS = irqsts;
}

static inline void kw41z_enable_seq_irq(void)
{
	ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_SEQMSK_MASK;
}

static inline void kw41z_disable_seq_irq(void)
{
	ZLL->PHY_CTRL |= ZLL_PHY_CTRL_SEQMSK_MASK;
}

/*
 * Set the T3CMP timer comparator. The 'timeout' value is an offset from
 * now.
 */
static void kw41z_tmr3_set_timeout(uint32_t timeout)
{
	uint32_t irqsts;

	/* Add in the current time so that we can get the comparator to
	 * match appropriately to our offset time.
	 */
	timeout += ZLL->EVENT_TMR >> ZLL_EVENT_TMR_EVENT_TMR_SHIFT;

	/* disable TMR3 compare */
	ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TMR3CMP_EN_MASK;
	ZLL->T3CMP = timeout & ZLL_T3CMP_T3CMP_MASK;

	/* acknowledge TMR3 IRQ */
	irqsts  = ZLL->IRQSTS & BM_ZLL_IRQSTS_TMRxMSK;
	irqsts |= ZLL_IRQSTS_TMR3IRQ_MASK;
	ZLL->IRQSTS = irqsts;
	/* enable TMR3 compare and autosequence stop by TC3 match */
	ZLL->PHY_CTRL |=
		(ZLL_PHY_CTRL_TMR3CMP_EN_MASK | ZLL_PHY_CTRL_TC3TMOUT_MASK);
}

static void kw41z_tmr3_disable(void)
{
	uint32_t irqsts;

	/*
	 * disable TMR3 compare and disable autosequence stop by TC3
	 * match
	 */
	ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_TMR3CMP_EN_MASK |
			ZLL_PHY_CTRL_TC3TMOUT_MASK);
	/* mask TMR3 interrupt (do not change other IRQ status) */
	irqsts  = ZLL->IRQSTS & BM_ZLL_IRQSTS_TMRxMSK;
	irqsts |= ZLL_IRQSTS_TMR3MSK_MASK;
	/* acknowledge TMR3 IRQ */
	irqsts |= ZLL_IRQSTS_TMR3IRQ_MASK;

	ZLL->IRQSTS = irqsts;
}

static enum ieee802154_hw_caps kw41z_get_capabilities(const struct device *dev)
{
	return IEEE802154_HW_FCS |
		IEEE802154_HW_2_4_GHZ |
		IEEE802154_HW_FILTER |
		IEEE802154_HW_TX_RX_ACK;
}

static int kw41z_cca(const struct device *dev)
{
	struct kw41z_context *kw41z = dev->data;

	kw41z_phy_abort();

	k_sem_init(&kw41z->seq_sync, 0, 1);

	kw41z_enable_seq_irq();
	ZLL->PHY_CTRL = (ZLL->PHY_CTRL & ~ZLL_PHY_CTRL_CCATYPE_MASK) |
			ZLL_PHY_CTRL_CCATYPE(KW41Z_CCA_MODE1);

	kw41z_set_seq_state(KW41Z_STATE_CCA);

	k_sem_take(&kw41z->seq_sync, K_FOREVER);

	return kw41z->seq_retval;
}

static int kw41z_set_channel(const struct device *dev, uint16_t channel)
{
	if (channel < 11 || channel > 26) {
		return -EINVAL;
	}

	ZLL->CHANNEL_NUM0 = channel;
	return 0;
}

static int kw41z_set_pan_id(const struct device *dev, uint16_t pan_id)
{
	ZLL->MACSHORTADDRS0 = (ZLL->MACSHORTADDRS0 &
			       ~ZLL_MACSHORTADDRS0_MACPANID0_MASK) |
			      ZLL_MACSHORTADDRS0_MACPANID0(pan_id);
	return 0;
}

static int kw41z_set_short_addr(const struct device *dev, uint16_t short_addr)
{
	ZLL->MACSHORTADDRS0 = (ZLL->MACSHORTADDRS0 &
			       ~ZLL_MACSHORTADDRS0_MACSHORTADDRS0_MASK) |
			      ZLL_MACSHORTADDRS0_MACSHORTADDRS0(short_addr);
	return 0;
}

static int kw41z_set_ieee_addr(const struct device *dev,
			       const uint8_t *ieee_addr)
{
	uint32_t val;

	memcpy(&val, ieee_addr, sizeof(val));
	ZLL->MACLONGADDRS0_LSB = val;

	memcpy(&val, ieee_addr + sizeof(val), sizeof(val));
	ZLL->MACLONGADDRS0_MSB = val;

	return 0;
}

static int kw41z_filter(const struct device *dev,
			bool set,
			enum ieee802154_filter_type type,
			const struct ieee802154_filter *filter)
{
	LOG_DBG("Applying filter %u", type);

	if (!set) {
		return -ENOTSUP;
	}

	if (type == IEEE802154_FILTER_TYPE_IEEE_ADDR) {
		return kw41z_set_ieee_addr(dev, filter->ieee_addr);
	} else if (type == IEEE802154_FILTER_TYPE_SHORT_ADDR) {
		return kw41z_set_short_addr(dev, filter->short_addr);
	} else if (type == IEEE802154_FILTER_TYPE_PAN_ID) {
		return kw41z_set_pan_id(dev, filter->pan_id);
	}

	return -ENOTSUP;
}

static int kw41z_set_txpower(const struct device *dev, int16_t dbm)
{
	if (dbm < KW41Z_OUTPUT_POWER_MIN) {
		LOG_INF("TX-power %d dBm below min of %d dBm, using %d dBm",
			    dbm,
			    KW41Z_OUTPUT_POWER_MIN,
			    KW41Z_OUTPUT_POWER_MIN);
		dbm = KW41Z_OUTPUT_POWER_MIN;
	} else if (dbm > KW41Z_OUTPUT_POWER_MAX) {
		LOG_INF("TX-power %d dBm above max of %d dBm, using %d dBm",
			    dbm,
			    KW41Z_OUTPUT_POWER_MAX,
			    KW41Z_OUTPUT_POWER_MAX);
		dbm = KW41Z_OUTPUT_POWER_MAX;
	}

	ZLL->PA_PWR = pa_pwr_lt[dbm - KW41Z_OUTPUT_POWER_MIN];

	return 0;
}

static int kw41z_start(const struct device *dev)
{
	irq_enable(Radio_1_IRQn);

	kw41z_set_seq_state(KW41Z_STATE_RX);
	kw41z_enable_seq_irq();

	return 0;
}

static int kw41z_stop(const struct device *dev)
{
	irq_disable(Radio_1_IRQn);

	kw41z_disable_seq_irq();
	kw41z_set_seq_state(KW41Z_STATE_IDLE);

	return 0;
}

static uint8_t kw41z_convert_lqi(uint8_t hw_lqi)
{
	if (hw_lqi >= 220U) {
		return 255;
	} else {
		return (hw_lqi * 51U) / 44;
	}
}

static inline void kw41z_rx(struct kw41z_context *kw41z, uint8_t len)
{
	struct net_pkt *pkt = NULL;
	struct net_buf *buf = NULL;
	uint8_t pkt_len, hw_lqi;
	int rslt;

	LOG_DBG("ENTRY: len: %d", len);

#if defined(CONFIG_NET_L2_OPENTHREAD)
	/*
	 * OpenThread stack expects a receive frame to include the FCS
	 */
	pkt_len = len;
#else
	pkt_len = len - KW41Z_FCS_LENGTH;
#endif

	pkt = net_pkt_alloc_with_buffer(kw41z->iface, pkt_len,
					AF_UNSPEC, 0, K_NO_WAIT);
	if (!pkt) {
		LOG_ERR("No buf available");
		goto out;
	}

	buf = pkt->buffer;

#if CONFIG_SOC_MKW41Z4
	/* PKT_BUFFER_RX needs to be accessed aligned to 16 bits */
	for (uint16_t reg_val = 0, i = 0; i < pkt_len; i++) {
		if (i % 2 == 0U) {
			reg_val = ZLL->PKT_BUFFER_RX[i/2U];
			buf->data[i] = reg_val & 0xFF;
		} else {
			buf->data[i] = reg_val >> 8;
		}
	}
#else /* CONFIG_SOC_MKW40Z4 */
	/* PKT_BUFFER needs to be accessed aligned to 32 bits */
	for (uint32_t reg_val = 0, i = 0; i < pkt_len; i++) {
		switch (i % 4) {
		case 0:
			reg_val = ZLL->PKT_BUFFER[i/4U];
			buf->data[i] = reg_val & 0xFF;
			break;
		case 1:
			buf->data[i] = (reg_val >> 8) & 0xFF;
			break;
		case 2:
			buf->data[i] = (reg_val >> 16) & 0xFF;
			break;
		default:
			buf->data[i] = reg_val >> 24;
		}
	}
#endif

	net_buf_add(buf, pkt_len);

	hw_lqi = (ZLL->LQI_AND_RSSI & ZLL_LQI_AND_RSSI_LQI_VALUE_MASK) >>
		 ZLL_LQI_AND_RSSI_LQI_VALUE_SHIFT;
	net_pkt_set_ieee802154_lqi(pkt, kw41z_convert_lqi(hw_lqi));
	/* ToDo: get the rssi as well and use net_pkt_set_ieee802154_rssi() */

	rslt = net_recv_data(kw41z->iface, pkt);
	if (rslt < 0) {
		LOG_ERR("RCV Packet dropped by NET stack: %d", rslt);
		goto out;
	}

	return;
out:
	if (pkt) {
		net_pkt_unref(pkt);
	}
}

#define ACK_FRAME_LEN 3
#define ACK_FRAME_TYPE (2 << 0)
#define ACK_FRAME_PENDING_BIT (1 << 4)

static void handle_ack(struct kw41z_context *kw41z, uint8_t seq_number)
{
	struct net_pkt *ack_pkt;
	uint8_t ack_psdu[ACK_FRAME_LEN];

	ack_pkt = net_pkt_alloc_with_buffer(kw41z->iface, ACK_FRAME_LEN,
					    AF_UNSPEC, 0, K_NO_WAIT);
	if (!ack_pkt) {
		LOG_ERR("No free packet available.");
		return;
	}

	/* Re-create ACK frame. */
	ack_psdu[0] = kw41z_context_data.frame_pending ?
		      ACK_FRAME_TYPE | ACK_FRAME_PENDING_BIT : ACK_FRAME_TYPE;
	ack_psdu[1] = 0;
	ack_psdu[2] = seq_number;

	if (net_pkt_write(ack_pkt, ack_psdu, sizeof(ack_psdu)) < 0) {
		LOG_ERR("Failed to write to a packet.");
		goto out;
	}

	/* Use some fake values for LQI and RSSI. */
	(void)net_pkt_set_ieee802154_lqi(ack_pkt, 80);
	(void)net_pkt_set_ieee802154_rssi(ack_pkt, -40);

	net_pkt_cursor_init(ack_pkt);

	if (ieee802154_radio_handle_ack(kw41z->iface, ack_pkt) != NET_OK) {
		LOG_INF("ACK packet not handled - releasing.");
	}

out:
	net_pkt_unref(ack_pkt);
}

static int kw41z_tx(const struct device *dev, enum ieee802154_tx_mode mode,
		    struct net_pkt *pkt, struct net_buf *frag)
{
	struct kw41z_context *kw41z = dev->data;
	uint8_t payload_len = frag->len;
	uint32_t tx_timeout;
	uint8_t xcvseq;
	unsigned int key;

	if (mode != IEEE802154_TX_MODE_DIRECT) {
		NET_ERR("TX mode %d not supported", mode);
		return -ENOTSUP;
	}

	/*
	 * The transmit requests are preceded by the CCA request. On
	 * completion of the CCA the sequencer should be in the IDLE
	 * state.
	 */
	if (kw41z_get_seq_state() != KW41Z_STATE_IDLE) {
		LOG_WRN("Can't initiate new SEQ state");
		return -EBUSY;
	}

	if (payload_len > KW41Z_PSDU_LENGTH) {
		LOG_ERR("Payload too long");
		return 0;
	}

	key = irq_lock();

	/* Disable the 802.15.4 radio IRQ */
	ZLL->PHY_CTRL |= ZLL_PHY_CTRL_TRCV_MSK_MASK;
	kw41z_disable_seq_irq();

#if CONFIG_SOC_MKW41Z4
	((uint8_t *)ZLL->PKT_BUFFER_TX)[0] = payload_len + KW41Z_FCS_LENGTH;
	memcpy(((uint8_t *)ZLL->PKT_BUFFER_TX) + 1,
		(void *)frag->data, payload_len);
#else /* CONFIG_SOC_MKW40Z4 */
	((uint8_t *)ZLL->PKT_BUFFER)[0] = payload_len + KW41Z_FCS_LENGTH;
	memcpy(((uint8_t *)ZLL->PKT_BUFFER) + 1,
		(void *)frag->data, payload_len);
#endif

	/* Set CCA mode */
	ZLL->PHY_CTRL = (ZLL->PHY_CTRL & ~ZLL_PHY_CTRL_CCATYPE_MASK) |
			ZLL_PHY_CTRL_CCATYPE(KW41Z_CCA_MODE1);

	/* Clear all IRQ flags */
	ZLL->IRQSTS = ZLL->IRQSTS;

	/*
	 * Current Zephyr 802.15.4 stack doesn't support ACK offload
	 */

	/* Perform automatic reception of ACK frame, if required */
	if (ieee802154_is_ar_flag_set(frag)) {
		tx_timeout = kw41z->tx_warmup_time + KW41Z_SHR_PHY_TIME +
				 payload_len * KW41Z_PER_BYTE_TIME + 10 +
				 KW41Z_ACK_WAIT_TIME;

		LOG_DBG("AUTOACK ENABLED: len: %d, timeout: %d, seq: %d",
			payload_len, tx_timeout, frag->data[2]);

		kw41z_tmr3_set_timeout(tx_timeout);
		ZLL->PHY_CTRL |= ZLL_PHY_CTRL_RXACKRQD_MASK;
		xcvseq = KW41Z_STATE_TXRX;
	} else {
		LOG_DBG("AUTOACK DISABLED: len: %d, seq: %d",
			payload_len, frag->data[2]);

		ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_RXACKRQD_MASK;
		xcvseq = KW41Z_STATE_TX;
	}

	kw41z_enable_seq_irq();
	/*
	 * PHY_CTRL is sensitive to multiple writes that can kick off
	 * the sequencer engine causing TX with AR request to send the
	 * TX frame multiple times.
	 *
	 * To minimize, ensure there is only one write to PHY_CTRL with
	 * TXRX sequence enable and the 802.15.4 radio IRQ.
	 */
	ZLL->PHY_CTRL = (ZLL->PHY_CTRL & ~ZLL_PHY_CTRL_TRCV_MSK_MASK) | xcvseq;
	irq_unlock(key);
	k_sem_take(&kw41z->seq_sync, K_FOREVER);

	if ((kw41z->seq_retval == 0) && ieee802154_is_ar_flag_set(frag)) {
		handle_ack(kw41z, frag->data[2]);
	}

	LOG_DBG("seq_retval: %ld", kw41z->seq_retval);
	return kw41z->seq_retval;
}

static void kw41z_isr(int unused)
{
	uint32_t irqsts = ZLL->IRQSTS;
	uint8_t state = kw41z_get_seq_state();
	uint8_t restart_rx = 1U;
	uint32_t rx_len;

	/*
	 * Variable is used in debug output to capture the state of the
	 * sequencer at interrupt.
	 */
	uint32_t seq_state = ZLL->SEQ_STATE;

	LOG_DBG("ENTRY: irqsts: 0x%08X, PHY_CTRL: 0x%08X, "
		"SEQ_STATE: 0x%08X, SEQ_CTRL: 0x%08X, TMR: %d, state: %d",
		irqsts, (unsigned int)ZLL->PHY_CTRL,
		(unsigned int)seq_state,
		(unsigned int)ZLL->SEQ_CTRL_STS,
		(unsigned int)(ZLL->EVENT_TMR >> ZLL_EVENT_TMR_EVENT_TMR_SHIFT),
		state);

	/* Clear interrupts */
	ZLL->IRQSTS = irqsts;

	if (irqsts & ZLL_IRQSTS_FILTERFAIL_IRQ_MASK) {
		LOG_DBG("Incoming RX failed packet filtering rules: "
			"CODE: 0x%08X, irqsts: 0x%08X, PHY_CTRL: 0x%08X, "
			"SEQ_STATE: 0x%08X, state: %d",
			(unsigned int)ZLL->FILTERFAIL_CODE,
			irqsts,
			(unsigned int)ZLL->PHY_CTRL,
			(unsigned int)seq_state, state);

		restart_rx = 0U;

	} else if ((!(ZLL->PHY_CTRL & ZLL_PHY_CTRL_RX_WMRK_MSK_MASK)) &&
	    (irqsts & ZLL_IRQSTS_RXWTRMRKIRQ_MASK)) {
		/*
		 * There is a bug in the KW41Z where in noisy environments
		 * the RX sequence can get lost. The watermark mask IRQ can
		 * start TMR3 to complete the rest of the read or to assert
		 * IRQ if the sequencer gets lost so we can reset things.
		 * Note that a TX from the upper layers will also reset
		 * things so the problem is contained a bit in normal
		 * operation.
		 */
		rx_len = (irqsts & ZLL_IRQSTS_RX_FRAME_LENGTH_MASK)
			>> ZLL_IRQSTS_RX_FRAME_LENGTH_SHIFT;

		KW_DBG_TRACE(KW41_DBG_TRACE_WTRM, irqsts,
			(unsigned int)ZLL->PHY_CTRL, seq_state);

		if (rx_len > IEEE802154_ACK_LENGTH) {

			LOG_DBG("WMRK irq: seq_state: 0x%08x, rx_len: %d",
				seq_state, rx_len);
			/*
			 * Assume the RX includes an auto-ACK so set the
			 * timer to include the RX frame size, crc, IFS,
			 * and ACK length and convert to symbols.
			 *
			 * IFS is 12 symbols
			 *
			 * ACK frame is 11 bytes: 4 preamble, 1 start of
			 * frame, 1 frame length, 2 frame control,
			 * 1 sequence, 2 FCS. Times two to convert to symbols.
			 */
			rx_len = rx_len * 2U + 12 + 22 + 2;
			kw41z_tmr3_set_timeout(rx_len);
		}
		restart_rx = 0U;
	}

	/* Sequence done IRQ */
	if ((state != KW41Z_STATE_IDLE) && (irqsts & ZLL_IRQSTS_SEQIRQ_MASK)) {
		/*
		 * PLL unlock, the autosequence has been aborted due to
		 * PLL unlock
		 */
		if (irqsts & ZLL_IRQSTS_PLL_UNLOCK_IRQ_MASK) {
			LOG_ERR("PLL unlock error");
			kw41z_isr_seq_cleanup();
			restart_rx = 1U;
		}
		/*
		 * TMR3 timeout, the autosequence has been aborted due to
		 * TMR3 timeout
		 */
		else if ((irqsts & ZLL_IRQSTS_TMR3IRQ_MASK) &&
			(!(irqsts & ZLL_IRQSTS_RXIRQ_MASK)) &&
			(state != KW41Z_STATE_TX)) {

			LOG_DBG("a) TMR3 timeout: irqsts: 0x%08X, "
				"seq_state: 0x%08X, PHY_CTRL: 0x%08X, "
				"state: %d",
				irqsts, seq_state,
				(unsigned int)ZLL->PHY_CTRL, state);

			KW_DBG_TRACE(KW41_DBG_TRACE_TMR3, irqsts,
				(unsigned int)ZLL->PHY_CTRL, seq_state);

			kw41z_isr_timeout_cleanup();
			restart_rx = 1U;

			if (state == KW41Z_STATE_TXRX) {
				/* TODO: What is the right error for no ACK? */
				atomic_set(&kw41z_context_data.seq_retval,
					   -EBUSY);
				k_sem_give(&kw41z_context_data.seq_sync);
			}
		} else {
			kw41z_isr_seq_cleanup();

			switch (state) {
			case KW41Z_STATE_RX:
				LOG_DBG("RX seq done: SEQ_STATE: 0x%08X",
					(unsigned int)seq_state);

				KW_DBG_TRACE(KW41_DBG_TRACE_RX, irqsts,
					(unsigned int)ZLL->PHY_CTRL, seq_state);

				kw41z_tmr3_disable();

				rx_len = (ZLL->IRQSTS &
					  ZLL_IRQSTS_RX_FRAME_LENGTH_MASK) >>
					  ZLL_IRQSTS_RX_FRAME_LENGTH_SHIFT;

				if (irqsts & ZLL_IRQSTS_RXIRQ_MASK) {
					if (rx_len != 0U) {
						kw41z_rx(&kw41z_context_data,
							rx_len);
					}
				}
				restart_rx = 1U;
				break;
			case KW41Z_STATE_TXRX:
				LOG_DBG("TXRX seq done");
				kw41z_tmr3_disable();
				/* Store the frame pending bit status. */
				kw41z_context_data.frame_pending =
					irqsts & ZLL_IRQSTS_RX_FRM_PEND_MASK;
			case KW41Z_STATE_TX:
				LOG_DBG("TX seq done");
				KW_DBG_TRACE(KW41_DBG_TRACE_TX, irqsts,
					(unsigned int)ZLL->PHY_CTRL, seq_state);
				if (irqsts & ZLL_IRQSTS_CCA_MASK) {
					atomic_set(
						&kw41z_context_data.seq_retval,
						-EBUSY);
				} else {
					atomic_set(
						&kw41z_context_data.seq_retval,
						0);
				}

				k_sem_give(&kw41z_context_data.seq_sync);
				restart_rx = 1U;

				break;
			case KW41Z_STATE_CCA:
				LOG_DBG("CCA seq done");
				KW_DBG_TRACE(KW41_DBG_TRACE_CCA, irqsts,
					(unsigned int)ZLL->PHY_CTRL, seq_state);
				if (irqsts & ZLL_IRQSTS_CCA_MASK) {
					atomic_set(
						&kw41z_context_data.seq_retval,
						-EBUSY);
					restart_rx = 1U;
				} else {
					atomic_set(
						&kw41z_context_data.seq_retval,
						0);
					restart_rx = 0U;
				}

				k_sem_give(&kw41z_context_data.seq_sync);
				break;
			default:
				LOG_DBG("Unhandled state: %d", state);
				restart_rx = 1U;
				break;
			}
		}
	} else {
		/* Timer 3 Compare Match */
		if ((irqsts & ZLL_IRQSTS_TMR3IRQ_MASK) &&
			(!(irqsts & ZLL_IRQSTS_TMR3MSK_MASK))) {

			LOG_DBG("b) TMR3 timeout: irqsts: 0x%08X, "
				"seq_state: 0x%08X, state: %d",
				irqsts, seq_state, state);

			kw41z_tmr3_disable();
			restart_rx = 0U;
			if (state != KW41Z_STATE_IDLE) {
				kw41z_isr_timeout_cleanup();
				restart_rx = 1U;
				/* If we are not running an automated
				 * sequence then handle event. TMR3 can expire
				 * during Recv/Ack sequence where the transmit
				 * of the ACK is not being interrupted.
				 */
			}
		}
	}

	/* Restart RX */
	if (restart_rx) {
		LOG_DBG("RESET RX");
		kw41z_phy_abort();
		kw41z_set_seq_state(KW41Z_STATE_RX);
		kw41z_enable_seq_irq();
	}
}

static inline uint8_t *get_mac(const struct device *dev)
{
	struct kw41z_context *kw41z = dev->data;

	/*
	 * The KW40Z has two 32-bit registers for the MAC address where
	 * 40 bits of the registers are factory programmed to be unique
	 * and the rest are to be assigned as the "company-specific" value.
	 * 802.15.4 defines a EUI-64 64-bit address with company specific
	 * being 24 or 36 bits with the unique value being 24 or 40 bits.
	 *
	 * TODO: Grab from RSIM->MAC_LSB/MAC_MSB for the unique 40 bits
	 *       and how to allow for a OUI portion?
	 */

	uint32_t *ptr = (uint32_t *)(kw41z->mac_addr);

	UNALIGNED_PUT(sys_rand32_get(), ptr);
	ptr = (uint32_t *)(kw41z->mac_addr + 4);
	UNALIGNED_PUT(sys_rand32_get(), ptr);

	/*
	 * Clear bit 0 to ensure it isn't a multicast address and set
	 * bit 1 to indicate address is locally administered and may
	 * not be globally unique.
	 */
	kw41z->mac_addr[0] = (kw41z->mac_addr[0] & ~0x01) | 0x02;

	return kw41z->mac_addr;
}

static int kw41z_init(const struct device *dev)
{
	struct kw41z_context *kw41z = dev->data;
	xcvrStatus_t xcvrStatus;

	xcvrStatus = XCVR_Init(ZIGBEE_MODE, DR_500KBPS);
	if (xcvrStatus != gXcvrSuccess_c) {
		return -EIO;
	}

	/* Disable all timers, enable AUTOACK, mask all interrupts */
	ZLL->PHY_CTRL = ZLL_PHY_CTRL_CCATYPE(KW41Z_CCA_MODE1)	|
			ZLL_PHY_CTRL_CRC_MSK_MASK		|
			ZLL_PHY_CTRL_PLL_UNLOCK_MSK_MASK	|
			/*ZLL_PHY_CTRL_FILTERFAIL_MSK_MASK	|*/
			ZLL_PHY_CTRL_RX_WMRK_MSK_MASK	|
			ZLL_PHY_CTRL_CCAMSK_MASK		|
			ZLL_PHY_CTRL_RXMSK_MASK			|
			ZLL_PHY_CTRL_TXMSK_MASK			|
			ZLL_PHY_CTRL_CCABFRTX_MASK		|
			ZLL_PHY_CTRL_SEQMSK_MASK;

#if CONFIG_SOC_MKW41Z4
	ZLL->PHY_CTRL |= ZLL_IRQSTS_WAKE_IRQ_MASK;
#endif

	ZLL->PHY_CTRL |= ZLL_PHY_CTRL_AUTOACK_MASK;

	/*
	 * Clear all PP IRQ bits to avoid unexpected interrupts immediately
	 * after init disable all timer interrupts
	 */
	ZLL->IRQSTS = ZLL->IRQSTS;

	/* Clear HW indirect queue */
	ZLL->SAM_TABLE |= ZLL_SAM_TABLE_INVALIDATE_ALL_MASK;

	/* Accept FrameVersion 0 and 1 packets, reject all others */
	ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_PROMISCUOUS_MASK;
	ZLL->RX_FRAME_FILTER &= ~ZLL_RX_FRAME_FILTER_FRM_VER_FILTER_MASK;
	ZLL->RX_FRAME_FILTER = ZLL_RX_FRAME_FILTER_FRM_VER_FILTER(3)	|
			       ZLL_RX_FRAME_FILTER_CMD_FT_MASK		|
			       ZLL_RX_FRAME_FILTER_DATA_FT_MASK		|
			       ZLL_RX_FRAME_FILTER_ACK_FT_MASK		|
			       ZLL_RX_FRAME_FILTER_BEACON_FT_MASK;

	/* Set prescaler to obtain 1 symbol (16us) timebase */
	ZLL->TMR_PRESCALE = 0x05;

	kw41z_tmr3_disable();

	/* Compute warmup times (scaled to 16us) */
	kw41z->rx_warmup_time = (XCVR_TSM->END_OF_SEQ &
				 XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_MASK) >>
				XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_SHIFT;
	kw41z->tx_warmup_time = (XCVR_TSM->END_OF_SEQ &
				 XCVR_TSM_END_OF_SEQ_END_OF_TX_WU_MASK) >>
				XCVR_TSM_END_OF_SEQ_END_OF_TX_WU_SHIFT;

	if (kw41z->rx_warmup_time & 0x0F) {
		kw41z->rx_warmup_time = 1 + (kw41z->rx_warmup_time >> 4);
	} else {
		kw41z->rx_warmup_time = kw41z->rx_warmup_time >> 4;
	}

	if (kw41z->tx_warmup_time & 0x0F) {
		kw41z->tx_warmup_time = 1 + (kw41z->tx_warmup_time >> 4);
	} else {
		kw41z->tx_warmup_time = kw41z->tx_warmup_time >> 4;
	}

	/* Set CCA threshold to -75 dBm */
	ZLL->CCA_LQI_CTRL &= ~ZLL_CCA_LQI_CTRL_CCA1_THRESH_MASK;
	ZLL->CCA_LQI_CTRL |= ZLL_CCA_LQI_CTRL_CCA1_THRESH(0xB5);

	/* Set the default power level */
	kw41z_set_txpower(dev, 0);

	/* Adjust ACK delay to fulfill the 802.15.4 turnaround requirements */
	ZLL->ACKDELAY &= ~ZLL_ACKDELAY_ACKDELAY_MASK;
	ZLL->ACKDELAY |= ZLL_ACKDELAY_ACKDELAY(-8);

	/* Adjust LQI compensation */
	ZLL->CCA_LQI_CTRL &= ~ZLL_CCA_LQI_CTRL_LQI_OFFSET_COMP_MASK;
	ZLL->CCA_LQI_CTRL |= ZLL_CCA_LQI_CTRL_LQI_OFFSET_COMP(96);

	/* Enable the RxWatermark IRQ  */
	ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_RX_WMRK_MSK_MASK);
	/* Set Rx watermark level */
	ZLL->RX_WTR_MARK = 0;


	/* Set default channel to 2405 MHZ */
	kw41z_set_channel(dev, KW41Z_DEFAULT_CHANNEL);

	/* Unmask Transceiver Global Interrupts */
	ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TRCV_MSK_MASK;

	/* Configure Radio IRQ */
	NVIC_ClearPendingIRQ(Radio_1_IRQn);
	IRQ_CONNECT(Radio_1_IRQn, RADIO_0_IRQ_PRIO, kw41z_isr, 0, 0);

	return 0;
}

static void kw41z_iface_init(struct net_if *iface)
{
	const struct device *dev = net_if_get_device(iface);
	struct kw41z_context *kw41z = dev->data;
	uint8_t *mac = get_mac(dev);

#if defined(CONFIG_KW41_DBG_TRACE)
	kw41_dbg_idx = 0;
#endif

	net_if_set_link_addr(iface, mac, 8, NET_LINK_IEEE802154);
	kw41z->iface = iface;
	ieee802154_init(iface);
}

static int kw41z_configure(const struct device *dev,
			   enum ieee802154_config_type type,
			   const struct ieee802154_config *config)
{
	return 0;
}

static struct ieee802154_radio_api kw41z_radio_api = {
	.iface_api.init	= kw41z_iface_init,

	.get_capabilities	= kw41z_get_capabilities,
	.cca			= kw41z_cca,
	.set_channel		= kw41z_set_channel,
	.filter			= kw41z_filter,
	.set_txpower		= kw41z_set_txpower,
	.start			= kw41z_start,
	.stop			= kw41z_stop,
	.tx			= kw41z_tx,
	.configure		= kw41z_configure,
};

#if defined(CONFIG_NET_L2_IEEE802154)

#define L2 IEEE802154_L2
#define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(IEEE802154_L2)
#define MTU KW41Z_PSDU_LENGTH

#elif defined(CONFIG_NET_L2_OPENTHREAD)

#define L2 OPENTHREAD_L2
#define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(OPENTHREAD_L2)
#define MTU 1280

#endif

NET_DEVICE_DT_INST_DEFINE(
	0,
	kw41z_init,                         /* Initialization Function */
	NULL,              /* No PM API support */
	&kw41z_context_data,                /* Context data */
	NULL,                               /* Configuration info */
	CONFIG_IEEE802154_KW41Z_INIT_PRIO,  /* Initial priority */
	&kw41z_radio_api,                   /* API interface functions */
	L2,                                 /* L2 */
	L2_CTX_TYPE,                        /* L2 context type */
	MTU);                               /* MTU size */
