drivers: ieee802154: add CSL receiver for nRF5

Implement CSL receiver functionality in nRF5 radio driver.

Signed-off-by: Eduardo Montoya <eduardo.montoya@nordicsemi.no>
This commit is contained in:
Eduardo Montoya 2021-06-23 16:52:35 +02:00 committed by Anas Nashif
commit 0f73fbdbfe
8 changed files with 210 additions and 35 deletions

View file

@ -135,6 +135,18 @@ config IEEE802154_2015
help help
Enable radio driver support for IEEE 802.15.4-2015 frames, including security handling of frames and ACKs. Enable radio driver support for IEEE 802.15.4-2015 frames, including security handling of frames and ACKs.
config IEEE802154_DELAY_TRX_ACC
int "Clock accuracy for delayed operations"
default 20
help
Accuracy of the clock used for scheduling radio delayed operations (delayed transmission
or delayed reception), in ppm.
config IEEE802154_CSL_ENDPOINT
bool "Enable support for CSL Endpoint"
help
Enable support for CSL Endpoint with delayed reception handling and CSL IE injection.
module = IEEE802154_DRIVER module = IEEE802154_DRIVER
module-str = IEEE 802.15.4 driver module-str = IEEE 802.15.4 driver
module-help = Sets log level for IEEE 802.15.4 Device Drivers. module-help = Sets log level for IEEE 802.15.4 Device Drivers.

View file

@ -57,7 +57,11 @@ static struct nrf5_802154_data nrf5_data;
#define ACK_REQUEST_BIT (1 << 5) #define ACK_REQUEST_BIT (1 << 5)
#define FRAME_PENDING_BYTE 1 #define FRAME_PENDING_BYTE 1
#define FRAME_PENDING_BIT (1 << 4) #define FRAME_PENDING_BIT (1 << 4)
#define TXTIME_OFFSET_US (5 * USEC_PER_MSEC) #define TXTIME_OFFSET_US (1 * USEC_PER_MSEC)
#define DRX_SLOT_PH 0 /* Placeholder delayed reception window ID */
#define DRX_SLOT_RX 1 /* Actual delayed reception window ID */
#define PH_DURATION 10 /* Duration of the placeholder window, in microseconds */
#if defined(CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE) #if defined(CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE)
#if defined(CONFIG_SOC_NRF5340_CPUAPP) #if defined(CONFIG_SOC_NRF5340_CPUAPP)
@ -217,6 +221,7 @@ static void nrf5_get_capabilities_at_boot(void)
IEEE802154_HW_TX_RX_ACK | IEEE802154_HW_TX_RX_ACK |
IEEE802154_HW_ENERGY_SCAN | IEEE802154_HW_ENERGY_SCAN |
((caps & NRF_802154_CAPABILITY_DELAYED_TX) ? IEEE802154_HW_TXTIME : 0UL) | ((caps & NRF_802154_CAPABILITY_DELAYED_TX) ? IEEE802154_HW_TXTIME : 0UL) |
((caps & NRF_802154_CAPABILITY_DELAYED_RX) ? IEEE802154_HW_RXTIME : 0UL) |
IEEE802154_HW_SLEEP_TO_TX | IEEE802154_HW_SLEEP_TO_TX |
((caps & NRF_802154_CAPABILITY_SECURITY) ? IEEE802154_HW_TX_SEC : 0UL); ((caps & NRF_802154_CAPABILITY_SECURITY) ? IEEE802154_HW_TX_SEC : 0UL);
} }
@ -565,6 +570,13 @@ static uint64_t nrf5_get_time(const struct device *dev)
return nrf_802154_time_get(); return nrf_802154_time_get();
} }
static uint8_t nrf5_get_acc(const struct device *dev)
{
ARG_UNUSED(dev);
return CONFIG_IEEE802154_DELAY_TRX_ACC;
}
static int nrf5_start(const struct device *dev) static int nrf5_start(const struct device *dev)
{ {
ARG_UNUSED(dev); ARG_UNUSED(dev);
@ -582,7 +594,18 @@ static int nrf5_start(const struct device *dev)
static int nrf5_stop(const struct device *dev) static int nrf5_stop(const struct device *dev)
{ {
#if defined(CONFIG_IEEE802154_CSL_ENDPOINT)
if (nrf_802154_sleep_if_idle() != NRF_802154_SLEEP_ERROR_NONE) {
if (nrf5_data.event_handler) {
nrf5_data.event_handler(dev, IEEE802154_EVENT_SLEEP, NULL);
} else {
LOG_WRN("Transition to radio sleep cannot be handled.");
}
return 0;
}
#else
ARG_UNUSED(dev); ARG_UNUSED(dev);
#endif
if (!nrf_802154_sleep()) { if (!nrf_802154_sleep()) {
LOG_ERR("Error while stopping radio"); LOG_ERR("Error while stopping radio");
@ -692,6 +715,35 @@ static void nrf5_config_mac_keys(struct ieee802154_key *mac_keys)
} }
#endif /* CONFIG_NRF_802154_ENCRYPTION */ #endif /* CONFIG_NRF_802154_ENCRYPTION */
#if defined(CONFIG_IEEE802154_CSL_ENDPOINT)
static void nrf5_receive_at(uint32_t start, uint32_t duration, uint8_t channel, uint32_t id)
{
nrf_802154_receive_at(start - TXTIME_OFFSET_US, TXTIME_OFFSET_US, duration, channel, id);
}
static void nrf5_config_csl_period(uint16_t period)
{
nrf_802154_receive_at_cancel(DRX_SLOT_PH);
nrf_802154_receive_at_cancel(DRX_SLOT_RX);
nrf_802154_csl_writer_period_set(period);
/* A placeholder reception window is scheduled so that the radio driver is able to inject
* the proper CSL Phase in the transmitted CSL Information Elements.
*/
nrf5_receive_at(nrf5_data.csl_rx_time, PH_DURATION, nrf_802154_channel_get(), DRX_SLOT_PH);
}
static void nrf5_schedule_rx(uint8_t channel, uint32_t start, uint32_t duration)
{
nrf5_receive_at(start, duration, channel, DRX_SLOT_RX);
/* The placeholder reception window is rescheduled for the next period */
nrf_802154_receive_at_cancel(DRX_SLOT_PH);
nrf5_receive_at(nrf5_data.csl_rx_time, PH_DURATION, channel, DRX_SLOT_PH);
}
#endif /* CONFIG_IEEE802154_CSL_ENDPOINT */
static int nrf5_configure(const struct device *dev, static int nrf5_configure(const struct device *dev,
enum ieee802154_config_type type, enum ieee802154_config_type type,
const struct ieee802154_config *config) const struct ieee802154_config *config)
@ -766,6 +818,43 @@ static int nrf5_configure(const struct device *dev,
break; break;
#endif /* CONFIG_NRF_802154_ENCRYPTION */ #endif /* CONFIG_NRF_802154_ENCRYPTION */
case IEEE802154_CONFIG_ENH_ACK_HEADER_IE: {
uint8_t short_addr_le[SHORT_ADDRESS_SIZE];
uint8_t ext_addr_le[EXTENDED_ADDRESS_SIZE];
sys_put_le16(config->ack_ie.short_addr, short_addr_le);
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
memcpy(ext_addr_le, config->ack_ie.ext_addr, EXTENDED_ADDRESS_SIZE);
#else
sys_memcpy_swap(ext_addr_le, config->ack_ie.ext_addr, EXTENDED_ADDRESS_SIZE);
#endif
if (config->ack_ie.data_len > 0) {
nrf_802154_ack_data_set(short_addr_le, false, config->ack_ie.data,
config->ack_ie.data_len, NRF_802154_ACK_DATA_IE);
nrf_802154_ack_data_set(ext_addr_le, true, config->ack_ie.data,
config->ack_ie.data_len, NRF_802154_ACK_DATA_IE);
} else {
nrf_802154_ack_data_clear(short_addr_le, false, NRF_802154_ACK_DATA_IE);
nrf_802154_ack_data_clear(ext_addr_le, true, NRF_802154_ACK_DATA_IE);
}
} break;
#if defined(CONFIG_IEEE802154_CSL_ENDPOINT)
case IEEE802154_CONFIG_CSL_RX_TIME:
nrf5_data.csl_rx_time = config->csl_rx_time;
break;
case IEEE802154_CONFIG_RX_SLOT:
nrf5_schedule_rx(config->rx_slot.channel, config->rx_slot.start,
config->rx_slot.duration);
break;
case IEEE802154_CONFIG_CSL_PERIOD:
nrf5_config_csl_period(config->csl_period);
break;
#endif /* CONFIG_IEEE802154_CSL_ENDPOINT */
default: default:
return -EINVAL; return -EINVAL;
} }
@ -807,7 +896,14 @@ void nrf_802154_received_timestamp_raw(uint8_t *data, int8_t power, uint8_t lqi,
void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id) void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id)
{ {
#if defined(CONFIG_IEEE802154_CSL_ENDPOINT)
if ((id == DRX_SLOT_PH) || (id == DRX_SLOT_RX)) {
nrf5_stop(net_if_get_device(nrf5_data.iface));
return;
}
#else
ARG_UNUSED(id); ARG_UNUSED(id);
#endif
enum ieee802154_rx_fail_reason reason; enum ieee802154_rx_fail_reason reason;
@ -949,6 +1045,7 @@ static struct ieee802154_radio_api nrf5_radio_api = {
.tx = nrf5_tx, .tx = nrf5_tx,
.ed_scan = nrf5_energy_scan_start, .ed_scan = nrf5_energy_scan_start,
.get_time = nrf5_get_time, .get_time = nrf5_get_time,
.get_sch_acc = nrf5_get_acc,
.configure = nrf5_configure, .configure = nrf5_configure,
}; };

View file

@ -83,6 +83,9 @@ struct nrf5_802154_data {
/* Capabilities of the network interface. */ /* Capabilities of the network interface. */
enum ieee802154_hw_caps capabilities; enum ieee802154_hw_caps capabilities;
/* Next CSL receive time */
uint32_t csl_rx_time;
}; };
#endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_NRF5_H_ */ #endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_NRF5_H_ */

View file

@ -69,7 +69,8 @@ enum ieee802154_filter_type {
enum ieee802154_event { enum ieee802154_event {
IEEE802154_EVENT_TX_STARTED, /* Data transmission started */ IEEE802154_EVENT_TX_STARTED, /* Data transmission started */
IEEE802154_EVENT_RX_FAILED /* Data reception failed */ IEEE802154_EVENT_RX_FAILED, /* Data reception failed */
IEEE802154_EVENT_SLEEP, /* Sleep pending */
}; };
enum ieee802154_rx_fail_reason { enum ieee802154_rx_fail_reason {
@ -168,11 +169,45 @@ enum ieee802154_config_type {
/** Sets the current MAC frame counter value for radios supporting transmit security. */ /** Sets the current MAC frame counter value for radios supporting transmit security. */
IEEE802154_CONFIG_FRAME_COUNTER, IEEE802154_CONFIG_FRAME_COUNTER,
/** Configure a radio reception slot */ /** Configure a radio reception slot. This can be used for any scheduler reception, e.g.:
* Zigbee GP device, CSL, TSCH, etc.
*
* In order to configure a CSL receiver the upper layer should combine several
* configuration options in the following way:
* 1. Use ``IEEE802154_CONFIG_ENH_ACK_HEADER_IE`` once to inform the radio driver of the
* short and extended addresses of the peer to which it should inject CSL IEs.
* 2. Use ``IEEE802154_CONFIG_CSL_RX_TIME`` periodically, before each use of
* ``IEEE802154_CONFIG_CSL_PERIOD`` setting parameters of the nearest CSL RX window, and
* before each use of IEEE_CONFIG_RX_SLOT setting parameters of the following (not the
* nearest one) CSL RX window, to allow the radio driver to calculate the proper CSL Phase
* to the nearest CSL window to inject in the CSL IEs for both transmitted data and ack
* frames.
* 3. Use ``IEEE802154_CONFIG_CSL_PERIOD`` on each value change to update the current CSL
* period value which will be injected in the CSL IEs together with the CSL Phase based on
* ``IEEE802154_CONFIG_CSL_RX_TIME``.
* 4. Use ``IEEE802154_CONFIG_RX_SLOT`` periodically to schedule the immediate receive
* window earlier enough before the expected window start time, taking into account
* possible clock drifts and scheduling uncertainties.
*
* This diagram shows the usage of the four options over time:
* Start CSL Schedule CSL window
*
* ENH_ACK_HEADER_IE CSL_RX_TIME (following window)
* | |
* | CSL_RX_TIME (nearest window) | RX_SLOT (nearest window)
* | | | |
* | | CSL_PERIOD | |
* | | | | |
* v v v v v
* ----------------------------------------------------------[ CSL window ]-----+
* ^ |
* | |
* +--------------------- loop ---------+
*/
IEEE802154_CONFIG_RX_SLOT, IEEE802154_CONFIG_RX_SLOT,
/** Enable CSL receiver (Endpoint) */ /** Configure CSL receiver (Endpoint) period */
IEEE802154_CONFIG_CSL_RECEIVER, IEEE802154_CONFIG_CSL_PERIOD,
/** Configure the next CSL receive window center, in units of microseconds, /** Configure the next CSL receive window center, in units of microseconds,
* based on the radio time. * based on the radio time.
@ -235,11 +270,8 @@ struct ieee802154_config {
uint32_t duration; uint32_t duration;
} rx_slot; } rx_slot;
/** ``IEEE802154_CONFIG_CSL_RECEIVER`` */ /** ``IEEE802154_CONFIG_CSL_PERIOD`` */
struct { uint32_t csl_period;
uint32_t period;
const uint8_t *addr;
} csl_recv;
/** ``IEEE802154_CONFIG_CSL_RX_TIME`` */ /** ``IEEE802154_CONFIG_CSL_RX_TIME`` */
uint32_t csl_rx_time; uint32_t csl_rx_time;
@ -315,11 +347,11 @@ struct ieee802154_radio_api {
uint64_t (*get_time)(const struct device *dev); uint64_t (*get_time)(const struct device *dev);
/** Get the current accuracy, in units of ± ppm, of the clock used for /** Get the current accuracy, in units of ± ppm, of the clock used for
* scheduling CSL transmissions or receive windows. * scheduling delayed receive or transmit radio operations.
* Note: Implementations may optimize this value based on operational * Note: Implementations may optimize this value based on operational
* conditions (i.e.: temperature). * conditions (i.e.: temperature).
*/ */
uint8_t (*get_csl_acc)(const struct device *dev); uint8_t (*get_sch_acc)(const struct device *dev);
}; };
/* Make sure that the network interface API is properly setup inside /* Make sure that the network interface API is properly setup inside

View file

@ -88,7 +88,13 @@ config OPENTHREAD_CSL_SAMPLE_WINDOW
config OPENTHREAD_CSL_RECEIVE_TIME_AHEAD config OPENTHREAD_CSL_RECEIVE_TIME_AHEAD
int "CSL receiver wake up margin in units of 10 symbols" int "CSL receiver wake up margin in units of 10 symbols"
default 3 default 480
config OPENTHREAD_CSL_MIN_RECEIVE_ON
int "Minimum CSL receive window"
default 5696
help
The minimum CSL receive window (in microseconds) required to receive a full IEEE 802.15.4 frame
config OPENTHREAD_MAC_SOFTWARE_TX_SECURITY_ENABLE config OPENTHREAD_MAC_SOFTWARE_TX_SECURITY_ENABLE
bool "Enable software transmission security logic" bool "Enable software transmission security logic"

View file

@ -22,6 +22,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include <stdio.h> #include <stdio.h>
#include "platform-zephyr.h" #include "platform-zephyr.h"
#include "openthread-core-zephyr-config.h"
static bool timer_ms_fired, timer_us_fired; static bool timer_ms_fired, timer_us_fired;

View file

@ -140,8 +140,8 @@
* in platform. * in platform.
* *
*/ */
#define OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE \ #define OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE \
(OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE && \ (CONFIG_OPENTHREAD_CSL_RECEIVER && \
(OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)) (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2))
/* Zephyr does not use OpenThread's heap. mbedTLS will use heap memory allocated /* Zephyr does not use OpenThread's heap. mbedTLS will use heap memory allocated
@ -283,7 +283,7 @@
* *
* For some reasons, CSL receivers wake up a little later than expected. This * For some reasons, CSL receivers wake up a little later than expected. This
* variable specifies how much time that CSL receiver would wake up earlier * variable specifies how much time that CSL receiver would wake up earlier
* than the expected sample window. The time is in unit of 10 symbols. * than the expected sample window. The time is in unit of microseconds.
* *
*/ */
#ifdef CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD #ifdef CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD
@ -291,6 +291,16 @@
CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD
#endif /* CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD */ #endif /* CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD */
/**
* @def OPENTHREAD_CONFIG_CSL_MIN_RECEIVE_ON
*
* The minimum CSL receive window (in microseconds) required to receive an IEEE 802.15.4 frame.
*
*/
#ifdef CONFIG_OPENTHREAD_CSL_MIN_RECEIVE_ON
#define OPENTHREAD_CONFIG_CSL_MIN_RECEIVE_ON CONFIG_OPENTHREAD_CSL_MIN_RECEIVE_ON
#endif /* CONFIG_OPENTHREAD_CSL_MIN_RECEIVE_ON */
/** /**
* @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
* *

View file

@ -60,11 +60,10 @@ enum pending_events {
PENDING_EVENT_RX_FAILED, /* The RX failed */ PENDING_EVENT_RX_FAILED, /* The RX failed */
PENDING_EVENT_TX_STARTED, /* Radio has started transmitting */ PENDING_EVENT_TX_STARTED, /* Radio has started transmitting */
PENDING_EVENT_TX_DONE, /* Radio transmission finished */ PENDING_EVENT_TX_DONE, /* Radio transmission finished */
PENDING_EVENT_DETECT_ENERGY, /* Requested to start Energy Detection PENDING_EVENT_DETECT_ENERGY, /* Requested to start Energy Detection procedure */
* procedure. PENDING_EVENT_DETECT_ENERGY_DONE, /* Energy Detection finished */
*/ PENDING_EVENT_SLEEP, /* Sleep if idle */
PENDING_EVENT_DETECT_ENERGY_DONE, /* Energy Detection finished. */ PENDING_EVENT_COUNT /* Keep last */
PENDING_EVENT_COUNT /* keep last */
}; };
K_SEM_DEFINE(radio_sem, 0, 1); K_SEM_DEFINE(radio_sem, 0, 1);
@ -200,6 +199,10 @@ void handle_radio_event(const struct device *dev, enum ieee802154_event evt,
} }
set_pending_event(PENDING_EVENT_RX_FAILED); set_pending_event(PENDING_EVENT_RX_FAILED);
} }
break;
case IEEE802154_EVENT_SLEEP:
set_pending_event(PENDING_EVENT_SLEEP);
break;
default: default:
/* do nothing - ignore event */ /* do nothing - ignore event */
break; break;
@ -476,6 +479,11 @@ void platformRadioProcess(otInstance *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 */ /* handle events that can't run during transmission */
if (sState != OT_RADIO_STATE_TRANSMIT) { if (sState != OT_RADIO_STATE_TRANSMIT) {
if (is_pending_event_set(PENDING_EVENT_DETECT_ENERGY)) { if (is_pending_event_set(PENDING_EVENT_DETECT_ENERGY)) {
@ -570,8 +578,9 @@ otError otPlatRadioSleep(otInstance *aInstance)
sState == OT_RADIO_STATE_RECEIVE || sState == OT_RADIO_STATE_RECEIVE ||
sState == OT_RADIO_STATE_TRANSMIT) { sState == OT_RADIO_STATE_TRANSMIT) {
error = OT_ERROR_NONE; error = OT_ERROR_NONE;
sState = OT_RADIO_STATE_SLEEP; if (radio_api->stop(radio_dev)) {
radio_api->stop(radio_dev); sState = OT_RADIO_STATE_SLEEP;
}
} }
return error; return error;
@ -1015,33 +1024,38 @@ void otPlatRadioSetMacFrameCounter(otInstance *aInstance,
#endif #endif
#if defined(CONFIG_OPENTHREAD_CSL_RECEIVER) #if defined(CONFIG_OPENTHREAD_CSL_RECEIVER)
otError otPlatRadioEnableCsl(otInstance *aInstance, uint32_t aCslPeriod, otError otPlatRadioEnableCsl(otInstance *aInstance, uint32_t aCslPeriod, otShortAddress aShortAddr,
const otExtAddress *aExtAddr) const otExtAddress *aExtAddr)
{ {
int result; int result;
uint8_t ie_header[OT_IE_HEADER_SIZE + OT_CSL_IE_SIZE];
struct ieee802154_config config;
ARG_UNUSED(aInstance); ARG_UNUSED(aInstance);
struct ieee802154_config config = { ie_header[0] = CSL_IE_HEADER_BYTES_LO;
.csl_recv.period = aCslPeriod, ie_header[1] = CSL_IE_HEADER_BYTES_HI;
.csl_recv.addr = aExtAddr->m8, /* Leave CSL Phase empty intentionally */
}; sys_put_le16(aCslPeriod, &ie_header[OT_IE_HEADER_SIZE + 2]);
config.ack_ie.data = ie_header;
config.ack_ie.data_len = OT_IE_HEADER_SIZE + OT_CSL_IE_SIZE;
config.ack_ie.short_addr = aShortAddr;
config.ack_ie.ext_addr = aExtAddr->m8;
result = radio_api->configure(radio_dev, IEEE802154_CONFIG_ENH_ACK_HEADER_IE, &config);
result = radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_RECEIVER, config.csl_period = aCslPeriod;
&config); result += radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_PERIOD, &config);
return result ? OT_ERROR_FAILED : OT_ERROR_NONE; return result ? OT_ERROR_FAILED : OT_ERROR_NONE;
} }
void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTime)
uint32_t aCslSampleTime)
{ {
ARG_UNUSED(aInstance); ARG_UNUSED(aInstance);
struct ieee802154_config config = { .csl_rx_time = aCslSampleTime }; struct ieee802154_config config = { .csl_rx_time = aCslSampleTime };
(void)radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_RX_TIME, (void)radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_RX_TIME, &config);
&config);
} }
#endif /* CONFIG_OPENTHREAD_CSL_RECEIVER */ #endif /* CONFIG_OPENTHREAD_CSL_RECEIVER */
@ -1049,7 +1063,7 @@ uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance)
{ {
ARG_UNUSED(aInstance); ARG_UNUSED(aInstance);
return radio_api->get_csl_acc(radio_dev); return radio_api->get_sch_acc(radio_dev);
} }
#if defined(CONFIG_OPENTHREAD_LINK_METRICS) #if defined(CONFIG_OPENTHREAD_LINK_METRICS)