1 /*
2  * Copyright (c) 2017-2020 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stddef.h>
8 #include <string.h>
9 
10 #include <zephyr/toolchain.h>
11 
12 #include <soc.h>
13 
14 #include "hal/cpu.h"
15 #include "hal/cntr.h"
16 #include "hal/ccm.h"
17 #include "hal/radio.h"
18 #include "hal/radio_df.h"
19 
20 #include "util/memq.h"
21 #include "util/util.h"
22 #include "util/dbuf.h"
23 
24 #include "pdu_df.h"
25 #include "pdu_vendor.h"
26 #include "pdu.h"
27 
28 #include "lll.h"
29 #include "lll_clock.h"
30 #include "lll_internal.h"
31 
32 #if defined(CONFIG_BT_CTLR_DF)
33 #include "lll_df_types.h"
34 #include "lll_df.h"
35 #endif /* CONFIG_BT_CTLR_DF */
36 
37 #include "ll_test.h"
38 
39 #if defined(CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT)
40 #include "ull_df_types.h"
41 #include "ull_df_internal.h"
42 #endif /* CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT */
43 
44 #include <zephyr/bluetooth/hci_types.h>
45 
46 #include "hal/debug.h"
47 
48 #define CNTR_MIN_DELTA 3
49 
50 /* Helper definitions for repeated payload sequence */
51 #define PAYLOAD_11110000 0x0f
52 #define PAYLOAD_10101010 0x55
53 #define PAYLOAD_11111111 0xff
54 #define PAYLOAD_00000000 0x00
55 #define PAYLOAD_00001111 0xf0
56 #define PAYLOAD_01010101 0xaa
57 
58 static const uint32_t test_sync_word = 0x71764129;
59 static uint8_t        test_phy;
60 static uint8_t        test_phy_flags;
61 
62 #if defined(CONFIG_BT_CTLR_DF_CTE_RX)
63 static uint8_t        test_cte_type;
64 #endif /* CONFIG_BT_CTLR_DF_CTE_RX */
65 
66 #if defined(CONFIG_BT_CTLR_DF_CTE_TX) || defined(CONFIG_BT_CTLR_DF_CTE_RX)
67 static uint8_t        test_cte_len;
68 #endif  /* CONFIG_BT_CTLR_DF_CTE_TX || CONFIG_BT_CTLR_DF_CTE_RX */
69 
70 #if defined(CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT)
71 static uint8_t        test_chan;
72 static uint8_t        test_slot_duration;
73 #endif /* CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT */
74 
75 static uint32_t    tx_tifs;
76 static uint16_t    test_num_rx;
77 static bool        started;
78 
79 /* NOTE: The PRBS9 sequence used as packet payload.
80  * The bytes in the sequence are in the right order, but the bits of each byte
81  * in the array are reverse from that found by running the PRBS9 algorithm. This
82  * is done to transmit MSbit first on air.
83  */
84 
85 static const uint8_t prbs9[] = {
86 	0xFF, 0xC1, 0xFB, 0xE8, 0x4C, 0x90, 0x72, 0x8B,
87 	0xE7, 0xB3, 0x51, 0x89, 0x63, 0xAB, 0x23, 0x23,
88 	0x02, 0x84, 0x18, 0x72, 0xAA, 0x61, 0x2F, 0x3B,
89 	0x51, 0xA8, 0xE5, 0x37, 0x49, 0xFB, 0xC9, 0xCA,
90 	0x0C, 0x18, 0x53, 0x2C, 0xFD, 0x45, 0xE3, 0x9A,
91 	0xE6, 0xF1, 0x5D, 0xB0, 0xB6, 0x1B, 0xB4, 0xBE,
92 	0x2A, 0x50, 0xEA, 0xE9, 0x0E, 0x9C, 0x4B, 0x5E,
93 	0x57, 0x24, 0xCC, 0xA1, 0xB7, 0x59, 0xB8, 0x87,
94 	0xFF, 0xE0, 0x7D, 0x74, 0x26, 0x48, 0xB9, 0xC5,
95 	0xF3, 0xD9, 0xA8, 0xC4, 0xB1, 0xD5, 0x91, 0x11,
96 	0x01, 0x42, 0x0C, 0x39, 0xD5, 0xB0, 0x97, 0x9D,
97 	0x28, 0xD4, 0xF2, 0x9B, 0xA4, 0xFD, 0x64, 0x65,
98 	0x06, 0x8C, 0x29, 0x96, 0xFE, 0xA2, 0x71, 0x4D,
99 	0xF3, 0xF8, 0x2E, 0x58, 0xDB, 0x0D, 0x5A, 0x5F,
100 	0x15, 0x28, 0xF5, 0x74, 0x07, 0xCE, 0x25, 0xAF,
101 	0x2B, 0x12, 0xE6, 0xD0, 0xDB, 0x2C, 0xDC, 0xC3,
102 	0x7F, 0xF0, 0x3E, 0x3A, 0x13, 0xA4, 0xDC, 0xE2,
103 	0xF9, 0x6C, 0x54, 0xE2, 0xD8, 0xEA, 0xC8, 0x88,
104 	0x00, 0x21, 0x86, 0x9C, 0x6A, 0xD8, 0xCB, 0x4E,
105 	0x14, 0x6A, 0xF9, 0x4D, 0xD2, 0x7E, 0xB2, 0x32,
106 	0x03, 0xC6, 0x14, 0x4B, 0x7F, 0xD1, 0xB8, 0xA6,
107 	0x79, 0x7C, 0x17, 0xAC, 0xED, 0x06, 0xAD, 0xAF,
108 	0x0A, 0x94, 0x7A, 0xBA, 0x03, 0xE7, 0x92, 0xD7,
109 	0x15, 0x09, 0x73, 0xE8, 0x6D, 0x16, 0xEE, 0xE1,
110 	0x3F, 0x78, 0x1F, 0x9D, 0x09, 0x52, 0x6E, 0xF1,
111 	0x7C, 0x36, 0x2A, 0x71, 0x6C, 0x75, 0x64, 0x44,
112 	0x80, 0x10, 0x43, 0x4E, 0x35, 0xEC, 0x65, 0x27,
113 	0x0A, 0xB5, 0xFC, 0x26, 0x69, 0x3F, 0x59, 0x99,
114 	0x01, 0x63, 0x8A, 0xA5, 0xBF, 0x68, 0x5C, 0xD3,
115 	0x3C, 0xBE, 0x0B, 0xD6, 0x76, 0x83, 0xD6, 0x57,
116 	0x05, 0x4A, 0x3D, 0xDD, 0x81, 0x73, 0xC9, 0xEB,
117 	0x8A, 0x84, 0x39, 0xF4, 0x36, 0x0B, 0xF7};
118 
119 /* TODO: fill correct prbs15 */
120 static const uint8_t prbs15[255] = { 0x00, };
121 
122 static uint8_t tx_req;
123 static uint8_t volatile tx_ack;
124 
125 #if defined(CONFIG_BT_CTLR_DF_CTE_RX)
126 static bool check_rx_cte(bool cte_ready);
127 #endif /* CONFIG_BT_CTLR_DF_CTE_RX */
128 
129 #if defined(CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT)
create_iq_report(bool crc_ok)130 static int create_iq_report(bool crc_ok)
131 {
132 	struct node_rx_iq_report *iq_report;
133 	struct node_rx_ftr *ftr;
134 	uint8_t sample_cnt;
135 	uint8_t cte_info;
136 	uint8_t ant;
137 
138 	sample_cnt = radio_df_iq_samples_amount_get();
139 
140 	/* If there are no samples available, the CTEInfo was
141 	 * not detected and sampling was not started.
142 	 */
143 	if (!sample_cnt) {
144 		return -EINVAL;
145 	}
146 
147 	cte_info = radio_df_cte_status_get();
148 	ant = radio_df_pdu_antenna_switch_pattern_get();
149 	iq_report = ull_df_iq_report_alloc();
150 	if (!iq_report) {
151 		return -ENOBUFS;
152 	}
153 
154 	iq_report->rx.hdr.type = NODE_RX_TYPE_DTM_IQ_SAMPLE_REPORT;
155 	iq_report->sample_count = sample_cnt;
156 	iq_report->packet_status = ((crc_ok) ? BT_HCI_LE_CTE_CRC_OK :
157 					       BT_HCI_LE_CTE_CRC_ERR_CTE_BASED_TIME);
158 	iq_report->rssi_ant_id = ant;
159 	iq_report->cte_info = *(struct pdu_cte_info *)&cte_info;
160 	iq_report->local_slot_durations = test_slot_duration;
161 	iq_report->chan_idx = test_chan;
162 
163 	ftr = &iq_report->rx.rx_ftr;
164 	ftr->param = NULL;
165 	ftr->rssi = BT_HCI_LE_RSSI_NOT_AVAILABLE;
166 
167 	ull_rx_put(iq_report->rx.hdr.link, iq_report);
168 
169 	return 0;
170 }
171 #endif /* CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT */
172 
isr_tx(void * param)173 static void isr_tx(void *param)
174 {
175 	/* Clear radio status and events */
176 	radio_status_reset();
177 	radio_tmr_status_reset();
178 
179 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
180 	radio_gpio_pa_lna_disable();
181 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
182 
183 	/* Exit if radio disabled */
184 	if (((tx_req - tx_ack) & 0x01) == 0U) {
185 		tx_ack = tx_req;
186 
187 		return;
188 	}
189 
190 	/* Setup next Tx */
191 	radio_tmr_tifs_set(tx_tifs);
192 	radio_switch_complete_and_b2b_tx(test_phy, test_phy_flags, test_phy, test_phy_flags);
193 
194 	radio_tmr_end_capture();
195 
196 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
197 	radio_gpio_pa_setup();
198 	radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() +
199 				 tx_tifs -
200 				 radio_tx_ready_delay_get(test_phy, test_phy_flags) -
201 				 HAL_RADIO_GPIO_PA_OFFSET);
202 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
203 }
204 
isr_rx(void * param)205 static void isr_rx(void *param)
206 {
207 	uint8_t crc_ok = 0U;
208 	uint8_t trx_done;
209 
210 #if defined(CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT)
211 	struct node_rx_iq_report *node_rx;
212 #endif /* CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT */
213 
214 #if defined(CONFIG_BT_CTLR_DF_CTE_RX)
215 	bool cte_ready;
216 	bool cte_ok = 0;
217 #endif /* CONFIG_BT_CTLR_DF_CTE_RX */
218 
219 	/* Read radio status and events */
220 	trx_done = radio_is_done();
221 	if (trx_done) {
222 		crc_ok = radio_crc_is_valid();
223 #if defined(CONFIG_BT_CTLR_DF_CTE_RX)
224 		cte_ready = radio_df_cte_ready();
225 #endif /* CONFIG_BT_CTLR_DF_CTE_RX */
226 	}
227 
228 	/* Clear radio status and events */
229 	radio_status_reset();
230 	radio_tmr_status_reset();
231 
232 	/* Exit if radio disabled */
233 	if (!trx_done) {
234 		return;
235 	}
236 
237 #if defined(CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT)
238 	if (test_cte_len > 0) {
239 		/* Get free iq report node for next Rx operation. */
240 		node_rx = ull_df_iq_report_alloc_peek(1);
241 		LL_ASSERT(node_rx);
242 
243 		radio_df_iq_data_packet_set(node_rx->pdu, IQ_SAMPLE_TOTAL_CNT);
244 	}
245 #endif /* CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT */
246 
247 	/* Setup next Rx */
248 	radio_tmr_tifs_set(EVENT_IFS_US);
249 	radio_switch_complete_and_b2b_rx(test_phy, test_phy_flags, test_phy, test_phy_flags);
250 
251 	/* Count Rx-ed packets */
252 	if (crc_ok) {
253 
254 #if defined(CONFIG_BT_CTLR_DF_CTE_RX)
255 		if (test_cte_len > 0) {
256 			cte_ok = check_rx_cte(cte_ready);
257 			if (cte_ok) {
258 				test_num_rx++;
259 			}
260 		} else
261 #endif /* CONFIG_BT_CTLR_DF_CTE_RX */
262 
263 		{
264 			test_num_rx++;
265 		}
266 	}
267 
268 #if defined(CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT)
269 	if (cte_ok) {
270 		int err;
271 
272 		err = create_iq_report(crc_ok);
273 		if (!err) {
274 			ull_rx_sched();
275 		}
276 	}
277 #endif
278 }
279 
tx_power_check(int8_t tx_power)280 static uint8_t tx_power_check(int8_t tx_power)
281 {
282 	if ((tx_power != BT_HCI_TX_TEST_POWER_MIN_SET) &&
283 	    (tx_power != BT_HCI_TX_TEST_POWER_MAX_SET) &&
284 	    ((tx_power < BT_HCI_TX_TEST_POWER_MIN) || (tx_power > BT_HCI_TX_TEST_POWER_MAX))) {
285 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
286 	}
287 
288 	return BT_HCI_ERR_SUCCESS;
289 }
290 
tx_power_set(int8_t tx_power)291 static uint8_t tx_power_set(int8_t tx_power)
292 {
293 	uint8_t err;
294 
295 	err = tx_power_check(tx_power);
296 	if (err) {
297 		return err;
298 	}
299 
300 	if (tx_power == BT_HCI_TX_TEST_POWER_MAX_SET) {
301 		tx_power = radio_tx_power_max_get();
302 	} else if (tx_power == BT_HCI_TX_TEST_POWER_MIN_SET) {
303 		tx_power = radio_tx_power_min_get();
304 	} else {
305 		tx_power = radio_tx_power_floor(tx_power);
306 	}
307 
308 	radio_tx_power_set(tx_power);
309 
310 	return err;
311 }
312 
313 #if defined(CONFIG_BT_CTLR_DF_CTE_TX)
cte_tx_parameters_check(uint8_t cte_len,uint8_t cte_type,uint8_t switch_pattern_len)314 static uint8_t cte_tx_parameters_check(uint8_t cte_len, uint8_t cte_type,
315 					uint8_t switch_pattern_len)
316 {
317 	if ((cte_type > BT_HCI_LE_AOD_CTE_2US) ||
318 	    (cte_len < BT_HCI_LE_CTE_LEN_MIN) ||
319 	    (cte_len > BT_HCI_LE_CTE_LEN_MAX)) {
320 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
321 	}
322 
323 	if (cte_type != BT_HCI_LE_AOA_CTE) {
324 		if ((switch_pattern_len < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN) ||
325 		    (switch_pattern_len > BT_HCI_LE_SWITCH_PATTERN_LEN_MAX)) {
326 			return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
327 		}
328 	}
329 
330 	if ((cte_type == BT_HCI_LE_AOD_CTE_1US) &&
331 	    !IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US)) {
332 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
333 	}
334 
335 	return BT_HCI_ERR_SUCCESS;
336 }
337 
cte_tx_init(uint8_t cte_len,uint8_t cte_type,uint8_t switch_pattern_len,const uint8_t * ant_id)338 static uint8_t cte_tx_init(uint8_t cte_len, uint8_t cte_type, uint8_t switch_pattern_len,
339 			   const uint8_t *ant_id)
340 {
341 	uint8_t err;
342 
343 	err = cte_tx_parameters_check(cte_len, cte_type, switch_pattern_len);
344 	if (err) {
345 		return err;
346 	}
347 
348 	if (cte_type == BT_HCI_LE_AOA_CTE) {
349 		radio_df_mode_set_aoa();
350 		radio_df_cte_tx_aoa_set(cte_len);
351 	} else {
352 #if defined(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX)
353 		radio_df_mode_set_aod();
354 
355 		if (cte_type == BT_HCI_LE_AOD_CTE_1US) {
356 			radio_df_cte_tx_aod_2us_set(cte_len);
357 		} else {
358 			radio_df_cte_tx_aod_4us_set(cte_len);
359 		}
360 
361 		radio_df_ant_switching_pin_sel_cfg();
362 		radio_df_ant_switch_pattern_clear();
363 		radio_df_ant_switch_pattern_set(ant_id, switch_pattern_len);
364 #else
365 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
366 #endif /* CONFIG_BT_CTLR_DF_ANT_SWITCH_TX */
367 	}
368 
369 	return err;
370 }
371 #endif /* CONFIG_BT_CTLR_DF_CTE_TX */
372 
373 #if defined(CONFIG_BT_CTLR_DF_CTE_RX)
cte_rx_parameters_check(uint8_t expected_cte_len,uint8_t expected_cte_type,uint8_t slot_duration,uint8_t switch_pattern_len)374 static uint8_t cte_rx_parameters_check(uint8_t expected_cte_len, uint8_t expected_cte_type,
375 					uint8_t slot_duration, uint8_t switch_pattern_len)
376 {
377 	if ((expected_cte_type > BT_HCI_LE_AOD_CTE_2US) ||
378 	    (expected_cte_len < BT_HCI_LE_CTE_LEN_MIN) ||
379 	    (expected_cte_len > BT_HCI_LE_CTE_LEN_MAX)) {
380 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
381 	}
382 
383 	if (expected_cte_type == BT_HCI_LE_AOA_CTE) {
384 		if ((switch_pattern_len < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN) ||
385 		    (switch_pattern_len > BT_HCI_LE_SWITCH_PATTERN_LEN_MAX)) {
386 			return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
387 		}
388 
389 		if ((slot_duration == 0) ||
390 		    (slot_duration > BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US)) {
391 			return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
392 		}
393 	}
394 
395 	if ((slot_duration == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US) &&
396 	    (!IS_ENABLED(CONFIG_BT_CTLR_DF_CTE_RX_SAMPLE_1US))) {
397 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
398 	}
399 
400 	return BT_HCI_ERR_SUCCESS;
401 }
402 
cte_rx_init(uint8_t expected_cte_len,uint8_t expected_cte_type,uint8_t slot_duration,uint8_t switch_pattern_len,const uint8_t * ant_ids,uint8_t phy)403 static uint8_t cte_rx_init(uint8_t expected_cte_len, uint8_t expected_cte_type,
404 			   uint8_t slot_duration, uint8_t switch_pattern_len,
405 			   const uint8_t *ant_ids, uint8_t phy)
406 {
407 	uint8_t err;
408 	uint8_t cte_phy = (phy == BT_HCI_LE_RX_PHY_1M) ? PHY_1M : PHY_2M;
409 
410 	err = cte_rx_parameters_check(expected_cte_len, expected_cte_type,
411 				      slot_duration, switch_pattern_len);
412 	if (err) {
413 		return err;
414 	}
415 
416 	if (slot_duration == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US) {
417 #if defined(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US)
418 		radio_df_cte_rx_2us_switching(true, cte_phy);
419 #else
420 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
421 #endif /* CONFIG_BT_CTLR_DF_ANT_SWITCH_1US */
422 	} else {
423 		radio_df_cte_rx_4us_switching(true, cte_phy);
424 	}
425 
426 #if defined(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX)
427 	radio_df_ant_switching_pin_sel_cfg();
428 	radio_df_ant_switch_pattern_clear();
429 	radio_df_ant_switch_pattern_set(ant_ids, switch_pattern_len);
430 #else
431 	return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
432 #endif /* CONFIG_BT_CTLR_DF_ANT_SWITCH_RX */
433 
434 #if defined(CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT)
435 	struct node_rx_iq_report *node_rx;
436 
437 	node_rx = ull_df_iq_report_alloc_peek(1);
438 	LL_ASSERT(node_rx);
439 
440 	radio_df_iq_data_packet_set(node_rx->pdu, IQ_SAMPLE_TOTAL_CNT);
441 #else
442 	radio_df_iq_data_packet_set(NULL, 0);
443 #endif
444 
445 	return err;
446 }
447 
check_rx_cte(bool cte_ready)448 static bool check_rx_cte(bool cte_ready)
449 {
450 	uint8_t cte_status;
451 	struct pdu_cte_info *cte_info;
452 
453 	cte_status = radio_df_cte_status_get();
454 	cte_info = (struct pdu_cte_info *)&cte_status;
455 
456 	if ((cte_info->type != test_cte_type) || (cte_info->time != test_cte_len)) {
457 		return false;
458 	}
459 
460 	return true;
461 }
462 #endif /* CONFIG_BT_CTLR_DF_CTE_RX */
463 
calculate_tifs(uint8_t len)464 static uint32_t calculate_tifs(uint8_t len)
465 {
466 	uint32_t interval;
467 	uint32_t transmit_time;
468 
469 #if defined(CONFIG_BT_CTLR_DF_CTE_TX)
470 	/* Include additional byte for the CTEInfo field and CTE length in microseconds. */
471 	transmit_time = PDU_US((test_cte_len > 0) ? (len + 1) : len, 0, test_phy, test_phy_flags) +
472 			CTE_LEN_US(test_cte_len);
473 #else
474 	transmit_time = PDU_US(len, 0, test_phy, test_phy_flags);
475 #endif /* CONFIG_BT_CTLR_DF_CTE_TX */
476 
477 	/* Ble Core Specification Vol 6 Part F 4.1.6
478 	 * LE Test packet interval: I(L) = ceil((L + 249) / 625) * 625 us
479 	 * where L is an LE Test packet length in microseconds unit.
480 	 */
481 	interval = DIV_ROUND_UP((transmit_time + 249), SCAN_INT_UNIT_US) * SCAN_INT_UNIT_US;
482 
483 	return interval - transmit_time;
484 }
485 
init(uint8_t chan,uint8_t phy,int8_t tx_power,bool cte,void (* isr)(void *))486 static uint8_t init(uint8_t chan, uint8_t phy, int8_t tx_power,
487 		    bool cte, void (*isr)(void *))
488 {
489 	int err;
490 	uint8_t ret;
491 
492 	if (started) {
493 		return BT_HCI_ERR_CMD_DISALLOWED;
494 	}
495 
496 	/* start coarse timer */
497 	cntr_start();
498 
499 	/* Setup resources required by Radio */
500 	err = lll_hfclock_on_wait();
501 	LL_ASSERT(err >= 0);
502 
503 	/* Reset Radio h/w */
504 	radio_reset();
505 	radio_isr_set(isr, NULL);
506 
507 #if defined(CONFIG_BT_CTLR_DF)
508 	/* Reset  Radio DF */
509 	radio_df_reset();
510 #endif
511 
512 	/* Store value needed in Tx/Rx ISR */
513 	if (phy < BT_HCI_LE_TX_PHY_CODED_S2) {
514 		test_phy = BIT(phy - 1);
515 		test_phy_flags = 1U;
516 	} else {
517 		test_phy = BIT(2);
518 		test_phy_flags = 0U;
519 	}
520 
521 	/* Setup Radio in Tx/Rx */
522 	/* NOTE: No whitening in test mode. */
523 	radio_phy_set(test_phy, test_phy_flags);
524 
525 	ret = tx_power_set(tx_power);
526 
527 	radio_freq_chan_set((chan << 1) + 2);
528 	radio_aa_set((uint8_t *)&test_sync_word);
529 	radio_crc_configure(0x65b, PDU_AC_CRC_IV);
530 	radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, PDU_DTM_PAYLOAD_SIZE_MAX,
531 			    RADIO_PKT_CONF_PHY(test_phy) |
532 			    RADIO_PKT_CONF_PDU_TYPE(IS_ENABLED(CONFIG_BT_CTLR_DF_CTE_TX) ?
533 								RADIO_PKT_CONF_PDU_TYPE_DC :
534 								RADIO_PKT_CONF_PDU_TYPE_AC) |
535 			    RADIO_PKT_CONF_CTE(cte ? RADIO_PKT_CONF_CTE_ENABLED :
536 						     RADIO_PKT_CONF_CTE_DISABLED));
537 
538 	return ret;
539 }
540 
payload_set(uint8_t type,uint8_t len,uint8_t cte_len,uint8_t cte_type)541 static void payload_set(uint8_t type, uint8_t len, uint8_t cte_len, uint8_t cte_type)
542 {
543 	struct pdu_dtm *pdu = radio_pkt_scratch_get();
544 
545 	pdu->type = type;
546 	pdu->len = len;
547 
548 #if defined(CONFIG_BT_CTLR_DF_CTE_TX)
549 	pdu->cp = cte_len ? 1U : 0U;
550 	pdu->octet3.cte_info.time = cte_len;
551 	pdu->octet3.cte_info.type = cte_type;
552 #else
553 	ARG_UNUSED(cte_len);
554 	ARG_UNUSED(cte_type);
555 #endif /* CONFIG_BT_CTLR_DF_CTE_TX */
556 
557 	switch (type) {
558 	case BT_HCI_TEST_PKT_PAYLOAD_PRBS9:
559 		(void)memcpy(pdu->payload, prbs9, len);
560 		break;
561 
562 	case BT_HCI_TEST_PKT_PAYLOAD_11110000:
563 		(void)memset(pdu->payload, PAYLOAD_11110000, len);
564 		break;
565 
566 	case BT_HCI_TEST_PKT_PAYLOAD_10101010:
567 		(void)memset(pdu->payload, PAYLOAD_10101010, len);
568 		break;
569 
570 	case BT_HCI_TEST_PKT_PAYLOAD_PRBS15:
571 		(void)memcpy(pdu->payload, prbs15, len);
572 		break;
573 
574 	case BT_HCI_TEST_PKT_PAYLOAD_11111111:
575 		(void)memset(pdu->payload, PAYLOAD_11111111, len);
576 		break;
577 
578 	case BT_HCI_TEST_PKT_PAYLOAD_00000000:
579 		(void)memset(pdu->payload, PAYLOAD_00000000, len);
580 		break;
581 
582 	case BT_HCI_TEST_PKT_PAYLOAD_00001111:
583 		(void)memset(pdu->payload, PAYLOAD_00001111, len);
584 		break;
585 
586 	case BT_HCI_TEST_PKT_PAYLOAD_01010101:
587 		(void)memset(pdu->payload, PAYLOAD_01010101, len);
588 		break;
589 	}
590 
591 	radio_pkt_tx_set(pdu);
592 }
593 
ll_test_tx(uint8_t chan,uint8_t len,uint8_t type,uint8_t phy,uint8_t cte_len,uint8_t cte_type,uint8_t switch_pattern_len,const uint8_t * ant_id,int8_t tx_power)594 uint8_t ll_test_tx(uint8_t chan, uint8_t len, uint8_t type, uint8_t phy,
595 		   uint8_t cte_len, uint8_t cte_type, uint8_t switch_pattern_len,
596 		   const uint8_t *ant_id, int8_t tx_power)
597 {
598 	uint32_t start_us;
599 	uint8_t err;
600 	const bool cte_request = (cte_len > 0) ? true : false;
601 
602 	if ((type > BT_HCI_TEST_PKT_PAYLOAD_01010101) || !phy ||
603 	    (phy > BT_HCI_LE_TX_PHY_CODED_S2)) {
604 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
605 	}
606 
607 	err = init(chan, phy, tx_power, cte_request, isr_tx);
608 	if (err) {
609 		return err;
610 	}
611 
612 	/* Configure Constant Tone Extension */
613 	if (cte_request) {
614 #if defined(CONFIG_BT_CTLR_DF_CTE_TX)
615 		if (phy > BT_HCI_LE_TX_PHY_2M) {
616 			return BT_HCI_ERR_CMD_DISALLOWED;
617 		}
618 
619 		err = cte_tx_init(cte_len, cte_type, switch_pattern_len, ant_id);
620 		if (err) {
621 			return err;
622 		}
623 #else
624 		return BT_HCI_ERR_CMD_DISALLOWED;
625 #endif /* CONFIG_BT_CTLR_DF_CTE_TX */
626 	}
627 
628 	tx_req++;
629 
630 	payload_set(type, len, cte_len, cte_type);
631 
632 #if defined(CONFIG_BT_CTLR_DF_CTE_TX)
633 	/* Store CTE parameters needed in Tx ISR */
634 	test_cte_len = cte_len;
635 #endif /* CONFIG_BT_CTLR_DF_CTE_TX */
636 
637 	tx_tifs = calculate_tifs(len);
638 
639 	radio_tmr_tifs_set(tx_tifs);
640 	radio_switch_complete_and_b2b_tx(test_phy, test_phy_flags, test_phy, test_phy_flags);
641 
642 	start_us = radio_tmr_start(1, cntr_cnt_get() + CNTR_MIN_DELTA, 0);
643 	radio_tmr_end_capture();
644 
645 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
646 	radio_gpio_pa_setup();
647 	radio_gpio_pa_lna_enable(start_us +
648 				 radio_tx_ready_delay_get(test_phy,
649 							  test_phy_flags) -
650 				 HAL_RADIO_GPIO_PA_OFFSET);
651 #else /* !HAL_RADIO_GPIO_HAVE_PA_PIN */
652 	ARG_UNUSED(start_us);
653 #endif /* !HAL_RADIO_GPIO_HAVE_PA_PIN */
654 
655 	started = true;
656 
657 	return BT_HCI_ERR_SUCCESS;
658 }
659 
ll_test_rx(uint8_t chan,uint8_t phy,uint8_t mod_idx,uint8_t expected_cte_len,uint8_t expected_cte_type,uint8_t slot_duration,uint8_t switch_pattern_len,const uint8_t * ant_ids)660 uint8_t ll_test_rx(uint8_t chan, uint8_t phy, uint8_t mod_idx, uint8_t expected_cte_len,
661 		   uint8_t expected_cte_type, uint8_t slot_duration, uint8_t switch_pattern_len,
662 		   const uint8_t *ant_ids)
663 {
664 	uint8_t err;
665 	const bool cte_expected = (expected_cte_len > 0) ? true : false;
666 
667 	if (!phy || (phy > BT_HCI_LE_RX_PHY_CODED)) {
668 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
669 	}
670 
671 	err = init(chan, phy, BT_HCI_TX_TEST_POWER_MAX_SET, cte_expected, isr_rx);
672 	if (err) {
673 		return err;
674 	}
675 
676 	if (cte_expected) {
677 #if defined(CONFIG_BT_CTLR_DF_CTE_RX)
678 		if (phy == BT_HCI_LE_RX_PHY_CODED) {
679 			return BT_HCI_ERR_CMD_DISALLOWED;
680 		}
681 
682 		err = cte_rx_init(expected_cte_len, expected_cte_type, slot_duration,
683 				  switch_pattern_len, ant_ids, phy);
684 		if (err) {
685 			return err;
686 		}
687 #else
688 		return BT_HCI_ERR_CMD_DISALLOWED;
689 #endif /* CONFIG_BT_CTLR_DF_CTE_RX */
690 	}
691 
692 #if defined(CONFIG_BT_CTLR_DF_CTE_RX)
693 	/* Store CTE parameters needed in Rx ISR */
694 	test_cte_type = expected_cte_type;
695 	test_cte_len = expected_cte_len;
696 #endif /* CONFIG_BT_CTLR_DF_CTE_RX */
697 
698 #if defined(CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT)
699 	test_chan = chan;
700 	test_slot_duration = slot_duration;
701 #endif /* CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT */
702 
703 	radio_pkt_rx_set(radio_pkt_scratch_get());
704 	radio_tmr_tifs_set(EVENT_IFS_US);
705 	radio_switch_complete_and_b2b_rx(test_phy, test_phy_flags, test_phy, test_phy_flags);
706 	radio_tmr_start(0, cntr_cnt_get() + CNTR_MIN_DELTA, 0);
707 
708 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
709 	radio_gpio_lna_on();
710 #endif /* !HAL_RADIO_GPIO_HAVE_LNA_PIN */
711 
712 	started = true;
713 
714 	return BT_HCI_ERR_SUCCESS;
715 }
716 
ll_test_end(uint16_t * num_rx)717 uint8_t ll_test_end(uint16_t *num_rx)
718 {
719 	int err;
720 	uint8_t ack;
721 
722 	if (!started) {
723 		return BT_HCI_ERR_CMD_DISALLOWED;
724 	}
725 
726 	/* Return packets Rx-ed/Completed */
727 	*num_rx = test_num_rx;
728 	test_num_rx = 0U;
729 
730 	/* Disable Radio, if in Rx test */
731 	ack = tx_ack;
732 	if (tx_req == ack) {
733 		radio_disable();
734 	} else {
735 		/* Wait for Tx to complete */
736 		tx_req = ack + 2;
737 		while (tx_req != tx_ack) {
738 			cpu_sleep();
739 		}
740 	}
741 
742 	/* Stop packet timer */
743 	radio_tmr_stop();
744 
745 	/* Release resources acquired for Radio */
746 	err = lll_hfclock_off();
747 	LL_ASSERT(err >= 0);
748 
749 	/* Stop coarse timer */
750 	cntr_stop();
751 
752 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
753 	radio_gpio_lna_off();
754 #endif /* !HAL_RADIO_GPIO_HAVE_LNA_PIN */
755 
756 	started = false;
757 
758 	return BT_HCI_ERR_SUCCESS;
759 }
760