/* ieee802154_cc2520.c - TI CC2520 driver */

#define DT_DRV_COMPAT ti_cc2520

/*
 * Copyright (c) 2016 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define LOG_MODULE_NAME ieee802154_cc2520
#define LOG_LEVEL CONFIG_IEEE802154_DRIVER_LOG_LEVEL

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

#include <errno.h>

#include <zephyr/kernel.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/debug/stack.h>

#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_pkt.h>

#include <zephyr/sys/byteorder.h>
#include <string.h>
#include <zephyr/random/random.h>

#include <zephyr/drivers/gpio.h>

#ifdef CONFIG_IEEE802154_CC2520_CRYPTO

#include <zephyr/crypto/crypto.h>
#include <zephyr/crypto/cipher.h>

#endif /* CONFIG_IEEE802154_CC2520_CRYPTO */

#include <zephyr/net/ieee802154_radio.h>

#include "ieee802154_cc2520.h"

/**
 * Content is split as follows:
 * 1 - Debug related functions
 * 2 - Generic helper functions (for any parts)
 * 3 - GPIO related functions
 * 4 - TX related helper functions
 * 5 - RX related helper functions
 * 6 - Radio device API functions
 * 7 - Legacy radio device API functions
 * 8 - Initialization
 */


#define CC2520_AUTOMATISM		(FRMCTRL0_AUTOCRC | FRMCTRL0_AUTOACK)
#define CC2520_TX_THRESHOLD		(0x7F)
#define CC2520_FCS_LENGTH		(2)

/*********
 * DEBUG *
 ********/
#if LOG_LEVEL == LOG_LEVEL_DBG
static inline void cc2520_print_gpio_config(const struct device *dev)
{
	struct cc2520_context *cc2520 = dev->data;

	LOG_DBG("GPIOCTRL0/1/2/3/4/5 = 0x%x/0x%x/0x%x/0x%x/0x%x/0x%x",
		read_reg_gpioctrl0(cc2520),
		read_reg_gpioctrl1(cc2520),
		read_reg_gpioctrl2(cc2520),
		read_reg_gpioctrl3(cc2520),
		read_reg_gpioctrl4(cc2520),
		read_reg_gpioctrl5(cc2520));
	LOG_DBG("GPIOPOLARITY: 0x%x",
		read_reg_gpiopolarity(cc2520));
	LOG_DBG("GPIOCTRL: 0x%x",
		read_reg_gpioctrl(cc2520));
}

static inline void cc2520_print_exceptions(struct cc2520_context *cc2520)
{
	uint8_t flag = read_reg_excflag0(cc2520);

	LOG_DBG("EXCFLAG0:");

	if (flag & EXCFLAG0_RF_IDLE) {
		LOG_DBG(" RF_IDLE");
	}

	if (flag & EXCFLAG0_TX_FRM_DONE) {
		LOG_DBG(" TX_FRM_DONE");
	}

	if (flag & EXCFLAG0_TX_ACK_DONE) {
		LOG_DBG(" TX_ACK_DONE");
	}

	if (flag & EXCFLAG0_TX_UNDERFLOW) {
		LOG_DBG(" TX_UNDERFLOW");
	}

	if (flag & EXCFLAG0_TX_OVERFLOW) {
		LOG_DBG(" TX_OVERFLOW");
	}

	if (flag & EXCFLAG0_RX_UNDERFLOW) {
		LOG_DBG(" RX_UNDERFLOW");
	}

	if (flag & EXCFLAG0_RX_OVERFLOW) {
		LOG_DBG(" RX_OVERFLOW");
	}

	if (flag & EXCFLAG0_RXENABLE_ZERO) {
		LOG_DBG(" RXENABLE_ZERO");
	}

	flag = read_reg_excflag1(cc2520);

	LOG_DBG("EXCFLAG1:");

	if (flag & EXCFLAG1_RX_FRM_DONE) {
		LOG_DBG(" RX_FRM_DONE");
	}

	if (flag & EXCFLAG1_RX_FRM_ACCEPTED) {
		LOG_DBG(" RX_FRM_ACCEPTED");
	}

	if (flag & EXCFLAG1_SRC_MATCH_DONE) {
		LOG_DBG(" SRC_MATCH_DONE");
	}

	if (flag & EXCFLAG1_SRC_MATCH_FOUND) {
		LOG_DBG(" SRC_MATCH_FOUND");
	}

	if (flag & EXCFLAG1_FIFOP) {
		LOG_DBG(" FIFOP");
	}

	if (flag & EXCFLAG1_SFD) {
		LOG_DBG(" SFD");
	}

	if (flag & EXCFLAG1_DPU_DONE_L) {
		LOG_DBG(" DPU_DONE_L");
	}

	if (flag & EXCFLAG1_DPU_DONE_H) {
		LOG_DBG(" DPU_DONE_H");
	}
}

static inline void cc2520_print_errors(struct cc2520_context *cc2520)
{
	uint8_t flag = read_reg_excflag2(cc2520);

	LOG_DBG("EXCFLAG2:");

	if (flag & EXCFLAG2_MEMADDR_ERROR) {
		LOG_DBG(" MEMADDR_ERROR");
	}

	if (flag & EXCFLAG2_USAGE_ERROR) {
		LOG_DBG(" USAGE_ERROR");
	}

	if (flag & EXCFLAG2_OPERAND_ERROR) {
		LOG_DBG(" OPERAND_ERROR");
	}

	if (flag & EXCFLAG2_SPI_ERROR) {
		LOG_DBG(" SPI_ERROR");
	}

	if (flag & EXCFLAG2_RF_NO_LOCK) {
		LOG_DBG(" RF_NO_LOCK");
	}

	if (flag & EXCFLAG2_RX_FRM_ABORTED) {
		LOG_DBG(" RX_FRM_ABORTED");
	}

	if (flag & EXCFLAG2_RFBUFMOV_TIMEOUT) {
		LOG_DBG(" RFBUFMOV_TIMEOUT");
	}
}
#else
#define cc2520_print_gpio_config(...)
#define cc2520_print_exceptions(...)
#define cc2520_print_errors(...)
#endif /* LOG_LEVEL == LOG_LEVEL_DBG */


/*********************
 * Generic functions *
 ********************/
#define z_usleep(usec) k_busy_wait(usec)

bool z_cc2520_access(const struct device *dev, bool read, uint8_t ins,
		     uint16_t addr, void *data, size_t length)
{
	const struct cc2520_config *cfg = dev->config;
	uint8_t cmd_buf[2];
	struct spi_buf buf[2] = {
		{
			.buf = cmd_buf,
			.len = 1,
		},
		{
			.buf = data,
			.len = length,

		}
	};
	struct spi_buf_set tx = {
		.buffers = buf,
	};


	cmd_buf[0] = ins;

	if (ins == CC2520_INS_MEMRD || ins == CC2520_INS_MEMWR) {
		buf[0].len = 2;
		cmd_buf[0] |= (uint8_t)(addr >> 8);
		cmd_buf[1] = (uint8_t)(addr & 0xff);
	} else if (ins == CC2520_INS_REGRD || ins == CC2520_INS_REGWR) {
		cmd_buf[0] |= (uint8_t)(addr & 0xff);
	}

	if (read) {
		const struct spi_buf_set rx = {
			.buffers = buf,
			.count = 2
		};

		tx.count = 1;

		return (spi_transceive_dt(&cfg->bus, &tx, &rx) == 0);
	}

	tx.count = data ? 2 : 1;

	return (spi_write_dt(&cfg->bus, &tx) == 0);
}

static inline uint8_t cc2520_status(const struct device *dev)
{
	uint8_t status;

	if (z_cc2520_access(dev, true, CC2520_INS_SNOP, 0, &status, 1)) {
		return status;
	}

	return 0;
}

static bool verify_osc_stabilization(const struct device *dev)
{
	uint8_t timeout = 100U;
	uint8_t status;

	do {
		status = cc2520_status(dev);
		z_usleep(1);
		timeout--;
	} while (!(status & CC2520_STATUS_XOSC_STABLE_N_RUNNING) && timeout);

	return !!(status & CC2520_STATUS_XOSC_STABLE_N_RUNNING);
}


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

#if defined(CONFIG_IEEE802154_CC2520_RANDOM_MAC)
	sys_rand_get(&cc2520->mac_addr[4], 4U);

	cc2520->mac_addr[7] = (cc2520->mac_addr[7] & ~0x01) | 0x02;
#else
	cc2520->mac_addr[4] = CONFIG_IEEE802154_CC2520_MAC4;
	cc2520->mac_addr[5] = CONFIG_IEEE802154_CC2520_MAC5;
	cc2520->mac_addr[6] = CONFIG_IEEE802154_CC2520_MAC6;
	cc2520->mac_addr[7] = CONFIG_IEEE802154_CC2520_MAC7;
#endif

	cc2520->mac_addr[0] = 0x00;
	cc2520->mac_addr[1] = 0x12;
	cc2520->mac_addr[2] = 0x4b;
	cc2520->mac_addr[3] = 0x00;

	return cc2520->mac_addr;
}

static int cc2520_set_pan_id(const struct device *dev, uint16_t pan_id)
{
	LOG_DBG("0x%x", pan_id);

	pan_id = sys_le16_to_cpu(pan_id);

	if (!write_mem_pan_id(dev, (uint8_t *) &pan_id)) {
		LOG_ERR("Failed");
		return -EIO;
	}

	return 0;
}

static int cc2520_set_short_addr(const struct device *dev,
				 uint16_t short_addr)
{
	LOG_DBG("0x%x", short_addr);

	short_addr = sys_le16_to_cpu(short_addr);

	if (!write_mem_short_addr(dev, (uint8_t *) &short_addr)) {
		LOG_ERR("Failed");
		return -EIO;
	}

	return 0;
}

static int cc2520_set_ieee_addr(const struct device *dev,
				const uint8_t *ieee_addr)
{
	if (!write_mem_ext_addr(dev, (void *)ieee_addr)) {
		LOG_ERR("Failed");
		return -EIO;
	}

	LOG_DBG("IEEE address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
		ieee_addr[7], ieee_addr[6], ieee_addr[5], ieee_addr[4],
		ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]);

	return 0;
}

/******************
 * GPIO functions *
 *****************/
static inline void set_reset(const struct device *dev, uint32_t value)
{
	const struct cc2520_config *cfg = dev->config;

	gpio_pin_set_raw(cfg->reset.port, cfg->reset.pin, value);
}

static inline void set_vreg_en(const struct device *dev, uint32_t value)
{
	const struct cc2520_config *cfg = dev->config;

	gpio_pin_set_raw(cfg->vreg_en.port, cfg->vreg_en.pin, value);
}

static inline uint32_t get_fifo(const struct device *dev)
{
	const struct cc2520_config *cfg = dev->config;

	return gpio_pin_get_raw(cfg->fifo.port, cfg->fifo.pin);
}

static inline uint32_t get_fifop(const struct device *dev)
{
	const struct cc2520_config *cfg = dev->config;

	return gpio_pin_get_raw(cfg->fifop.port, cfg->fifop.pin);
}

static inline uint32_t get_cca(const struct device *dev)
{
	const struct cc2520_config *cfg = dev->config;

	return gpio_pin_get_raw(cfg->cca.port, cfg->cca.pin);
}

static inline void sfd_int_handler(const struct device *port,
				   struct gpio_callback *cb, uint32_t pins)
{
	struct cc2520_context *cc2520 =
		CONTAINER_OF(cb, struct cc2520_context, sfd_cb);

	if (atomic_get(&cc2520->tx) == 1) {
		atomic_set(&cc2520->tx, 0);
		k_sem_give(&cc2520->tx_sync);
	}
}

static inline void fifop_int_handler(const struct device *port,
				     struct gpio_callback *cb, uint32_t pins)
{
	struct cc2520_context *cc2520 =
		CONTAINER_OF(cb, struct cc2520_context, fifop_cb);

	/* Note: Errata document - 1.2 */
	if (!get_fifop(cc2520->dev) && !get_fifop(cc2520->dev)) {
		return;
	}

	if (!get_fifo(cc2520->dev)) {
		cc2520->overflow = true;
	}

	k_sem_give(&cc2520->rx_lock);
}

static void enable_fifop_interrupt(const struct device *dev,
				   bool enable)
{
	const struct cc2520_config *cfg = dev->config;
	gpio_flags_t mode = enable ? GPIO_INT_EDGE_TO_ACTIVE : GPIO_INT_DISABLE;

	gpio_pin_interrupt_configure_dt(&cfg->fifop, mode);
}

static void enable_sfd_interrupt(const struct device *dev,
				 bool enable)
{
	const struct cc2520_config *cfg = dev->config;
	gpio_flags_t mode = enable ? GPIO_INT_EDGE_TO_ACTIVE : GPIO_INT_DISABLE;

	gpio_pin_interrupt_configure_dt(&cfg->sfd, mode);
}

static inline int setup_gpio_callbacks(const struct device *dev)
{
	const struct cc2520_config *cfg = dev->config;
	struct cc2520_context *cc2520 = dev->data;

	gpio_init_callback(&cc2520->sfd_cb, sfd_int_handler, BIT(cfg->sfd.pin));
	if (gpio_add_callback(cfg->sfd.port, &cc2520->sfd_cb) != 0) {
		return -EIO;
	}


	gpio_init_callback(&cc2520->fifop_cb, fifop_int_handler, BIT(cfg->fifop.pin));
	if (gpio_add_callback(cfg->fifop.port, &cc2520->fifop_cb) != 0) {
		return -EIO;
	}

	return 0;
}


/****************
 * TX functions *
 ***************/
static inline bool write_txfifo_length(const struct device *dev, uint8_t len)
{
	uint8_t length = len + CC2520_FCS_LENGTH;

	return z_cc2520_access(dev, false, CC2520_INS_TXBUF, 0, &length, 1);
}

static inline bool write_txfifo_content(const struct device *dev,
					uint8_t *frame, uint8_t len)
{
	return z_cc2520_access(dev, false, CC2520_INS_TXBUF, 0, frame, len);
}

static inline bool verify_txfifo_status(const struct device *dev,
					uint8_t len)
{
	if (read_reg_txfifocnt(dev) < len ||
	    (read_reg_excflag0(dev) & EXCFLAG0_TX_UNDERFLOW)) {
		return false;
	}

	return true;
}

static inline bool verify_tx_done(const struct device *dev)
{
	uint8_t timeout = 10U;
	uint8_t status;

	do {
		z_usleep(1);
		timeout--;
		status = read_reg_excflag0(dev);
	} while (!(status & EXCFLAG0_TX_FRM_DONE) && timeout);

	return !!(status & EXCFLAG0_TX_FRM_DONE);
}

/****************
 * RX functions *
 ***************/

static inline void flush_rxfifo(const struct device *dev)
{
	/* Note: Errata document - 1.1 */
	enable_fifop_interrupt(dev, false);

	instruct_sflushrx(dev);
	instruct_sflushrx(dev);

	enable_fifop_interrupt(dev, true);

	write_reg_excflag0(dev, EXCFLAG0_RESET_RX_FLAGS);
}

static inline uint8_t read_rxfifo_length(const struct device *dev)
{
	uint8_t len;


	if (z_cc2520_access(dev, true, CC2520_INS_RXBUF, 0, &len, 1)) {
		return len;
	}

	return 0;
}

static inline bool read_rxfifo_content(const struct device *dev,
				       struct net_buf *buf, uint8_t len)
{
	if (!z_cc2520_access(dev, true, CC2520_INS_RXBUF, 0, buf->data, len)) {
		return false;
	}

	if (read_reg_excflag0(dev) & EXCFLAG0_RX_UNDERFLOW) {
		LOG_ERR("RX underflow!");
		return false;
	}

	net_buf_add(buf, len);

	return true;
}

static inline void insert_radio_noise_details(struct net_pkt *pkt, uint8_t *status)
{
	uint8_t lqi;

	net_pkt_set_ieee802154_rssi_dbm(pkt, (int8_t) status[0]);

	/**
	 * CC2520 does not provide an LQI but a correlation factor.
	 * See Section 20.6
	 * Such calculation can be loosely used to transform it to lqi:
	 * corr <= 50 ? lqi = 0
	 * or:
	 * corr >= 110 ? lqi = 255
	 * else:
	 * lqi = (lqi - 50) * 4
	 */
	lqi = status[1] & CC2520_FCS_CORRELATION;
	if (lqi <= 50U) {
		lqi = 0U;
	} else if (lqi >= 110U) {
		lqi = 255U;
	} else {
		lqi = (lqi - 50U) << 2;
	}

	net_pkt_set_ieee802154_lqi(pkt, lqi);
}

static inline bool verify_crc(const struct device *dev, struct net_pkt *pkt)
{
	uint8_t status[2];

	if (!z_cc2520_access(dev, true, CC2520_INS_RXBUF, 0, &status, 2)) {
		return false;
	}

	if (!(status[1] & CC2520_FCS_CRC_OK)) {
		return false;
	}

	insert_radio_noise_details(pkt, status);

	return true;
}

static inline bool verify_rxfifo_validity(const struct device *dev,
					  uint8_t pkt_len)
{
	if (pkt_len < 2 || read_reg_rxfifocnt(dev) != pkt_len) {
		return false;
	}

	return true;
}

static void cc2520_rx(void *p1, void *p2, void *p3)
{
	ARG_UNUSED(p2);
	ARG_UNUSED(p3);

	const struct device *dev = p1;
	struct cc2520_context *cc2520 = dev->data;
	struct net_pkt *pkt;
	uint8_t pkt_len;

	while (1) {
		pkt = NULL;

		k_sem_take(&cc2520->rx_lock, K_FOREVER);

		if (cc2520->overflow) {
			LOG_ERR("RX overflow!");
			cc2520->overflow = false;

			goto flush;
		}

		pkt_len = read_rxfifo_length(dev) & 0x7f;
		if (!verify_rxfifo_validity(dev, pkt_len)) {
			LOG_ERR("Invalid content");
			goto flush;
		}

		pkt = net_pkt_rx_alloc_with_buffer(cc2520->iface, pkt_len,
						   AF_UNSPEC, 0, K_NO_WAIT);
		if (!pkt) {
			LOG_ERR("No pkt available");
			goto flush;
		}

		if (!IS_ENABLED(CONFIG_IEEE802154_RAW_MODE)) {
			pkt_len -= 2U;
		}

		if (!read_rxfifo_content(dev, pkt->buffer, pkt_len)) {
			LOG_ERR("No content read");
			goto flush;
		}

		if (!verify_crc(dev, pkt)) {
			LOG_ERR("Bad packet CRC");
			goto out;
		}

		if (ieee802154_handle_ack(cc2520->iface, pkt) == NET_OK) {
			LOG_DBG("ACK packet handled");
			goto out;
		}

		LOG_DBG("Caught a packet (%u)", pkt_len);

		if (net_recv_data(cc2520->iface, pkt) < 0) {
			LOG_DBG("Packet dropped by NET stack");
			goto out;
		}

		log_stack_usage(&cc2520->cc2520_rx_thread);
		continue;
flush:
		cc2520_print_exceptions(cc2520);
		cc2520_print_errors(cc2520);
		flush_rxfifo(dev);
out:
		if (pkt) {
			net_pkt_unref(pkt);
		}
	}
}

/********************
 * Radio device API *
 *******************/
static enum ieee802154_hw_caps cc2520_get_capabilities(const struct device *dev)
{
	/* TODO: Add support for IEEE802154_HW_PROMISC */
	return IEEE802154_HW_FCS | IEEE802154_HW_FILTER |
	       IEEE802154_HW_RX_TX_ACK;
}

static int cc2520_cca(const struct device *dev)
{
	if (!get_cca(dev)) {
		LOG_WRN("Busy");
		return -EBUSY;
	}

	return 0;
}

static int cc2520_set_channel(const struct device *dev, uint16_t channel)
{
	LOG_DBG("%u", channel);

	if (channel > 26) {
		return -EINVAL;
	}

	if (channel < 11) {
		return -ENOTSUP;
	}

	/* See chapter 16 */
	channel = 11 + (channel - 11) * 5U;

	if (!write_reg_freqctrl(dev, FREQCTRL_FREQ(channel))) {
		LOG_ERR("Failed");
		return -EIO;
	}

	return 0;
}

static int cc2520_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 cc2520_set_ieee_addr(dev, filter->ieee_addr);
	} else if (type == IEEE802154_FILTER_TYPE_SHORT_ADDR) {
		return cc2520_set_short_addr(dev, filter->short_addr);
	} else if (type == IEEE802154_FILTER_TYPE_PAN_ID) {
		return cc2520_set_pan_id(dev, filter->pan_id);
	}

	return -ENOTSUP;
}

static int cc2520_set_txpower(const struct device *dev, int16_t dbm)
{
	uint8_t pwr;

	LOG_DBG("%d", dbm);

	/* See chapter 19 part 8 */
	switch (dbm) {
	case 5:
		pwr = 0xF7;
		break;
	case 3:
		pwr = 0xF2;
		break;
	case 2:
		pwr = 0xAB;
		break;
	case 1:
		pwr = 0x13;
		break;
	case 0:
		pwr = 0x32;
		break;
	case -2:
		pwr = 0x81;
		break;
	case -4:
		pwr = 0x88;
		break;
	case -7:
		pwr = 0x2C;
		break;
	case -18:
		pwr = 0x03;
		break;
	default:
		goto error;
	}

	if (!write_reg_txpower(dev, pwr)) {
		goto error;
	}

	return 0;
error:
	LOG_ERR("Failed");
	return -EIO;
}

static int cc2520_tx(const struct device *dev,
		     enum ieee802154_tx_mode mode,
		     struct net_pkt *pkt,
		     struct net_buf *frag)
{
	uint8_t *frame = frag->data;
	uint8_t len = frag->len;
	struct cc2520_context *cc2520 = dev->data;
	uint8_t retry = 2U;
	bool status;

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

	LOG_DBG("%p (%u)", frag, len);

	if (!write_reg_excflag0(dev, EXCFLAG0_RESET_TX_FLAGS) ||
	    !write_txfifo_length(dev, len) ||
	    !write_txfifo_content(dev, frame, len)) {
		LOG_ERR("Cannot feed in TX fifo");
		goto error;
	}

	if (!verify_txfifo_status(dev, len)) {
		LOG_ERR("Did not write properly into TX FIFO");
		goto error;
	}

#ifdef CONFIG_IEEE802154_CC2520_CRYPTO
	k_sem_take(&cc2520->access_lock, K_FOREVER);
#endif

	/* 1 retry is allowed here */
	do {
		atomic_set(&cc2520->tx, 1);
		k_sem_init(&cc2520->tx_sync, 0, K_SEM_MAX_LIMIT);

		if (!instruct_stxoncca(dev)) {
			LOG_ERR("Cannot start transmission");
			goto error;
		}

		/* TODO: Implement standard conforming CSMA/CA or use the soft MAC's default. */
		k_sem_take(&cc2520->tx_sync, K_MSEC(10));

		retry--;
		status = verify_tx_done(dev);
	} while (!status && retry);

#ifdef CONFIG_IEEE802154_CC2520_CRYPTO
	k_sem_give(&cc2520->access_lock);
#endif

	if (status) {
		return 0;
	}

error:
#ifdef CONFIG_IEEE802154_CC2520_CRYPTO
	k_sem_give(&cc2520->access_lock);
#endif
	LOG_ERR("No TX_FRM_DONE");
	cc2520_print_exceptions(cc2520);
	cc2520_print_errors(cc2520);

	atomic_set(&cc2520->tx, 0);
	instruct_sflushtx(dev);

	return -EIO;
}

static int cc2520_start(const struct device *dev)
{
	if (!instruct_sxoscon(dev) ||
	    !instruct_srxon(dev) ||
	    !verify_osc_stabilization(dev)) {
		LOG_ERR("Error starting CC2520");
		return -EIO;
	}

	flush_rxfifo(dev);

	enable_fifop_interrupt(dev, true);
	enable_sfd_interrupt(dev, true);

	return 0;
}

static int cc2520_stop(const struct device *dev)
{
	flush_rxfifo(dev);

	enable_fifop_interrupt(dev, false);
	enable_sfd_interrupt(dev, false);

	if (!instruct_srfoff(dev) ||
	    !instruct_sxoscoff(dev)) {
		LOG_ERR("Error stopping CC2520");
		return -EIO;
	}

	return 0;
}

/* driver-allocated attribute memory - constant across all driver instances */
IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26);

static int cc2520_attr_get(const struct device *dev, enum ieee802154_attr attr,
			   struct ieee802154_attr_value *value)
{
	ARG_UNUSED(dev);

	return ieee802154_attr_get_channel_page_and_range(
		attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915,
		&drv_attr.phy_supported_channels, value);
}

/******************
 * Initialization *
 *****************/
static int power_on_and_setup(const struct device *dev)
{
	/* Switching to LPM2 mode */
	set_reset(dev, 0);
	z_usleep(150);

	set_vreg_en(dev, 0);
	z_usleep(250);

	/* Then to ACTIVE mode */
	set_vreg_en(dev, 1);
	z_usleep(250);

	set_reset(dev, 1);
	z_usleep(150);

	if (!verify_osc_stabilization(dev)) {
		return -EIO;
	}

	/* Default settings to always write (see chapter 28 part 1) */
	if (!write_reg_txpower(dev, CC2520_TXPOWER_DEFAULT) ||
	    !write_reg_ccactrl0(dev, CC2520_CCACTRL0_DEFAULT) ||
	    !write_reg_mdmctrl0(dev, CC2520_MDMCTRL0_DEFAULT) ||
	    !write_reg_mdmctrl1(dev, CC2520_MDMCTRL1_DEFAULT) ||
	    !write_reg_rxctrl(dev, CC2520_RXCTRL_DEFAULT) ||
	    !write_reg_fsctrl(dev, CC2520_FSCTRL_DEFAULT) ||
	    !write_reg_fscal1(dev, CC2520_FSCAL1_DEFAULT) ||
	    !write_reg_agcctrl1(dev, CC2520_AGCCTRL1_DEFAULT) ||
	    !write_reg_adctest0(dev, CC2520_ADCTEST0_DEFAULT) ||
	    !write_reg_adctest1(dev, CC2520_ADCTEST1_DEFAULT) ||
	    !write_reg_adctest2(dev, CC2520_ADCTEST2_DEFAULT)) {
		return -EIO;
	}

	/* EXTCLOCK0: Disabling external clock
	 * FRMCTRL0: AUTOACK and AUTOCRC enabled
	 * FRMCTRL1: SET_RXENMASK_ON_TX and IGNORE_TX_UNDERF
	 * FRMFILT0: Frame filtering (setting CC2520_FRAME_FILTERING)
	 * FIFOPCTRL: Set TX threshold (setting CC2520_TX_THRESHOLD)
	 */
	if (!write_reg_extclock(dev, 0) ||
	    !write_reg_frmctrl0(dev, CC2520_AUTOMATISM) ||
	    !write_reg_frmctrl1(dev, FRMCTRL1_IGNORE_TX_UNDERF |
				FRMCTRL1_SET_RXENMASK_ON_TX) ||
	    !write_reg_frmfilt0(dev, FRMFILT0_FRAME_FILTER_EN |
				FRMFILT0_MAX_FRAME_VERSION(3)) ||
	    !write_reg_frmfilt1(dev, FRMFILT1_ACCEPT_ALL) ||
	    !write_reg_srcmatch(dev, SRCMATCH_DEFAULTS) ||
	    !write_reg_fifopctrl(dev,
				 FIFOPCTRL_FIFOP_THR(CC2520_TX_THRESHOLD))) {
		return -EIO;
	}

	/* Cleaning up TX fifo */
	instruct_sflushtx(dev);

	if (setup_gpio_callbacks(dev) != 0) {
		return -EIO;
	}

	cc2520_print_gpio_config(dev);

	return 0;
}

static int configure_gpios(const struct device *dev)
{
	const struct cc2520_config *cfg = dev->config;

	if (!gpio_is_ready_dt(&cfg->vreg_en) ||
	    !gpio_is_ready_dt(&cfg->reset) ||
	    !gpio_is_ready_dt(&cfg->fifo) ||
	    !gpio_is_ready_dt(&cfg->cca) ||
	    !gpio_is_ready_dt(&cfg->sfd) ||
	    !gpio_is_ready_dt(&cfg->fifop)) {
		return -ENODEV;
	}

	gpio_pin_configure_dt(&cfg->vreg_en, GPIO_OUTPUT_LOW);
	gpio_pin_configure_dt(&cfg->reset, GPIO_OUTPUT_LOW);
	gpio_pin_configure_dt(&cfg->fifo, GPIO_INPUT);
	gpio_pin_configure_dt(&cfg->cca, GPIO_INPUT);
	gpio_pin_configure_dt(&cfg->sfd, GPIO_INPUT);
	gpio_pin_configure_dt(&cfg->fifop, GPIO_INPUT);

	return 0;
}

static int cc2520_init(const struct device *dev)
{
	const struct cc2520_config *cfg = dev->config;
	struct cc2520_context *cc2520 = dev->data;

	cc2520->dev = dev;

	atomic_set(&cc2520->tx, 0);
	k_sem_init(&cc2520->rx_lock, 0, K_SEM_MAX_LIMIT);

#ifdef CONFIG_IEEE802154_CC2520_CRYPTO
	k_sem_init(&cc2520->access_lock, 1, 1);
#endif

	if (configure_gpios(dev) != 0) {
		LOG_ERR("Configuring GPIOS failed");
		return -EIO;
	}

	if (!spi_is_ready_dt(&cfg->bus)) {
		LOG_ERR("SPI bus %s not ready", cfg->bus.bus->name);
		return -EIO;
	}

	LOG_DBG("GPIO and SPI configured");

	if (power_on_and_setup(dev) != 0) {
		LOG_ERR("Configuring CC2520 failed");
		return -EIO;
	}

	k_thread_create(&cc2520->cc2520_rx_thread, cc2520->cc2520_rx_stack,
			CONFIG_IEEE802154_CC2520_RX_STACK_SIZE,
			cc2520_rx,
			(void *)dev, NULL, NULL, K_PRIO_COOP(2), 0, K_NO_WAIT);
	k_thread_name_set(&cc2520->cc2520_rx_thread, "cc2520_rx");

	LOG_INF("CC2520 initialized");

	return 0;
}

static void cc2520_iface_init(struct net_if *iface)
{
	const struct device *dev = net_if_get_device(iface);
	struct cc2520_context *cc2520 = dev->data;
	uint8_t *mac = get_mac(dev);

	net_if_set_link_addr(iface, mac, 8, NET_LINK_IEEE802154);

	cc2520->iface = iface;

	ieee802154_init(iface);
}

static const struct cc2520_config cc2520_config = {
	.bus = SPI_DT_SPEC_INST_GET(0, SPI_WORD_SET(8), 0),
	.vreg_en = GPIO_DT_SPEC_INST_GET(0, vreg_en_gpios),
	.reset = GPIO_DT_SPEC_INST_GET(0, reset_gpios),
	.fifo = GPIO_DT_SPEC_INST_GET(0, fifo_gpios),
	.cca = GPIO_DT_SPEC_INST_GET(0, cca_gpios),
	.sfd = GPIO_DT_SPEC_INST_GET(0, sfd_gpios),
	.fifop = GPIO_DT_SPEC_INST_GET(0, fifop_gpios)
};

static struct cc2520_context cc2520_context_data;

static const struct ieee802154_radio_api cc2520_radio_api = {
	.iface_api.init	= cc2520_iface_init,

	.get_capabilities	= cc2520_get_capabilities,
	.cca			= cc2520_cca,
	.set_channel		= cc2520_set_channel,
	.filter			= cc2520_filter,
	.set_txpower		= cc2520_set_txpower,
	.start			= cc2520_start,
	.stop			= cc2520_stop,
	.tx			= cc2520_tx,
	.attr_get		= cc2520_attr_get,
};

#if defined(CONFIG_IEEE802154_RAW_MODE)
DEVICE_DT_INST_DEFINE(0, cc2520_init, NULL, &cc2520_context_data, NULL,
		      POST_KERNEL, CONFIG_IEEE802154_CC2520_INIT_PRIO,
		      &cc2520_radio_api);
#else
NET_DEVICE_DT_INST_DEFINE(0, cc2520_init, NULL, &cc2520_context_data,
			  &cc2520_config, CONFIG_IEEE802154_CC2520_INIT_PRIO,
			  &cc2520_radio_api, IEEE802154_L2,
			  NET_L2_GET_CTX_TYPE(IEEE802154_L2), 125);
#endif


#ifdef CONFIG_IEEE802154_CC2520_CRYPTO

static inline bool cc2520_read_ram(const struct device *dev, uint16_t addr,
				   uint8_t *data_buf, uint8_t len)
{
	return z_cc2520_access(dev, true, CC2520_INS_MEMRD,
			       addr, data_buf, len);
}

static inline bool cc2520_write_ram(const struct device *dev, uint16_t addr,
				    uint8_t *data_buf, uint8_t len)
{
	return z_cc2520_access(dev, false, CC2520_INS_MEMWR,
			       addr, data_buf, len);
}

static inline bool instruct_uccm_ccm(const struct device *dev,
				     bool uccm,
				     uint8_t key_addr,
				     uint8_t auth_crypt,
				     uint8_t nonce_addr,
				     uint16_t input_addr,
				     uint16_t output_addr,
				     uint8_t in_len,
				     uint8_t m)
{
	const struct cc2520_config *cfg = dev->config;
	struct cc2520_context *ctx = dev->data;
	uint8_t cmd[9];
	const struct spi_buf buf[1] = {
		{
			.buf = cmd,
			.len = 9,
		},
	};
	const struct spi_buf_set tx = {
		.buffers = buf,
		.count = 1
	};

	int ret;

	LOG_DBG("%sCCM(P={01} K={%02x} C={%02x} N={%02x}"
		    " A={%03x} E={%03x} F{%02x} M={%02x})",
		    uccm ? "U" : "", key_addr, auth_crypt, nonce_addr,
		    input_addr, output_addr, in_len, m);

	cmd[0] = uccm ? CC2520_INS_UCCM | 1 : CC2520_INS_CCM | 1;
	cmd[1] = key_addr;
	cmd[2] = (auth_crypt & 0x7f);
	cmd[3] = nonce_addr;
	cmd[4] = (uint8_t)(((input_addr & 0x0f00) >> 4) |
			   ((output_addr & 0x0f00) >> 8));
	cmd[5] = (uint8_t)(input_addr & 0x00ff);
	cmd[6] = (uint8_t)(output_addr & 0x00ff);
	cmd[7] = (in_len & 0x7f);
	cmd[8] = (m & 0x03);

	k_sem_take(&ctx->access_lock, K_FOREVER);

	ret = spi_write_dt(&cfg->bus, &tx);

	k_sem_give(&ctx->access_lock);

	if (ret) {
		LOG_ERR("%sCCM Failed", uccm ? "U" : "");
		return false;
	}

	return true;
}

static inline void generate_nonce(uint8_t *ccm_nonce, uint8_t *nonce,
				  struct cipher_aead_pkt *apkt, uint8_t m)
{
	nonce[0] = 0 | (apkt->ad_len ? 0x40 : 0) | (m << 3) | 1;

	memcpy(&nonce[1], ccm_nonce, 13);

	nonce[14] = (uint8_t)(apkt->pkt->in_len >> 8);
	nonce[15] = (uint8_t)(apkt->pkt->in_len);

	/* See section 26.8.1 */
	sys_mem_swap(nonce, 16);
}

static int insert_crypto_parameters(struct cipher_ctx *ctx,
				    struct cipher_aead_pkt *apkt,
				    uint8_t *ccm_nonce, uint8_t *auth_crypt)
{
	const struct device *cc2520 = ctx->device;
	uint8_t data[128];
	uint8_t *in_buf;
	uint8_t in_len;
	uint8_t m = 0U;

	if (!apkt->pkt->out_buf || !apkt->pkt->out_buf_max) {
		LOG_ERR("Out buffer needs to be set");
		return -EINVAL;
	}

	if (!ctx->key.bit_stream || !ctx->keylen) {
		LOG_ERR("No key installed");
		return -EINVAL;
	}

	if (!(ctx->flags & CAP_INPLACE_OPS)) {
		LOG_ERR("It supports only in-place operation");
		return -EINVAL;
	}

	if (!apkt->ad || !apkt->ad_len) {
		LOG_ERR("CCM needs associated data");
		return -EINVAL;
	}

	if (apkt->pkt->in_buf && apkt->pkt->in_buf - apkt->ad_len != apkt->ad) {
		LOG_ERR("In-place needs ad and input in same memory");
		return -EINVAL;
	}

	if (!apkt->pkt->in_buf) {
		if (!ctx->mode_params.ccm_info.tag_len) {
			LOG_ERR("Auth only needs a tag length");
			return -EINVAL;
		}

		in_buf = apkt->ad;
		in_len = apkt->ad_len;

		*auth_crypt = 0U;
	} else {
		in_buf = data;

		memcpy(in_buf, apkt->ad, apkt->ad_len);
		memcpy(in_buf + apkt->ad_len,
		       apkt->pkt->in_buf, apkt->pkt->in_len);
		in_len = apkt->ad_len + apkt->pkt->in_len;

		*auth_crypt = !apkt->tag ? apkt->pkt->in_len :
			apkt->pkt->in_len - ctx->mode_params.ccm_info.tag_len;
	}

	if (ctx->mode_params.ccm_info.tag_len) {
		if ((ctx->mode_params.ccm_info.tag_len >> 2) > 3) {
			m = 3U;
		} else {
			m = ctx->mode_params.ccm_info.tag_len >> 2;
		}
	}

	/* Writing the frame in RAM */
	if (!cc2520_write_ram(cc2520, CC2520_MEM_DATA, in_buf, in_len)) {
		LOG_ERR("Cannot write the frame in RAM");
		return -EIO;
	}

	/* See section 26.8.1 */
	sys_memcpy_swap(data, ctx->key.bit_stream, ctx->keylen);

	/* Writing the key in RAM */
	if (!cc2520_write_ram(cc2520, CC2520_MEM_KEY, data, 16)) {
		LOG_ERR("Cannot write the key in RAM");
		return -EIO;
	}

	generate_nonce(ccm_nonce, data, apkt, m);

	/* Writing the nonce in RAM */
	if (!cc2520_write_ram(cc2520, CC2520_MEM_NONCE, data, 16)) {
		LOG_ERR("Cannot write the nonce in RAM");
		return -EIO;
	}

	return m;
}

static int cc2520_crypto_ccm(struct cipher_ctx *ctx,
			      struct cipher_aead_pkt *apkt,
			      uint8_t *ccm_nonce)
{
	const struct device *cc2520 = ctx->device;
	uint8_t auth_crypt;
	int m;

	if (!apkt || !apkt->pkt) {
		LOG_ERR("Invalid crypto packet to operate with");
		return -EINVAL;
	}

	m = insert_crypto_parameters(ctx, apkt, ccm_nonce, &auth_crypt);
	if (m < 0) {
		LOG_ERR("Inserting crypto parameters failed");
		return m;
	}

	apkt->pkt->out_len = apkt->pkt->in_len + apkt->ad_len +
		(m ? ctx->mode_params.ccm_info.tag_len : 0);

	if (apkt->pkt->out_len > apkt->pkt->out_buf_max) {
		LOG_ERR("Result will not fit into out buffer %u vs %u",
			    apkt->pkt->out_len, apkt->pkt->out_buf_max);
		return -ENOBUFS;
	}

	if (!instruct_uccm_ccm(cc2520, false, CC2520_MEM_KEY >> 4, auth_crypt,
			       CC2520_MEM_NONCE >> 4, CC2520_MEM_DATA,
			       0x000, apkt->ad_len, m) ||
	    !cc2520_read_ram(cc2520, CC2520_MEM_DATA,
			      apkt->pkt->out_buf, apkt->pkt->out_len)) {
		LOG_ERR("CCM or reading result from RAM failed");
		return -EIO;
	}

	if (apkt->tag) {
		memcpy(apkt->tag, apkt->pkt->out_buf + apkt->pkt->in_len,
					ctx->mode_params.ccm_info.tag_len);
	}

	return 0;
}

static int cc2520_crypto_uccm(struct cipher_ctx *ctx,
			       struct cipher_aead_pkt *apkt,
			       uint8_t *ccm_nonce)
{
	const struct device *cc2520 = ctx->device;
	uint8_t auth_crypt;
	int m;

	if (!apkt || !apkt->pkt) {
		LOG_ERR("Invalid crypto packet to operate with");
		return -EINVAL;
	}

	if (ctx->mode_params.ccm_info.tag_len && !apkt->tag) {
		LOG_ERR("In case of MIC you need to provide a tag");
		return -EINVAL;
	}

	m = insert_crypto_parameters(ctx, apkt, ccm_nonce, &auth_crypt);
	if (m < 0) {
		return m;
	}

	apkt->pkt->out_len = apkt->pkt->in_len + apkt->ad_len;

	if (!instruct_uccm_ccm(cc2520, true, CC2520_MEM_KEY >> 4, auth_crypt,
			       CC2520_MEM_NONCE >> 4, CC2520_MEM_DATA,
			       0x000, apkt->ad_len, m) ||
	    !cc2520_read_ram(cc2520, CC2520_MEM_DATA,
			      apkt->pkt->out_buf, apkt->pkt->out_len)) {
		LOG_ERR("UCCM or reading result from RAM failed");
		return -EIO;
	}

	if (m && (!(read_reg_dpustat(cc2520) & DPUSTAT_AUTHSTAT_H))) {
		LOG_ERR("Authentication of the frame failed");
		return -EBADMSG;
	}

	return 0;
}

static int cc2520_crypto_hw_caps(const struct device *dev)
{
	return CAP_RAW_KEY | CAP_INPLACE_OPS | CAP_SYNC_OPS;
}

static int cc2520_crypto_begin_session(const struct device *dev,
				       struct cipher_ctx *ctx,
				       enum cipher_algo algo,
				       enum cipher_mode mode,
				       enum cipher_op op_type)
{
	if (algo != CRYPTO_CIPHER_ALGO_AES || mode != CRYPTO_CIPHER_MODE_CCM) {
		LOG_ERR("Wrong algo (%u) or mode (%u)", algo, mode);
		return -EINVAL;
	}

	if (ctx->mode_params.ccm_info.nonce_len != 13U) {
		LOG_ERR("Nonce length erroneous (%u)",
			    ctx->mode_params.ccm_info.nonce_len);
		return -EINVAL;
	}

	if (op_type == CRYPTO_CIPHER_OP_ENCRYPT) {
		ctx->ops.ccm_crypt_hndlr = cc2520_crypto_ccm;
	} else {
		ctx->ops.ccm_crypt_hndlr = cc2520_crypto_uccm;
	}

	ctx->ops.cipher_mode = mode;
	ctx->device = dev;

	return 0;
}

static int cc2520_crypto_free_session(const struct device *dev,
				      struct cipher_ctx *ctx)
{
	ARG_UNUSED(dev);

	ctx->ops.ccm_crypt_hndlr = NULL;
	ctx->device = NULL;

	return 0;
}

static int cc2520_crypto_init(const struct device *dev)
{
	LOG_INF("CC2520 crypto part initialized");

	return 0;
}

struct crypto_driver_api cc2520_crypto_api = {
	.query_hw_caps			= cc2520_crypto_hw_caps,
	.cipher_begin_session			= cc2520_crypto_begin_session,
	.cipher_free_session			= cc2520_crypto_free_session,
	.cipher_async_callback_set	= NULL
};

DEVICE_DEFINE(cc2520_crypto, "cc2520_crypto",
		cc2520_crypto_init, NULL,
		&cc2520_context_data, NULL, POST_KERNEL,
		CONFIG_IEEE802154_CC2520_CRYPTO_INIT_PRIO, &cc2520_crypto_api);

#endif /* CONFIG_IEEE802154_CC2520_CRYPTO */
