/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 *   This file implements the OpenThread platform abstraction
 *   for radio communication.
 *
 */

#define LOG_MODULE_NAME net_otPlat_radio

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

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/net/ieee802154_radio.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/net_time.h>
#include <zephyr/sys/__assert.h>

#include <openthread/ip6.h>
#include <openthread-system.h>
#include <openthread/instance.h>
#include <openthread/platform/radio.h>
#include <openthread/platform/diag.h>
#include <openthread/platform/time.h>
#include <openthread/message.h>

#include "platform-zephyr.h"

#define SHORT_ADDRESS_SIZE 2

#define FCS_SIZE     2
#if defined(CONFIG_OPENTHREAD_THREAD_VERSION_1_1)
#define ACK_PKT_LENGTH 5
#else
#define ACK_PKT_LENGTH 127
#endif

#define FRAME_TYPE_MASK 0x07
#define FRAME_TYPE_ACK 0x02

#if defined(CONFIG_NET_TC_THREAD_COOPERATIVE)
#define OT_WORKER_PRIORITY K_PRIO_COOP(CONFIG_OPENTHREAD_THREAD_PRIORITY)
#else
#define OT_WORKER_PRIORITY K_PRIO_PREEMPT(CONFIG_OPENTHREAD_THREAD_PRIORITY)
#endif

#define CHANNEL_COUNT OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX - OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN + 1

/* PHY header duration in us (i.e. 2 symbol periods @ 62.5k symbol rate), see
 * IEEE 802.15.4, sections 12.1.3.1, 12.2.5 and 12.3.3.
 */
#define PHR_DURATION_US 32U

#define DEFAULT_SENSITIVITY -100

enum pending_events {
	PENDING_EVENT_FRAME_TO_SEND, /* There is a tx frame to send  */
	PENDING_EVENT_FRAME_RECEIVED, /* Radio has received new frame */
	PENDING_EVENT_RX_FAILED, /* The RX failed */
	PENDING_EVENT_TX_STARTED, /* Radio has started transmitting */
	PENDING_EVENT_TX_DONE, /* Radio transmission finished */
	PENDING_EVENT_DETECT_ENERGY, /* Requested to start Energy Detection procedure */
	PENDING_EVENT_DETECT_ENERGY_DONE, /* Energy Detection finished */
	PENDING_EVENT_SLEEP, /* Sleep if idle */
	PENDING_EVENT_COUNT /* Keep last */
};

K_SEM_DEFINE(radio_sem, 0, 1);

static otRadioState sState = OT_RADIO_STATE_DISABLED;

static otRadioFrame sTransmitFrame;
static otRadioFrame ack_frame;
static uint8_t ack_psdu[ACK_PKT_LENGTH];

static struct net_pkt *tx_pkt;
static struct net_buf *tx_payload;

static const struct device *const radio_dev =
	DEVICE_DT_GET(DT_CHOSEN(zephyr_ieee802154));
static struct ieee802154_radio_api *radio_api;

/* Get the default tx output power from Kconfig */
static int8_t tx_power = CONFIG_OPENTHREAD_DEFAULT_TX_POWER;
static uint16_t channel;
static bool promiscuous;

static uint16_t energy_detection_time;
static uint8_t energy_detection_channel;
static int16_t energy_detected_value;

static int8_t max_tx_power_table[CHANNEL_COUNT];

ATOMIC_DEFINE(pending_events, PENDING_EVENT_COUNT);
K_KERNEL_STACK_DEFINE(ot_task_stack,
		      CONFIG_OPENTHREAD_RADIO_WORKQUEUE_STACK_SIZE);
static struct k_work_q ot_work_q;
static otError rx_result;
static otError tx_result;

K_FIFO_DEFINE(rx_pkt_fifo);
K_FIFO_DEFINE(tx_pkt_fifo);

static int8_t get_transmit_power_for_channel(uint8_t aChannel)
{
	int8_t channel_max_power = OT_RADIO_POWER_INVALID;
	int8_t power = 0; /* 0 dbm as default value */

	if (aChannel >= OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN &&
	    aChannel <= OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX) {
		channel_max_power =
			max_tx_power_table[aChannel - OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN];
	}

	if (tx_power != OT_RADIO_POWER_INVALID) {
		power = (channel_max_power < tx_power) ? channel_max_power : tx_power;
	} else if (channel_max_power != OT_RADIO_POWER_INVALID) {
		power = channel_max_power;
	}

	return power;
}

static inline bool is_pending_event_set(enum pending_events event)
{
	return atomic_test_bit(pending_events, event);
}

static void set_pending_event(enum pending_events event)
{
	atomic_set_bit(pending_events, event);
	otSysEventSignalPending();
}

static void reset_pending_event(enum pending_events event)
{
	atomic_clear_bit(pending_events, event);
}

static inline void clear_pending_events(void)
{
	atomic_clear(pending_events);
}

void energy_detected(const struct device *dev, int16_t max_ed)
{
	if (dev == radio_dev) {
		energy_detected_value = max_ed;
		set_pending_event(PENDING_EVENT_DETECT_ENERGY_DONE);
	}
}

enum net_verdict ieee802154_handle_ack(struct net_if *iface, struct net_pkt *pkt)
{
	ARG_UNUSED(iface);

	size_t ack_len = net_pkt_get_len(pkt);

	if (ack_len > ACK_PKT_LENGTH) {
		return NET_CONTINUE;
	}

	if ((*net_pkt_data(pkt) & FRAME_TYPE_MASK) != FRAME_TYPE_ACK) {
		return NET_CONTINUE;
	}

	if (ack_frame.mLength != 0) {
		LOG_ERR("Overwriting unhandled ACK frame.");
	}

	if (net_pkt_read(pkt, ack_psdu, ack_len) < 0) {
		LOG_ERR("Failed to read ACK frame.");
		return NET_CONTINUE;
	}

	ack_frame.mPsdu = ack_psdu;
	ack_frame.mLength = ack_len;
	ack_frame.mInfo.mRxInfo.mLqi = net_pkt_ieee802154_lqi(pkt);
	ack_frame.mInfo.mRxInfo.mRssi = net_pkt_ieee802154_rssi_dbm(pkt);

#if defined(CONFIG_NET_PKT_TIMESTAMP)
	ack_frame.mInfo.mRxInfo.mTimestamp = net_pkt_timestamp_ns(pkt) / NSEC_PER_USEC;
#endif

	return NET_OK;
}

void handle_radio_event(const struct device *dev, enum ieee802154_event evt,
			void *event_params)
{
	ARG_UNUSED(event_params);

	switch (evt) {
	case IEEE802154_EVENT_TX_STARTED:
		if (sState == OT_RADIO_STATE_TRANSMIT) {
			set_pending_event(PENDING_EVENT_TX_STARTED);
		}
		break;
	case IEEE802154_EVENT_RX_FAILED:
		if (sState == OT_RADIO_STATE_RECEIVE) {
			switch (*(enum ieee802154_rx_fail_reason *) event_params) {
			case IEEE802154_RX_FAIL_NOT_RECEIVED:
				rx_result = OT_ERROR_NO_FRAME_RECEIVED;
				break;

			case IEEE802154_RX_FAIL_INVALID_FCS:
				rx_result = OT_ERROR_FCS;
				break;

			case IEEE802154_RX_FAIL_ADDR_FILTERED:
				rx_result = OT_ERROR_DESTINATION_ADDRESS_FILTERED;
				break;

			case IEEE802154_RX_FAIL_OTHER:
			default:
				rx_result = OT_ERROR_FAILED;
				break;
			}
			set_pending_event(PENDING_EVENT_RX_FAILED);
		}
		break;
	case IEEE802154_EVENT_RX_OFF:
		set_pending_event(PENDING_EVENT_SLEEP);
		break;
	default:
		/* do nothing - ignore event */
		break;
	}
}

#if defined(CONFIG_NET_PKT_TXTIME) || defined(CONFIG_OPENTHREAD_CSL_RECEIVER)
/**
 * @brief Convert 32-bit (potentially wrapped) OpenThread microsecond timestamps
 * to 64-bit Zephyr network subsystem nanosecond timestamps.
 *
 * This is a workaround until OpenThread is able to schedule 64-bit RX/TX time.
 *
 * @param target_time_ns_wrapped time in nanoseconds referred to the radio clock
 * modulo UINT32_MAX.
 *
 * @return 64-bit nanosecond timestamp
 */
static net_time_t convert_32bit_us_wrapped_to_64bit_ns(uint32_t target_time_us_wrapped)
{
	/**
	 * OpenThread provides target time as a (potentially wrapped) 32-bit
	 * integer defining a moment in time in the microsecond domain.
	 *
	 * The target time can point to a moment in the future, but can be
	 * overdue as well. In order to determine what's the case and correctly
	 * set the absolute (non-wrapped) target time, it's necessary to compare
	 * the least significant 32 bits of the current 64-bit network subsystem
	 * time with the provided 32-bit target time. Let's assume that half of
	 * the 32-bit range can be used for specifying target times in the
	 * future, and the other half - in the past.
	 */
	uint64_t now_us = otPlatTimeGet();
	uint32_t now_us_wrapped = (uint32_t)now_us;
	uint32_t time_diff = target_time_us_wrapped - now_us_wrapped;
	uint64_t result = UINT64_C(0);

	if (time_diff < 0x80000000) {
		/**
		 * Target time is assumed to be in the future. Check if a 32-bit overflow
		 * occurs between the current time and the target time.
		 */
		if (now_us_wrapped > target_time_us_wrapped) {
			/**
			 * Add a 32-bit overflow and replace the least significant 32 bits
			 * with the provided target time.
			 */
			result = now_us + UINT32_MAX + 1;
			result &= ~(uint64_t)UINT32_MAX;
			result |= target_time_us_wrapped;
		} else {
			/**
			 * Leave the most significant 32 bits and replace the least significant
			 * 32 bits with the provided target time.
			 */
			result = (now_us & (~(uint64_t)UINT32_MAX)) | target_time_us_wrapped;
		}
	} else {
		/**
		 * Target time is assumed to be in the past. Check if a 32-bit overflow
		 * occurs between the target time and the current time.
		 */
		if (now_us_wrapped > target_time_us_wrapped) {
			/**
			 * Leave the most significant 32 bits and replace the least significant
			 * 32 bits with the provided target time.
			 */
			result = (now_us & (~(uint64_t)UINT32_MAX)) | target_time_us_wrapped;
		} else {
			/**
			 * Subtract a 32-bit overflow and replace the least significant
			 * 32 bits with the provided target time.
			 */
			result = now_us - UINT32_MAX - 1;
			result &= ~(uint64_t)UINT32_MAX;
			result |= target_time_us_wrapped;
		}
	}

	__ASSERT_NO_MSG(result <= INT64_MAX / NSEC_PER_USEC);
	return (net_time_t)result * NSEC_PER_USEC;
}
#endif /* CONFIG_NET_PKT_TXTIME || CONFIG_OPENTHREAD_CSL_RECEIVER */

static void dataInit(void)
{
	tx_pkt = net_pkt_alloc(K_NO_WAIT);
	__ASSERT_NO_MSG(tx_pkt != NULL);

	tx_payload = net_pkt_get_reserve_tx_data(IEEE802154_MAX_PHY_PACKET_SIZE,
						 K_NO_WAIT);
	__ASSERT_NO_MSG(tx_payload != NULL);

	net_pkt_append_buffer(tx_pkt, tx_payload);

	sTransmitFrame.mPsdu = tx_payload->data;

	for (size_t i = 0; i < CHANNEL_COUNT; i++) {
		max_tx_power_table[i] = OT_RADIO_POWER_INVALID;
	}
}

void platformRadioInit(void)
{
	struct ieee802154_config cfg;

	dataInit();

	__ASSERT_NO_MSG(device_is_ready(radio_dev));

	radio_api = (struct ieee802154_radio_api *)radio_dev->api;
	if (!radio_api) {
		return;
	}

	k_work_queue_start(&ot_work_q, ot_task_stack,
			   K_KERNEL_STACK_SIZEOF(ot_task_stack),
			   OT_WORKER_PRIORITY, NULL);
	k_thread_name_set(&ot_work_q.thread, "ot_radio_workq");

	if ((radio_api->get_capabilities(radio_dev) &
	     IEEE802154_HW_TX_RX_ACK) != IEEE802154_HW_TX_RX_ACK) {
		LOG_ERR("Only radios with automatic ack handling "
			"are currently supported");
		k_panic();
	}

	cfg.event_handler = handle_radio_event;
	radio_api->configure(radio_dev, IEEE802154_CONFIG_EVENT_HANDLER, &cfg);
}

void transmit_message(struct k_work *tx_job)
{
	int tx_err;

	ARG_UNUSED(tx_job);

	/*
	 * The payload is already in tx_payload->data,
	 * but we need to set the length field
	 * according to sTransmitFrame.length.
	 * We subtract the FCS size as radio driver
	 * adds CRC and increases frame length on its own.
	 */
	tx_payload->len = sTransmitFrame.mLength - FCS_SIZE;

	channel = sTransmitFrame.mChannel;

	radio_api->set_channel(radio_dev, channel);
	radio_api->set_txpower(radio_dev, get_transmit_power_for_channel(channel));

	net_pkt_set_ieee802154_frame_secured(tx_pkt,
					     sTransmitFrame.mInfo.mTxInfo.mIsSecurityProcessed);
	net_pkt_set_ieee802154_mac_hdr_rdy(tx_pkt, sTransmitFrame.mInfo.mTxInfo.mIsHeaderUpdated);

	if ((radio_api->get_capabilities(radio_dev) & IEEE802154_HW_TXTIME) &&
	    (sTransmitFrame.mInfo.mTxInfo.mTxDelay != 0)) {
#if defined(CONFIG_NET_PKT_TXTIME)
		uint32_t tx_at = sTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime +
				 sTransmitFrame.mInfo.mTxInfo.mTxDelay;
		net_pkt_set_timestamp_ns(tx_pkt, convert_32bit_us_wrapped_to_64bit_ns(tx_at));
#endif
		tx_err =
			radio_api->tx(radio_dev, IEEE802154_TX_MODE_TXTIME_CCA, tx_pkt, tx_payload);
	} else if (sTransmitFrame.mInfo.mTxInfo.mCsmaCaEnabled) {
		if (radio_api->get_capabilities(radio_dev) & IEEE802154_HW_CSMA) {
			tx_err = radio_api->tx(radio_dev, IEEE802154_TX_MODE_CSMA_CA, tx_pkt,
					       tx_payload);
		} else {
			tx_err = radio_api->cca(radio_dev);
			if (tx_err == 0) {
				tx_err = radio_api->tx(radio_dev, IEEE802154_TX_MODE_DIRECT, tx_pkt,
						       tx_payload);
			}
		}
	} else {
		tx_err = radio_api->tx(radio_dev, IEEE802154_TX_MODE_DIRECT, tx_pkt, tx_payload);
	}

	/*
	 * OpenThread handles the following errors:
	 * - OT_ERROR_NONE
	 * - OT_ERROR_NO_ACK
	 * - OT_ERROR_CHANNEL_ACCESS_FAILURE
	 * - OT_ERROR_ABORT
	 * Any other error passed to `otPlatRadioTxDone` will result in assertion.
	 */
	switch (tx_err) {
	case 0:
		tx_result = OT_ERROR_NONE;
		break;
	case -ENOMSG:
		tx_result = OT_ERROR_NO_ACK;
		break;
	case -EBUSY:
		tx_result = OT_ERROR_CHANNEL_ACCESS_FAILURE;
		break;
	case -EIO:
		tx_result = OT_ERROR_ABORT;
		break;
	default:
		tx_result = OT_ERROR_CHANNEL_ACCESS_FAILURE;
		break;
	}

	set_pending_event(PENDING_EVENT_TX_DONE);
}

static inline void handle_tx_done(otInstance *aInstance)
{
	sTransmitFrame.mInfo.mTxInfo.mIsSecurityProcessed =
		net_pkt_ieee802154_frame_secured(tx_pkt);
	sTransmitFrame.mInfo.mTxInfo.mIsHeaderUpdated = net_pkt_ieee802154_mac_hdr_rdy(tx_pkt);

	if (IS_ENABLED(CONFIG_OPENTHREAD_DIAG) && otPlatDiagModeGet()) {
		otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, tx_result);
	} else {
		otPlatRadioTxDone(aInstance, &sTransmitFrame, ack_frame.mLength ? &ack_frame : NULL,
				  tx_result);
		ack_frame.mLength = 0;
	}
}

static void openthread_handle_received_frame(otInstance *instance,
					     struct net_pkt *pkt)
{
	otRadioFrame recv_frame;
	memset(&recv_frame, 0, sizeof(otRadioFrame));

	recv_frame.mPsdu = net_buf_frag_last(pkt->buffer)->data;
	/* Length inc. CRC. */
	recv_frame.mLength = net_buf_frags_len(pkt->buffer);
	recv_frame.mChannel = platformRadioChannelGet(instance);
	recv_frame.mInfo.mRxInfo.mLqi = net_pkt_ieee802154_lqi(pkt);
	recv_frame.mInfo.mRxInfo.mRssi = net_pkt_ieee802154_rssi_dbm(pkt);
	recv_frame.mInfo.mRxInfo.mAckedWithFramePending = net_pkt_ieee802154_ack_fpb(pkt);

#if defined(CONFIG_NET_PKT_TIMESTAMP)
	recv_frame.mInfo.mRxInfo.mTimestamp = net_pkt_timestamp_ns(pkt) / NSEC_PER_USEC;
#endif

	recv_frame.mInfo.mRxInfo.mAckedWithSecEnhAck = net_pkt_ieee802154_ack_seb(pkt);
	recv_frame.mInfo.mRxInfo.mAckFrameCounter = net_pkt_ieee802154_ack_fc(pkt);
	recv_frame.mInfo.mRxInfo.mAckKeyId = net_pkt_ieee802154_ack_keyid(pkt);

	if (IS_ENABLED(CONFIG_OPENTHREAD_DIAG) && otPlatDiagModeGet()) {
		otPlatDiagRadioReceiveDone(instance, &recv_frame, OT_ERROR_NONE);
	} else {
		otPlatRadioReceiveDone(instance, &recv_frame, OT_ERROR_NONE);
	}

	net_pkt_unref(pkt);
}

static void openthread_handle_frame_to_send(otInstance *instance,
					    struct net_pkt *pkt)
{
	struct net_buf *buf;
	otMessage *message;
	otMessageSettings settings;

	NET_DBG("Sending Ip6 packet to ot stack");

	settings.mPriority = OT_MESSAGE_PRIORITY_NORMAL;
	settings.mLinkSecurityEnabled = true;
	message = otIp6NewMessage(instance, &settings);
	if (message == NULL) {
		goto exit;
	}

	for (buf = pkt->buffer; buf; buf = buf->frags) {
		if (otMessageAppend(message, buf->data, buf->len) != OT_ERROR_NONE) {
			NET_ERR("Error while appending to otMessage");
			otMessageFree(message);
			goto exit;
		}
	}

	if (otIp6Send(instance, message) != OT_ERROR_NONE) {
		NET_ERR("Error while calling otIp6Send");
		goto exit;
	}

exit:
	net_pkt_unref(pkt);
}

int notify_new_rx_frame(struct net_pkt *pkt)
{
	k_fifo_put(&rx_pkt_fifo, pkt);
	set_pending_event(PENDING_EVENT_FRAME_RECEIVED);

	return 0;
}

int notify_new_tx_frame(struct net_pkt *pkt)
{
	k_fifo_put(&tx_pkt_fifo, pkt);
	set_pending_event(PENDING_EVENT_FRAME_TO_SEND);

	return 0;
}

static int run_tx_task(otInstance *aInstance)
{
	static K_WORK_DEFINE(tx_job, transmit_message);

	ARG_UNUSED(aInstance);

	if (!k_work_is_pending(&tx_job)) {
		sState = OT_RADIO_STATE_TRANSMIT;

		k_work_submit_to_queue(&ot_work_q, &tx_job);
		return 0;
	} else {
		return -EBUSY;
	}
}

void platformRadioProcess(otInstance *aInstance)
{
	bool event_pending = false;

	if (is_pending_event_set(PENDING_EVENT_FRAME_TO_SEND)) {
		struct net_pkt *evt_pkt;

		reset_pending_event(PENDING_EVENT_FRAME_TO_SEND);
		while ((evt_pkt = (struct net_pkt *) k_fifo_get(&tx_pkt_fifo, K_NO_WAIT)) != NULL) {
			if (IS_ENABLED(CONFIG_OPENTHREAD_COPROCESSOR_RCP)) {
				net_pkt_unref(evt_pkt);
			} else {
				openthread_handle_frame_to_send(aInstance, evt_pkt);
			}
		}
	}

	if (is_pending_event_set(PENDING_EVENT_FRAME_RECEIVED)) {
		struct net_pkt *rx_pkt;

		reset_pending_event(PENDING_EVENT_FRAME_RECEIVED);
		while ((rx_pkt = (struct net_pkt *) k_fifo_get(&rx_pkt_fifo, K_NO_WAIT)) != NULL) {
			openthread_handle_received_frame(aInstance, rx_pkt);
		}
	}

	if (is_pending_event_set(PENDING_EVENT_RX_FAILED)) {
		reset_pending_event(PENDING_EVENT_RX_FAILED);
		if (IS_ENABLED(CONFIG_OPENTHREAD_DIAG) && otPlatDiagModeGet()) {
			otPlatDiagRadioReceiveDone(aInstance, NULL, rx_result);
		} else {
			otPlatRadioReceiveDone(aInstance, NULL, rx_result);
		}
	}

	if (is_pending_event_set(PENDING_EVENT_TX_STARTED)) {
		reset_pending_event(PENDING_EVENT_TX_STARTED);
		otPlatRadioTxStarted(aInstance, &sTransmitFrame);
	}

	if (is_pending_event_set(PENDING_EVENT_TX_DONE)) {
		reset_pending_event(PENDING_EVENT_TX_DONE);

		if (sState == OT_RADIO_STATE_TRANSMIT ||
		    radio_api->get_capabilities(radio_dev) & IEEE802154_HW_SLEEP_TO_TX) {
			sState = OT_RADIO_STATE_RECEIVE;
			handle_tx_done(aInstance);
		}
	}

	if (is_pending_event_set(PENDING_EVENT_SLEEP)) {
		reset_pending_event(PENDING_EVENT_SLEEP);
		ARG_UNUSED(otPlatRadioSleep(aInstance));
	}

	/* handle events that can't run during transmission */
	if (sState != OT_RADIO_STATE_TRANSMIT) {
		if (is_pending_event_set(PENDING_EVENT_DETECT_ENERGY)) {
			radio_api->set_channel(radio_dev,
					       energy_detection_channel);

			if (!radio_api->ed_scan(radio_dev,
						energy_detection_time,
						energy_detected)) {
				reset_pending_event(
					PENDING_EVENT_DETECT_ENERGY);
			} else {
				event_pending = true;
			}
		}

		if (is_pending_event_set(PENDING_EVENT_DETECT_ENERGY_DONE)) {
			otPlatRadioEnergyScanDone(aInstance, (int8_t) energy_detected_value);
			reset_pending_event(PENDING_EVENT_DETECT_ENERGY_DONE);
		}
	}

	if (event_pending) {
		otSysEventSignalPending();
	}
}

uint16_t platformRadioChannelGet(otInstance *aInstance)
{
	ARG_UNUSED(aInstance);

	return channel;
}

void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanId)
{
	ARG_UNUSED(aInstance);

	radio_api->filter(radio_dev, true, IEEE802154_FILTER_TYPE_PAN_ID,
			  (struct ieee802154_filter *) &aPanId);
}

void otPlatRadioSetExtendedAddress(otInstance *aInstance,
				   const otExtAddress *aExtAddress)
{
	ARG_UNUSED(aInstance);

	radio_api->filter(radio_dev, true, IEEE802154_FILTER_TYPE_IEEE_ADDR,
			  (struct ieee802154_filter *) &aExtAddress);
}

void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aShortAddress)
{
	ARG_UNUSED(aInstance);

	radio_api->filter(radio_dev, true, IEEE802154_FILTER_TYPE_SHORT_ADDR,
			  (struct ieee802154_filter *) &aShortAddress);
}

bool otPlatRadioIsEnabled(otInstance *aInstance)
{
	ARG_UNUSED(aInstance);

	return (sState != OT_RADIO_STATE_DISABLED) ? true : false;
}

otError otPlatRadioEnable(otInstance *aInstance)
{
	if (!otPlatRadioIsEnabled(aInstance)) {
		sState = OT_RADIO_STATE_SLEEP;
	}

	return OT_ERROR_NONE;
}

otError otPlatRadioDisable(otInstance *aInstance)
{
	if (otPlatRadioIsEnabled(aInstance)) {
		sState = OT_RADIO_STATE_DISABLED;
	}

	return OT_ERROR_NONE;
}

otError otPlatRadioSleep(otInstance *aInstance)
{
	ARG_UNUSED(aInstance);

	otError error = OT_ERROR_INVALID_STATE;

	if (sState == OT_RADIO_STATE_SLEEP ||
	    sState == OT_RADIO_STATE_RECEIVE ||
	    sState == OT_RADIO_STATE_TRANSMIT) {
		error = OT_ERROR_NONE;
		radio_api->stop(radio_dev);
		sState = OT_RADIO_STATE_SLEEP;
	}

	return error;
}

otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
{
	ARG_UNUSED(aInstance);

	channel = aChannel;

	radio_api->set_channel(radio_dev, aChannel);
	radio_api->set_txpower(radio_dev, get_transmit_power_for_channel(channel));
	radio_api->start(radio_dev);
	sState = OT_RADIO_STATE_RECEIVE;

	return OT_ERROR_NONE;
}

#if defined(CONFIG_OPENTHREAD_CSL_RECEIVER)
otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel,
			     uint32_t aStart, uint32_t aDuration)
{
	int result;

	ARG_UNUSED(aInstance);

	struct ieee802154_config config = {
		.rx_slot.channel = aChannel,
		.rx_slot.start = convert_32bit_us_wrapped_to_64bit_ns(aStart),
		.rx_slot.duration = (net_time_t)aDuration * NSEC_PER_USEC,
	};

	result = radio_api->configure(radio_dev, IEEE802154_CONFIG_RX_SLOT,
				      &config);

	return result ? OT_ERROR_FAILED : OT_ERROR_NONE;
}
#endif

otError platformRadioTransmitCarrier(otInstance *aInstance, bool aEnable)
{
	if (radio_api->continuous_carrier == NULL) {
		return OT_ERROR_NOT_IMPLEMENTED;
	}

	if ((aEnable) && (sState == OT_RADIO_STATE_RECEIVE)) {
		radio_api->set_txpower(radio_dev, get_transmit_power_for_channel(channel));

		if (radio_api->continuous_carrier(radio_dev) != 0) {
			return OT_ERROR_FAILED;
		}

		sState = OT_RADIO_STATE_TRANSMIT;
	} else if ((!aEnable) && (sState == OT_RADIO_STATE_TRANSMIT)) {
		return otPlatRadioReceive(aInstance, channel);
	} else {
		return OT_ERROR_INVALID_STATE;
	}

	return OT_ERROR_NONE;
}

otRadioState otPlatRadioGetState(otInstance *aInstance)
{
	ARG_UNUSED(aInstance);

	return sState;
}

otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aPacket)
{
	otError error = OT_ERROR_INVALID_STATE;

	ARG_UNUSED(aInstance);
	ARG_UNUSED(aPacket);

	__ASSERT_NO_MSG(aPacket == &sTransmitFrame);

	enum ieee802154_hw_caps radio_caps;

	radio_caps = radio_api->get_capabilities(radio_dev);

	if ((sState == OT_RADIO_STATE_RECEIVE) || (radio_caps & IEEE802154_HW_SLEEP_TO_TX)) {
		if (run_tx_task(aInstance) == 0) {
			error = OT_ERROR_NONE;
		}
	}

	return error;
}

otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
{
	ARG_UNUSED(aInstance);

	return &sTransmitFrame;
}

static void get_rssi_energy_detected(const struct device *dev, int16_t max_ed)
{
	ARG_UNUSED(dev);
	energy_detected_value = max_ed;
	k_sem_give(&radio_sem);
}

int8_t otPlatRadioGetRssi(otInstance *aInstance)
{
	int8_t ret_rssi = INT8_MAX;
	int error = 0;
	const uint16_t detection_time = 1;
	enum ieee802154_hw_caps radio_caps;
	ARG_UNUSED(aInstance);

	radio_caps = radio_api->get_capabilities(radio_dev);

	if (!(radio_caps & IEEE802154_HW_ENERGY_SCAN)) {
		/*
		 * TODO: No API in Zephyr to get the RSSI
		 * when IEEE802154_HW_ENERGY_SCAN is not available
		 */
		ret_rssi = 0;
	} else {
		/*
		 * Blocking implementation of get RSSI
		 * using no-blocking ed_scan
		 */
		error = radio_api->ed_scan(radio_dev, detection_time,
					   get_rssi_energy_detected);

		if (error == 0) {
			k_sem_take(&radio_sem, K_FOREVER);

			ret_rssi = (int8_t)energy_detected_value;
		}
	}

	return ret_rssi;
}

otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
{
	otRadioCaps caps = OT_RADIO_CAPS_NONE;

	enum ieee802154_hw_caps radio_caps;
	ARG_UNUSED(aInstance);
	__ASSERT(radio_api,
	    "platformRadioInit needs to be called prior to otPlatRadioGetCaps");

	radio_caps = radio_api->get_capabilities(radio_dev);

	if (radio_caps & IEEE802154_HW_ENERGY_SCAN) {
		caps |= OT_RADIO_CAPS_ENERGY_SCAN;
	}

	if (radio_caps & IEEE802154_HW_CSMA) {
		caps |= OT_RADIO_CAPS_CSMA_BACKOFF;
	}

	if (radio_caps & IEEE802154_HW_TX_RX_ACK) {
		caps |= OT_RADIO_CAPS_ACK_TIMEOUT;
	}

	if (radio_caps & IEEE802154_HW_SLEEP_TO_TX) {
		caps |= OT_RADIO_CAPS_SLEEP_TO_TX;
	}

#if !defined(CONFIG_OPENTHREAD_THREAD_VERSION_1_1)
	if (radio_caps & IEEE802154_HW_TX_SEC) {
		caps |= OT_RADIO_CAPS_TRANSMIT_SEC;
	}
#endif

#if defined(CONFIG_NET_PKT_TXTIME)
	if (radio_caps & IEEE802154_HW_TXTIME) {
		caps |= OT_RADIO_CAPS_TRANSMIT_TIMING;
	}
#endif

	if (radio_caps & IEEE802154_HW_RXTIME) {
		caps |= OT_RADIO_CAPS_RECEIVE_TIMING;
	}

	if (radio_caps & IEEE802154_RX_ON_WHEN_IDLE) {
		caps |= OT_RADIO_CAPS_RX_ON_WHEN_IDLE;
	}

	return caps;
}

void otPlatRadioSetRxOnWhenIdle(otInstance *aInstance, bool aRxOnWhenIdle)
{
	struct ieee802154_config config = {
		.rx_on_when_idle = aRxOnWhenIdle
	};

	ARG_UNUSED(aInstance);

	LOG_DBG("RxOnWhenIdle=%d", aRxOnWhenIdle ? 1 : 0);

	radio_api->configure(radio_dev, IEEE802154_CONFIG_RX_ON_WHEN_IDLE, &config);
}

bool otPlatRadioGetPromiscuous(otInstance *aInstance)
{
	ARG_UNUSED(aInstance);

	LOG_DBG("PromiscuousMode=%d", promiscuous ? 1 : 0);

	return promiscuous;
}

void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
{
	struct ieee802154_config config = {
		.promiscuous = aEnable
	};

	ARG_UNUSED(aInstance);

	LOG_DBG("PromiscuousMode=%d", aEnable ? 1 : 0);

	promiscuous = aEnable;
	/* TODO: Should check whether the radio driver actually supports
	 *       promiscuous mode, see net_if_l2(iface)->get_flags() and
	 *       ieee802154_radio_get_hw_capabilities(iface).
	 */
	radio_api->configure(radio_dev, IEEE802154_CONFIG_PROMISCUOUS, &config);
}

otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel,
			      uint16_t aScanDuration)
{
	energy_detection_time    = aScanDuration;
	energy_detection_channel = aScanChannel;

	if (radio_api->ed_scan == NULL) {
		return OT_ERROR_NOT_IMPLEMENTED;
	}

	reset_pending_event(PENDING_EVENT_DETECT_ENERGY);
	reset_pending_event(PENDING_EVENT_DETECT_ENERGY_DONE);

	radio_api->set_channel(radio_dev, aScanChannel);

	if (radio_api->ed_scan(radio_dev, energy_detection_time, energy_detected) != 0) {
		/*
		 * OpenThread API does not accept failure of this function,
		 * it can return 'No Error' or 'Not Implemented' error only.
		 * If ed_scan start failed event is set to schedule the scan at
		 * later time.
		 */
		LOG_ERR("Failed do start energy scan, scheduling for later");
		set_pending_event(PENDING_EVENT_DETECT_ENERGY);
	}

	return OT_ERROR_NONE;
}

otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance,
					       int8_t *aThreshold)
{
	OT_UNUSED_VARIABLE(aInstance);
	OT_UNUSED_VARIABLE(aThreshold);

	return OT_ERROR_NOT_IMPLEMENTED;
}

otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance,
					       int8_t aThreshold)
{
	OT_UNUSED_VARIABLE(aInstance);
	OT_UNUSED_VARIABLE(aThreshold);

	return OT_ERROR_NOT_IMPLEMENTED;
}

void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
{
	ARG_UNUSED(aInstance);

	struct ieee802154_config config = {
		.auto_ack_fpb.enabled = aEnable,
		.auto_ack_fpb.mode = IEEE802154_FPB_ADDR_MATCH_THREAD,
	};

	(void)radio_api->configure(radio_dev, IEEE802154_CONFIG_AUTO_ACK_FPB,
				   &config);
}

otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance,
					 const uint16_t aShortAddress)
{
	ARG_UNUSED(aInstance);

	uint8_t short_address[SHORT_ADDRESS_SIZE];
	struct ieee802154_config config = {
		.ack_fpb.enabled = true,
		.ack_fpb.addr = short_address,
		.ack_fpb.extended = false
	};

	sys_put_le16(aShortAddress, short_address);

	if (radio_api->configure(radio_dev, IEEE802154_CONFIG_ACK_FPB,
				 &config) != 0) {
		return OT_ERROR_NO_BUFS;
	}

	return OT_ERROR_NONE;
}

otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance,
				       const otExtAddress *aExtAddress)
{
	ARG_UNUSED(aInstance);

	struct ieee802154_config config = {
		.ack_fpb.enabled = true,
		.ack_fpb.addr = (uint8_t *)aExtAddress->m8,
		.ack_fpb.extended = true
	};

	if (radio_api->configure(radio_dev, IEEE802154_CONFIG_ACK_FPB,
				 &config) != 0) {
		return OT_ERROR_NO_BUFS;
	}

	return OT_ERROR_NONE;
}

otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance,
					   const uint16_t aShortAddress)
{
	ARG_UNUSED(aInstance);

	uint8_t short_address[SHORT_ADDRESS_SIZE];
	struct ieee802154_config config = {
		.ack_fpb.enabled = false,
		.ack_fpb.addr = short_address,
		.ack_fpb.extended = false
	};

	sys_put_le16(aShortAddress, short_address);

	if (radio_api->configure(radio_dev, IEEE802154_CONFIG_ACK_FPB,
				 &config) != 0) {
		return OT_ERROR_NO_BUFS;
	}

	return OT_ERROR_NONE;
}

otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance,
					 const otExtAddress *aExtAddress)
{
	ARG_UNUSED(aInstance);

	struct ieee802154_config config = {
		.ack_fpb.enabled = false,
		.ack_fpb.addr = (uint8_t *)aExtAddress->m8,
		.ack_fpb.extended = true
	};

	if (radio_api->configure(radio_dev, IEEE802154_CONFIG_ACK_FPB,
				 &config) != 0) {
		return OT_ERROR_NO_BUFS;
	}

	return OT_ERROR_NONE;
}

void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
{
	ARG_UNUSED(aInstance);

	struct ieee802154_config config = {
		.ack_fpb.enabled = false,
		.ack_fpb.addr = NULL,
		.ack_fpb.extended = false
	};

	(void)radio_api->configure(radio_dev, IEEE802154_CONFIG_ACK_FPB,
				   &config);
}

void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
{
	ARG_UNUSED(aInstance);

	struct ieee802154_config config = {
		.ack_fpb.enabled = false,
		.ack_fpb.addr = NULL,
		.ack_fpb.extended = true
	};

	(void)radio_api->configure(radio_dev, IEEE802154_CONFIG_ACK_FPB,
				   &config);
}

int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
	ARG_UNUSED(aInstance);

	return DEFAULT_SENSITIVITY;
}

otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
{
	ARG_UNUSED(aInstance);

	if (aPower == NULL) {
		return OT_ERROR_INVALID_ARGS;
	}

	*aPower = tx_power;

	return OT_ERROR_NONE;
}

otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
{
	ARG_UNUSED(aInstance);

	tx_power = aPower;

	return OT_ERROR_NONE;
}

uint64_t otPlatTimeGet(void)
{
	if (radio_api == NULL || radio_api->get_time == NULL) {
		return k_ticks_to_us_floor64(k_uptime_ticks());
	} else {
		return radio_api->get_time(radio_dev) / NSEC_PER_USEC;
	}
}

#if defined(CONFIG_NET_PKT_TXTIME)
uint64_t otPlatRadioGetNow(otInstance *aInstance)
{
	ARG_UNUSED(aInstance);

	return otPlatTimeGet();
}
#endif

#if !defined(CONFIG_OPENTHREAD_THREAD_VERSION_1_1)
void otPlatRadioSetMacKey(otInstance *aInstance, uint8_t aKeyIdMode, uint8_t aKeyId,
			  const otMacKeyMaterial *aPrevKey, const otMacKeyMaterial *aCurrKey,
			  const otMacKeyMaterial *aNextKey, otRadioKeyType aKeyType)
{
	ARG_UNUSED(aInstance);
	__ASSERT_NO_MSG(aPrevKey != NULL && aCurrKey != NULL && aNextKey != NULL);

#if defined(CONFIG_OPENTHREAD_PLATFORM_KEYS_EXPORTABLE_ENABLE)
	__ASSERT_NO_MSG(aKeyType == OT_KEY_TYPE_KEY_REF);
	size_t keyLen;
	otError error;

	error = otPlatCryptoExportKey(aPrevKey->mKeyMaterial.mKeyRef,
				      (uint8_t *)aPrevKey->mKeyMaterial.mKey.m8, OT_MAC_KEY_SIZE,
				      &keyLen);
	__ASSERT_NO_MSG(error == OT_ERROR_NONE);
	error = otPlatCryptoExportKey(aCurrKey->mKeyMaterial.mKeyRef,
				      (uint8_t *)aCurrKey->mKeyMaterial.mKey.m8, OT_MAC_KEY_SIZE,
				      &keyLen);
	__ASSERT_NO_MSG(error == OT_ERROR_NONE);
	error = otPlatCryptoExportKey(aNextKey->mKeyMaterial.mKeyRef,
				      (uint8_t *)aNextKey->mKeyMaterial.mKey.m8, OT_MAC_KEY_SIZE,
				      &keyLen);
	__ASSERT_NO_MSG(error == OT_ERROR_NONE);
#else
	__ASSERT_NO_MSG(aKeyType == OT_KEY_TYPE_LITERAL_KEY);
#endif

	uint8_t key_id_mode = aKeyIdMode >> 3;

	struct ieee802154_key keys[] = {
		{
			.key_id_mode = key_id_mode,
			.frame_counter_per_key = false,
		},
		{
			.key_id_mode = key_id_mode,
			.frame_counter_per_key = false,
		},
		{
			.key_id_mode = key_id_mode,
			.frame_counter_per_key = false,
		},
		{
			.key_value = NULL,
		},
	};

	struct ieee802154_key clear_keys[] = {
		{
			.key_value = NULL,
		},
	};

	if (key_id_mode == 1) {
		/* aKeyId in range: (1, 0x80) means valid keys */
		uint8_t prev_key_id = aKeyId == 1 ? 0x80 : aKeyId - 1;
		uint8_t next_key_id = aKeyId == 0x80 ? 1 : aKeyId + 1;

		keys[0].key_id = &prev_key_id;
		keys[0].key_value = (uint8_t *)aPrevKey->mKeyMaterial.mKey.m8;

		keys[1].key_id = &aKeyId;
		keys[1].key_value = (uint8_t *)aCurrKey->mKeyMaterial.mKey.m8;

		keys[2].key_id = &next_key_id;
		keys[2].key_value = (uint8_t *)aNextKey->mKeyMaterial.mKey.m8;
	} else {
		/* aKeyId == 0 is used only to clear keys for stack reset in RCP */
		__ASSERT_NO_MSG((key_id_mode == 0) && (aKeyId == 0));
	}

	struct ieee802154_config config = {
		.mac_keys = aKeyId == 0 ? clear_keys : keys,
	};

	(void)radio_api->configure(radio_dev, IEEE802154_CONFIG_MAC_KEYS,
				   &config);
}

void otPlatRadioSetMacFrameCounter(otInstance *aInstance,
				   uint32_t aMacFrameCounter)
{
	ARG_UNUSED(aInstance);

	struct ieee802154_config config = { .frame_counter = aMacFrameCounter };

	(void)radio_api->configure(radio_dev, IEEE802154_CONFIG_FRAME_COUNTER,
				   &config);
}

void otPlatRadioSetMacFrameCounterIfLarger(otInstance *aInstance, uint32_t aMacFrameCounter)
{
	ARG_UNUSED(aInstance);

	struct ieee802154_config config = { .frame_counter = aMacFrameCounter };
	(void)radio_api->configure(radio_dev, IEEE802154_CONFIG_FRAME_COUNTER_IF_LARGER,
				   &config);
}
#endif

#if defined(CONFIG_OPENTHREAD_CSL_RECEIVER)
otError otPlatRadioEnableCsl(otInstance *aInstance, uint32_t aCslPeriod, otShortAddress aShortAddr,
			     const otExtAddress *aExtAddr)
{
	struct ieee802154_config config = { 0 };
	int result;

	ARG_UNUSED(aInstance);

	/* Configure the CSL period first to give drivers a chance to validate
	 * the IE for consistency if they wish to.
	 */
	config.csl_period = aCslPeriod;
	result = radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_PERIOD, &config);
	if (result) {
		return OT_ERROR_FAILED;
	}
	config.ack_ie.short_addr = aShortAddr;
	config.ack_ie.ext_addr = aExtAddr != NULL ? aExtAddr->m8 : NULL;

	/* Configure the CSL IE. */
	if (aCslPeriod > 0) {
		uint8_t header_ie_buf[OT_IE_HEADER_SIZE + OT_CSL_IE_SIZE] = {
			CSL_IE_HEADER_BYTES_LO,
			CSL_IE_HEADER_BYTES_HI,
		};
		struct ieee802154_header_ie *header_ie =
			(struct ieee802154_header_ie *)header_ie_buf;

		/* Write CSL period and leave CSL phase empty as it will be
		 * injected on-the-fly by the driver.
		 */
		header_ie->content.csl.reduced.csl_period = sys_cpu_to_le16(aCslPeriod);
		config.ack_ie.header_ie = header_ie;
	} else {
		config.ack_ie.header_ie = NULL;
	}

	result = radio_api->configure(radio_dev, IEEE802154_CONFIG_ENH_ACK_HEADER_IE, &config);

	return result ? OT_ERROR_FAILED : OT_ERROR_NONE;
}

otError otPlatRadioResetCsl(otInstance *aInstance)
{
	struct ieee802154_config config = { 0 };
	int result;

	result = radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_PERIOD, &config);
	if (result) {
		return OT_ERROR_FAILED;
	}

	config.ack_ie.purge_ie = true;
	result = radio_api->configure(radio_dev, IEEE802154_CONFIG_ENH_ACK_HEADER_IE, &config);

	return result ? OT_ERROR_FAILED : OT_ERROR_NONE;
}

void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTime)
{
	ARG_UNUSED(aInstance);

	/* CSL sample time points to "start of MAC" while the expected RX time
	 * refers to "end of SFD".
	 */
	struct ieee802154_config config = {
		.expected_rx_time =
			convert_32bit_us_wrapped_to_64bit_ns(aCslSampleTime - PHR_DURATION_US),
	};

	(void)radio_api->configure(radio_dev, IEEE802154_CONFIG_EXPECTED_RX_TIME, &config);
}
#endif /* CONFIG_OPENTHREAD_CSL_RECEIVER */

uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance)
{
	ARG_UNUSED(aInstance);

	return radio_api->get_sch_acc(radio_dev);
}

#if defined(CONFIG_OPENTHREAD_PLATFORM_CSL_UNCERT)
uint8_t otPlatRadioGetCslUncertainty(otInstance *aInstance)
{
	ARG_UNUSED(aInstance);

	return CONFIG_OPENTHREAD_PLATFORM_CSL_UNCERT;
}
#endif

#if defined(CONFIG_OPENTHREAD_LINK_METRICS_SUBJECT)
/**
 * Header IE format - IEEE Std. 802.15.4-2015, 7.4.2.1 && 7.4.2.2
 *
 * +---------------------------------+----------------------+
 * | Length    | Element ID | Type=0 |      Vendor OUI      |
 * +-----------+------------+--------+----------------------+
 * |           Bytes: 0-1            |          2-4         |
 * +-----------+---------------------+----------------------+
 * | Bits: 0-6 |    7-14    |   15   | IE_VENDOR_THREAD_OUI |
 * +-----------+------------+--------+----------------------|
 *
 * Thread v1.2.1 Spec., 4.11.3.4.4.6
 * +---------------------------------+-------------------+------------------+
 * |                  Vendor Specific Information                           |
 * +---------------------------------+-------------------+------------------+
 * |                5                |         6         |   7 (optional)   |
 * +---------------------------------+-------------------+------------------+
 * | IE_VENDOR_THREAD_ACK_PROBING_ID | LINK_METRIC_TOKEN | LINK_METRIC_TOKEN|
 * |---------------------------------|-------------------|------------------|
 */
static void set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, uint8_t *ie_header)
{
	/* Vendor-specific IE identifier */
	const uint8_t ie_vendor_id = 0x00;
	/* Thread Vendor-specific ACK Probing IE subtype ID */
	const uint8_t ie_vendor_thread_ack_probing_id = 0x00;
	/* Thread Vendor-specific IE OUI */
	const uint32_t ie_vendor_thread_oui = 0xeab89b;
	/* Thread Vendor-specific ACK Probing IE RSSI value placeholder */
	const uint8_t ie_vendor_thread_rssi_token = 0x01;
	/* Thread Vendor-specific ACK Probing IE Link margin value placeholder */
	const uint8_t ie_vendor_thread_margin_token = 0x02;
	/* Thread Vendor-specific ACK Probing IE LQI value placeholder */
	const uint8_t ie_vendor_thread_lqi_token = 0x03;
	const uint8_t oui_size = 3;
	const uint8_t sub_type = 1;
	const uint8_t id_offset = 7;
	const uint16_t id_mask = 0x00ff << id_offset;
	const uint8_t type = 0x00;
	const uint8_t type_offset = 7;
	const uint8_t type_mask = 0x01 << type_offset;
	const uint8_t length_mask = 0x7f;
	uint8_t content_len;
	uint16_t element_id = 0x0000;
	uint8_t link_metrics_idx = 6;
	uint8_t link_metrics_data_len = (uint8_t)lqi + (uint8_t)link_margin + (uint8_t)rssi;

	__ASSERT(link_metrics_data_len <= 2, "Thread limits to 2 metrics at most");
	__ASSERT(ie_header, "Invalid argument");

	if (link_metrics_data_len == 0) {
		ie_header[0] = 0;
		return;
	}

	/* Set Element ID */
	element_id = (((uint16_t)ie_vendor_id) << id_offset) & id_mask;
	sys_put_le16(element_id, &ie_header[0]);

	/* Set Length - number of octets in content field. */
	content_len = oui_size + sub_type + link_metrics_data_len;
	ie_header[0] = (ie_header[0] & ~length_mask) | (content_len & length_mask);

	/* Set Type */
	ie_header[1] = (ie_header[1] & ~type_mask) | (type & type_mask);

	/* Set Vendor Oui */
	sys_put_le24(ie_vendor_thread_oui, &ie_header[2]);

	/* Set SubType */
	ie_header[5] = ie_vendor_thread_ack_probing_id;

	/* Set Link Metrics Tokens
	 * TODO: Thread requires the order of requested metrics by the Link Metrics Initiator
	 *       to be kept by the Link Metrics Subject in the ACKs.
	 */
	if (lqi) {
		ie_header[link_metrics_idx++] = ie_vendor_thread_lqi_token;
	}

	if (link_margin) {
		ie_header[link_metrics_idx++] = ie_vendor_thread_margin_token;
	}

	if (rssi) {
		ie_header[link_metrics_idx++] = ie_vendor_thread_rssi_token;
	}
}

otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance, otLinkMetrics aLinkMetrics,
					  const otShortAddress aShortAddress,
					  const otExtAddress *aExtAddress)
{
	struct ieee802154_config config = {
		.ack_ie.short_addr = aShortAddress,
		.ack_ie.ext_addr = aExtAddress->m8,
	};
	uint8_t header_ie_buf[OT_ACK_IE_MAX_SIZE];
	int result;

	ARG_UNUSED(aInstance);

	set_vendor_ie_header_lm(aLinkMetrics.mLqi, aLinkMetrics.mLinkMargin,
				aLinkMetrics.mRssi, header_ie_buf);
	config.ack_ie.header_ie = (struct ieee802154_header_ie *)header_ie_buf;
	result = radio_api->configure(radio_dev, IEEE802154_CONFIG_ENH_ACK_HEADER_IE, &config);

	return result ? OT_ERROR_FAILED : OT_ERROR_NONE;
}

#endif /* CONFIG_OPENTHREAD_LINK_METRICS_SUBJECT */

otError otPlatRadioSetChannelMaxTransmitPower(otInstance *aInstance, uint8_t aChannel,
					      int8_t aMaxPower)
{
	ARG_UNUSED(aInstance);

	if (aChannel < OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN ||
	    aChannel > OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX) {
		return OT_ERROR_INVALID_ARGS;
	}

	max_tx_power_table[aChannel - OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN] = aMaxPower;

	if (aChannel == channel) {
		radio_api->set_txpower(radio_dev, get_transmit_power_for_channel(aChannel));
	}

	return OT_ERROR_NONE;
}
