1 /*
2  * Copyright (c) 2019 Brett Witherspoon
3  * Copyright (c) 2020 Friedt Professional Engineering Services, Inc
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #define DT_DRV_COMPAT ti_cc13xx_cc26xx_ieee802154
9 
10 #define LOG_LEVEL CONFIG_IEEE802154_DRIVER_LOG_LEVEL
11 #include <zephyr/logging/log.h>
12 LOG_MODULE_REGISTER(ieee802154_cc13xx_cc26xx);
13 
14 #include <zephyr/device.h>
15 #include <errno.h>
16 #include <zephyr/sys/byteorder.h>
17 #include <zephyr/net/ieee802154_radio.h>
18 #include <zephyr/net/ieee802154.h>
19 #include <zephyr/net/net_pkt.h>
20 #include <zephyr/random/random.h>
21 #include <string.h>
22 #include <zephyr/sys/sys_io.h>
23 
24 #include <driverlib/rf_ieee_mailbox.h>
25 #include <driverlib/rfc.h>
26 #include <inc/hw_ccfg.h>
27 #include <inc/hw_fcfg1.h>
28 #include <rf_patches/rf_patch_cpe_multi_protocol.h>
29 
30 #include <ti/drivers/rf/RF.h>
31 
32 #include "ieee802154_cc13xx_cc26xx.h"
33 
34 #if defined(CONFIG_NET_L2_OPENTHREAD)
35 #include <zephyr/net/openthread.h>
36 #endif
37 
38 /* Overrides from SmartRF Studio 7 2.13.0 */
39 static uint32_t overrides[] = {
40 	/* DC/DC regulator: In Tx, use DCDCCTL5[3:0]=0x3 (DITHER_EN=0 and IPEAK=3). */
41 	0x00F388D3,
42 	/* Rx: Set LNA bias current offset to +15 to saturate trim to max (default: 0) */
43 	0x000F8883,
44 	0xFFFFFFFF
45 };
46 
47 /* 2.4 GHz power table */
48 static const RF_TxPowerTable_Entry txPowerTable_2_4[] = {
49 	{-20, RF_TxPowerTable_DEFAULT_PA_ENTRY(6, 3, 0, 2)},
50 	{-15, RF_TxPowerTable_DEFAULT_PA_ENTRY(10, 3, 0, 3)},
51 	{-10, RF_TxPowerTable_DEFAULT_PA_ENTRY(15, 3, 0, 5)},
52 	{-5, RF_TxPowerTable_DEFAULT_PA_ENTRY(22, 3, 0, 9)},
53 	{0, RF_TxPowerTable_DEFAULT_PA_ENTRY(19, 1, 0, 20)},
54 	{1, RF_TxPowerTable_DEFAULT_PA_ENTRY(22, 1, 0, 20)},
55 	{2, RF_TxPowerTable_DEFAULT_PA_ENTRY(25, 1, 0, 25)},
56 	{3, RF_TxPowerTable_DEFAULT_PA_ENTRY(29, 1, 0, 28)},
57 	{4, RF_TxPowerTable_DEFAULT_PA_ENTRY(35, 1, 0, 39)},
58 	{5, RF_TxPowerTable_DEFAULT_PA_ENTRY(23, 0, 0, 57)},
59 	RF_TxPowerTable_TERMINATION_ENTRY,
60 };
61 
62 static void ieee802154_cc13xx_cc26xx_rx_done(
63 	struct ieee802154_cc13xx_cc26xx_data *drv_data);
64 static int ieee802154_cc13xx_cc26xx_stop(const struct device *dev);
65 
66 /* TODO remove when rf driver bugfix is pulled in */
update_saved_cmdhandle(RF_CmdHandle ch,RF_CmdHandle * saved)67 static void update_saved_cmdhandle(RF_CmdHandle ch, RF_CmdHandle *saved)
68 {
69 	*saved = MAX(ch, *saved);
70 }
71 
72 /* This is really the TX callback, because CSMA and TX are chained */
cmd_ieee_csma_callback(RF_Handle h,RF_CmdHandle ch,RF_EventMask e)73 static void cmd_ieee_csma_callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
74 {
75 	ARG_UNUSED(h);
76 
77 	const struct device *const dev = DEVICE_DT_INST_GET(0);
78 	struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data;
79 
80 	update_saved_cmdhandle(ch, (RF_CmdHandle *) &drv_data->saved_cmdhandle);
81 
82 	LOG_DBG("e: 0x%" PRIx64, e);
83 
84 	if (e & RF_EventInternalError) {
85 		LOG_ERR("Internal error");
86 	}
87 }
88 
cmd_ieee_rx_callback(RF_Handle h,RF_CmdHandle ch,RF_EventMask e)89 static void cmd_ieee_rx_callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
90 {
91 	ARG_UNUSED(h);
92 
93 	const struct device *const dev = DEVICE_DT_INST_GET(0);
94 	struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data;
95 
96 	update_saved_cmdhandle(ch, (RF_CmdHandle *) &drv_data->saved_cmdhandle);
97 
98 	LOG_DBG("e: 0x%" PRIx64, e);
99 
100 	if (e & RF_EventRxBufFull) {
101 		LOG_WRN("RX buffer is full");
102 	}
103 
104 	if (e & RF_EventInternalError) {
105 		LOG_ERR("Internal error");
106 	}
107 
108 	if (e & RF_EventRxEntryDone) {
109 		ieee802154_cc13xx_cc26xx_rx_done(drv_data);
110 	}
111 }
112 
client_error_callback(RF_Handle h,RF_CmdHandle ch,RF_EventMask e)113 static void client_error_callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
114 {
115 	ARG_UNUSED(h);
116 	ARG_UNUSED(ch);
117 	LOG_DBG("e: 0x%" PRIx64, e);
118 }
119 
client_event_callback(RF_Handle h,RF_ClientEvent event,void * arg)120 static void client_event_callback(RF_Handle h, RF_ClientEvent event, void *arg)
121 {
122 	ARG_UNUSED(h);
123 	LOG_DBG("event: %d arg: %p", event, arg);
124 }
125 
126 static enum ieee802154_hw_caps
ieee802154_cc13xx_cc26xx_get_capabilities(const struct device * dev)127 ieee802154_cc13xx_cc26xx_get_capabilities(const struct device *dev)
128 {
129 	return IEEE802154_HW_FCS | IEEE802154_HW_FILTER |
130 	       IEEE802154_HW_RX_TX_ACK | IEEE802154_HW_TX_RX_ACK | IEEE802154_HW_CSMA |
131 	       IEEE802154_HW_RETRANSMISSION;
132 }
133 
ieee802154_cc13xx_cc26xx_cca(const struct device * dev)134 static int ieee802154_cc13xx_cc26xx_cca(const struct device *dev)
135 {
136 	struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data;
137 	RF_Stat status;
138 
139 	status = RF_runImmediateCmd(drv_data->rf_handle,
140 		(uint32_t *)&drv_data->cmd_ieee_cca_req);
141 	if (status != RF_StatSuccess) {
142 		LOG_ERR("Failed to request CCA (0x%x)", status);
143 		return -EIO;
144 	}
145 
146 	switch (drv_data->cmd_ieee_cca_req.ccaInfo.ccaState) {
147 	case 0:
148 		return 0;
149 	case 1:
150 		return -EBUSY;
151 	default:
152 		return -EIO;
153 	}
154 }
155 
ieee802154_cc13xx_cc26xx_channel_to_frequency(uint16_t channel,uint16_t * frequency,uint16_t * fractFreq)156 static inline int ieee802154_cc13xx_cc26xx_channel_to_frequency(
157 	uint16_t channel, uint16_t *frequency, uint16_t *fractFreq)
158 {
159 	__ASSERT_NO_MSG(frequency != NULL);
160 	__ASSERT_NO_MSG(fractFreq != NULL);
161 
162 	/* See IEEE 802.15.4-2020, section 10.1.3.3. */
163 	if (channel >= 11 && channel <= 26) {
164 		*frequency = 2405 + 5 * (channel - 11);
165 		*fractFreq = 0;
166 		return 0;
167 	} else {
168 		/* TODO: Support sub-GHz for CC13xx rather than having separate drivers */
169 		*frequency = 0;
170 		*fractFreq = 0;
171 		return channel < 11 ? -ENOTSUP : -EINVAL;
172 	}
173 }
174 
ieee802154_cc13xx_cc26xx_set_channel(const struct device * dev,uint16_t channel)175 static int ieee802154_cc13xx_cc26xx_set_channel(const struct device *dev,
176 						uint16_t channel)
177 {
178 	int ret;
179 	RF_CmdHandle cmd_handle;
180 	RF_EventMask reason;
181 	uint16_t freq, fract;
182 	struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data;
183 
184 	ret = ieee802154_cc13xx_cc26xx_channel_to_frequency(channel, &freq, &fract);
185 	if (ret < 0) {
186 		return ret;
187 	}
188 
189 	/* Abort FG and BG processes */
190 	if (ieee802154_cc13xx_cc26xx_stop(dev) < 0) {
191 		ret = -EIO;
192 		goto out;
193 	}
194 
195 	/* Block TX while changing channel */
196 	k_mutex_lock(&drv_data->tx_mutex, K_FOREVER);
197 
198 	/* Set the frequency */
199 	drv_data->cmd_fs.status = IDLE;
200 	drv_data->cmd_fs.frequency = freq;
201 	drv_data->cmd_fs.fractFreq = fract;
202 	reason = RF_runCmd(drv_data->rf_handle, (RF_Op *)&drv_data->cmd_fs,
203 			   RF_PriorityNormal, NULL, 0);
204 	if (reason != RF_EventLastCmdDone) {
205 		LOG_ERR("Failed to set frequency: 0x%" PRIx64, reason);
206 		ret = -EIO;
207 		goto out;
208 	}
209 
210 	/* Run BG receive process on requested channel */
211 	drv_data->cmd_ieee_rx.status = IDLE;
212 	drv_data->cmd_ieee_rx.channel = channel;
213 	cmd_handle = RF_postCmd(drv_data->rf_handle,
214 		(RF_Op *)&drv_data->cmd_ieee_rx, RF_PriorityNormal,
215 		cmd_ieee_rx_callback, RF_EventRxEntryDone);
216 	if (cmd_handle < 0) {
217 		LOG_ERR("Failed to post RX command (%d)", cmd_handle);
218 		ret = -EIO;
219 		goto out;
220 	}
221 
222 	ret = 0;
223 
224 out:
225 	k_mutex_unlock(&drv_data->tx_mutex);
226 	return ret;
227 }
228 
229 /* TODO remove when rf driver bugfix is pulled in */
ieee802154_cc13xx_cc26xx_reset_channel(const struct device * dev)230 static int ieee802154_cc13xx_cc26xx_reset_channel(
231 	const struct device *dev)
232 {
233 	uint8_t channel;
234 	struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data;
235 
236 	/* extract the channel from cmd_ieee_rx */
237 	channel = drv_data->cmd_ieee_rx.channel;
238 
239 	__ASSERT_NO_MSG(11 <= channel && channel <= 26);
240 
241 	LOG_DBG("re-setting channel to %u", channel);
242 
243 	return ieee802154_cc13xx_cc26xx_set_channel(dev, channel);
244 }
245 
246 static int
ieee802154_cc13xx_cc26xx_filter(const struct device * dev,bool set,enum ieee802154_filter_type type,const struct ieee802154_filter * filter)247 ieee802154_cc13xx_cc26xx_filter(const struct device *dev, bool set,
248 				enum ieee802154_filter_type type,
249 				const struct ieee802154_filter *filter)
250 {
251 	struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data;
252 
253 	if (!set) {
254 		return -ENOTSUP;
255 	}
256 
257 	if (type == IEEE802154_FILTER_TYPE_IEEE_ADDR) {
258 		memcpy((uint8_t *)&drv_data->cmd_ieee_rx.localExtAddr,
259 		       filter->ieee_addr,
260 		       sizeof(drv_data->cmd_ieee_rx.localExtAddr));
261 	} else if (type == IEEE802154_FILTER_TYPE_SHORT_ADDR) {
262 		drv_data->cmd_ieee_rx.localShortAddr = filter->short_addr;
263 	} else if (type == IEEE802154_FILTER_TYPE_PAN_ID) {
264 		drv_data->cmd_ieee_rx.localPanID = filter->pan_id;
265 	} else {
266 		return -ENOTSUP;
267 	}
268 
269 	return 0;
270 }
271 
ieee802154_cc13xx_cc26xx_set_txpower(const struct device * dev,int16_t dbm)272 static int ieee802154_cc13xx_cc26xx_set_txpower(const struct device *dev,
273 						int16_t dbm)
274 {
275 	RF_Stat status;
276 	const RF_TxPowerTable_Entry *table;
277 	struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data;
278 
279 	/* TODO Support sub-GHz for CC13xx */
280 	table = txPowerTable_2_4;
281 
282 	RF_TxPowerTable_Value power_table_value = RF_TxPowerTable_findValue(
283 		(RF_TxPowerTable_Entry *)table, dbm);
284 	if (power_table_value.rawValue == RF_TxPowerTable_INVALID_VALUE) {
285 		LOG_ERR("RF_TxPowerTable_findValue() failed");
286 		return -EINVAL;
287 	}
288 
289 	status = RF_setTxPower(drv_data->rf_handle, power_table_value);
290 	if (status != RF_StatSuccess) {
291 		LOG_ERR("RF_setTxPower() failed: %d", status);
292 		return -EIO;
293 	}
294 
295 	return 0;
296 }
297 
298 /* See IEEE 802.15.4 section 6.2.5.1 and TRM section 25.5.4.3 */
ieee802154_cc13xx_cc26xx_tx(const struct device * dev,enum ieee802154_tx_mode mode,struct net_pkt * pkt,struct net_buf * frag)299 static int ieee802154_cc13xx_cc26xx_tx(const struct device *dev,
300 				       enum ieee802154_tx_mode mode,
301 				       struct net_pkt *pkt,
302 				       struct net_buf *frag)
303 {
304 	int r;
305 	RF_EventMask reason;
306 	RF_ScheduleCmdParams sched_params = {
307 		.allowDelay = true,
308 	};
309 	struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data;
310 	bool ack = ieee802154_is_ar_flag_set(frag);
311 	int retry = CONFIG_IEEE802154_CC13XX_CC26XX_RADIO_TX_RETRIES;
312 
313 	if (mode != IEEE802154_TX_MODE_CSMA_CA) {
314 		NET_ERR("TX mode %d not supported", mode);
315 		return -ENOTSUP;
316 	}
317 
318 	k_mutex_lock(&drv_data->tx_mutex, K_FOREVER);
319 
320 	/* Workaround for Issue #29418 where the driver stalls after
321 	 * wrapping around RF command handle 4096. This change
322 	 * effectively empties the RF command queue every ~4 minutes
323 	 * but otherwise causes the system to incur little overhead.
324 	 * A subsequent SimpleLink SDK release should resolve the issue.
325 	 */
326 	if (drv_data->saved_cmdhandle >= BIT(12) - 5) {
327 		r = ieee802154_cc13xx_cc26xx_reset_channel(dev);
328 		if (r < 0) {
329 			goto out;
330 		}
331 		drv_data->saved_cmdhandle = -1;
332 	}
333 
334 	do {
335 
336 		drv_data->cmd_ieee_csma.status = IDLE;
337 		drv_data->cmd_ieee_csma.randomState = sys_rand32_get();
338 
339 		drv_data->cmd_ieee_tx.status = IDLE;
340 		drv_data->cmd_ieee_tx.payloadLen = frag->len;
341 		drv_data->cmd_ieee_tx.pPayload = frag->data;
342 		drv_data->cmd_ieee_tx.condition.rule =
343 			ack ? COND_STOP_ON_FALSE : COND_NEVER;
344 
345 		if (ack) {
346 			drv_data->cmd_ieee_rx_ack.status = IDLE;
347 			drv_data->cmd_ieee_rx_ack.seqNo = frag->data[2];
348 		}
349 
350 		reason = RF_runScheduleCmd(drv_data->rf_handle,
351 			(RF_Op *)&drv_data->cmd_ieee_csma, &sched_params,
352 			cmd_ieee_csma_callback,
353 			RF_EventLastFGCmdDone | RF_EventLastCmdDone);
354 		if ((reason & (RF_EventLastFGCmdDone | RF_EventLastCmdDone))
355 			== 0) {
356 			LOG_DBG("Failed to run command (0x%" PRIx64 ")",
357 				reason);
358 			continue;
359 		}
360 
361 		if (drv_data->cmd_ieee_csma.status != IEEE_DONE_OK) {
362 			/* TODO: According to IEEE 802.15.4 CSMA/CA failure
363 			 *       fails TX immediately and should not trigger
364 			 *       attempt (which is reserved for ACK timeouts).
365 			 */
366 			LOG_DBG("Channel access failure (0x%x)",
367 				drv_data->cmd_ieee_csma.status);
368 			continue;
369 		}
370 
371 		if (drv_data->cmd_ieee_tx.status != IEEE_DONE_OK) {
372 			/* TODO: According to IEEE 802.15.4 transmission failure
373 			 *       fails TX immediately and should not trigger
374 			 *       attempt (which is reserved for ACK timeouts).
375 			 */
376 			LOG_DBG("Transmit failed (0x%x)",
377 				drv_data->cmd_ieee_tx.status);
378 			continue;
379 		}
380 
381 		if (!ack || drv_data->cmd_ieee_rx_ack.status == IEEE_DONE_ACK ||
382 		    drv_data->cmd_ieee_rx_ack.status == IEEE_DONE_ACKPEND) {
383 			r = 0;
384 			goto out;
385 		}
386 
387 		LOG_DBG("No acknowledgment (0x%x)",
388 			drv_data->cmd_ieee_rx_ack.status);
389 	} while (retry-- > 0);
390 
391 	LOG_DBG("Failed to TX");
392 	r = -EIO;
393 
394 out:
395 	k_mutex_unlock(&drv_data->tx_mutex);
396 	return r;
397 }
398 
ieee802154_cc13xx_cc26xx_rx_done(struct ieee802154_cc13xx_cc26xx_data * drv_data)399 static void ieee802154_cc13xx_cc26xx_rx_done(
400 	struct ieee802154_cc13xx_cc26xx_data *drv_data)
401 {
402 	struct net_pkt *pkt;
403 	uint8_t len, seq, corr, lqi;
404 	int8_t rssi;
405 	uint8_t *sdu;
406 
407 	for (int i = 0; i < CC13XX_CC26XX_NUM_RX_BUF; i++) {
408 		if (drv_data->rx_entry[i].status == DATA_ENTRY_FINISHED) {
409 			/* rx_data contains length, psdu, fcs, rssi, corr */
410 			len = drv_data->rx_data[i][0];
411 			sdu = drv_data->rx_data[i] + 1;
412 			seq = drv_data->rx_data[i][3];
413 			corr = drv_data->rx_data[i][len--] & 0x3F;
414 			rssi = drv_data->rx_data[i][len--];
415 
416 			/* remove fcs as it is not expected by L2
417 			 * But keep it for RAW mode
418 			 */
419 			if (IS_ENABLED(CONFIG_NET_L2_IEEE802154)) {
420 				len -= 2;
421 			}
422 
423 			/* scale 6-bit corr to 8-bit lqi */
424 			lqi = corr << 2;
425 
426 			LOG_DBG("Received: len = %u, seq = %u, rssi = %d, lqi = %u",
427 				len, seq, rssi, lqi);
428 
429 			pkt = net_pkt_rx_alloc_with_buffer(
430 				drv_data->iface, len, AF_UNSPEC, 0, K_NO_WAIT);
431 			if (!pkt) {
432 				LOG_WRN("Cannot allocate packet");
433 				continue;
434 			}
435 
436 			if (net_pkt_write(pkt, sdu, len)) {
437 				LOG_WRN("Cannot write packet");
438 				net_pkt_unref(pkt);
439 				continue;
440 			}
441 
442 			drv_data->rx_entry[i].status = DATA_ENTRY_PENDING;
443 
444 			net_pkt_set_ieee802154_lqi(pkt, lqi);
445 			net_pkt_set_ieee802154_rssi_dbm(pkt,
446 							rssi == CC13XX_CC26XX_INVALID_RSSI
447 								? IEEE802154_MAC_RSSI_DBM_UNDEFINED
448 								: rssi);
449 
450 			if (net_recv_data(drv_data->iface, pkt)) {
451 				LOG_WRN("Packet dropped");
452 				net_pkt_unref(pkt);
453 			}
454 
455 		} else if (drv_data->rx_entry[i].status ==
456 			   DATA_ENTRY_UNFINISHED) {
457 			LOG_WRN("Frame not finished");
458 			drv_data->rx_entry[i].status = DATA_ENTRY_PENDING;
459 		}
460 	}
461 }
462 
ieee802154_cc13xx_cc26xx_start(const struct device * dev)463 static int ieee802154_cc13xx_cc26xx_start(const struct device *dev)
464 {
465 	ARG_UNUSED(dev);
466 
467 	return 0;
468 }
469 
ieee802154_cc13xx_cc26xx_stop(const struct device * dev)470 static int ieee802154_cc13xx_cc26xx_stop(const struct device *dev)
471 {
472 	struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data;
473 
474 	RF_Stat status;
475 
476 	status = RF_flushCmd(drv_data->rf_handle, RF_CMDHANDLE_FLUSH_ALL, 0);
477 	if (!(status == RF_StatCmdDoneSuccess
478 		|| status == RF_StatSuccess
479 		|| status == RF_StatRadioInactiveError
480 		|| status == RF_StatInvalidParamsError)) {
481 		LOG_DBG("Failed to abort radio operations (%d)", status);
482 		return -EIO;
483 	}
484 
485 	return 0;
486 }
487 
488 /**
489  * Stops the sub-GHz interface and yields the radio (tells RF module to power
490  * down).
491  */
ieee802154_cc13xx_cc26xx_stop_if(const struct device * dev)492 static int ieee802154_cc13xx_cc26xx_stop_if(const struct device *dev)
493 {
494 	struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data;
495 	int ret;
496 
497 	ret = ieee802154_cc13xx_cc26xx_stop(dev);
498 	if (ret < 0) {
499 		return ret;
500 	}
501 
502 	/* power down radio */
503 	RF_yield(drv_data->rf_handle);
504 	return 0;
505 }
506 
507 static int
ieee802154_cc13xx_cc26xx_configure(const struct device * dev,enum ieee802154_config_type type,const struct ieee802154_config * config)508 ieee802154_cc13xx_cc26xx_configure(const struct device *dev,
509 				   enum ieee802154_config_type type,
510 				   const struct ieee802154_config *config)
511 {
512 	return -ENOTSUP;
513 }
514 
515 /* driver-allocated attribute memory - constant across all driver instances */
516 IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26);
517 
ieee802154_cc13xx_cc26xx_attr_get(const struct device * dev,enum ieee802154_attr attr,struct ieee802154_attr_value * value)518 static int ieee802154_cc13xx_cc26xx_attr_get(const struct device *dev, enum ieee802154_attr attr,
519 					     struct ieee802154_attr_value *value)
520 {
521 	ARG_UNUSED(dev);
522 
523 	return ieee802154_attr_get_channel_page_and_range(
524 		attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915,
525 		&drv_attr.phy_supported_channels, value);
526 }
527 
ieee802154_cc13xx_cc26xx_data_init(const struct device * dev)528 static void ieee802154_cc13xx_cc26xx_data_init(const struct device *dev)
529 {
530 	struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data;
531 	uint8_t *mac;
532 
533 	if (sys_read32(CCFG_BASE + CCFG_O_IEEE_MAC_0) != 0xFFFFFFFF &&
534 	    sys_read32(CCFG_BASE + CCFG_O_IEEE_MAC_1) != 0xFFFFFFFF) {
535 		mac = (uint8_t *)(CCFG_BASE + CCFG_O_IEEE_MAC_0);
536 	} else {
537 		mac = (uint8_t *)(FCFG1_BASE + FCFG1_O_MAC_15_4_0);
538 	}
539 
540 	sys_memcpy_swap(&drv_data->mac, mac, sizeof(drv_data->mac));
541 
542 	/* Setup circular RX queue (TRM 25.3.2.7) */
543 	memset(&drv_data->rx_entry[0], 0, sizeof(drv_data->rx_entry[0]));
544 	memset(&drv_data->rx_entry[1], 0, sizeof(drv_data->rx_entry[1]));
545 
546 	drv_data->rx_entry[0].pNextEntry = (uint8_t *)&drv_data->rx_entry[1];
547 	drv_data->rx_entry[0].config.type = DATA_ENTRY_TYPE_PTR;
548 	drv_data->rx_entry[0].config.lenSz = 1;
549 	drv_data->rx_entry[0].length = sizeof(drv_data->rx_data[0]);
550 	drv_data->rx_entry[0].pData = drv_data->rx_data[0];
551 
552 	drv_data->rx_entry[1].pNextEntry = (uint8_t *)&drv_data->rx_entry[0];
553 	drv_data->rx_entry[1].config.type = DATA_ENTRY_TYPE_PTR;
554 	drv_data->rx_entry[1].config.lenSz = 1;
555 	drv_data->rx_entry[1].length = sizeof(drv_data->rx_data[1]);
556 	drv_data->rx_entry[1].pData = drv_data->rx_data[1];
557 
558 	drv_data->rx_queue.pCurrEntry = (uint8_t *)&drv_data->rx_entry[0];
559 	drv_data->rx_queue.pLastEntry = NULL;
560 
561 	k_mutex_init(&drv_data->tx_mutex);
562 }
563 
ieee802154_cc13xx_cc26xx_iface_init(struct net_if * iface)564 static void ieee802154_cc13xx_cc26xx_iface_init(struct net_if *iface)
565 {
566 	const struct device *dev = net_if_get_device(iface);
567 	struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data;
568 
569 	net_if_set_link_addr(iface, drv_data->mac, sizeof(drv_data->mac),
570 			     NET_LINK_IEEE802154);
571 
572 	drv_data->iface = iface;
573 
574 	ieee802154_init(iface);
575 }
576 
577 static const struct ieee802154_radio_api ieee802154_cc13xx_cc26xx_radio_api = {
578 	.iface_api.init = ieee802154_cc13xx_cc26xx_iface_init,
579 
580 	.get_capabilities = ieee802154_cc13xx_cc26xx_get_capabilities,
581 	.cca = ieee802154_cc13xx_cc26xx_cca,
582 	.set_channel = ieee802154_cc13xx_cc26xx_set_channel,
583 	.filter = ieee802154_cc13xx_cc26xx_filter,
584 	.set_txpower = ieee802154_cc13xx_cc26xx_set_txpower,
585 	.tx = ieee802154_cc13xx_cc26xx_tx,
586 	.start = ieee802154_cc13xx_cc26xx_start,
587 	.stop = ieee802154_cc13xx_cc26xx_stop_if,
588 	.configure = ieee802154_cc13xx_cc26xx_configure,
589 	.attr_get = ieee802154_cc13xx_cc26xx_attr_get,
590 };
591 
592 /** RF patches to use (note: RF core keeps a pointer to this, so no stack). */
593 static RF_Mode rf_mode = {
594 	.rfMode      = RF_MODE_MULTIPLE,
595 	.cpePatchFxn = &rf_patch_cpe_multi_protocol,
596 };
597 
ieee802154_cc13xx_cc26xx_init(const struct device * dev)598 static int ieee802154_cc13xx_cc26xx_init(const struct device *dev)
599 {
600 	RF_Params rf_params;
601 	RF_EventMask reason;
602 	struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data;
603 
604 	/* Initialize driver data */
605 	ieee802154_cc13xx_cc26xx_data_init(dev);
606 
607 	/* Setup radio */
608 	RF_Params_init(&rf_params);
609 	rf_params.pErrCb = client_error_callback;
610 	rf_params.pClientEventCb = client_event_callback;
611 
612 	drv_data->rf_handle = RF_open(&drv_data->rf_object,
613 		&rf_mode, (RF_RadioSetup *)&drv_data->cmd_radio_setup,
614 		&rf_params);
615 	if (drv_data->rf_handle == NULL) {
616 		LOG_ERR("RF_open() failed");
617 		return -EIO;
618 	}
619 
620 	/*
621 	 * Run CMD_FS with frequency 0 to ensure RF_currClient is not NULL.
622 	 * RF_currClient is a static variable in the TI RF Driver library.
623 	 * If this is not done, then even CMD_ABORT fails.
624 	 */
625 	drv_data->cmd_fs.status = IDLE;
626 	drv_data->cmd_fs.pNextOp = NULL;
627 	drv_data->cmd_fs.condition.rule = COND_NEVER;
628 	drv_data->cmd_fs.synthConf.bTxMode = false;
629 	drv_data->cmd_fs.frequency = 0;
630 	drv_data->cmd_fs.fractFreq = 0;
631 
632 	reason = RF_runCmd(drv_data->rf_handle, (RF_Op *)&drv_data->cmd_fs,
633 		RF_PriorityNormal, NULL, 0);
634 	if (reason != RF_EventLastCmdDone) {
635 		LOG_ERR("Failed to set frequency: 0x%" PRIx64, reason);
636 		return -EIO;
637 	}
638 
639 	return 0;
640 }
641 
642 static struct ieee802154_cc13xx_cc26xx_data ieee802154_cc13xx_cc26xx_data = {
643 	.cmd_fs = {
644 		.commandNo = CMD_FS,
645 	},
646 
647 	.cmd_ieee_cca_req = {
648 		.commandNo = CMD_IEEE_CCA_REQ,
649 	},
650 
651 	.cmd_ieee_rx = {
652 		.commandNo = CMD_IEEE_RX,
653 		.status = IDLE,
654 		.pNextOp = NULL,
655 		.startTrigger.triggerType = TRIG_NOW,
656 		.condition.rule = COND_NEVER,
657 		.channel = 0,
658 		.rxConfig = {
659 			.bAutoFlushCrc = 1,
660 			.bAutoFlushIgn = 1,
661 			.bIncludePhyHdr = 0,
662 			.bIncludeCrc = 1,
663 			.bAppendRssi = 1,
664 			.bAppendCorrCrc = 1,
665 			.bAppendSrcInd = 0,
666 			.bAppendTimestamp = 0
667 		},
668 		.pRxQ = &ieee802154_cc13xx_cc26xx_data.rx_queue,
669 		.pOutput = NULL,
670 		.frameFiltOpt = {
671 			.frameFiltEn = 1,
672 			.frameFiltStop = 0,
673 			.autoAckEn = 1,
674 			.slottedAckEn = 0,
675 			.autoPendEn = 0,
676 			.defaultPend = 0,
677 			.bPendDataReqOnly = 0,
678 			.bPanCoord = 0,
679 			.maxFrameVersion = 3,
680 			.fcfReservedMask = 0,
681 			.modifyFtFilter = 0,
682 			.bStrictLenFilter = 1
683 		},
684 		.frameTypes = {
685 			.bAcceptFt0Beacon = 0,
686 			.bAcceptFt1Data = 1,
687 			.bAcceptFt2Ack = 0,
688 			.bAcceptFt3MacCmd = 1,
689 			.bAcceptFt4Reserved = 0,
690 			.bAcceptFt5Reserved = 0,
691 			.bAcceptFt6Reserved = 0,
692 			.bAcceptFt7Reserved = 0
693 		},
694 		.ccaOpt = {
695 #if IEEE802154_PHY_CCA_MODE == 1
696 			.ccaEnEnergy = 1,
697 			.ccaEnCorr = 0,
698 #elif IEEE802154_PHY_CCA_MODE == 2
699 			.ccaEnEnergy = 0,
700 			.ccaEnCorr = 1,
701 #elif IEEE802154_PHY_CCA_MODE == 3
702 			.ccaEnEnergy = 1,
703 			.ccaEnCorr = 1,
704 #else
705 #error "Invalid CCA mode"
706 #endif
707 			.ccaEnSync = 1,
708 			.ccaSyncOp = 0,
709 			.ccaCorrOp = 0,
710 			.ccaCorrThr = 3,
711 		},
712 		/* See IEEE 802.15.4-2006 6.9.9*/
713 		.ccaRssiThr = CC13XX_CC26XX_RECEIVER_SENSITIVITY + 10,
714 		.numExtEntries = 0x00,
715 		.numShortEntries = 0x00,
716 		.pExtEntryList = NULL,
717 		.pShortEntryList = NULL,
718 		.localExtAddr = 0x0000000000000000,
719 		.localShortAddr = 0x0000,
720 		.localPanID = 0x0000,
721 		.endTrigger.triggerType = TRIG_NEVER
722 	},
723 
724 	.cmd_ieee_csma = {
725 		.commandNo = CMD_IEEE_CSMA,
726 		.status = IDLE,
727 		.pNextOp = (rfc_radioOp_t *)&ieee802154_cc13xx_cc26xx_data.cmd_ieee_tx,
728 		.startTrigger.triggerType = TRIG_NOW,
729 		.condition.rule = COND_STOP_ON_FALSE,
730 		.randomState = 0,
731 		.macMaxBE =
732 			CONFIG_IEEE802154_CC13XX_CC26XX_RADIO_CSMA_CA_MAX_BE,
733 		.macMaxCSMABackoffs =
734 			CONFIG_IEEE802154_CC13XX_CC26XX_RADIO_CSMA_CA_MAX_BO,
735 		.csmaConfig = {
736 			/* Initial value of CW for unslotted CSMA */
737 			.initCW = 1,
738 			/* Unslotted CSMA for non-beacon enabled PAN */
739 			.bSlotted = 0,
740 			/* RX stays on during CSMA backoffs */
741 			.rxOffMode = 0,
742 		},
743 		.NB = 0,
744 		.BE = CONFIG_IEEE802154_CC13XX_CC26XX_RADIO_CSMA_CA_MIN_BE,
745 		.remainingPeriods = 0,
746 		.endTrigger.triggerType = TRIG_NEVER,
747 	},
748 
749 	.cmd_ieee_tx = {
750 		.commandNo = CMD_IEEE_TX,
751 		.status = IDLE,
752 		.pNextOp =  (rfc_radioOp_t *)&ieee802154_cc13xx_cc26xx_data.cmd_ieee_rx_ack,
753 		.startTrigger.triggerType = TRIG_NOW,
754 		.condition.rule = COND_NEVER,
755 		.txOpt = {
756 			/* Automatically insert PHY header */
757 			.bIncludePhyHdr = 0x0,
758 			/* Automatically append CRC */
759 			.bIncludeCrc = 0x0,
760 			/* Disable long frame testing */
761 			.payloadLenMsb = 0x0,
762 		},
763 		.payloadLen = 0x0,
764 		.pPayload = NULL,
765 	},
766 
767 	.cmd_ieee_rx_ack = {
768 		.commandNo = CMD_IEEE_RX_ACK,
769 		.status = IDLE,
770 		.pNextOp = NULL,
771 		.startTrigger.triggerType = TRIG_NOW,
772 		.condition.rule = COND_NEVER,
773 		.seqNo = 0,
774 		.endTrigger = {
775 			.triggerType = TRIG_REL_START,
776 			.pastTrig = 1,
777 		},
778 		.endTime = IEEE802154_MAC_ACK_WAIT_DURATION *
779 			   CC13XX_CC26XX_RAT_CYCLES_PER_SECOND /
780 			   IEEE802154_2450MHZ_OQPSK_SYMBOLS_PER_SECOND,
781 	},
782 
783 	.cmd_radio_setup = {
784 #if defined(CONFIG_SOC_CC1352R) || defined(CONFIG_SOC_CC2652R) || \
785 	defined(CONFIG_SOC_CC1352R7) || defined(CONFIG_SOC_CC2652R7)
786 		.commandNo = CMD_RADIO_SETUP,
787 #elif defined(CONFIG_SOC_CC1352P) || defined(CONFIG_SOC_CC2652P) || \
788 	defined(CONFIG_SOC_CC1352P7) || defined(CONFIG_SOC_CC2652P7)
789 		.commandNo = CMD_RADIO_SETUP_PA,
790 #endif /* CONFIG_SOC_CCxx52x */
791 		.status = IDLE,
792 		.pNextOp = NULL,
793 		.startTrigger.triggerType = TRIG_NOW,
794 		.condition.rule = COND_NEVER,
795 		.mode = 0x01, /* IEEE 802.15.4 */
796 		.loDivider = 0x00,
797 		.config = {
798 			.frontEndMode = 0x0,
799 			.biasMode = 0x0,
800 			.analogCfgMode = 0x0,
801 			.bNoFsPowerUp = 0x0,
802 		},
803 		.txPower = 0x2853, /* 0 dBm */
804 		.pRegOverride = overrides
805 	},
806 };
807 
808 #if defined(CONFIG_NET_L2_IEEE802154)
809 #define L2 IEEE802154_L2
810 #define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(IEEE802154_L2)
811 #define MTU IEEE802154_MTU
812 #elif defined(CONFIG_NET_L2_OPENTHREAD)
813 #define L2 OPENTHREAD_L2
814 #define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(OPENTHREAD_L2)
815 #define MTU 1280
816 #endif
817 
818 #if defined(CONFIG_NET_L2_IEEE802154) || defined(CONFIG_NET_L2_PHY_IEEE802154)
819 NET_DEVICE_DT_INST_DEFINE(0, ieee802154_cc13xx_cc26xx_init, NULL,
820 			  &ieee802154_cc13xx_cc26xx_data, NULL,
821 			  CONFIG_IEEE802154_CC13XX_CC26XX_INIT_PRIO,
822 			  &ieee802154_cc13xx_cc26xx_radio_api, L2,
823 			  L2_CTX_TYPE, MTU);
824 #else
825 DEVICE_DT_INST_DEFINE(0, ieee802154_cc13xx_cc26xx_init, NULL,
826 		      &ieee802154_cc13xx_cc26xx_data, NULL, POST_KERNEL,
827 		      CONFIG_IEEE802154_CC13XX_CC26XX_INIT_PRIO,
828 		      &ieee802154_cc13xx_cc26xx_radio_api);
829 #endif
830