/* 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/rand32.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)
	uint32_t *ptr = (uint32_t *)(cc2520->mac_addr + 4);

	UNALIGNED_PUT(sys_rand32_get(), ptr);

	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 *buf)
{
	uint8_t lqi;

	net_pkt_set_ieee802154_rssi(pkt, buf[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 = buf[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 fcs[2];

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

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

	insert_radio_noise_details(pkt, fcs);

	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 *arg)
{
	const struct device *dev = arg;
	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_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_radio_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_2_4_GHZ |
		IEEE802154_HW_FILTER;
}

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 < 11 || channel > 26) {
		return -EINVAL;
	}

	/* 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;
		}

		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;
}

/******************
 * 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 (!device_is_ready(cfg->vreg_en.port) ||
	    !device_is_ready(cfg->reset.port) ||
	    !device_is_ready(cfg->fifo.port) ||
	    !device_is_ready(cfg->cca.port) ||
	    !device_is_ready(cfg->sfd.port) ||
	    !device_is_ready(cfg->fifop.port)) {
		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(&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,
			(k_thread_entry_t)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 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,
};

#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 */
