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