1 /*
2  * Copyright (c) 2021 Telink Semiconductor
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT telink_b91_zb
8 
9 #include "rf.h"
10 #include "stimer.h"
11 
12 #define LOG_MODULE_NAME ieee802154_b91
13 #if defined(CONFIG_IEEE802154_DRIVER_LOG_LEVEL)
14 #define LOG_LEVEL CONFIG_IEEE802154_DRIVER_LOG_LEVEL
15 #else
16 #define LOG_LEVEL LOG_LEVEL_NONE
17 #endif
18 
19 #include <zephyr/logging/log.h>
20 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
21 
22 #include <zephyr/random/random.h>
23 #include <zephyr/net/ieee802154_radio.h>
24 #include <zephyr/irq.h>
25 #if defined(CONFIG_NET_L2_OPENTHREAD)
26 #include <zephyr/net/openthread.h>
27 #endif
28 
29 #include <zephyr/drivers/interrupt_controller/riscv_plic.h>
30 
31 #include "ieee802154_b91.h"
32 
33 
34 /* B91 data structure */
35 static struct b91_data data;
36 
37 /* Set filter PAN ID */
b91_set_pan_id(uint16_t pan_id)38 static int b91_set_pan_id(uint16_t pan_id)
39 {
40 	uint8_t pan_id_le[B91_PAN_ID_SIZE];
41 
42 	sys_put_le16(pan_id, pan_id_le);
43 	memcpy(data.filter_pan_id, pan_id_le, B91_PAN_ID_SIZE);
44 
45 	return 0;
46 }
47 
48 /* Set filter short address */
b91_set_short_addr(uint16_t short_addr)49 static int b91_set_short_addr(uint16_t short_addr)
50 {
51 	uint8_t short_addr_le[B91_SHORT_ADDRESS_SIZE];
52 
53 	sys_put_le16(short_addr, short_addr_le);
54 	memcpy(data.filter_short_addr, short_addr_le, B91_SHORT_ADDRESS_SIZE);
55 
56 	return 0;
57 }
58 
59 /* Set filter IEEE address */
b91_set_ieee_addr(const uint8_t * ieee_addr)60 static int b91_set_ieee_addr(const uint8_t *ieee_addr)
61 {
62 	memcpy(data.filter_ieee_addr, ieee_addr, B91_IEEE_ADDRESS_SIZE);
63 
64 	return 0;
65 }
66 
67 /* Filter PAN ID, short address and IEEE address */
b91_run_filter(uint8_t * rx_buffer)68 static bool b91_run_filter(uint8_t *rx_buffer)
69 {
70 	/* Check destination PAN Id */
71 	if (memcmp(&rx_buffer[B91_PAN_ID_OFFSET], data.filter_pan_id,
72 		   B91_PAN_ID_SIZE) != 0 &&
73 	    memcmp(&rx_buffer[B91_PAN_ID_OFFSET], B91_BROADCAST_ADDRESS,
74 		   B91_PAN_ID_SIZE) != 0) {
75 		return false;
76 	}
77 
78 	/* Check destination address */
79 	switch (rx_buffer[B91_DEST_ADDR_TYPE_OFFSET] & B91_DEST_ADDR_TYPE_MASK) {
80 	case B91_DEST_ADDR_TYPE_SHORT:
81 		/* First check if the destination is broadcast */
82 		/* If not broadcast, check if length and address matches */
83 		if (memcmp(&rx_buffer[B91_DEST_ADDR_OFFSET], B91_BROADCAST_ADDRESS,
84 			   B91_SHORT_ADDRESS_SIZE) != 0 &&
85 		    memcmp(&rx_buffer[B91_DEST_ADDR_OFFSET], data.filter_short_addr,
86 			   B91_SHORT_ADDRESS_SIZE) != 0) {
87 			return false;
88 		}
89 		break;
90 
91 	case B91_DEST_ADDR_TYPE_IEEE:
92 		/* If not broadcast, check if length and address matches */
93 		if ((net_if_get_link_addr(data.iface)->len != B91_IEEE_ADDRESS_SIZE) ||
94 		    memcmp(&rx_buffer[B91_DEST_ADDR_OFFSET], data.filter_ieee_addr,
95 			   B91_IEEE_ADDRESS_SIZE) != 0) {
96 			return false;
97 		}
98 		break;
99 
100 	default:
101 		return false;
102 	}
103 
104 	return true;
105 }
106 
107 /* Get MAC address */
b91_get_mac(const struct device * dev)108 static inline uint8_t *b91_get_mac(const struct device *dev)
109 {
110 	struct b91_data *b91 = dev->data;
111 
112 #if defined(CONFIG_IEEE802154_B91_RANDOM_MAC)
113 	uint32_t *ptr = (uint32_t *)(b91->mac_addr);
114 
115 	UNALIGNED_PUT(sys_rand32_get(), ptr);
116 	ptr = (uint32_t *)(b91->mac_addr + 4);
117 	UNALIGNED_PUT(sys_rand32_get(), ptr);
118 
119 	/*
120 	 * Clear bit 0 to ensure it isn't a multicast address and set
121 	 * bit 1 to indicate address is locally administered and may
122 	 * not be globally unique.
123 	 */
124 	b91->mac_addr[0] = (b91->mac_addr[0] & ~0x01) | 0x02;
125 #else
126 	/* Vendor Unique Identifier */
127 	b91->mac_addr[0] = 0xC4;
128 	b91->mac_addr[1] = 0x19;
129 	b91->mac_addr[2] = 0xD1;
130 	b91->mac_addr[3] = 0x00;
131 
132 	/* Extended Unique Identifier */
133 	b91->mac_addr[4] = CONFIG_IEEE802154_B91_MAC4;
134 	b91->mac_addr[5] = CONFIG_IEEE802154_B91_MAC5;
135 	b91->mac_addr[6] = CONFIG_IEEE802154_B91_MAC6;
136 	b91->mac_addr[7] = CONFIG_IEEE802154_B91_MAC7;
137 #endif
138 
139 	return b91->mac_addr;
140 }
141 
142 /* Convert RSSI to LQI */
b91_convert_rssi_to_lqi(int8_t rssi)143 static uint8_t b91_convert_rssi_to_lqi(int8_t rssi)
144 {
145 	uint32_t lqi32 = 0;
146 
147 	/* check for MIN value */
148 	if (rssi < B91_RSSI_TO_LQI_MIN) {
149 		return 0;
150 	}
151 
152 	/* convert RSSI to LQI */
153 	lqi32 = B91_RSSI_TO_LQI_SCALE * (rssi - B91_RSSI_TO_LQI_MIN);
154 
155 	/* check for MAX value */
156 	if (lqi32 > 0xFF) {
157 		lqi32 = 0xFF;
158 	}
159 
160 	return (uint8_t)lqi32;
161 }
162 
163 /* Update RSSI and LQI parameters */
b91_update_rssi_and_lqi(struct net_pkt * pkt)164 static void b91_update_rssi_and_lqi(struct net_pkt *pkt)
165 {
166 	int8_t rssi;
167 	uint8_t lqi;
168 
169 	rssi = ((signed char)(data.rx_buffer
170 			      [data.rx_buffer[B91_LENGTH_OFFSET] + B91_RSSI_OFFSET])) - 110;
171 	lqi = b91_convert_rssi_to_lqi(rssi);
172 
173 	net_pkt_set_ieee802154_lqi(pkt, lqi);
174 	net_pkt_set_ieee802154_rssi_dbm(pkt, rssi);
175 }
176 
177 /* Prepare TX buffer */
b91_set_tx_payload(uint8_t * payload,uint8_t payload_len)178 static int b91_set_tx_payload(uint8_t *payload, uint8_t payload_len)
179 {
180 	unsigned char rf_data_len;
181 	unsigned int rf_tx_dma_len;
182 
183 	/* See Telink SDK Dev Handbook, AN-21010600, section 21.5.2.2. */
184 	if (payload_len > (B91_TRX_LENGTH - B91_PAYLOAD_OFFSET - IEEE802154_FCS_LENGTH)) {
185 		return -EINVAL;
186 	}
187 
188 	rf_data_len = payload_len + 1;
189 	rf_tx_dma_len = rf_tx_packet_dma_len(rf_data_len);
190 	data.tx_buffer[0] = rf_tx_dma_len & 0xff;
191 	data.tx_buffer[1] = (rf_tx_dma_len >> 8) & 0xff;
192 	data.tx_buffer[2] = (rf_tx_dma_len >> 16) & 0xff;
193 	data.tx_buffer[3] = (rf_tx_dma_len >> 24) & 0xff;
194 	data.tx_buffer[4] = payload_len + IEEE802154_FCS_LENGTH;
195 	memcpy(data.tx_buffer + B91_PAYLOAD_OFFSET, payload, payload_len);
196 
197 	return 0;
198 }
199 
200 /* Enable ack handler */
b91_handle_ack_en(void)201 static void b91_handle_ack_en(void)
202 {
203 	data.ack_handler_en = true;
204 }
205 
206 /* Disable ack handler */
b91_handle_ack_dis(void)207 static void b91_handle_ack_dis(void)
208 {
209 	data.ack_handler_en = false;
210 }
211 
212 /* Handle acknowledge packet */
b91_handle_ack(void)213 static void b91_handle_ack(void)
214 {
215 	struct net_pkt *ack_pkt;
216 
217 	/* allocate ack packet */
218 	ack_pkt = net_pkt_rx_alloc_with_buffer(data.iface, B91_ACK_FRAME_LEN,
219 					       AF_UNSPEC, 0, K_NO_WAIT);
220 	if (!ack_pkt) {
221 		LOG_ERR("No free packet available.");
222 		return;
223 	}
224 
225 	/* update packet data */
226 	if (net_pkt_write(ack_pkt, data.rx_buffer + B91_PAYLOAD_OFFSET,
227 			  B91_ACK_FRAME_LEN) < 0) {
228 		LOG_ERR("Failed to write to a packet.");
229 		goto out;
230 	}
231 
232 	/* update RSSI and LQI */
233 	b91_update_rssi_and_lqi(ack_pkt);
234 
235 	/* init net cursor */
236 	net_pkt_cursor_init(ack_pkt);
237 
238 	/* handle ack */
239 	if (ieee802154_handle_ack(data.iface, ack_pkt) != NET_OK) {
240 		LOG_INF("ACK packet not handled - releasing.");
241 	}
242 
243 	/* release ack_wait semaphore */
244 	k_sem_give(&data.ack_wait);
245 
246 out:
247 	net_pkt_unref(ack_pkt);
248 }
249 
250 /* Send acknowledge packet */
b91_send_ack(uint8_t seq_num)251 static void b91_send_ack(uint8_t seq_num)
252 {
253 	uint8_t ack_buf[] = { B91_ACK_TYPE, 0, seq_num };
254 
255 	if (b91_set_tx_payload(ack_buf, sizeof(ack_buf))) {
256 		return;
257 	}
258 
259 	rf_set_txmode();
260 	delay_us(CONFIG_IEEE802154_B91_SET_TXRX_DELAY_US);
261 	rf_tx_pkt(data.tx_buffer);
262 }
263 
264 /* RX IRQ handler */
b91_rf_rx_isr(void)265 static void b91_rf_rx_isr(void)
266 {
267 	uint8_t status;
268 	uint8_t length;
269 	uint8_t *payload;
270 	struct net_pkt *pkt;
271 
272 	/* disable DMA and clear IRQ flag */
273 	dma_chn_dis(DMA1);
274 	rf_clr_irq_status(FLD_RF_IRQ_RX);
275 
276 	/* check CRC */
277 	if (rf_zigbee_packet_crc_ok(data.rx_buffer)) {
278 		/* get payload length */
279 		if (IS_ENABLED(CONFIG_IEEE802154_RAW_MODE) ||
280 		    IS_ENABLED(CONFIG_NET_L2_OPENTHREAD)) {
281 			length = data.rx_buffer[B91_LENGTH_OFFSET];
282 		} else {
283 			length = data.rx_buffer[B91_LENGTH_OFFSET] - B91_FCS_LENGTH;
284 		}
285 
286 		/* check length */
287 		if ((length < B91_PAYLOAD_MIN) || (length > B91_PAYLOAD_MAX)) {
288 			LOG_ERR("Invalid length\n");
289 			goto exit;
290 		}
291 
292 		/* get payload */
293 		payload = (uint8_t *)(data.rx_buffer + B91_PAYLOAD_OFFSET);
294 
295 		/* handle acknowledge packet if enabled */
296 		if ((length == (B91_ACK_FRAME_LEN + B91_FCS_LENGTH)) &&
297 		    ((payload[B91_FRAME_TYPE_OFFSET] & B91_FRAME_TYPE_MASK) == B91_ACK_TYPE)) {
298 			if (data.ack_handler_en) {
299 				b91_handle_ack();
300 			}
301 			goto exit;
302 		}
303 
304 		/* run filter (check PAN ID and destination address) */
305 		if (b91_run_filter(payload) == false) {
306 			LOG_DBG("Packet received is not addressed to me");
307 			goto exit;
308 		}
309 
310 		/* send ack if requested */
311 		if (payload[B91_FRAME_TYPE_OFFSET] & B91_ACK_REQUEST) {
312 			b91_send_ack(payload[B91_DSN_OFFSET]);
313 		}
314 
315 		/* get packet pointer from NET stack */
316 		pkt = net_pkt_rx_alloc_with_buffer(data.iface, length, AF_UNSPEC, 0, K_NO_WAIT);
317 		if (!pkt) {
318 			LOG_ERR("No pkt available");
319 			goto exit;
320 		}
321 
322 		/* update packet data */
323 		if (net_pkt_write(pkt, payload, length)) {
324 			LOG_ERR("Failed to write to a packet.");
325 			net_pkt_unref(pkt);
326 			goto exit;
327 		}
328 
329 		/* update RSSI and LQI parameters */
330 		b91_update_rssi_and_lqi(pkt);
331 
332 		/* transfer data to NET stack */
333 		status = net_recv_data(data.iface, pkt);
334 		if (status < 0) {
335 			LOG_ERR("RCV Packet dropped by NET stack: %d", status);
336 			net_pkt_unref(pkt);
337 		}
338 	}
339 
340 exit:
341 	dma_chn_en(DMA1);
342 }
343 
344 /* TX IRQ handler */
b91_rf_tx_isr(void)345 static void b91_rf_tx_isr(void)
346 {
347 	/* clear irq status */
348 	rf_clr_irq_status(FLD_RF_IRQ_TX);
349 
350 	/* release tx semaphore */
351 	k_sem_give(&data.tx_wait);
352 
353 	/* set to rx mode */
354 	rf_set_rxmode();
355 }
356 
357 /* IRQ handler */
b91_rf_isr(void)358 static void b91_rf_isr(void)
359 {
360 	if (rf_get_irq_status(FLD_RF_IRQ_RX)) {
361 		b91_rf_rx_isr();
362 	} else if (rf_get_irq_status(FLD_RF_IRQ_TX)) {
363 		b91_rf_tx_isr();
364 	} else {
365 		rf_clr_irq_status(FLD_RF_IRQ_ALL);
366 	}
367 }
368 
369 /* Driver initialization */
b91_init(const struct device * dev)370 static int b91_init(const struct device *dev)
371 {
372 	struct b91_data *b91 = dev->data;
373 
374 	/* init semaphores */
375 	k_sem_init(&b91->tx_wait, 0, 1);
376 	k_sem_init(&b91->ack_wait, 0, 1);
377 
378 	/* init rf module */
379 	rf_mode_init();
380 	rf_set_zigbee_250K_mode();
381 	rf_set_tx_dma(2, B91_TRX_LENGTH);
382 	rf_set_rx_dma(data.rx_buffer, 3, B91_TRX_LENGTH);
383 	rf_set_rxmode();
384 
385 	/* init IRQs */
386 	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), b91_rf_isr, 0, 0);
387 	riscv_plic_irq_enable(DT_INST_IRQN(0));
388 	riscv_plic_set_priority(DT_INST_IRQN(0), DT_INST_IRQ(0, priority));
389 	rf_set_irq_mask(FLD_RF_IRQ_RX | FLD_RF_IRQ_TX);
390 
391 	/* init data variables */
392 	data.is_started = true;
393 	data.ack_handler_en = false;
394 	data.current_channel = 0;
395 
396 	return 0;
397 }
398 
399 /* API implementation: iface_init */
b91_iface_init(struct net_if * iface)400 static void b91_iface_init(struct net_if *iface)
401 {
402 	const struct device *dev = net_if_get_device(iface);
403 	struct b91_data *b91 = dev->data;
404 	uint8_t *mac = b91_get_mac(dev);
405 
406 	net_if_set_link_addr(iface, mac, B91_IEEE_ADDRESS_SIZE, NET_LINK_IEEE802154);
407 
408 	b91->iface = iface;
409 
410 	ieee802154_init(iface);
411 }
412 
413 /* API implementation: get_capabilities */
b91_get_capabilities(const struct device * dev)414 static enum ieee802154_hw_caps b91_get_capabilities(const struct device *dev)
415 {
416 	ARG_UNUSED(dev);
417 
418 	return IEEE802154_HW_FCS | IEEE802154_HW_FILTER |
419 	       IEEE802154_HW_TX_RX_ACK | IEEE802154_HW_RX_TX_ACK;
420 }
421 
422 /* API implementation: cca */
b91_cca(const struct device * dev)423 static int b91_cca(const struct device *dev)
424 {
425 	ARG_UNUSED(dev);
426 
427 	unsigned int t1 = stimer_get_tick();
428 
429 	while (!clock_time_exceed(t1, B91_CCA_TIME_MAX_US)) {
430 		if (rf_get_rssi() < CONFIG_IEEE802154_B91_CCA_RSSI_THRESHOLD) {
431 			return 0;
432 		}
433 	}
434 
435 	return -EBUSY;
436 }
437 
438 /* API implementation: set_channel */
b91_set_channel(const struct device * dev,uint16_t channel)439 static int b91_set_channel(const struct device *dev, uint16_t channel)
440 {
441 	ARG_UNUSED(dev);
442 
443 	if (channel > 26) {
444 		return -EINVAL;
445 	}
446 
447 	if (channel < 11) {
448 		return -ENOTSUP;
449 	}
450 
451 	if (data.current_channel != channel) {
452 		data.current_channel = channel;
453 		rf_set_chn(B91_LOGIC_CHANNEL_TO_PHYSICAL(channel));
454 		rf_set_rxmode();
455 	}
456 
457 	return 0;
458 }
459 
460 /* API implementation: filter */
b91_filter(const struct device * dev,bool set,enum ieee802154_filter_type type,const struct ieee802154_filter * filter)461 static int b91_filter(const struct device *dev,
462 		      bool set,
463 		      enum ieee802154_filter_type type,
464 		      const struct ieee802154_filter *filter)
465 {
466 	if (!set) {
467 		return -ENOTSUP;
468 	}
469 
470 	if (type == IEEE802154_FILTER_TYPE_IEEE_ADDR) {
471 		return b91_set_ieee_addr(filter->ieee_addr);
472 	} else if (type == IEEE802154_FILTER_TYPE_SHORT_ADDR) {
473 		return b91_set_short_addr(filter->short_addr);
474 	} else if (type == IEEE802154_FILTER_TYPE_PAN_ID) {
475 		return b91_set_pan_id(filter->pan_id);
476 	}
477 
478 	return -ENOTSUP;
479 }
480 
481 /* API implementation: set_txpower */
b91_set_txpower(const struct device * dev,int16_t dbm)482 static int b91_set_txpower(const struct device *dev, int16_t dbm)
483 {
484 	ARG_UNUSED(dev);
485 
486 	/* check for supported Min/Max range */
487 	if (dbm < B91_TX_POWER_MIN) {
488 		dbm = B91_TX_POWER_MIN;
489 	} else if (dbm > B91_TX_POWER_MAX) {
490 		dbm = B91_TX_POWER_MAX;
491 	}
492 
493 	/* set TX power */
494 	rf_set_power_level(b91_tx_pwr_lt[dbm - B91_TX_POWER_MIN]);
495 
496 	return 0;
497 }
498 
499 /* API implementation: start */
b91_start(const struct device * dev)500 static int b91_start(const struct device *dev)
501 {
502 	ARG_UNUSED(dev);
503 
504 	/* check if RF is already started */
505 	if (!data.is_started) {
506 		rf_set_rxmode();
507 		delay_us(CONFIG_IEEE802154_B91_SET_TXRX_DELAY_US);
508 		riscv_plic_irq_enable(DT_INST_IRQN(0));
509 		data.is_started = true;
510 	}
511 
512 	return 0;
513 }
514 
515 /* API implementation: stop */
b91_stop(const struct device * dev)516 static int b91_stop(const struct device *dev)
517 {
518 	ARG_UNUSED(dev);
519 
520 	/* check if RF is already stopped */
521 	if (data.is_started) {
522 		riscv_plic_irq_disable(DT_INST_IRQN(0));
523 		rf_set_tx_rx_off();
524 		delay_us(CONFIG_IEEE802154_B91_SET_TXRX_DELAY_US);
525 		data.is_started = false;
526 	}
527 
528 	return 0;
529 }
530 
531 /* API implementation: tx */
b91_tx(const struct device * dev,enum ieee802154_tx_mode mode,struct net_pkt * pkt,struct net_buf * frag)532 static int b91_tx(const struct device *dev,
533 		  enum ieee802154_tx_mode mode,
534 		  struct net_pkt *pkt,
535 		  struct net_buf *frag)
536 {
537 	ARG_UNUSED(pkt);
538 
539 	int status;
540 	struct b91_data *b91 = dev->data;
541 
542 	/* check for supported mode */
543 	if (mode != IEEE802154_TX_MODE_DIRECT) {
544 		LOG_DBG("TX mode %d not supported", mode);
545 		return -ENOTSUP;
546 	}
547 
548 	/* prepare tx buffer */
549 	status = b91_set_tx_payload(frag->data, frag->len);
550 	if (status) {
551 		return status;
552 	}
553 
554 	/* reset semaphores */
555 	k_sem_reset(&b91->tx_wait);
556 	k_sem_reset(&b91->ack_wait);
557 
558 	/* start transmission */
559 	rf_set_txmode();
560 	delay_us(CONFIG_IEEE802154_B91_SET_TXRX_DELAY_US);
561 	rf_tx_pkt(data.tx_buffer);
562 
563 	/* wait for tx done */
564 	status = k_sem_take(&b91->tx_wait, K_MSEC(B91_TX_WAIT_TIME_MS));
565 	if (status != 0) {
566 		rf_set_rxmode();
567 		return -EIO;
568 	}
569 
570 	/* wait for ACK if requested */
571 	if (frag->data[B91_FRAME_TYPE_OFFSET] & B91_ACK_REQUEST) {
572 		b91_handle_ack_en();
573 		status = k_sem_take(&b91->ack_wait, K_MSEC(B91_ACK_WAIT_TIME_MS));
574 		b91_handle_ack_dis();
575 	}
576 
577 	return status;
578 }
579 
580 /* API implementation: ed_scan */
b91_ed_scan(const struct device * dev,uint16_t duration,energy_scan_done_cb_t done_cb)581 static int b91_ed_scan(const struct device *dev, uint16_t duration,
582 		       energy_scan_done_cb_t done_cb)
583 {
584 	ARG_UNUSED(dev);
585 	ARG_UNUSED(duration);
586 	ARG_UNUSED(done_cb);
587 
588 	/* ed_scan not supported */
589 
590 	return -ENOTSUP;
591 }
592 
593 /* API implementation: configure */
b91_configure(const struct device * dev,enum ieee802154_config_type type,const struct ieee802154_config * config)594 static int b91_configure(const struct device *dev,
595 			 enum ieee802154_config_type type,
596 			 const struct ieee802154_config *config)
597 {
598 	ARG_UNUSED(dev);
599 	ARG_UNUSED(type);
600 	ARG_UNUSED(config);
601 
602 	/* configure not supported */
603 
604 	return -ENOTSUP;
605 }
606 
607 /* driver-allocated attribute memory - constant across all driver instances */
608 IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26);
609 
610 /* API implementation: attr_get */
b91_attr_get(const struct device * dev,enum ieee802154_attr attr,struct ieee802154_attr_value * value)611 static int b91_attr_get(const struct device *dev, enum ieee802154_attr attr,
612 			struct ieee802154_attr_value *value)
613 {
614 	ARG_UNUSED(dev);
615 
616 	return ieee802154_attr_get_channel_page_and_range(
617 		attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915,
618 		&drv_attr.phy_supported_channels, value);
619 }
620 
621 /* IEEE802154 driver APIs structure */
622 static const struct ieee802154_radio_api b91_radio_api = {
623 	.iface_api.init = b91_iface_init,
624 	.get_capabilities = b91_get_capabilities,
625 	.cca = b91_cca,
626 	.set_channel = b91_set_channel,
627 	.filter = b91_filter,
628 	.set_txpower = b91_set_txpower,
629 	.start = b91_start,
630 	.stop = b91_stop,
631 	.tx = b91_tx,
632 	.ed_scan = b91_ed_scan,
633 	.configure = b91_configure,
634 	.attr_get = b91_attr_get,
635 };
636 
637 
638 #if defined(CONFIG_NET_L2_IEEE802154)
639 #define L2 IEEE802154_L2
640 #define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(IEEE802154_L2)
641 #define MTU 125
642 #elif defined(CONFIG_NET_L2_OPENTHREAD)
643 #define L2 OPENTHREAD_L2
644 #define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(OPENTHREAD_L2)
645 #define MTU 1280
646 #endif
647 
648 
649 /* IEEE802154 driver registration */
650 #if defined(CONFIG_NET_L2_IEEE802154) || defined(CONFIG_NET_L2_OPENTHREAD)
651 NET_DEVICE_DT_INST_DEFINE(0, b91_init, NULL, &data, NULL,
652 			  CONFIG_IEEE802154_B91_INIT_PRIO,
653 			  &b91_radio_api, L2, L2_CTX_TYPE, MTU);
654 #else
655 DEVICE_DT_INST_DEFINE(0, b91_init, NULL, &data, NULL,
656 		      POST_KERNEL, CONFIG_IEEE802154_B91_INIT_PRIO,
657 		      &b91_radio_api);
658 #endif
659