1 /* ieee802154_nrf5.c - nRF5 802.15.4 driver */
2
3 /*
4 * Copyright (c) 2017-2023 Nordic Semiconductor ASA
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #define DT_DRV_COMPAT nordic_nrf_ieee802154
10
11 #define LOG_MODULE_NAME ieee802154_nrf5
12 #if defined(CONFIG_IEEE802154_DRIVER_LOG_LEVEL)
13 #define LOG_LEVEL CONFIG_IEEE802154_DRIVER_LOG_LEVEL
14 #else
15 #define LOG_LEVEL LOG_LEVEL_NONE
16 #endif
17
18 #include <zephyr/logging/log.h>
19 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
20
21 #include <errno.h>
22
23 #include <zephyr/kernel.h>
24 #include <zephyr/arch/cpu.h>
25 #include <zephyr/debug/stack.h>
26
27 #include <soc.h>
28 #include <soc_secure.h>
29 #include <zephyr/device.h>
30 #include <zephyr/init.h>
31 #include <zephyr/debug/stack.h>
32 #include <zephyr/net/net_if.h>
33 #include <zephyr/net/net_pkt.h>
34
35 #if defined(CONFIG_NET_L2_OPENTHREAD)
36 #include <zephyr/net/openthread.h>
37 #include <zephyr/net/ieee802154_radio_openthread.h>
38 #endif
39
40 #include <zephyr/sys/byteorder.h>
41 #include <string.h>
42 #include <zephyr/random/random.h>
43
44 #include <zephyr/net/ieee802154_radio.h>
45 #include <zephyr/irq.h>
46
47 #include "ieee802154_nrf5.h"
48 #include "nrf_802154.h"
49 #include "nrf_802154_const.h"
50
51 #if defined(CONFIG_NRF_802154_SER_HOST)
52 #include "nrf_802154_serialization_error.h"
53 #endif
54
55 struct nrf5_802154_config {
56 void (*irq_config_func)(const struct device *dev);
57 };
58
59 static struct nrf5_802154_data nrf5_data;
60
61 #define ACK_REQUEST_BYTE 1
62 #define ACK_REQUEST_BIT (1 << 5)
63 #define FRAME_PENDING_BYTE 1
64 #define FRAME_PENDING_BIT (1 << 4)
65
66 #define DRX_SLOT_RX 0 /* Delayed reception window ID */
67
68 #if defined(CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE)
69 #if defined(CONFIG_SOC_NRF5340_CPUAPP)
70 #if defined(CONFIG_TRUSTED_EXECUTION_NONSECURE)
71 #error "NRF_UICR->OTP is not supported to read from non-secure"
72 #else
73 #define EUI64_ADDR (NRF_UICR->OTP)
74 #endif /* CONFIG_TRUSTED_EXECUTION_NONSECURE */
75 #else
76 #define EUI64_ADDR (NRF_UICR->CUSTOMER)
77 #endif /* CONFIG_SOC_NRF5340_CPUAPP */
78 #endif /* CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE */
79
80 #if defined(CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE)
81 #define EUI64_ADDR_HIGH CONFIG_IEEE802154_NRF5_UICR_EUI64_REG
82 #define EUI64_ADDR_LOW (CONFIG_IEEE802154_NRF5_UICR_EUI64_REG + 1)
83 #else
84 #define EUI64_ADDR_HIGH 0
85 #define EUI64_ADDR_LOW 1
86 #endif /* CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE */
87
88 /* Convenience defines for RADIO */
89 #define NRF5_802154_DATA(dev) \
90 ((struct nrf5_802154_data * const)(dev)->data)
91
92 #define NRF5_802154_CFG(dev) \
93 ((const struct nrf5_802154_config * const)(dev)->config)
94
95 #if CONFIG_IEEE802154_VENDOR_OUI_ENABLE
96 #define IEEE802154_NRF5_VENDOR_OUI CONFIG_IEEE802154_VENDOR_OUI
97 #else
98 #define IEEE802154_NRF5_VENDOR_OUI (uint32_t)0xF4CE36
99 #endif
100
nrf5_get_eui64(uint8_t * mac)101 static void nrf5_get_eui64(uint8_t *mac)
102 {
103 uint64_t factoryAddress;
104 uint32_t index = 0;
105
106 #if !defined(CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE)
107 uint32_t deviceid[2];
108
109 /* Set the MAC Address Block Larger (MA-L) formerly called OUI. */
110 mac[index++] = (IEEE802154_NRF5_VENDOR_OUI >> 16) & 0xff;
111 mac[index++] = (IEEE802154_NRF5_VENDOR_OUI >> 8) & 0xff;
112 mac[index++] = IEEE802154_NRF5_VENDOR_OUI & 0xff;
113
114 soc_secure_read_deviceid(deviceid);
115
116 factoryAddress = (uint64_t)deviceid[EUI64_ADDR_HIGH] << 32;
117 factoryAddress |= deviceid[EUI64_ADDR_LOW];
118 #else
119 /* Use device identifier assigned during the production. */
120 factoryAddress = (uint64_t)EUI64_ADDR[EUI64_ADDR_HIGH] << 32;
121 factoryAddress |= EUI64_ADDR[EUI64_ADDR_LOW];
122 #endif
123 memcpy(mac + index, &factoryAddress, sizeof(factoryAddress) - index);
124 }
125
nrf5_rx_thread(void * arg1,void * arg2,void * arg3)126 static void nrf5_rx_thread(void *arg1, void *arg2, void *arg3)
127 {
128 struct nrf5_802154_data *nrf5_radio = (struct nrf5_802154_data *)arg1;
129 struct net_pkt *pkt;
130 struct nrf5_802154_rx_frame *rx_frame;
131 uint8_t pkt_len;
132 uint8_t *psdu;
133
134 ARG_UNUSED(arg2);
135 ARG_UNUSED(arg3);
136
137 while (1) {
138 pkt = NULL;
139 rx_frame = NULL;
140
141 LOG_DBG("Waiting for frame");
142
143 rx_frame = k_fifo_get(&nrf5_radio->rx_fifo, K_FOREVER);
144
145 __ASSERT_NO_MSG(rx_frame->psdu);
146
147 /* rx_mpdu contains length, psdu, fcs|lqi
148 * The last 2 bytes contain LQI or FCS, depending if
149 * automatic CRC handling is enabled or not, respectively.
150 */
151 if (IS_ENABLED(CONFIG_IEEE802154_NRF5_FCS_IN_LENGTH)) {
152 pkt_len = rx_frame->psdu[0];
153 } else {
154 pkt_len = rx_frame->psdu[0] - IEEE802154_FCS_LENGTH;
155 }
156
157 #if defined(CONFIG_NET_BUF_DATA_SIZE)
158 __ASSERT_NO_MSG(pkt_len <= CONFIG_NET_BUF_DATA_SIZE);
159 #endif
160
161 LOG_DBG("Frame received");
162
163 /* Block the RX thread until net_pkt is available, so that we
164 * don't drop already ACKed frame in case of temporary net_pkt
165 * scarcity. The nRF 802154 radio driver will accumulate any
166 * incoming frames until it runs out of internal buffers (and
167 * thus stops acknowledging consecutive frames).
168 */
169 pkt = net_pkt_rx_alloc_with_buffer(nrf5_radio->iface, pkt_len,
170 AF_UNSPEC, 0, K_FOREVER);
171
172 if (net_pkt_write(pkt, rx_frame->psdu + 1, pkt_len)) {
173 goto drop;
174 }
175
176 net_pkt_set_ieee802154_lqi(pkt, rx_frame->lqi);
177 net_pkt_set_ieee802154_rssi_dbm(pkt, rx_frame->rssi);
178 net_pkt_set_ieee802154_ack_fpb(pkt, rx_frame->ack_fpb);
179
180 #if defined(CONFIG_NET_PKT_TIMESTAMP)
181 net_pkt_set_timestamp_ns(pkt, rx_frame->time * NSEC_PER_USEC);
182 #endif
183
184 LOG_DBG("Caught a packet (%u) (LQI: %u)",
185 pkt_len, rx_frame->lqi);
186
187 if (net_recv_data(nrf5_radio->iface, pkt) < 0) {
188 LOG_ERR("Packet dropped by NET stack");
189 goto drop;
190 }
191
192 psdu = rx_frame->psdu;
193 rx_frame->psdu = NULL;
194 nrf_802154_buffer_free_raw(psdu);
195
196 if (LOG_LEVEL >= LOG_LEVEL_DBG) {
197 log_stack_usage(&nrf5_radio->rx_thread);
198 }
199
200 continue;
201
202 drop:
203 psdu = rx_frame->psdu;
204 rx_frame->psdu = NULL;
205 nrf_802154_buffer_free_raw(psdu);
206
207 net_pkt_unref(pkt);
208 }
209 }
210
nrf5_get_capabilities_at_boot(void)211 static void nrf5_get_capabilities_at_boot(void)
212 {
213 nrf_802154_capabilities_t caps = nrf_802154_capabilities_get();
214
215 nrf5_data.capabilities =
216 IEEE802154_HW_FCS |
217 IEEE802154_HW_PROMISC |
218 IEEE802154_HW_FILTER |
219 ((caps & NRF_802154_CAPABILITY_CSMA) ? IEEE802154_HW_CSMA : 0UL) |
220 IEEE802154_HW_TX_RX_ACK |
221 IEEE802154_HW_RX_TX_ACK |
222 IEEE802154_HW_ENERGY_SCAN |
223 ((caps & NRF_802154_CAPABILITY_DELAYED_TX) ? IEEE802154_HW_TXTIME : 0UL) |
224 ((caps & NRF_802154_CAPABILITY_DELAYED_RX) ? IEEE802154_HW_RXTIME : 0UL) |
225 IEEE802154_HW_SLEEP_TO_TX |
226 ((caps & NRF_802154_CAPABILITY_SECURITY) ? IEEE802154_HW_TX_SEC : 0UL)
227 #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA)
228 | IEEE802154_OPENTHREAD_HW_MULTIPLE_CCA
229 #endif
230 ;
231 }
232
233 /* Radio device API */
234
nrf5_get_capabilities(const struct device * dev)235 static enum ieee802154_hw_caps nrf5_get_capabilities(const struct device *dev)
236 {
237 return nrf5_data.capabilities;
238 }
239
nrf5_cca(const struct device * dev)240 static int nrf5_cca(const struct device *dev)
241 {
242 struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
243
244 if (!nrf_802154_cca()) {
245 LOG_DBG("CCA failed");
246 return -EBUSY;
247 }
248
249 /* The nRF driver guarantees that a callback will be called once
250 * the CCA function is done, thus unlocking the semaphore.
251 */
252 k_sem_take(&nrf5_radio->cca_wait, K_FOREVER);
253
254 LOG_DBG("Channel free? %d", nrf5_radio->channel_free);
255
256 return nrf5_radio->channel_free ? 0 : -EBUSY;
257 }
258
nrf5_set_channel(const struct device * dev,uint16_t channel)259 static int nrf5_set_channel(const struct device *dev, uint16_t channel)
260 {
261 ARG_UNUSED(dev);
262
263 LOG_DBG("%u", channel);
264
265 if (channel < 11 || channel > 26) {
266 return channel < 11 ? -ENOTSUP : -EINVAL;
267 }
268
269 nrf_802154_channel_set(channel);
270
271 return 0;
272 }
273
nrf5_energy_scan_start(const struct device * dev,uint16_t duration,energy_scan_done_cb_t done_cb)274 static int nrf5_energy_scan_start(const struct device *dev,
275 uint16_t duration,
276 energy_scan_done_cb_t done_cb)
277 {
278 int err = 0;
279
280 ARG_UNUSED(dev);
281
282 if (nrf5_data.energy_scan_done == NULL) {
283 nrf5_data.energy_scan_done = done_cb;
284
285 if (nrf_802154_energy_detection(duration * 1000) == false) {
286 nrf5_data.energy_scan_done = NULL;
287 err = -EBUSY;
288 }
289 } else {
290 err = -EALREADY;
291 }
292
293 return err;
294 }
295
nrf5_set_pan_id(const struct device * dev,uint16_t pan_id)296 static int nrf5_set_pan_id(const struct device *dev, uint16_t pan_id)
297 {
298 uint8_t pan_id_le[2];
299
300 ARG_UNUSED(dev);
301
302 sys_put_le16(pan_id, pan_id_le);
303 nrf_802154_pan_id_set(pan_id_le);
304
305 LOG_DBG("0x%x", pan_id);
306
307 return 0;
308 }
309
nrf5_set_short_addr(const struct device * dev,uint16_t short_addr)310 static int nrf5_set_short_addr(const struct device *dev, uint16_t short_addr)
311 {
312 uint8_t short_addr_le[2];
313
314 ARG_UNUSED(dev);
315
316 sys_put_le16(short_addr, short_addr_le);
317 nrf_802154_short_address_set(short_addr_le);
318
319 LOG_DBG("0x%x", short_addr);
320
321 return 0;
322 }
323
nrf5_set_ieee_addr(const struct device * dev,const uint8_t * ieee_addr)324 static int nrf5_set_ieee_addr(const struct device *dev,
325 const uint8_t *ieee_addr)
326 {
327 ARG_UNUSED(dev);
328
329 LOG_DBG("IEEE address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
330 ieee_addr[7], ieee_addr[6], ieee_addr[5], ieee_addr[4],
331 ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]);
332
333 nrf_802154_extended_address_set(ieee_addr);
334
335 return 0;
336 }
337
nrf5_filter(const struct device * dev,bool set,enum ieee802154_filter_type type,const struct ieee802154_filter * filter)338 static int nrf5_filter(const struct device *dev, bool set,
339 enum ieee802154_filter_type type,
340 const struct ieee802154_filter *filter)
341 {
342 LOG_DBG("Applying filter %u", type);
343
344 if (!set) {
345 return -ENOTSUP;
346 }
347
348 if (type == IEEE802154_FILTER_TYPE_IEEE_ADDR) {
349 return nrf5_set_ieee_addr(dev, filter->ieee_addr);
350 } else if (type == IEEE802154_FILTER_TYPE_SHORT_ADDR) {
351 return nrf5_set_short_addr(dev, filter->short_addr);
352 } else if (type == IEEE802154_FILTER_TYPE_PAN_ID) {
353 return nrf5_set_pan_id(dev, filter->pan_id);
354 }
355
356 return -ENOTSUP;
357 }
358
nrf5_set_txpower(const struct device * dev,int16_t dbm)359 static int nrf5_set_txpower(const struct device *dev, int16_t dbm)
360 {
361 ARG_UNUSED(dev);
362
363 LOG_DBG("%d", dbm);
364
365 nrf_802154_tx_power_set(dbm);
366
367 return 0;
368 }
369
handle_ack(struct nrf5_802154_data * nrf5_radio)370 static int handle_ack(struct nrf5_802154_data *nrf5_radio)
371 {
372 uint8_t ack_len;
373 struct net_pkt *ack_pkt;
374 int err = 0;
375
376 if (IS_ENABLED(CONFIG_IEEE802154_NRF5_FCS_IN_LENGTH)) {
377 ack_len = nrf5_radio->ack_frame.psdu[0];
378 } else {
379 ack_len = nrf5_radio->ack_frame.psdu[0] - IEEE802154_FCS_LENGTH;
380 }
381
382 ack_pkt = net_pkt_rx_alloc_with_buffer(nrf5_radio->iface, ack_len,
383 AF_UNSPEC, 0, K_NO_WAIT);
384 if (!ack_pkt) {
385 LOG_ERR("No free packet available.");
386 err = -ENOMEM;
387 goto free_nrf_ack;
388 }
389
390 /* Upper layers expect the frame to start at the MAC header, skip the
391 * PHY header (1 byte).
392 */
393 if (net_pkt_write(ack_pkt, nrf5_radio->ack_frame.psdu + 1,
394 ack_len) < 0) {
395 LOG_ERR("Failed to write to a packet.");
396 err = -ENOMEM;
397 goto free_net_ack;
398 }
399
400 net_pkt_set_ieee802154_lqi(ack_pkt, nrf5_radio->ack_frame.lqi);
401 net_pkt_set_ieee802154_rssi_dbm(ack_pkt, nrf5_radio->ack_frame.rssi);
402
403 #if defined(CONFIG_NET_PKT_TIMESTAMP)
404 net_pkt_set_timestamp_ns(ack_pkt, nrf5_radio->ack_frame.time * NSEC_PER_USEC);
405 #endif
406
407 net_pkt_cursor_init(ack_pkt);
408
409 if (ieee802154_handle_ack(nrf5_radio->iface, ack_pkt) != NET_OK) {
410 LOG_INF("ACK packet not handled - releasing.");
411 }
412
413 free_net_ack:
414 net_pkt_unref(ack_pkt);
415
416 free_nrf_ack:
417 nrf_802154_buffer_free_raw(nrf5_radio->ack_frame.psdu);
418 nrf5_radio->ack_frame.psdu = NULL;
419
420 return err;
421 }
422
nrf5_tx_started(const struct device * dev,struct net_pkt * pkt,struct net_buf * frag)423 static void nrf5_tx_started(const struct device *dev,
424 struct net_pkt *pkt,
425 struct net_buf *frag)
426 {
427 ARG_UNUSED(pkt);
428
429 if (nrf5_data.event_handler) {
430 nrf5_data.event_handler(dev, IEEE802154_EVENT_TX_STARTED,
431 (void *)frag);
432 }
433 }
434
nrf5_tx_immediate(struct net_pkt * pkt,uint8_t * payload,bool cca)435 static bool nrf5_tx_immediate(struct net_pkt *pkt, uint8_t *payload, bool cca)
436 {
437 nrf_802154_transmit_metadata_t metadata = {
438 .frame_props = {
439 .is_secured = net_pkt_ieee802154_frame_secured(pkt),
440 .dynamic_data_is_set = net_pkt_ieee802154_mac_hdr_rdy(pkt),
441 },
442 .cca = cca,
443 .tx_power = {
444 .use_metadata_value = IS_ENABLED(CONFIG_IEEE802154_SELECTIVE_TXPOWER),
445 #if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER)
446 .power = net_pkt_ieee802154_txpwr(pkt),
447 #endif
448 },
449 };
450
451 return nrf_802154_transmit_raw(payload, &metadata);
452 }
453
454 #if NRF_802154_CSMA_CA_ENABLED
nrf5_tx_csma_ca(struct net_pkt * pkt,uint8_t * payload)455 static bool nrf5_tx_csma_ca(struct net_pkt *pkt, uint8_t *payload)
456 {
457 nrf_802154_transmit_csma_ca_metadata_t metadata = {
458 .frame_props = {
459 .is_secured = net_pkt_ieee802154_frame_secured(pkt),
460 .dynamic_data_is_set = net_pkt_ieee802154_mac_hdr_rdy(pkt),
461 },
462 .tx_power = {
463 .use_metadata_value = IS_ENABLED(CONFIG_IEEE802154_SELECTIVE_TXPOWER),
464 #if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER)
465 .power = net_pkt_ieee802154_txpwr(pkt),
466 #endif
467 },
468 };
469
470 return nrf_802154_transmit_csma_ca_raw(payload, &metadata);
471 }
472 #endif
473
474 #if defined(CONFIG_NET_PKT_TXTIME)
nrf5_tx_at(struct nrf5_802154_data * nrf5_radio,struct net_pkt * pkt,uint8_t * payload,enum ieee802154_tx_mode mode)475 static bool nrf5_tx_at(struct nrf5_802154_data *nrf5_radio, struct net_pkt *pkt,
476 uint8_t *payload, enum ieee802154_tx_mode mode)
477 {
478 bool cca = false;
479 #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA)
480 uint8_t max_extra_cca_attempts = 0;
481 #endif
482
483 switch (mode) {
484 case IEEE802154_TX_MODE_TXTIME:
485 break;
486 case IEEE802154_TX_MODE_TXTIME_CCA:
487 cca = true;
488 break;
489 #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA)
490 case IEEE802154_OPENTHREAD_TX_MODE_TXTIME_MULTIPLE_CCA:
491 cca = true;
492 max_extra_cca_attempts = nrf5_data.max_extra_cca_attempts;
493 break;
494 #endif
495 break;
496 default:
497 __ASSERT_NO_MSG(false);
498 return false;
499 }
500
501 nrf_802154_transmit_at_metadata_t metadata = {
502 .frame_props = {
503 .is_secured = net_pkt_ieee802154_frame_secured(pkt),
504 .dynamic_data_is_set = net_pkt_ieee802154_mac_hdr_rdy(pkt),
505 },
506 .cca = cca,
507 .channel = nrf_802154_channel_get(),
508 .tx_power = {
509 .use_metadata_value = IS_ENABLED(CONFIG_IEEE802154_SELECTIVE_TXPOWER),
510 #if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER)
511 .power = net_pkt_ieee802154_txpwr(pkt),
512 #endif
513 },
514 #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA)
515 .extra_cca_attempts = max_extra_cca_attempts,
516 #endif
517 };
518
519 /* The timestamp points to the start of PHR but `nrf_802154_transmit_raw_at`
520 * expects a timestamp pointing to start of SHR.
521 */
522 uint64_t tx_at = nrf_802154_timestamp_phr_to_shr_convert(
523 net_pkt_timestamp_ns(pkt) / NSEC_PER_USEC);
524
525 return nrf_802154_transmit_raw_at(payload, tx_at, &metadata);
526 }
527 #endif /* CONFIG_NET_PKT_TXTIME */
528
nrf5_tx(const struct device * dev,enum ieee802154_tx_mode mode,struct net_pkt * pkt,struct net_buf * frag)529 static int nrf5_tx(const struct device *dev,
530 enum ieee802154_tx_mode mode,
531 struct net_pkt *pkt,
532 struct net_buf *frag)
533 {
534 struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
535 uint8_t payload_len = frag->len;
536 uint8_t *payload = frag->data;
537 bool ret = true;
538
539 if (payload_len > IEEE802154_MTU) {
540 LOG_ERR("Payload too large: %d", payload_len);
541 return -EMSGSIZE;
542 }
543
544 LOG_DBG("%p (%u)", payload, payload_len);
545
546 nrf5_radio->tx_psdu[0] = payload_len + IEEE802154_FCS_LENGTH;
547 memcpy(nrf5_radio->tx_psdu + 1, payload, payload_len);
548
549 /* Reset semaphore in case ACK was received after timeout */
550 k_sem_reset(&nrf5_radio->tx_wait);
551
552 switch (mode) {
553 case IEEE802154_TX_MODE_DIRECT:
554 case IEEE802154_TX_MODE_CCA:
555 ret = nrf5_tx_immediate(pkt, nrf5_radio->tx_psdu,
556 mode == IEEE802154_TX_MODE_CCA);
557 break;
558 #if NRF_802154_CSMA_CA_ENABLED
559 case IEEE802154_TX_MODE_CSMA_CA:
560 ret = nrf5_tx_csma_ca(pkt, nrf5_radio->tx_psdu);
561 break;
562 #endif
563 #if defined(CONFIG_NET_PKT_TXTIME)
564 case IEEE802154_TX_MODE_TXTIME:
565 case IEEE802154_TX_MODE_TXTIME_CCA:
566 #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA)
567 case IEEE802154_OPENTHREAD_TX_MODE_TXTIME_MULTIPLE_CCA:
568 #endif
569 __ASSERT_NO_MSG(pkt);
570 ret = nrf5_tx_at(nrf5_radio, pkt, nrf5_radio->tx_psdu, mode);
571 break;
572 #endif /* CONFIG_NET_PKT_TXTIME */
573 default:
574 NET_ERR("TX mode %d not supported", mode);
575 return -ENOTSUP;
576 }
577
578 if (!ret) {
579 LOG_ERR("Cannot send frame");
580 return -EIO;
581 }
582
583 nrf5_tx_started(dev, pkt, frag);
584
585 LOG_DBG("Sending frame (ch:%d, txpower:%d)",
586 nrf_802154_channel_get(), nrf_802154_tx_power_get());
587
588 /* Wait for the callback from the radio driver. */
589 k_sem_take(&nrf5_radio->tx_wait, K_FOREVER);
590
591 LOG_DBG("Result: %d", nrf5_data.tx_result);
592
593 #if defined(CONFIG_NRF_802154_ENCRYPTION)
594 /*
595 * When frame encryption by the radio driver is enabled, the frame stored in
596 * the tx_psdu buffer is:
597 * 1) authenticated and encrypted in place which causes that after an unsuccessful
598 * TX attempt, this frame must be propagated back to the upper layer for retransmission.
599 * The upper layer must ensure that the exact same secured frame is used for
600 * retransmission
601 * 2) frame counters are updated in place and for keeping the link frame counter up to date,
602 * this information must be propagated back to the upper layer
603 */
604 memcpy(payload, nrf5_radio->tx_psdu + 1, payload_len);
605 #endif
606 net_pkt_set_ieee802154_frame_secured(pkt, nrf5_radio->tx_frame_is_secured);
607 net_pkt_set_ieee802154_mac_hdr_rdy(pkt, nrf5_radio->tx_frame_mac_hdr_rdy);
608
609 switch (nrf5_radio->tx_result) {
610 case NRF_802154_TX_ERROR_NONE:
611 if (nrf5_radio->ack_frame.psdu == NULL) {
612 /* No ACK was requested. */
613 return 0;
614 }
615 /* Handle ACK packet. */
616 return handle_ack(nrf5_radio);
617 case NRF_802154_TX_ERROR_NO_MEM:
618 return -ENOBUFS;
619 case NRF_802154_TX_ERROR_BUSY_CHANNEL:
620 return -EBUSY;
621 case NRF_802154_TX_ERROR_INVALID_ACK:
622 case NRF_802154_TX_ERROR_NO_ACK:
623 return -ENOMSG;
624 case NRF_802154_TX_ERROR_ABORTED:
625 case NRF_802154_TX_ERROR_TIMESLOT_DENIED:
626 case NRF_802154_TX_ERROR_TIMESLOT_ENDED:
627 default:
628 return -EIO;
629 }
630 }
631
nrf5_get_time(const struct device * dev)632 static net_time_t nrf5_get_time(const struct device *dev)
633 {
634 ARG_UNUSED(dev);
635
636 return (net_time_t)nrf_802154_time_get() * NSEC_PER_USEC;
637 }
638
nrf5_get_acc(const struct device * dev)639 static uint8_t nrf5_get_acc(const struct device *dev)
640 {
641 ARG_UNUSED(dev);
642
643 return CONFIG_IEEE802154_NRF5_DELAY_TRX_ACC;
644 }
645
nrf5_start(const struct device * dev)646 static int nrf5_start(const struct device *dev)
647 {
648 ARG_UNUSED(dev);
649
650 if (!nrf_802154_receive()) {
651 LOG_ERR("Failed to enter receive state");
652 return -EIO;
653 }
654
655 LOG_DBG("nRF5 802154 radio started (channel: %d)",
656 nrf_802154_channel_get());
657
658 return 0;
659 }
660
nrf5_stop(const struct device * dev)661 static int nrf5_stop(const struct device *dev)
662 {
663 #if defined(CONFIG_IEEE802154_CSL_ENDPOINT)
664 if (nrf_802154_sleep_if_idle() != NRF_802154_SLEEP_ERROR_NONE) {
665 if (nrf5_data.event_handler) {
666 nrf5_data.event_handler(dev, IEEE802154_EVENT_SLEEP, NULL);
667 } else {
668 LOG_WRN("Transition to radio sleep cannot be handled.");
669 }
670 return 0;
671 }
672 #else
673 ARG_UNUSED(dev);
674
675 if (!nrf_802154_sleep()) {
676 LOG_ERR("Error while stopping radio");
677 return -EIO;
678 }
679 #endif
680
681 LOG_DBG("nRF5 802154 radio stopped");
682
683 return 0;
684 }
685
686 #if defined(CONFIG_NRF_802154_CARRIER_FUNCTIONS)
nrf5_continuous_carrier(const struct device * dev)687 static int nrf5_continuous_carrier(const struct device *dev)
688 {
689 ARG_UNUSED(dev);
690
691 if (!nrf_802154_continuous_carrier()) {
692 LOG_ERR("Failed to enter continuous carrier state");
693 return -EIO;
694 }
695
696 LOG_DBG("Continuous carrier wave transmission started (channel: %d)",
697 nrf_802154_channel_get());
698
699 return 0;
700 }
701 #endif
702
703 #if !IS_ENABLED(CONFIG_IEEE802154_NRF5_EXT_IRQ_MGMT)
nrf5_radio_irq(const void * arg)704 static void nrf5_radio_irq(const void *arg)
705 {
706 ARG_UNUSED(arg);
707
708 nrf_802154_radio_irq_handler();
709 }
710 #endif
711
nrf5_irq_config(const struct device * dev)712 static void nrf5_irq_config(const struct device *dev)
713 {
714 ARG_UNUSED(dev);
715
716 #if !IS_ENABLED(CONFIG_IEEE802154_NRF5_EXT_IRQ_MGMT)
717 IRQ_CONNECT(RADIO_IRQn, NRF_802154_IRQ_PRIORITY,
718 nrf5_radio_irq, NULL, 0);
719 irq_enable(RADIO_IRQn);
720 #endif
721 }
722
nrf5_init(const struct device * dev)723 static int nrf5_init(const struct device *dev)
724 {
725 const struct nrf5_802154_config *nrf5_radio_cfg = NRF5_802154_CFG(dev);
726 struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
727
728 k_fifo_init(&nrf5_radio->rx_fifo);
729 k_sem_init(&nrf5_radio->tx_wait, 0, 1);
730 k_sem_init(&nrf5_radio->cca_wait, 0, 1);
731
732 nrf_802154_init();
733
734 nrf5_get_capabilities_at_boot();
735
736 nrf5_radio_cfg->irq_config_func(dev);
737
738 k_thread_create(&nrf5_radio->rx_thread, nrf5_radio->rx_stack,
739 CONFIG_IEEE802154_NRF5_RX_STACK_SIZE,
740 nrf5_rx_thread, nrf5_radio, NULL, NULL,
741 K_PRIO_COOP(2), 0, K_NO_WAIT);
742
743 k_thread_name_set(&nrf5_radio->rx_thread, "nrf5_rx");
744
745 LOG_INF("nRF5 802154 radio initialized");
746
747 return 0;
748 }
749
nrf5_iface_init(struct net_if * iface)750 static void nrf5_iface_init(struct net_if *iface)
751 {
752 const struct device *dev = net_if_get_device(iface);
753 struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
754
755 nrf5_get_eui64(nrf5_radio->mac);
756 net_if_set_link_addr(iface, nrf5_radio->mac, sizeof(nrf5_radio->mac),
757 NET_LINK_IEEE802154);
758
759 nrf5_radio->iface = iface;
760
761 ieee802154_init(iface);
762 }
763
764 #if defined(CONFIG_NRF_802154_ENCRYPTION)
nrf5_config_mac_keys(struct ieee802154_key * mac_keys)765 static void nrf5_config_mac_keys(struct ieee802154_key *mac_keys)
766 {
767 static nrf_802154_key_id_t stored_key_ids[NRF_802154_SECURITY_KEY_STORAGE_SIZE];
768 static uint8_t stored_ids[NRF_802154_SECURITY_KEY_STORAGE_SIZE];
769 uint8_t i;
770
771 for (i = 0; i < NRF_802154_SECURITY_KEY_STORAGE_SIZE && stored_key_ids[i].p_key_id; i++) {
772 nrf_802154_security_key_remove(&stored_key_ids[i]);
773 stored_key_ids[i].p_key_id = NULL;
774 }
775
776 i = 0;
777 for (struct ieee802154_key *keys = mac_keys; keys->key_value
778 && i < NRF_802154_SECURITY_KEY_STORAGE_SIZE; keys++, i++) {
779 nrf_802154_key_t key = {
780 .value.p_cleartext_key = keys->key_value,
781 .id.mode = keys->key_id_mode,
782 .id.p_key_id = &(keys->key_index),
783 .type = NRF_802154_KEY_CLEARTEXT,
784 .frame_counter = 0,
785 .use_global_frame_counter = !(keys->frame_counter_per_key),
786 };
787
788 __ASSERT_EVAL((void)nrf_802154_security_key_store(&key),
789 nrf_802154_security_error_t err = nrf_802154_security_key_store(&key),
790 err == NRF_802154_SECURITY_ERROR_NONE ||
791 err == NRF_802154_SECURITY_ERROR_ALREADY_PRESENT,
792 "Storing key failed, err: %d", err);
793
794 stored_ids[i] = *key.id.p_key_id;
795 stored_key_ids[i].mode = key.id.mode;
796 stored_key_ids[i].p_key_id = &stored_ids[i];
797 };
798 }
799 #endif /* CONFIG_NRF_802154_ENCRYPTION */
800
nrf5_configure(const struct device * dev,enum ieee802154_config_type type,const struct ieee802154_config * config)801 static int nrf5_configure(const struct device *dev,
802 enum ieee802154_config_type type,
803 const struct ieee802154_config *config)
804 {
805 ARG_UNUSED(dev);
806
807 switch (type) {
808 case IEEE802154_CONFIG_AUTO_ACK_FPB:
809 if (config->auto_ack_fpb.enabled) {
810 switch (config->auto_ack_fpb.mode) {
811 case IEEE802154_FPB_ADDR_MATCH_THREAD:
812 nrf_802154_src_addr_matching_method_set(
813 NRF_802154_SRC_ADDR_MATCH_THREAD);
814 break;
815
816 case IEEE802154_FPB_ADDR_MATCH_ZIGBEE:
817 nrf_802154_src_addr_matching_method_set(
818 NRF_802154_SRC_ADDR_MATCH_ZIGBEE);
819 break;
820
821 default:
822 return -EINVAL;
823 }
824 }
825
826 nrf_802154_auto_pending_bit_set(config->auto_ack_fpb.enabled);
827 break;
828
829 case IEEE802154_CONFIG_ACK_FPB:
830 if (config->ack_fpb.enabled) {
831 if (!nrf_802154_pending_bit_for_addr_set(
832 config->ack_fpb.addr,
833 config->ack_fpb.extended)) {
834 return -ENOMEM;
835 }
836
837 break;
838 }
839
840 if (config->ack_fpb.addr != NULL) {
841 if (!nrf_802154_pending_bit_for_addr_clear(
842 config->ack_fpb.addr,
843 config->ack_fpb.extended)) {
844 return -ENOENT;
845 }
846 } else {
847 nrf_802154_pending_bit_for_addr_reset(
848 config->ack_fpb.extended);
849 }
850
851 break;
852
853 case IEEE802154_CONFIG_PAN_COORDINATOR:
854 nrf_802154_pan_coord_set(config->pan_coordinator);
855 break;
856
857 case IEEE802154_CONFIG_PROMISCUOUS:
858 nrf_802154_promiscuous_set(config->promiscuous);
859 break;
860
861 case IEEE802154_CONFIG_EVENT_HANDLER:
862 nrf5_data.event_handler = config->event_handler;
863 break;
864
865 #if defined(CONFIG_NRF_802154_ENCRYPTION)
866 case IEEE802154_CONFIG_MAC_KEYS:
867 nrf5_config_mac_keys(config->mac_keys);
868 break;
869
870 case IEEE802154_CONFIG_FRAME_COUNTER:
871 nrf_802154_security_global_frame_counter_set(config->frame_counter);
872 break;
873
874 case IEEE802154_CONFIG_FRAME_COUNTER_IF_LARGER:
875 nrf_802154_security_global_frame_counter_set_if_larger(config->frame_counter);
876 break;
877 #endif /* CONFIG_NRF_802154_ENCRYPTION */
878
879 case IEEE802154_CONFIG_ENH_ACK_HEADER_IE: {
880 uint8_t short_addr_le[SHORT_ADDRESS_SIZE];
881 uint8_t ext_addr_le[EXTENDED_ADDRESS_SIZE];
882
883 sys_put_le16(config->ack_ie.short_addr, short_addr_le);
884 /**
885 * The extended address field passed to this function starts
886 * with the most significant octet and ends with the least
887 * significant octet (i.e. big endian byte order).
888 * The IEEE 802.15.4 transmission order mandates this order to be
889 * reversed (i.e. little endian byte order) in a transmitted frame.
890 *
891 * The nrf_802154_ack_data_set expects extended address in transmission
892 * order.
893 */
894 sys_memcpy_swap(ext_addr_le, config->ack_ie.ext_addr, EXTENDED_ADDRESS_SIZE);
895
896 if (config->ack_ie.data_len > 0) {
897 nrf_802154_ack_data_set(short_addr_le, false, config->ack_ie.data,
898 config->ack_ie.data_len, NRF_802154_ACK_DATA_IE);
899 nrf_802154_ack_data_set(ext_addr_le, true, config->ack_ie.data,
900 config->ack_ie.data_len, NRF_802154_ACK_DATA_IE);
901 } else {
902 nrf_802154_ack_data_clear(short_addr_le, false, NRF_802154_ACK_DATA_IE);
903 nrf_802154_ack_data_clear(ext_addr_le, true, NRF_802154_ACK_DATA_IE);
904 }
905 } break;
906
907 #if defined(CONFIG_IEEE802154_CSL_ENDPOINT)
908 case IEEE802154_CONFIG_CSL_RX_TIME: {
909 nrf_802154_csl_writer_anchor_time_set(config->csl_rx_time / NSEC_PER_USEC);
910 } break;
911
912 case IEEE802154_CONFIG_RX_SLOT: {
913 /* Note that even if the nrf_802154_receive_at function is not called in time
914 * (for example due to the call being blocked by higher priority threads) and
915 * the delayed reception window is not scheduled, the CSL phase will still be
916 * calculated as if the following reception windows were at times
917 * anchor_time + n * csl_period. The previously set
918 * anchor_time will be used for calculations.
919 */
920 nrf_802154_receive_at(config->rx_slot.start / NSEC_PER_USEC,
921 config->rx_slot.duration / NSEC_PER_USEC,
922 config->rx_slot.channel, DRX_SLOT_RX);
923 } break;
924
925 case IEEE802154_CONFIG_CSL_PERIOD:
926 nrf_802154_csl_writer_period_set(config->csl_period);
927 break;
928 #endif /* CONFIG_IEEE802154_CSL_ENDPOINT */
929
930 #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA)
931 case IEEE802154_OPENTHREAD_CONFIG_MAX_EXTRA_CCA_ATTEMPTS:
932 nrf5_data.max_extra_cca_attempts =
933 ((const struct ieee802154_openthread_config *)config)
934 ->max_extra_cca_attempts;
935 break;
936 #endif /* CONFIG_IEEE802154_NRF5_MULTIPLE_CCA */
937
938 default:
939 return -EINVAL;
940 }
941
942 return 0;
943 }
944
945 /* driver-allocated attribute memory - constant across all driver instances */
946 IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26);
947
nrf5_attr_get(const struct device * dev,enum ieee802154_attr attr,struct ieee802154_attr_value * value)948 static int nrf5_attr_get(const struct device *dev,
949 enum ieee802154_attr attr,
950 struct ieee802154_attr_value *value)
951 {
952 ARG_UNUSED(dev);
953
954 if (ieee802154_attr_get_channel_page_and_range(
955 attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915,
956 &drv_attr.phy_supported_channels, value) == 0) {
957 return 0;
958 }
959
960 switch ((uint32_t)attr) {
961 #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA)
962 /* TODO: t_recca and t_ccatx should be provided by the public API of the
963 * nRF 802.15.4 Radio Driver.
964 */
965 case IEEE802154_OPENTHREAD_ATTR_T_RECCA:
966 ((struct ieee802154_openthread_attr_value *)value)->t_recca = 0;
967 break;
968 case IEEE802154_OPENTHREAD_ATTR_T_CCATX:
969 ((struct ieee802154_openthread_attr_value *)value)->t_ccatx = 20;
970 break;
971 #endif
972 default:
973 return -ENOENT;
974 }
975
976 return 0;
977 }
978
979 /* nRF5 radio driver callbacks */
980
nrf_802154_received_timestamp_raw(uint8_t * data,int8_t power,uint8_t lqi,uint64_t time)981 void nrf_802154_received_timestamp_raw(uint8_t *data, int8_t power, uint8_t lqi, uint64_t time)
982 {
983 for (uint32_t i = 0; i < ARRAY_SIZE(nrf5_data.rx_frames); i++) {
984 if (nrf5_data.rx_frames[i].psdu != NULL) {
985 continue;
986 }
987
988 nrf5_data.rx_frames[i].psdu = data;
989 nrf5_data.rx_frames[i].rssi = power;
990 nrf5_data.rx_frames[i].lqi = lqi;
991
992 #if defined(CONFIG_NET_PKT_TIMESTAMP)
993 nrf5_data.rx_frames[i].time =
994 nrf_802154_timestamp_end_to_phr_convert(time, data[0]);
995 #endif
996
997 if (data[ACK_REQUEST_BYTE] & ACK_REQUEST_BIT) {
998 nrf5_data.rx_frames[i].ack_fpb = nrf5_data.last_frame_ack_fpb;
999 } else {
1000 nrf5_data.rx_frames[i].ack_fpb = false;
1001 }
1002
1003 nrf5_data.last_frame_ack_fpb = false;
1004
1005 k_fifo_put(&nrf5_data.rx_fifo, &nrf5_data.rx_frames[i]);
1006
1007 return;
1008 }
1009
1010 __ASSERT(false, "Not enough rx frames allocated for 15.4 driver");
1011 }
1012
nrf_802154_receive_failed(nrf_802154_rx_error_t error,uint32_t id)1013 void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id)
1014 {
1015 const struct device *dev = net_if_get_device(nrf5_data.iface);
1016
1017 #if defined(CONFIG_IEEE802154_CSL_ENDPOINT)
1018 if (id == DRX_SLOT_RX) {
1019 __ASSERT_NO_MSG(nrf5_data.event_handler);
1020 #if !defined(CONFIG_IEEE802154_CSL_DEBUG)
1021 /* When CSL debug option is used we intentionally avoid notifying the higher layer
1022 * about the finalization of a DRX slot, so that the radio stays in receive state
1023 * for receiving "out of slot" frames.
1024 * As a side effect, regular failure notifications would be reported with the
1025 * incorrect ID.
1026 */
1027 nrf5_data.event_handler(dev, IEEE802154_EVENT_SLEEP, NULL);
1028 #endif
1029 if (error == NRF_802154_RX_ERROR_DELAYED_TIMEOUT) {
1030 return;
1031 }
1032 }
1033 #else
1034 ARG_UNUSED(id);
1035 #endif
1036
1037 enum ieee802154_rx_fail_reason reason;
1038
1039 switch (error) {
1040 case NRF_802154_RX_ERROR_INVALID_FRAME:
1041 case NRF_802154_RX_ERROR_DELAYED_TIMEOUT:
1042 reason = IEEE802154_RX_FAIL_NOT_RECEIVED;
1043 break;
1044
1045 case NRF_802154_RX_ERROR_INVALID_FCS:
1046 reason = IEEE802154_RX_FAIL_INVALID_FCS;
1047 break;
1048
1049 case NRF_802154_RX_ERROR_INVALID_DEST_ADDR:
1050 reason = IEEE802154_RX_FAIL_ADDR_FILTERED;
1051 break;
1052
1053 default:
1054 reason = IEEE802154_RX_FAIL_OTHER;
1055 break;
1056 }
1057
1058 if (IS_ENABLED(CONFIG_IEEE802154_NRF5_LOG_RX_FAILURES)) {
1059 LOG_INF("Rx failed, error = %d", error);
1060 }
1061
1062 nrf5_data.last_frame_ack_fpb = false;
1063 if (nrf5_data.event_handler) {
1064 nrf5_data.event_handler(dev, IEEE802154_EVENT_RX_FAILED, (void *)&reason);
1065 }
1066 }
1067
nrf_802154_tx_ack_started(const uint8_t * data)1068 void nrf_802154_tx_ack_started(const uint8_t *data)
1069 {
1070 nrf5_data.last_frame_ack_fpb =
1071 data[FRAME_PENDING_BYTE] & FRAME_PENDING_BIT;
1072 }
1073
nrf_802154_transmitted_raw(uint8_t * frame,const nrf_802154_transmit_done_metadata_t * metadata)1074 void nrf_802154_transmitted_raw(uint8_t *frame,
1075 const nrf_802154_transmit_done_metadata_t *metadata)
1076 {
1077 ARG_UNUSED(frame);
1078
1079 nrf5_data.tx_result = NRF_802154_TX_ERROR_NONE;
1080 nrf5_data.tx_frame_is_secured = metadata->frame_props.is_secured;
1081 nrf5_data.tx_frame_mac_hdr_rdy = metadata->frame_props.dynamic_data_is_set;
1082 nrf5_data.ack_frame.psdu = metadata->data.transmitted.p_ack;
1083
1084 if (nrf5_data.ack_frame.psdu) {
1085 nrf5_data.ack_frame.rssi = metadata->data.transmitted.power;
1086 nrf5_data.ack_frame.lqi = metadata->data.transmitted.lqi;
1087
1088 #if defined(CONFIG_NET_PKT_TIMESTAMP)
1089 nrf5_data.ack_frame.time = nrf_802154_timestamp_end_to_phr_convert(
1090 metadata->data.transmitted.time, nrf5_data.ack_frame.psdu[0]);
1091 #endif
1092 }
1093
1094 k_sem_give(&nrf5_data.tx_wait);
1095 }
1096
nrf_802154_transmit_failed(uint8_t * frame,nrf_802154_tx_error_t error,const nrf_802154_transmit_done_metadata_t * metadata)1097 void nrf_802154_transmit_failed(uint8_t *frame,
1098 nrf_802154_tx_error_t error,
1099 const nrf_802154_transmit_done_metadata_t *metadata)
1100 {
1101 ARG_UNUSED(frame);
1102
1103 nrf5_data.tx_result = error;
1104 nrf5_data.tx_frame_is_secured = metadata->frame_props.is_secured;
1105 nrf5_data.tx_frame_mac_hdr_rdy = metadata->frame_props.dynamic_data_is_set;
1106
1107 k_sem_give(&nrf5_data.tx_wait);
1108 }
1109
nrf_802154_cca_done(bool channel_free)1110 void nrf_802154_cca_done(bool channel_free)
1111 {
1112 nrf5_data.channel_free = channel_free;
1113
1114 k_sem_give(&nrf5_data.cca_wait);
1115 }
1116
nrf_802154_cca_failed(nrf_802154_cca_error_t error)1117 void nrf_802154_cca_failed(nrf_802154_cca_error_t error)
1118 {
1119 ARG_UNUSED(error);
1120
1121 nrf5_data.channel_free = false;
1122
1123 k_sem_give(&nrf5_data.cca_wait);
1124 }
1125
nrf_802154_energy_detected(const nrf_802154_energy_detected_t * result)1126 void nrf_802154_energy_detected(const nrf_802154_energy_detected_t *result)
1127 {
1128 if (nrf5_data.energy_scan_done != NULL) {
1129 energy_scan_done_cb_t callback = nrf5_data.energy_scan_done;
1130
1131 nrf5_data.energy_scan_done = NULL;
1132 callback(net_if_get_device(nrf5_data.iface), result->ed_dbm);
1133 }
1134 }
1135
nrf_802154_energy_detection_failed(nrf_802154_ed_error_t error)1136 void nrf_802154_energy_detection_failed(nrf_802154_ed_error_t error)
1137 {
1138 if (nrf5_data.energy_scan_done != NULL) {
1139 energy_scan_done_cb_t callback = nrf5_data.energy_scan_done;
1140
1141 nrf5_data.energy_scan_done = NULL;
1142 callback(net_if_get_device(nrf5_data.iface), SHRT_MAX);
1143 }
1144 }
1145
1146 #if defined(CONFIG_NRF_802154_SER_HOST)
nrf_802154_serialization_error(const nrf_802154_ser_err_data_t * err)1147 void nrf_802154_serialization_error(const nrf_802154_ser_err_data_t *err)
1148 {
1149 __ASSERT(false, "802.15.4 serialization error: %d", err->reason);
1150 k_oops();
1151 }
1152 #endif
1153
1154 static const struct nrf5_802154_config nrf5_radio_cfg = {
1155 .irq_config_func = nrf5_irq_config,
1156 };
1157
1158 static struct ieee802154_radio_api nrf5_radio_api = {
1159 .iface_api.init = nrf5_iface_init,
1160
1161 .get_capabilities = nrf5_get_capabilities,
1162 .cca = nrf5_cca,
1163 .set_channel = nrf5_set_channel,
1164 .filter = nrf5_filter,
1165 .set_txpower = nrf5_set_txpower,
1166 .start = nrf5_start,
1167 .stop = nrf5_stop,
1168 #if defined(CONFIG_NRF_802154_CARRIER_FUNCTIONS)
1169 .continuous_carrier = nrf5_continuous_carrier,
1170 #endif
1171 .tx = nrf5_tx,
1172 .ed_scan = nrf5_energy_scan_start,
1173 .get_time = nrf5_get_time,
1174 .get_sch_acc = nrf5_get_acc,
1175 .configure = nrf5_configure,
1176 .attr_get = nrf5_attr_get
1177 };
1178
1179 #if defined(CONFIG_NET_L2_IEEE802154)
1180 #define L2 IEEE802154_L2
1181 #define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(IEEE802154_L2)
1182 #define MTU IEEE802154_MTU
1183 #elif defined(CONFIG_NET_L2_OPENTHREAD)
1184 #define L2 OPENTHREAD_L2
1185 #define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(OPENTHREAD_L2)
1186 #define MTU 1280
1187 #elif defined(CONFIG_NET_L2_CUSTOM_IEEE802154)
1188 #define L2 CUSTOM_IEEE802154_L2
1189 #define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(CUSTOM_IEEE802154_L2)
1190 #define MTU CONFIG_NET_L2_CUSTOM_IEEE802154_MTU
1191 #endif
1192
1193 #if defined(CONFIG_NET_L2_PHY_IEEE802154)
1194 NET_DEVICE_DT_INST_DEFINE(0, nrf5_init, NULL, &nrf5_data, &nrf5_radio_cfg,
1195 CONFIG_IEEE802154_NRF5_INIT_PRIO, &nrf5_radio_api, L2,
1196 L2_CTX_TYPE, MTU);
1197 #else
1198 DEVICE_DT_INST_DEFINE(0, nrf5_init, NULL, &nrf5_data, &nrf5_radio_cfg,
1199 POST_KERNEL, CONFIG_IEEE802154_NRF5_INIT_PRIO,
1200 &nrf5_radio_api);
1201 #endif
1202