/* ieee802154_rf2xx.c - ATMEL RF2XX IEEE 802.15.4 Driver */

#define DT_DRV_COMPAT atmel_rf2xx

/*
 * Copyright (c) 2019-2020 Gerson Fernando Budke
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define LOG_MODULE_NAME ieee802154_rf2xx
#define LOG_LEVEL CONFIG_IEEE802154_DRIVER_LOG_LEVEL

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

#include <errno.h>
#include <stdio.h>
#include <stdlib.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/linker/sections.h>
#include <zephyr/sys/atomic.h>

#include <zephyr/drivers/spi.h>
#include <zephyr/drivers/gpio.h>

#include <zephyr/net/ieee802154_radio.h>

#include "ieee802154_rf2xx.h"
#include "ieee802154_rf2xx_regs.h"
#include "ieee802154_rf2xx_iface.h"

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

#define RF2XX_OT_PSDU_LENGTH              1280

#define RF2XX_ACK_FRAME_LEN               3
#define RF2XX_ACK_FRAME_TYPE              (2 << 0)
#define RF2XX_ACK_FRAME_PENDING_BIT       (1 << 4)
#define RF2XX_FRAME_CTRL_ACK_REQUEST_BIT  (1 << 5)

static uint8_t rf2xx_ack_psdu[RF2XX_ACK_FRAME_LEN] = { 0 };
static struct net_buf rf2xx_ack_frame = {
	.data  = rf2xx_ack_psdu,
	.size  = RF2XX_ACK_FRAME_LEN,
	.len   = RF2XX_ACK_FRAME_LEN,
	.__buf = rf2xx_ack_psdu,
	.frags = NULL,
};
static struct net_pkt rf2xx_ack_pkt = {
	.buffer = &rf2xx_ack_frame,
	.cb = {
		.lqi = 80,
		.rssi = -40,
	}
};
#endif /* CONFIG_NET_L2_OPENTHREAD */

/* Radio Transceiver ISR */
static inline void trx_isr_handler(const struct device *port,
				   struct gpio_callback *cb,
				   uint32_t pins)
{
	struct rf2xx_context *ctx = CONTAINER_OF(cb,
						 struct rf2xx_context,
						 irq_cb);

	ARG_UNUSED(port);
	ARG_UNUSED(pins);

	k_sem_give(&ctx->trx_isr_lock);
}

static void rf2xx_trx_set_state(const struct device *dev,
				enum rf2xx_trx_state_cmd_t state)
{
	do {
		rf2xx_iface_reg_write(dev, RF2XX_TRX_STATE_REG,
				      RF2XX_TRX_PHY_STATE_CMD_FORCE_TRX_OFF);
	} while (RF2XX_TRX_PHY_STATUS_TRX_OFF !=
		 (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATUS_REG) &
		  RF2XX_TRX_PHY_STATUS_MASK));

	do {
		rf2xx_iface_reg_write(dev, RF2XX_TRX_STATE_REG, state);
	} while (state !=
		 (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATUS_REG) &
		  RF2XX_TRX_PHY_STATUS_MASK));
}

static void rf2xx_trx_set_tx_state(const struct device *dev)
{
	uint8_t status;

	/**
	 * Ensures that RX automatically ACK will be sent when requested.
	 * Datasheet: Chapter 7.2.3 RX_AACK_ON – Receive with Automatic ACK
	 * Datasheet: Figure 7-13. Timing Example of an RX_AACK Transaction
	 * for Slotted Operation.
	 *
	 * This will create a spin lock that wait transceiver be free from
	 * current receive frame process
	 */
	do {
		status = (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATUS_REG) &
			  RF2XX_TRX_PHY_STATUS_MASK);
	} while (status == RF2XX_TRX_PHY_STATUS_BUSY_RX_AACK ||
		 status == RF2XX_TRX_PHY_STATUS_STATE_TRANSITION);

	rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TRX_OFF);
	rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
	rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TX_ARET_ON);
}

static void rf2xx_trx_set_rx_state(const struct device *dev)
{
	rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TRX_OFF);
	rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
	/**
	 * Set extended RX mode
	 * Datasheet: chapter 7.2 Extended Operating Mode
	 */
	rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_RX_AACK_ON);
}

static void rf2xx_set_rssi_base(const struct device *dev, uint16_t channel)
{
	struct rf2xx_context *ctx = dev->data;
	int8_t base;

	if (ctx->cc_page == RF2XX_TRX_CC_PAGE_0) {
		base = channel == 0
				? RF2XX_RSSI_BPSK_20
				: RF2XX_RSSI_BPSK_40;
	} else if (ctx->cc_page == RF2XX_TRX_CC_PAGE_2) {
		base = channel == 0
				? RF2XX_RSSI_OQPSK_SIN_RC_100
				: RF2XX_RSSI_OQPSK_SIN_250;
	} else {
		base = RF2XX_RSSI_OQPSK_RC_250;
	}

	ctx->trx_rssi_base = base;
}

static void rf2xx_trx_rx(const struct device *dev)
{
	struct rf2xx_context *ctx = dev->data;
	struct net_pkt *pkt = NULL;
	uint8_t rx_buf[RX2XX_MAX_FRAME_SIZE];
	uint8_t pkt_len;
	uint8_t frame_len;
	uint8_t trac;

	/*
	 * The rf2xx frame buffer can have length > 128 bytes. The
	 * net_pkt_rx_alloc_with_buffer allocates max value of 128 bytes.
	 *
	 * This obligate the driver to have rx_buf statically allocated with
	 * RX2XX_MAX_FRAME_SIZE.
	 */
	if (ctx->trx_model != RF2XX_TRX_MODEL_231) {
		pkt_len = ctx->rx_phr;
	} else {
		rf2xx_iface_frame_read(dev, rx_buf, RX2XX_FRAME_HEADER_SIZE);
		pkt_len = rx_buf[RX2XX_FRAME_PHR_INDEX];
	}

	if (pkt_len < RX2XX_FRAME_MIN_PHR_SIZE) {
		LOG_ERR("invalid RX frame length");
		return;
	}

	frame_len = RX2XX_FRAME_HEADER_SIZE + pkt_len +
		    RX2XX_FRAME_FOOTER_SIZE;

	rf2xx_iface_frame_read(dev, rx_buf, frame_len);

	trac = rx_buf[pkt_len + RX2XX_FRAME_TRAC_INDEX];
	trac = (trac >> RF2XX_RX_TRAC_STATUS) & RF2XX_RX_TRAC_BIT_MASK;

	if (trac == RF2XX_TRX_PHY_STATE_TRAC_INVALID) {
		LOG_ERR("invalid RX frame");

		return;
	}

	ctx->pkt_lqi = rx_buf[pkt_len + RX2XX_FRAME_LQI_INDEX];
	ctx->pkt_ed = rx_buf[pkt_len + RX2XX_FRAME_ED_INDEX];

	if (!IS_ENABLED(CONFIG_IEEE802154_RAW_MODE) &&
	    !IS_ENABLED(CONFIG_NET_L2_OPENTHREAD)) {
		pkt_len -= RX2XX_FRAME_FCS_LENGTH;
	}

	pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, pkt_len,
					   AF_UNSPEC, 0, K_NO_WAIT);

	if (!pkt) {
		LOG_ERR("No buf available");
		return;
	}

	memcpy(pkt->buffer->data, rx_buf + RX2XX_FRAME_HEADER_SIZE, pkt_len);
	net_buf_add(pkt->buffer, pkt_len);
	net_pkt_set_ieee802154_lqi(pkt, ctx->pkt_lqi);
	net_pkt_set_ieee802154_rssi(pkt, ctx->pkt_ed + ctx->trx_rssi_base);

	LOG_DBG("Caught a packet (%02X) (LQI: %02X, RSSI: %d, ED: %02X)",
		pkt_len, ctx->pkt_lqi, ctx->trx_rssi_base + ctx->pkt_ed,
		ctx->pkt_ed);

	if (net_recv_data(ctx->iface, pkt) < 0) {
		LOG_DBG("Packet dropped by NET stack");
		net_pkt_unref(pkt);
		return;
	}

	if (LOG_LEVEL >= LOG_LEVEL_DBG) {
		log_stack_usage(&ctx->trx_thread);
	}
}

static void rf2xx_process_rx_frame(const struct device *dev)
{
	struct rf2xx_context *ctx = dev->data;

	/*
	 * NOTE: In promiscuous mode invalid frames will be processed.
	 */

	if (ctx->trx_model != RF2XX_TRX_MODEL_231) {
		rf2xx_trx_rx(dev);
	} else {
		/* Ensures that automatically ACK will be sent
		 * when requested
		 */
		while (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATUS_REG) ==
		       RF2XX_TRX_PHY_STATUS_BUSY_RX_AACK) {
			;
		}

		/* Set PLL_ON to avoid transceiver receive
		 * new data until finish reading process
		 */
		rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_PLL_ON);
		rf2xx_trx_rx(dev);
		rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_RX_AACK_ON);
	}
}

static void rf2xx_process_tx_frame(const struct device *dev)
{
	struct rf2xx_context *ctx = dev->data;

	ctx->trx_trac = (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATE_REG) >>
			 RF2XX_TRAC_STATUS) & RF2XX_TRAC_BIT_MASK;
	k_sem_give(&ctx->trx_tx_sync);
	rf2xx_trx_set_rx_state(dev);
}

static void rf2xx_process_trx_end(const struct device *dev)
{
	uint8_t trx_status = (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATUS_REG) &
			   RF2XX_TRX_PHY_STATUS_MASK);

	if (trx_status == RF2XX_TRX_PHY_STATUS_TX_ARET_ON) {
		rf2xx_process_tx_frame(dev);
	} else {
		rf2xx_process_rx_frame(dev);
	}
}

static void rf2xx_thread_main(void *arg)
{
	struct rf2xx_context *ctx = arg;
	uint8_t isr_status;

	while (true) {
		k_sem_take(&ctx->trx_isr_lock, K_FOREVER);

		isr_status = rf2xx_iface_reg_read(ctx->dev,
						  RF2XX_IRQ_STATUS_REG);

		/*
		 *  IRQ_7 (BAT_LOW) Indicates a supply voltage below the
		 *    programmed threshold. 9.5.4
		 *  IRQ_6 (TRX_UR) Indicates a Frame Buffer access
		 *    violation. 9.3.3
		 *  IRQ_5 (AMI) Indicates address matching. 8.2
		 *  IRQ_4 (CCA_ED_DONE) Multi-functional interrupt:
		 *   1. AWAKE_END: 7.1.2.5
		 *      • Indicates finished transition to TRX_OFF state
		 *        from P_ON, SLEEP, DEEP_SLEEP, or RESET state.
		 *   2. CCA_ED_DONE: 8.5.4
		 *      • Indicates the end of a CCA or ED
		 *        measurement. 8.6.4
		 *  IRQ_3 (TRX_END)
		 *    RX: Indicates the completion of a frame
		 *      reception. 7.1.3
		 *    TX: Indicates the completion of a frame
		 *      transmission. 7.1.3
		 *  IRQ_2 (RX_START) Indicates the start of a PSDU
		 *    reception; the AT86RF233 state changed to BUSY_RX;
		 *    the PHR can be read from Frame Buffer. 7.1.3
		 *  IRQ_1 (PLL_UNLOCK) Indicates PLL unlock. If the radio
		 *    transceiver is in BUSY_TX / BUSY_TX_ARET state, the
		 *    PA is turned off immediately. 9.7.5
		 *  IRQ_0 (PLL_LOCK) Indicates PLL lock.
		 */
		if (isr_status & (1 << RF2XX_RX_START)) {
			if (ctx->trx_model != RF2XX_TRX_MODEL_231) {
				rf2xx_iface_sram_read(ctx->dev, 0,
						      &ctx->rx_phr, 1);
			}
		}
		if (isr_status & (1 << RF2XX_TRX_END)) {
			rf2xx_process_trx_end(ctx->dev);
		}
	}
}

static inline uint8_t *get_mac(const struct device *dev)
{
	const struct rf2xx_config *conf = dev->config;
	struct rf2xx_context *ctx = dev->data;
	uint32_t *ptr = (uint32_t *)(ctx->mac_addr);

	if (!conf->has_mac) {
		UNALIGNED_PUT(sys_rand32_get(), ptr);
		ptr = (uint32_t *)(ctx->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.
	 */
	ctx->mac_addr[0] = (ctx->mac_addr[0] & ~0x01) | 0x02;

	return ctx->mac_addr;
}

static enum ieee802154_hw_caps rf2xx_get_capabilities(const struct device *dev)
{
	struct rf2xx_context *ctx = dev->data;

	LOG_DBG("HW Caps");

	return IEEE802154_HW_FCS |
	       IEEE802154_HW_PROMISC |
	       IEEE802154_HW_FILTER |
	       IEEE802154_HW_CSMA |
	       IEEE802154_HW_TX_RX_ACK |
	       (ctx->trx_model == RF2XX_TRX_MODEL_212
				? IEEE802154_HW_SUB_GHZ
				: IEEE802154_HW_2_4_GHZ);
}

static int rf2xx_configure_sub_channel(const struct device *dev, uint16_t channel)
{
	struct rf2xx_context *ctx = dev->data;
	uint8_t reg;
	uint8_t cc_mask;

	if (ctx->cc_page == RF2XX_TRX_CC_PAGE_0) {
		cc_mask = channel == 0
				   ? RF2XX_CC_BPSK_20
				   : RF2XX_CC_BPSK_40;
	} else if (ctx->cc_page == RF2XX_TRX_CC_PAGE_2) {
		cc_mask = channel == 0
				   ? RF2XX_CC_OQPSK_SIN_RC_100
				   : RF2XX_CC_OQPSK_SIN_250;
	} else {
		cc_mask = RF2XX_CC_OQPSK_RC_250;
	}

	reg = rf2xx_iface_reg_read(dev, RF2XX_TRX_CTRL_2_REG)
	    & ~RF2XX_SUB_CHANNEL_MASK;
	rf2xx_iface_reg_write(dev, RF2XX_TRX_CTRL_2_REG, reg | cc_mask);

	return 0;
}
static int rf2xx_configure_trx_path(const struct device *dev)
{
	struct rf2xx_context *ctx = dev->data;
	uint8_t reg;
	uint8_t gc_tx_offset;

	if (ctx->cc_page == RF2XX_TRX_CC_PAGE_0) {
		gc_tx_offset = 0x03;
	} else {
		gc_tx_offset = 0x02;
	}

	reg = rf2xx_iface_reg_read(dev, RF2XX_RF_CTRL_0_REG)
	    & ~RF2XX_GC_TX_OFFS_MASK;
	rf2xx_iface_reg_write(dev, RF2XX_RF_CTRL_0_REG, reg | gc_tx_offset);

	return 0;
}

static int rf2xx_cca(const struct device *dev)
{
	ARG_UNUSED(dev);

	LOG_DBG("CCA");

	return 0;
}

static int rf2xx_set_channel(const struct device *dev, uint16_t channel)
{
	struct rf2xx_context *ctx = dev->data;
	uint8_t reg;

	LOG_DBG("Set Channel %d", channel);

	if (ctx->trx_model == RF2XX_TRX_MODEL_212) {
		if ((ctx->cc_page == RF2XX_TRX_CC_PAGE_0
		     || ctx->cc_page == RF2XX_TRX_CC_PAGE_2)
		    && channel > 10) {
			LOG_ERR("Unsupported channel %u", channel);
			return -EINVAL;
		}
		if (ctx->cc_page == RF2XX_TRX_CC_PAGE_5 && channel > 3) {
			LOG_ERR("Unsupported channel %u", channel);
			return -EINVAL;
		}

		rf2xx_configure_sub_channel(dev, channel);
		rf2xx_configure_trx_path(dev);
		rf2xx_set_rssi_base(dev, channel);
	} else {
		if (channel < 11 || channel > 26) {
			LOG_ERR("Unsupported channel %u", channel);
			return -EINVAL;
		}
	}

	reg = rf2xx_iface_reg_read(dev, RF2XX_PHY_CC_CCA_REG) & ~0x1f;
	rf2xx_iface_reg_write(dev, RF2XX_PHY_CC_CCA_REG, reg | channel);

	return 0;
}

static int rf2xx_set_txpower(const struct device *dev, int16_t dbm)
{
	const struct rf2xx_config *conf = dev->config;
	struct rf2xx_context *ctx = dev->data;
	float min, max, step;
	uint8_t reg;
	uint8_t idx;
	uint8_t val;

	LOG_DBG("Try set Power to %d", dbm);

	/**
	 * if table size is equal 1 the code assumes a table was not defined. In
	 * this case the transceiver PHY_TX_PWR register will be set with value
	 * zero. This is a safe value for all variants and represents an output
	 * power above 0 dBm.
	 *
	 * Note: This is a special case too which avoid division by zero when
	 * computing the step variable.
	 */
	if (conf->tx_pwr_table_size == 1) {
		rf2xx_iface_reg_write(dev, RF2XX_PHY_TX_PWR_REG, 0);

		return 0;
	}

	min = conf->tx_pwr_min[1];
	if (conf->tx_pwr_min[0] == 0x01) {
		min *= -1.0f;
	}

	max = conf->tx_pwr_max[1];
	if (conf->tx_pwr_max[0] == 0x01) {
		min *= -1.0f;
	}

	step = (max - min) / ((float)conf->tx_pwr_table_size - 1.0f);

	if (step == 0.0f) {
		step = 1.0f;
	}

	LOG_DBG("Tx-power values: min %f, max %f, step %f, entries %d",
		(double)min, (double)max, (double)step, conf->tx_pwr_table_size);

	if (dbm < min) {
		LOG_INF("TX-power %d dBm below min of %f dBm, using %f dBm",
			dbm, (double)min, (double)max);
		dbm = min;
	} else if (dbm > max) {
		LOG_INF("TX-power %d dBm above max of %f dBm, using %f dBm",
			dbm, (double)min, (double)max);
		dbm = max;
	}

	idx = abs((int) (((float)(dbm - max) / step)));
	LOG_DBG("Tx-power idx: %d", idx);

	if (idx >= conf->tx_pwr_table_size) {
		idx = conf->tx_pwr_table_size - 1;
	}

	val = conf->tx_pwr_table[idx];

	if (ctx->trx_model != RF2XX_TRX_MODEL_212) {
		reg = rf2xx_iface_reg_read(dev, RF2XX_PHY_TX_PWR_REG) & 0xf0;
		val = reg + (val & 0x0f);
	}

	LOG_DBG("Tx-power normalized: %d dBm, PHY_TX_PWR 0x%02x, idx %d",
		dbm, val, idx);

	rf2xx_iface_reg_write(dev, RF2XX_PHY_TX_PWR_REG, val);

	return 0;
}

static int rf2xx_set_ieee_addr(const struct device *dev, bool set,
			       const uint8_t *ieee_addr)
{
	const uint8_t *ptr_to_reg = ieee_addr;

	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]);

	if (set) {
		for (uint8_t i = 0; i < 8; i++, ptr_to_reg++) {
			rf2xx_iface_reg_write(dev, (RF2XX_IEEE_ADDR_0_REG + i),
					      *ptr_to_reg);
		}
	} else {
		for (uint8_t i = 0; i < 8; i++) {
			rf2xx_iface_reg_write(dev, (RF2XX_IEEE_ADDR_0_REG + i),
					      0);
		}
	}

	return 0;
}

static int rf2xx_set_short_addr(const struct device *dev, bool set,
				uint16_t short_addr)
{
	uint8_t short_addr_le[2] = { 0xFF, 0xFF };

	if (set) {
		sys_put_le16(short_addr, short_addr_le);
	}

	rf2xx_iface_reg_write(dev, RF2XX_SHORT_ADDR_0_REG, short_addr_le[0]);
	rf2xx_iface_reg_write(dev, RF2XX_SHORT_ADDR_1_REG, short_addr_le[1]);
	rf2xx_iface_reg_write(dev, RF2XX_CSMA_SEED_0_REG,
			      short_addr_le[0] + short_addr_le[1]);

	LOG_DBG("Short Address: 0x%02X%02X", short_addr_le[1],
		short_addr_le[0]);

	return 0;
}

static int rf2xx_set_pan_id(const struct device *dev, bool set,
			    uint16_t pan_id)
{
	uint8_t pan_id_le[2] = { 0xFF, 0xFF };

	if (set) {
		sys_put_le16(pan_id, pan_id_le);
	}

	rf2xx_iface_reg_write(dev, RF2XX_PAN_ID_0_REG, pan_id_le[0]);
	rf2xx_iface_reg_write(dev, RF2XX_PAN_ID_1_REG, pan_id_le[1]);

	LOG_DBG("Pan Id: 0x%02X%02X", pan_id_le[1], pan_id_le[0]);

	return 0;
}

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

	if (type == IEEE802154_FILTER_TYPE_IEEE_ADDR) {
		return rf2xx_set_ieee_addr(dev, set, filter->ieee_addr);
	} else if (type == IEEE802154_FILTER_TYPE_SHORT_ADDR) {
		return rf2xx_set_short_addr(dev, set, filter->short_addr);
	} else if (type == IEEE802154_FILTER_TYPE_PAN_ID) {
		return rf2xx_set_pan_id(dev, set, filter->pan_id);
	}

	return -ENOTSUP;
}

#if defined(CONFIG_NET_L2_OPENTHREAD)
static void rf2xx_handle_ack(struct rf2xx_context *ctx, struct net_buf *frag)
{
	if ((frag->data[0] & RF2XX_FRAME_CTRL_ACK_REQUEST_BIT) == 0) {
		return;
	}

	rf2xx_ack_psdu[0] = RF2XX_ACK_FRAME_TYPE;
	rf2xx_ack_psdu[2] = frag->data[2];

	if (ctx->trx_trac == RF2XX_TRX_PHY_STATE_TRAC_SUCCESS_DATA_PENDING) {
		rf2xx_ack_psdu[0] |= RF2XX_ACK_FRAME_PENDING_BIT;
	}

	net_pkt_cursor_init(&rf2xx_ack_pkt);

	if (ieee802154_radio_handle_ack(ctx->iface, &rf2xx_ack_pkt) != NET_OK) {
		LOG_INF("ACK packet not handled.");
	}
}
#else
	#define rf2xx_handle_ack(...)
#endif

static int rf2xx_tx(const struct device *dev,
		    enum ieee802154_tx_mode mode,
		    struct net_pkt *pkt,
		    struct net_buf *frag)
{
	ARG_UNUSED(pkt);

	struct rf2xx_context *ctx = dev->data;
	int response = 0;

	LOG_DBG("TX");

	if (ctx->tx_mode != mode) {
		switch (mode) {
		case IEEE802154_TX_MODE_DIRECT:
			/* skip retries & csma/ca algorithm */
			rf2xx_iface_reg_write(dev, RF2XX_XAH_CTRL_0_REG, 0x0E);
			break;
		case IEEE802154_TX_MODE_CSMA_CA:
			/* backoff maxBE = 5, minBE = 3 */
			rf2xx_iface_reg_write(dev, RF2XX_CSMA_BE_REG, 0x53);
			/* max frame retries = 3, csma/ca retries = 4 */
			rf2xx_iface_reg_write(dev, RF2XX_XAH_CTRL_0_REG, 0x38);
			break;
		case IEEE802154_TX_MODE_CCA:
			/* backoff period = 0 */
			rf2xx_iface_reg_write(dev, RF2XX_CSMA_BE_REG, 0x00);
			/* no frame retries & no csma/ca retries */
			rf2xx_iface_reg_write(dev, RF2XX_XAH_CTRL_0_REG, 0x00);
			break;
		case IEEE802154_TX_MODE_TXTIME:
		case IEEE802154_TX_MODE_TXTIME_CCA:
		default:
			NET_ERR("TX mode %d not supported", mode);
			return -ENOTSUP;
		}

		ctx->tx_mode = mode;
	}

	rf2xx_trx_set_tx_state(dev);
	rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);

	k_sem_reset(&ctx->trx_tx_sync);
	rf2xx_iface_frame_write(dev, frag->data, frag->len);
	rf2xx_iface_phy_tx_start(dev);
	k_sem_take(&ctx->trx_tx_sync, K_FOREVER);

	switch (ctx->trx_trac) {
	/* Channel is still busy after attempting MAX_CSMA_RETRIES of
	 * CSMA-CA
	 */
	case RF2XX_TRX_PHY_STATE_TRAC_CHANNEL_ACCESS_FAILED:
		response = -EBUSY;
		break;
	/* No acknowledgment frames were received during all retry
	 * attempts
	 */
	case RF2XX_TRX_PHY_STATE_TRAC_NO_ACK:
		response = -EAGAIN;
		break;
	/* Transaction not yet finished */
	case RF2XX_TRX_PHY_STATE_TRAC_INVALID:
		response = -EINTR;
		break;
	/* RF2XX_TRX_PHY_STATE_TRAC_SUCCESS:
	 *  The transaction was responded to by a valid ACK, or, if no
	 *  ACK is requested, after a successful frame transmission.
	 *
	 * RF2XX_TRX_PHY_STATE_TRAC_SUCCESS_DATA_PENDING:
	 * Equivalent to SUCCESS and indicating that the “Frame
	 * Pending” bit (see Section 8.1.2.2) of the received
	 * acknowledgment frame was set.
	 */
	default:
		rf2xx_handle_ack(ctx, frag);
		break;
	}

	return response;
}

static int rf2xx_start(const struct device *dev)
{
	const struct rf2xx_config *conf = dev->config;

	LOG_DBG("Start");

	rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TRX_OFF);
	rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
	gpio_pin_interrupt_configure_dt(&conf->irq_gpio,
					GPIO_INT_EDGE_TO_ACTIVE);
	rf2xx_trx_set_rx_state(dev);

	return 0;
}

static int rf2xx_stop(const struct device *dev)
{
	const struct rf2xx_config *conf = dev->config;

	LOG_DBG("Stop");

	gpio_pin_interrupt_configure_dt(&conf->irq_gpio, GPIO_INT_DISABLE);
	rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TRX_OFF);
	rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);

	return 0;
}

static int rf2xx_pan_coord_set(const struct device *dev, bool pan_coordinator)
{
	uint8_t reg;

	if (pan_coordinator) {
		reg = rf2xx_iface_reg_read(dev, RF2XX_CSMA_SEED_1_REG);
		reg |= (1 << RF2XX_AACK_I_AM_COORD);
		rf2xx_iface_reg_write(dev, RF2XX_CSMA_SEED_1_REG, reg);
	} else {
		reg = rf2xx_iface_reg_read(dev, RF2XX_CSMA_SEED_1_REG);
		reg &= ~(1 << RF2XX_AACK_I_AM_COORD);
		rf2xx_iface_reg_write(dev, RF2XX_CSMA_SEED_1_REG, reg);
	}

	return 0;
}

static int rf2xx_promiscuous_set(const struct device *dev, bool promiscuous)
{
	uint8_t reg;

	if (promiscuous) {
		reg = rf2xx_iface_reg_read(dev, RF2XX_XAH_CTRL_1_REG);
		reg |= (1 << RF2XX_AACK_PROM_MODE);
		rf2xx_iface_reg_write(dev, RF2XX_XAH_CTRL_1_REG, reg);

		reg = rf2xx_iface_reg_read(dev, RF2XX_CSMA_SEED_1_REG);
		reg |= (1 << RF2XX_AACK_DIS_ACK);
		rf2xx_iface_reg_write(dev, RF2XX_CSMA_SEED_1_REG, reg);
	} else {
		reg = rf2xx_iface_reg_read(dev, RF2XX_XAH_CTRL_1_REG);
		reg &= ~(1 << RF2XX_AACK_PROM_MODE);
		rf2xx_iface_reg_write(dev, RF2XX_XAH_CTRL_1_REG, reg);

		reg = rf2xx_iface_reg_read(dev, RF2XX_CSMA_SEED_1_REG);
		reg &= ~(1 << RF2XX_AACK_DIS_ACK);
		rf2xx_iface_reg_write(dev, RF2XX_CSMA_SEED_1_REG, reg);
	}

	return 0;
}

int rf2xx_configure(const struct device *dev,
		    enum ieee802154_config_type type,
		    const struct ieee802154_config *config)
{
	int ret = -EINVAL;

	LOG_DBG("Configure %d", type);

	switch (type) {
	case IEEE802154_CONFIG_AUTO_ACK_FPB:
	case IEEE802154_CONFIG_ACK_FPB:
		break;

	case IEEE802154_CONFIG_PAN_COORDINATOR:
		ret = rf2xx_pan_coord_set(dev, config->pan_coordinator);
		break;

	case IEEE802154_CONFIG_PROMISCUOUS:
		ret = rf2xx_promiscuous_set(dev, config->promiscuous);
		break;

	case IEEE802154_CONFIG_EVENT_HANDLER:
	default:
		break;
	}

	return ret;
}

uint16_t rf2xx_get_subgiga_channel_count(const struct device *dev)
{
	struct rf2xx_context *ctx = dev->data;

	return ctx->cc_page == RF2XX_TRX_CC_PAGE_5 ? 4 : 11;
}

static int power_on_and_setup(const struct device *dev)
{
	const struct rf2xx_config *conf = dev->config;
	struct rf2xx_context *ctx = dev->data;
	uint8_t config;

	rf2xx_iface_phy_rst(dev);

	/* Sync transceiver state */
	do {
		rf2xx_iface_reg_write(dev, RF2XX_TRX_STATE_REG,
				      RF2XX_TRX_PHY_STATE_CMD_TRX_OFF);
	} while (RF2XX_TRX_PHY_STATUS_TRX_OFF !=
		 (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATUS_REG) &
		  RF2XX_TRX_PHY_STATUS_MASK));

	/* get device identification */
	ctx->trx_model = rf2xx_iface_reg_read(dev, RF2XX_PART_NUM_REG);
	ctx->trx_version = rf2xx_iface_reg_read(dev, RF2XX_VERSION_NUM_REG);

	/**
	 * Valid transceiver are:
	 *  231-Rev-A (Version 0x02)
	 *  232-Rev-A (Version 0x02)
	 *  233-Rev-A (Version 0x01) (Warning)
	 *  233-Rev-B (Version 0x02)
	 */
	if (ctx->trx_model <= RF2XX_TRX_MODEL_230) {
		LOG_DBG("Invalid or not supported transceiver");
		return -ENODEV;
	}

	if (ctx->trx_model == RF2XX_TRX_MODEL_233 && ctx->trx_version == 0x01) {
		LOG_DBG("Transceiver is old and unstable release");
	}

	/* Set RSSI base */
	if (ctx->trx_model == RF2XX_TRX_MODEL_212) {
		ctx->trx_rssi_base = -100;
	} else if (ctx->trx_model == RF2XX_TRX_MODEL_233) {
		ctx->trx_rssi_base = -94;
	} else if (ctx->trx_model == RF2XX_TRX_MODEL_231) {
		ctx->trx_rssi_base = -91;
	} else {
		ctx->trx_rssi_base = -90;
	}

	/* Disable All Features of TRX_CTRL_0 */
	config = 0;
	rf2xx_iface_reg_write(dev, RF2XX_TRX_CTRL_0_REG, config);

	/* Configure PHY behaviour */
	config = (1 << RF2XX_TX_AUTO_CRC_ON) |
		 (3 << RF2XX_SPI_CMD_MODE) |
		 (1 << RF2XX_IRQ_MASK_MODE);
	rf2xx_iface_reg_write(dev, RF2XX_TRX_CTRL_1_REG, config);

	config = (1 << RF2XX_RX_SAFE_MODE);
	if (ctx->trx_model != RF2XX_TRX_MODEL_232) {
		config |= (1 << RF2XX_OQPSK_SCRAM_EN);
	}
	rf2xx_iface_reg_write(dev, RF2XX_TRX_CTRL_2_REG, config);

	if (ctx->trx_model == RF2XX_TRX_MODEL_212) {
		rf2xx_configure_trx_path(dev);
		rf2xx_iface_reg_write(dev, RF2XX_CC_CTRL_1_REG, 0);
	}

	ctx->tx_mode = IEEE802154_TX_MODE_CSMA_CA;

	/* Configure INT behaviour */
	config = (1 << RF2XX_RX_START) |
		 (1 << RF2XX_TRX_END);
	rf2xx_iface_reg_write(dev, RF2XX_IRQ_MASK_REG, config);

	gpio_init_callback(&ctx->irq_cb, trx_isr_handler,
			   BIT(conf->irq_gpio.pin));

	if (gpio_add_callback(conf->irq_gpio.port, &ctx->irq_cb) < 0) {
		LOG_ERR("Could not set IRQ callback.");
		return -ENXIO;
	}

	return 0;
}

static inline int configure_gpios(const struct device *dev)
{
	const struct rf2xx_config *conf = dev->config;

	/* Chip IRQ line */
	if (!device_is_ready(conf->irq_gpio.port)) {
		LOG_ERR("IRQ GPIO device not ready");
		return -ENODEV;
	}
	gpio_pin_configure_dt(&conf->irq_gpio, GPIO_INPUT);
	gpio_pin_interrupt_configure_dt(&conf->irq_gpio,
					GPIO_INT_EDGE_TO_ACTIVE);

	/* Chip RESET line */
	if (!device_is_ready(conf->reset_gpio.port)) {
		LOG_ERR("RESET GPIO device not ready");
		return -ENODEV;
	}
	gpio_pin_configure_dt(&conf->reset_gpio, GPIO_OUTPUT_INACTIVE);

	/* Chip SLPTR line */
	if (!device_is_ready(conf->slptr_gpio.port)) {
		LOG_ERR("SLPTR GPIO device not ready");
		return -ENODEV;
	}
	gpio_pin_configure_dt(&conf->slptr_gpio, GPIO_OUTPUT_INACTIVE);

	/* Chip DIG2 line (Optional feature) */
	if (conf->dig2_gpio.port != NULL) {
		if (!device_is_ready(conf->dig2_gpio.port)) {
			LOG_ERR("DIG2 GPIO device not ready");
			return -ENODEV;
		}
		LOG_INF("Optional instance of %s device activated",
			conf->dig2_gpio.port->name);
		gpio_pin_configure_dt(&conf->dig2_gpio, GPIO_INPUT);
		gpio_pin_interrupt_configure_dt(&conf->dig2_gpio,
						GPIO_INT_EDGE_TO_ACTIVE);
	}

	/* Chip CLKM line (Optional feature) */
	if (conf->clkm_gpio.port != NULL) {
		if (!device_is_ready(conf->clkm_gpio.port)) {
			LOG_ERR("CLKM GPIO device not ready");
			return -ENODEV;
		}
		LOG_INF("Optional instance of %s device activated",
			conf->clkm_gpio.port->name);
		gpio_pin_configure_dt(&conf->clkm_gpio, GPIO_INPUT);
	}

	return 0;
}

static inline int configure_spi(const struct device *dev)
{
	const struct rf2xx_config *conf = dev->config;

	if (!spi_is_ready_dt(&conf->spi)) {
		LOG_ERR("SPI bus %s is not ready",
			conf->spi.bus->name);
		return -ENODEV;
	}

	return 0;
}

static int rf2xx_init(const struct device *dev)
{
	struct rf2xx_context *ctx = dev->data;
	const struct rf2xx_config *conf = dev->config;
	char thread_name[20];

	LOG_DBG("\nInitialize RF2XX Transceiver\n");

	ctx->dev = dev;

	k_sem_init(&ctx->trx_tx_sync, 0, 1);
	k_sem_init(&ctx->trx_isr_lock, 0, 1);

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

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

	LOG_DBG("GPIO and SPI configured");

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

	LOG_DBG("RADIO configured");

	k_thread_create(&ctx->trx_thread,
			ctx->trx_stack,
			CONFIG_IEEE802154_RF2XX_RX_STACK_SIZE,
			(k_thread_entry_t) rf2xx_thread_main,
			ctx, NULL, NULL,
			K_PRIO_COOP(2), 0, K_NO_WAIT);

	snprintk(thread_name, sizeof(thread_name),
		 "rf2xx_trx [%d]", conf->inst);
	k_thread_name_set(&ctx->trx_thread, thread_name);

	LOG_DBG("Thread OK");

	return 0;
}

static void rf2xx_iface_init(struct net_if *iface)
{
	const struct device *dev = net_if_get_device(iface);
	struct rf2xx_context *ctx = dev->data;
	uint8_t *mac = get_mac(dev);

	net_if_set_link_addr(iface, mac, 8, NET_LINK_IEEE802154);

	ctx->iface = iface;

	ieee802154_init(iface);
}

static struct ieee802154_radio_api rf2xx_radio_api = {
	.iface_api.init		= rf2xx_iface_init,

	.get_capabilities	= rf2xx_get_capabilities,
	.cca			= rf2xx_cca,
	.set_channel		= rf2xx_set_channel,
	.filter			= rf2xx_filter,
	.set_txpower		= rf2xx_set_txpower,
	.tx			= rf2xx_tx,
	.start			= rf2xx_start,
	.stop			= rf2xx_stop,
	.configure		= rf2xx_configure,
	.get_subg_channel_count	= rf2xx_get_subgiga_channel_count,
};

#if !defined(CONFIG_IEEE802154_RAW_MODE)
    #if defined(CONFIG_NET_L2_IEEE802154)
	#define L2 IEEE802154_L2
	#define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(IEEE802154_L2)
	#define MTU RF2XX_MAX_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 RF2XX_OT_PSDU_LENGTH
    #endif
#endif /* CONFIG_IEEE802154_RAW_MODE */

#define DRV_INST_LOCAL_MAC_ADDRESS(n)					\
	UTIL_AND(DT_INST_NODE_HAS_PROP(n, local_mac_address),		\
		 UTIL_AND(DT_INST_PROP_LEN(n, local_mac_address) == 8,	\
			  DT_INST_PROP(n, local_mac_address)))

#define IEEE802154_RF2XX_DEVICE_CONFIG(n)				  \
	BUILD_ASSERT(DT_INST_PROP_LEN(n, tx_pwr_min) == 2,		  \
	"rf2xx: Error TX-PWR-MIN len is different of two");		  \
	BUILD_ASSERT(DT_INST_PROP_LEN(n, tx_pwr_max) == 2,		  \
	"rf2xx: Error TX-PWR-MAX len is different of two");		  \
	BUILD_ASSERT(DT_INST_PROP_LEN(n, tx_pwr_table) != 0,		  \
	"rf2xx: Error TX-PWR-TABLE len must be greater than zero");	  \
	static const uint8_t rf2xx_pwr_table_##n[] =			  \
		DT_INST_PROP_OR(n, tx_pwr_table, 0);			  \
	static const struct rf2xx_config rf2xx_ctx_config_##n = {	  \
		.inst = n,						  \
		.has_mac = DT_INST_NODE_HAS_PROP(n, local_mac_address),   \
		.irq_gpio = GPIO_DT_SPEC_INST_GET(n, irq_gpios),	  \
		.reset_gpio = GPIO_DT_SPEC_INST_GET(n, reset_gpios),	  \
		.slptr_gpio = GPIO_DT_SPEC_INST_GET(n, slptr_gpios),	  \
		.dig2_gpio = GPIO_DT_SPEC_INST_GET_OR(n, dig2_gpios, {}), \
		.clkm_gpio = GPIO_DT_SPEC_INST_GET_OR(n, clkm_gpios, {}), \
		.spi = SPI_DT_SPEC_INST_GET(n, SPI_WORD_SET(8) |	  \
				 SPI_TRANSFER_MSB, 0),			  \
									  \
		.tx_pwr_min = DT_INST_PROP_OR(n, tx_pwr_min, 0),	  \
		.tx_pwr_max = DT_INST_PROP_OR(n, tx_pwr_max, 0),	  \
		.tx_pwr_table = rf2xx_pwr_table_##n,			  \
		.tx_pwr_table_size = DT_INST_PROP_LEN(n, tx_pwr_table),	  \
	}

#define IEEE802154_RF2XX_DEVICE_DATA(n)                                 \
	static struct rf2xx_context rf2xx_ctx_data_##n = {              \
		.mac_addr = { DRV_INST_LOCAL_MAC_ADDRESS(n) },          \
		.cc_page = DT_INST_ENUM_IDX_OR(n, channel_page, 0),	\
	}

#define IEEE802154_RF2XX_RAW_DEVICE_INIT(n)	   \
	DEVICE_DT_INST_DEFINE(			   \
		n,				   \
		&rf2xx_init,			   \
		NULL,				   \
		&rf2xx_ctx_data_##n,		   \
		&rf2xx_ctx_config_##n,		   \
		POST_KERNEL,			   \
		CONFIG_IEEE802154_RF2XX_INIT_PRIO, \
		&rf2xx_radio_api)

#define IEEE802154_RF2XX_NET_DEVICE_INIT(n)	   \
	NET_DEVICE_DT_INST_DEFINE(		   \
		n,				   \
		&rf2xx_init,			   \
		NULL,				   \
		&rf2xx_ctx_data_##n,		   \
		&rf2xx_ctx_config_##n,		   \
		CONFIG_IEEE802154_RF2XX_INIT_PRIO, \
		&rf2xx_radio_api,		   \
		L2,				   \
		L2_CTX_TYPE,			   \
		MTU)

#define IEEE802154_RF2XX_INIT(inst)				\
	IEEE802154_RF2XX_DEVICE_CONFIG(inst);			\
	IEEE802154_RF2XX_DEVICE_DATA(inst);			\
								\
	COND_CODE_1(CONFIG_IEEE802154_RAW_MODE,			\
		    (IEEE802154_RF2XX_RAW_DEVICE_INIT(inst);),	\
		    (IEEE802154_RF2XX_NET_DEVICE_INIT(inst);))

DT_INST_FOREACH_STATUS_OKAY(IEEE802154_RF2XX_INIT)
