1 /*
2  * Copyright 2024 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <errno.h>
8 #include <stddef.h>
9 #include <string.h>
10 
11 #include <zephyr/kernel.h>
12 #include <zephyr/arch/cpu.h>
13 
14 #include <zephyr/init.h>
15 #include <zephyr/drivers/uart.h>
16 #include <zephyr/drivers/gpio.h>
17 #include <zephyr/sys/util.h>
18 #include <zephyr/sys/byteorder.h>
19 #include <zephyr/sys/crc.h>
20 
21 #include <zephyr/bluetooth/bluetooth.h>
22 #include <zephyr/bluetooth/hci.h>
23 
24 #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL
25 #include <zephyr/logging/log.h>
26 LOG_MODULE_REGISTER(bt_nxp_ctlr);
27 
28 #include "common/bt_str.h"
29 
30 #include "bt_nxp_ctlr_fw.h"
31 
32 #define DT_DRV_COMPAT nxp_bt_hci_uart
33 
34 #define FW_UPLOAD_CHANGE_TIMEOUT_RETRY_COUNT 6
35 
36 static const struct device *uart_dev = DEVICE_DT_GET(DT_INST_GPARENT(0));
37 
38 #if DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios)
39 struct gpio_dt_spec sdio_reset = GPIO_DT_SPEC_GET(DT_DRV_INST(0), sdio_reset_gpios);
40 #endif /* DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios) */
41 #if DT_NODE_HAS_PROP(DT_DRV_INST(0), w_disable_gpios)
42 struct gpio_dt_spec w_disable = GPIO_DT_SPEC_GET(DT_DRV_INST(0), w_disable_gpios);
43 #endif /* DT_NODE_HAS_PROP(DT_DRV_INST(0), w_disable_gpios) */
44 
45 struct nxp_ctlr_dev_data {
46 	uint32_t primary_speed;
47 	bool primary_flowcontrol;
48 	uint32_t secondary_speed;
49 	bool secondary_flowcontrol;
50 };
51 
52 static struct nxp_ctlr_dev_data uart_dev_data;
53 
54 #define DI         0x07U
55 #define POLYNOMIAL 0x04c11db7UL
56 
57 #define CRC32_LEN 4
58 
59 static unsigned long crc_table[256U];
60 static bool made_table;
61 
fw_upload_gen_crc32_table(void)62 static void fw_upload_gen_crc32_table(void)
63 {
64 	int i, j;
65 	unsigned long crc_accum;
66 
67 	for (i = 0; i < 256; i++) {
68 		crc_accum = ((unsigned long)i << 24);
69 		for (j = 0; j < 8; j++) {
70 			if (crc_accum & 0x80000000L) {
71 				crc_accum = (crc_accum << 1) ^ POLYNOMIAL;
72 			} else {
73 				crc_accum = (crc_accum << 1);
74 			}
75 		}
76 		crc_table[i] = crc_accum;
77 	}
78 }
79 
fw_upload_crc8(unsigned char * array,unsigned char len)80 static unsigned char fw_upload_crc8(unsigned char *array, unsigned char len)
81 {
82 	unsigned char crc_8 = 0xff;
83 
84 	crc_8 = crc8(array, len, DI, crc_8, false);
85 
86 	return crc_8;
87 }
88 
fw_upload_update_crc32(unsigned long crc_accum,char * data_blk_ptr,int data_blk_size)89 static unsigned long fw_upload_update_crc32(unsigned long crc_accum, char *data_blk_ptr,
90 					 int data_blk_size)
91 {
92 	unsigned int i, j;
93 
94 	for (j = 0; j < data_blk_size; j++) {
95 		i = ((unsigned int)(crc_accum >> 24) ^ *data_blk_ptr++) & 0xff;
96 		crc_accum = (crc_accum << 8) ^ crc_table[i];
97 	}
98 	return crc_accum;
99 }
100 
101 #define CMD4 0x4U
102 #define CMD6 0x6U
103 #define CMD7 0x7U
104 
105 #define V1_HEADER_DATA_REQ  0xa5U
106 #define V1_START_INDICATION 0xaaU
107 #define V1_REQUEST_ACK      0x5aU
108 
109 #define V3_START_INDICATION 0xabU
110 #define V3_HEADER_DATA_REQ  0xa7U
111 #define V3_REQUEST_ACK      0x7aU
112 #define V3_TIMEOUT_ACK      0x7bU
113 #define V3_CRC_ERROR        0x7cU
114 
115 #define REQ_HEADER_LEN    1U
116 #define A6REQ_PAYLOAD_LEN 8U
117 #define AbREQ_PAYLOAD_LEN 3U
118 
119 #define CRC_ERR_BIT          BIT(0)
120 #define NAK_REC_BIT          BIT(1)
121 #define TIMEOUT_REC_ACK_BIT  BIT(2)
122 #define TIMEOUT_REC_HEAD_BIT BIT(3)
123 #define TIMEOUT_REC_DATA_BIT BIT(4)
124 #define INVALID_CMD_REC_BIT  BIT(5)
125 #define WIFI_MIC_FAIL_BIT    BIT(6)
126 #define BT_MIC_FAIL_BIT      BIT(7)
127 
128 #define CMD_HDR_LEN 16
129 
130 /* CMD5 Header to change bootloader baud rate */
131 static uint8_t cmd5_hdrData[CMD_HDR_LEN] = {0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 					    0x2c, 0x00, 0x00, 0x00, 0x77, 0xdb, 0xfd, 0xe0};
133 /* CMD7 Header to change timeout of bootloader */
134 static uint8_t cmd7_hdrData[CMD_HDR_LEN] = {0x07, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
135 					    0x00, 0x00, 0x00, 0x00, 0x5b, 0x88, 0xf8, 0xba};
136 
137 enum bt_nxp_ctlr_version {
138 	VER1 = 1,
139 	VER2,
140 	VER3,
141 };
142 
143 struct change_speed_config {
144 	uint32_t clk_div_addr;
145 	uint32_t clk_div_val;
146 	uint32_t uart_clk_div_addr;
147 	uint32_t uart_clk_div_val;
148 	uint32_t mcr_addr;
149 	uint32_t mcr_val;
150 	uint32_t reinit_addr;
151 	uint32_t reinit_val;
152 	uint32_t icr_addr;
153 	uint32_t icr_val;
154 	uint32_t fcr_addr;
155 	uint32_t fcr_val;
156 };
157 
158 #define SEND_BUFFER_MAX_LENGTH  0xFFFFU /* Maximum 2 byte value */
159 #define RECV_RING_BUFFER_LENGTH 1024
160 
161 struct nxp_ctlr_fw_upload_state {
162 	uint8_t version;
163 	uint8_t hdr_sig;
164 
165 	uint8_t buffer[A6REQ_PAYLOAD_LEN + REQ_HEADER_LEN + 1];
166 
167 	uint8_t send_buffer[SEND_BUFFER_MAX_LENGTH + 1];
168 
169 	struct {
170 		uint8_t buffer[RECV_RING_BUFFER_LENGTH];
171 		uint32_t head;
172 		uint32_t tail;
173 		struct k_sem sem;
174 	} rx;
175 
176 	uint16_t length;
177 	uint32_t offset;
178 	uint16_t error;
179 	uint8_t crc8;
180 
181 	uint32_t last_offset;
182 	uint8_t change_speed_buffer[sizeof(struct change_speed_config) + CRC32_LEN];
183 
184 	uint32_t fw_length;
185 	uint32_t current_length;
186 	const uint8_t *fw;
187 
188 	uint32_t cmd7_change_timeout_len;
189 	uint32_t change_speed_buffer_len;
190 
191 	bool wait_hdr_sig;
192 
193 	bool is_hdr_data;
194 	bool is_error_case;
195 	bool is_cmd7_req;
196 	bool is_entry_point_req;
197 	bool is_setup_done;
198 
199 	uint8_t last_5bytes_buffer[6];
200 };
201 
202 static struct nxp_ctlr_fw_upload_state fw_upload;
203 
fw_upload_read_data(uint8_t * buffer,uint32_t len)204 static int fw_upload_read_data(uint8_t *buffer, uint32_t len)
205 {
206 	int err;
207 
208 	while (len > 0) {
209 		err = k_sem_take(&fw_upload.rx.sem,
210 				 K_MSEC(CONFIG_BT_H4_NXP_CTLR_WAIT_HDR_SIG_TIMEOUT));
211 		if (err < 0) {
212 			LOG_ERR("Fail to read data");
213 			return err;
214 		}
215 		*buffer = fw_upload.rx.buffer[fw_upload.rx.tail];
216 		buffer++;
217 		fw_upload.rx.tail++;
218 		fw_upload.rx.tail = fw_upload.rx.tail % sizeof(fw_upload.rx.buffer);
219 		len--;
220 	}
221 	return 0;
222 }
223 
fw_upload_read_to_clear(void)224 static void fw_upload_read_to_clear(void)
225 {
226 	uint32_t key;
227 
228 	key = irq_lock();
229 	k_sem_reset(&fw_upload.rx.sem);
230 	fw_upload.rx.head = 0;
231 	fw_upload.rx.tail = 0;
232 	irq_unlock(key);
233 }
234 
fw_upload_wait_for_hdr_sig(void)235 static int fw_upload_wait_for_hdr_sig(void)
236 {
237 	int err;
238 	int64_t end;
239 	char c;
240 
241 	end = k_uptime_get() + CONFIG_BT_H4_NXP_CTLR_WAIT_HDR_SIG_TIMEOUT;
242 	fw_upload.hdr_sig = 0xFF;
243 
244 	while (k_uptime_get() < end) {
245 		err = fw_upload_read_data(&c, 1);
246 		if (err < 0) {
247 			k_msleep(1);
248 			continue;
249 		}
250 		if ((c == V1_HEADER_DATA_REQ) || (c == V1_START_INDICATION) ||
251 		    (c == V3_START_INDICATION) || (c == V3_HEADER_DATA_REQ)) {
252 			LOG_DBG("HDR SIG found 0x%02X", c);
253 			fw_upload.hdr_sig = c;
254 			if (fw_upload.version == 0) {
255 				if ((c == V3_START_INDICATION) || (c == V3_HEADER_DATA_REQ)) {
256 					fw_upload.version = VER3;
257 				} else {
258 					fw_upload.version = VER1;
259 				}
260 			}
261 			return 0;
262 		}
263 	}
264 	LOG_ERR("HDR SIG not found");
265 	return -EIO;
266 }
267 
fw_upload_write_data(const uint8_t * buffer,uint32_t len)268 static void fw_upload_write_data(const uint8_t *buffer, uint32_t len)
269 {
270 	for (int i = 0; i < len; i++) {
271 		uart_poll_out(uart_dev, buffer[i]);
272 	}
273 }
274 
fw_upload_request_check_crc(uint8_t * buffer,uint8_t request)275 static int fw_upload_request_check_crc(uint8_t *buffer, uint8_t request)
276 {
277 	uint8_t crc;
278 
279 	if (request == V3_HEADER_DATA_REQ) {
280 		crc = fw_upload_crc8(buffer, A6REQ_PAYLOAD_LEN + REQ_HEADER_LEN);
281 		if (crc != buffer[A6REQ_PAYLOAD_LEN + REQ_HEADER_LEN]) {
282 			LOG_ERR("Request %d, CRC check failed", request);
283 			return -EINVAL;
284 		}
285 	} else if (request == V3_START_INDICATION) {
286 		crc = fw_upload_crc8(buffer, AbREQ_PAYLOAD_LEN + REQ_HEADER_LEN);
287 		if (crc != buffer[AbREQ_PAYLOAD_LEN + REQ_HEADER_LEN]) {
288 			LOG_ERR("Request %d, CRC check failed", request);
289 			return -EINVAL;
290 		}
291 	} else {
292 		LOG_ERR("Invalid request %d", request);
293 	}
294 
295 	return 0;
296 }
297 
fw_upload_send_ack(uint8_t ack)298 static void fw_upload_send_ack(uint8_t ack)
299 {
300 	if ((ack == V3_REQUEST_ACK) || (ack == V3_CRC_ERROR)) {
301 		/* prepare crc for 0x7A or 0x7C */
302 		fw_upload.buffer[0] = ack;
303 		fw_upload.buffer[1] = fw_upload_crc8(fw_upload.buffer, 1);
304 		fw_upload_write_data(fw_upload.buffer, 2);
305 		LOG_DBG("ACK = %x, CRC = %x", ack, fw_upload.buffer[1]);
306 	} else if (ack == V3_TIMEOUT_ACK) {
307 		/* prepare crc for 0x7B */
308 		fw_upload.buffer[0] = ack;
309 		sys_put_le32(fw_upload.offset, &fw_upload.buffer[1]);
310 		fw_upload.buffer[5] = fw_upload_crc8(fw_upload.buffer, 5);
311 		fw_upload_write_data(fw_upload.buffer, 6);
312 		LOG_DBG("ACK = %x, CRC = %x", ack, fw_upload.buffer[5]);
313 	} else {
314 		LOG_ERR("Invalid ack");
315 	}
316 }
317 
fw_upload_wait_req(bool secondary_speed)318 static int fw_upload_wait_req(bool secondary_speed)
319 {
320 	int err;
321 	uint32_t len;
322 	uint8_t buffer[10];
323 
324 	buffer[0] = fw_upload.hdr_sig;
325 	if (fw_upload.hdr_sig == V3_HEADER_DATA_REQ) {
326 		/* CMD LINE: 0xA7 <len><offset><error><CRC8> */
327 		len = A6REQ_PAYLOAD_LEN + 1;
328 	} else if (fw_upload.hdr_sig == V3_START_INDICATION) {
329 		/* CMD LINE: 0xAB <CHIP ID><SW loader REV 1 byte><CRC8> */
330 		len = AbREQ_PAYLOAD_LEN + 1;
331 	} else {
332 		return -EINVAL;
333 	}
334 
335 	err = fw_upload_read_data(&buffer[1], len);
336 	if (err < 0) {
337 		LOG_ERR("Fail to read req");
338 		return err;
339 	}
340 
341 	err = fw_upload_request_check_crc(buffer, fw_upload.hdr_sig);
342 	if (err != 0) {
343 		LOG_ERR("Fail to check CRC");
344 		fw_upload_send_ack(V3_CRC_ERROR);
345 		return err;
346 	}
347 
348 	if (fw_upload.hdr_sig == V3_HEADER_DATA_REQ) {
349 		fw_upload.length = sys_get_le16(&buffer[1]);
350 		fw_upload.offset = sys_get_le32(&buffer[3]);
351 		fw_upload.error = sys_get_le16(&buffer[7]);
352 		fw_upload.crc8 = buffer[9];
353 		LOG_DBG("Req: %hhd, %hd, %d, %hd, %hhd", fw_upload.hdr_sig, fw_upload.length,
354 			fw_upload.offset, fw_upload.error, fw_upload.crc8);
355 	} else if (fw_upload.hdr_sig == V3_START_INDICATION) {
356 		uint16_t chip_id;
357 
358 		fw_upload_send_ack(V3_REQUEST_ACK);
359 		chip_id = sys_get_le16(&buffer[1]);
360 		LOG_DBG("Indicate: %hhd, %hd, %hhd, %hhd", fw_upload.hdr_sig, chip_id, buffer[3],
361 			buffer[4]);
362 
363 		if (!secondary_speed) {
364 			return -EINVAL;
365 		}
366 	}
367 
368 	return 0;
369 }
370 
fw_upload_change_timeout(void)371 static int fw_upload_change_timeout(void)
372 {
373 	int err = 0;
374 	bool first = true;
375 	uint8_t retry = FW_UPLOAD_CHANGE_TIMEOUT_RETRY_COUNT;
376 
377 	LOG_DBG("");
378 
379 	fw_upload_gen_crc32_table();
380 
381 	while (true) {
382 		err = fw_upload_wait_for_hdr_sig();
383 		if (err) {
384 			continue;
385 		}
386 
387 		if (fw_upload.version == VER1) {
388 			return 0;
389 		} else if (fw_upload.version == VER3) {
390 			err = fw_upload_wait_req(true);
391 			if (err) {
392 				continue;
393 			}
394 
395 			if (fw_upload.length == 0) {
396 				continue;
397 			}
398 
399 			if (fw_upload.error == 0) {
400 				if (first || (fw_upload.last_offset == fw_upload.offset)) {
401 					fw_upload_send_ack(V3_REQUEST_ACK);
402 					fw_upload_write_data(cmd7_hdrData,
403 							     fw_upload.length > CMD_HDR_LEN
404 								     ? CMD_HDR_LEN
405 								     : fw_upload.length);
406 					fw_upload.last_offset = fw_upload.offset;
407 					first = false;
408 				} else {
409 					fw_upload.cmd7_change_timeout_len = CMD_HDR_LEN;
410 					fw_upload.wait_hdr_sig = false;
411 					return 0;
412 				}
413 			} else {
414 				if (retry > 0) {
415 					retry--;
416 					fw_upload_send_ack(V3_TIMEOUT_ACK);
417 				} else {
418 					LOG_ERR("Fail to change timeout with response err %d",
419 						fw_upload.error);
420 					return -ENOTSUP;
421 				}
422 			}
423 		} else {
424 			LOG_ERR("Unsupported version %d", fw_upload.version);
425 			return -ENOTSUP;
426 		}
427 	}
428 
429 	return -EINVAL;
430 }
431 
432 typedef struct {
433 	uint32_t uartBaudRate;
434 	uint32_t uartDivisio;
435 	uint32_t uartClkDivisor;
436 } uart_baudrate_clkDiv_map_t;
437 
438 static const uart_baudrate_clkDiv_map_t clk_div_map[] = {
439 	{115200U, 16U, 0x0075F6FDU},
440 	{1000000U, 2U, 0x00800000U},
441 	{3000000U, 1U, 0x00C00000U},
442 };
443 
fw_upload_change_speed_config(struct change_speed_config * config,uint32_t speed)444 static int fw_upload_change_speed_config(struct change_speed_config *config, uint32_t speed)
445 {
446 	config->clk_div_addr = 0x7f00008fU;
447 	config->uart_clk_div_addr = 0x7f000090U;
448 	config->mcr_addr = 0x7f000091U;
449 	config->reinit_addr = 0x7f000092U;
450 	config->icr_addr = 0x7f000093U;
451 	config->fcr_addr = 0x7f000094U;
452 
453 	config->mcr_val = 0x00000022U;
454 	config->reinit_val = 0x00000001U;
455 	config->icr_val = 0x000000c7U;
456 	config->fcr_val = 0x000000c7U;
457 
458 	for (int i = 0; i < ARRAY_SIZE(clk_div_map); i++) {
459 		if (speed == clk_div_map[i].uartBaudRate) {
460 			config->clk_div_val = clk_div_map[i].uartClkDivisor;
461 			config->uart_clk_div_val = clk_div_map[i].uartDivisio;
462 			return 0;
463 		}
464 	}
465 	return -ENOTSUP;
466 }
467 
fw_upload_wait_length(uint8_t flag)468 static uint16_t fw_upload_wait_length(uint8_t flag)
469 {
470 	uint8_t buffer[4];
471 	uint16_t len;
472 	uint16_t len_comp;
473 	int err;
474 	uint8_t ack;
475 
476 	err = fw_upload_read_data(buffer, sizeof(buffer));
477 	if (err < 0) {
478 		return 0;
479 	}
480 
481 	len = sys_get_le16(buffer);
482 	len_comp = sys_get_le16(buffer);
483 
484 	if ((len ^ len_comp) == 0xFFFF) {
485 		LOG_DBG("remote asks for %d bytes", len);
486 
487 		/* Successful. Send back the ack. */
488 		if ((fw_upload.hdr_sig == V1_HEADER_DATA_REQ) ||
489 		    (fw_upload.hdr_sig == V1_START_INDICATION)) {
490 			ack = V1_REQUEST_ACK;
491 			fw_upload_write_data(&ack, 1);
492 			if (fw_upload.hdr_sig == V1_START_INDICATION) {
493 				/* Eliminated longjmp(resync, 1); returning restart status */
494 				return (uint16_t)V1_START_INDICATION;
495 			}
496 		}
497 	} else {
498 		LOG_ERR("remote asks len %d bytes", len);
499 		LOG_ERR("remote asks len_comp %d bytes", len_comp);
500 		/* Failure due to mismatch. */
501 		ack = 0xbf;
502 		fw_upload_write_data(&ack, 1);
503 		/* Start all over again. */
504 		if (flag) {
505 			/* Eliminated longjmp(resync, 1); returning restart status */
506 			return (uint16_t)V1_START_INDICATION;
507 		}
508 		len = 0;
509 	}
510 	return len;
511 }
512 
fw_upload_get_payload_length(uint8_t * cmd)513 static uint32_t fw_upload_get_payload_length(uint8_t *cmd)
514 {
515 	uint32_t len;
516 
517 	len = sys_get_le32(&cmd[8]);
518 
519 	return len;
520 }
521 
fw_upload_get_hdr_start(uint8_t * buffer)522 static void fw_upload_get_hdr_start(uint8_t *buffer)
523 {
524 	int err;
525 	bool done = false;
526 	uint32_t count = 0;
527 
528 	while (!done) {
529 		err = fw_upload_read_data(&fw_upload.hdr_sig, 1);
530 		if (err >= 0) {
531 			if (fw_upload.hdr_sig == V1_HEADER_DATA_REQ) {
532 				buffer[count++] = fw_upload.hdr_sig;
533 				done = true;
534 				LOG_DBG("Found header %x", fw_upload.hdr_sig);
535 			}
536 		} else {
537 			LOG_ERR("Fail to read HDR sig %d", err);
538 			return;
539 		}
540 	}
541 	err = fw_upload_read_data(&buffer[count], 4);
542 	if (err < 0) {
543 		LOG_ERR("Fail to read HDR payload %d", err);
544 	}
545 }
546 
fw_upload_len_valid(uint8_t * buffer,uint16_t * length)547 static int fw_upload_len_valid(uint8_t *buffer, uint16_t *length)
548 {
549 	uint16_t len;
550 	uint16_t len_comp;
551 
552 	len = sys_get_le16(&buffer[1]);
553 	len_comp = sys_get_le16(&buffer[3]);
554 
555 	if ((len ^ len_comp) == 0xFFFFU) {
556 		*length = len;
557 		return 0;
558 	} else {
559 		return -EINVAL;
560 	}
561 }
562 
fw_upload_get_last_5bytes(uint8_t * buffer)563 static int fw_upload_get_last_5bytes(uint8_t *buffer)
564 {
565 	int err;
566 	uint32_t payload_len;
567 	uint16_t len = 0;
568 
569 	memset(fw_upload.last_5bytes_buffer, 0, sizeof(fw_upload.last_5bytes_buffer));
570 
571 	fw_upload_get_hdr_start(fw_upload.last_5bytes_buffer);
572 	err = fw_upload_len_valid(fw_upload.last_5bytes_buffer, &len);
573 	if (err >= 0) {
574 		LOG_DBG("Valid len %d", len);
575 	} else {
576 		LOG_ERR("Invalid HDR");
577 		return err;
578 	}
579 
580 	payload_len = fw_upload_get_payload_length(buffer);
581 
582 	if ((len == CMD_HDR_LEN) || ((uint32_t)len == payload_len)) {
583 		LOG_DBG("Len valid");
584 		fw_upload.is_error_case = false;
585 		return 0;
586 	}
587 
588 	LOG_DBG("Len invalid");
589 	fw_upload.is_error_case = true;
590 
591 	return -EINVAL;
592 }
593 
fw_upload_update_result(uint32_t payload_len,uint16_t * sending_len,bool * first_chunk_sent)594 static void fw_upload_update_result(uint32_t payload_len, uint16_t *sending_len,
595 				    bool *first_chunk_sent)
596 {
597 	if (fw_upload.is_cmd7_req || fw_upload.is_entry_point_req) {
598 		*sending_len = CMD_HDR_LEN;
599 		*first_chunk_sent = true;
600 	} else {
601 		*sending_len = payload_len;
602 		*first_chunk_sent = false;
603 		if (*sending_len == CMD_HDR_LEN) {
604 			fw_upload.is_hdr_data = true;
605 		}
606 	}
607 }
608 
fw_upload_write_hdr_and_payload(uint16_t len_to_send,uint8_t * buffer,bool new_speed)609 static int fw_upload_write_hdr_and_payload(uint16_t len_to_send, uint8_t *buffer, bool new_speed)
610 {
611 	int err;
612 	uint32_t payload_len;
613 	bool send_done = false;
614 	uint16_t sending_len = CMD_HDR_LEN;
615 	bool first_chunk_sent = false;
616 
617 	LOG_DBG("");
618 
619 	payload_len = fw_upload_get_payload_length(buffer);
620 
621 	while (!send_done) {
622 		if (sending_len == len_to_send) {
623 			if ((sending_len == CMD_HDR_LEN) && (!fw_upload.is_hdr_data)) {
624 				if ((first_chunk_sent == false) ||
625 				    (first_chunk_sent && fw_upload.is_error_case)) {
626 					LOG_DBG("Send first chunk: len %d", sending_len);
627 					fw_upload_write_data(buffer, sending_len);
628 					fw_upload_update_result(payload_len, &sending_len,
629 								&first_chunk_sent);
630 				} else {
631 					send_done = true;
632 					break;
633 				}
634 			} else {
635 				LOG_DBG("Send data: len %d", sending_len);
636 				if (sending_len) {
637 					fw_upload_write_data(&buffer[CMD_HDR_LEN], sending_len);
638 					first_chunk_sent = true;
639 					sending_len = CMD_HDR_LEN;
640 					fw_upload.is_hdr_data = false;
641 					if (new_speed) {
642 						return 0;
643 					}
644 				} else {
645 					LOG_DBG("Download Complete");
646 					return 0;
647 				}
648 			}
649 		} else {
650 			if ((len_to_send & 0x01) == 0x01) {
651 				if (len_to_send == (CMD_HDR_LEN + 1)) {
652 					LOG_DBG("Resending first chunk...");
653 					fw_upload_write_data(buffer, len_to_send - 1);
654 					sending_len = payload_len;
655 					first_chunk_sent = false;
656 				} else if (len_to_send == (payload_len + 1)) {
657 					LOG_DBG("Resending second chunk...");
658 					fw_upload_write_data(&buffer[CMD_HDR_LEN], len_to_send - 1);
659 					sending_len = CMD_HDR_LEN;
660 					first_chunk_sent = true;
661 				}
662 			} else if (len_to_send == CMD_HDR_LEN) {
663 				LOG_DBG("Resending send buffer...");
664 				fw_upload_write_data(buffer, len_to_send);
665 				sending_len = payload_len;
666 				first_chunk_sent = false;
667 			} else if (len_to_send == payload_len) {
668 				LOG_DBG("Resending second chunk...");
669 				fw_upload_write_data(&buffer[CMD_HDR_LEN], len_to_send);
670 				sending_len = CMD_HDR_LEN;
671 				first_chunk_sent = true;
672 			}
673 		}
674 
675 		err = fw_upload_get_last_5bytes(buffer);
676 		if (err < 0) {
677 			LOG_ERR("Fail to get response");
678 			return err;
679 		}
680 
681 		if (fw_upload_len_valid(fw_upload.last_5bytes_buffer, &len_to_send) == 0) {
682 			fw_upload_send_ack(V1_REQUEST_ACK);
683 			LOG_DBG("BOOT_HEADER_ACK 0x5a sent");
684 		}
685 	}
686 	return len_to_send;
687 }
688 
fw_upload_uart_reconfig(uint32_t speed,bool flow_control)689 static int fw_upload_uart_reconfig(uint32_t speed, bool flow_control)
690 {
691 	struct uart_config config;
692 	int err;
693 
694 	config.baudrate = speed;
695 	config.data_bits = UART_CFG_DATA_BITS_8;
696 	config.flow_ctrl = flow_control ? UART_CFG_FLOW_CTRL_RTS_CTS : UART_CFG_FLOW_CTRL_NONE;
697 	config.parity = UART_CFG_PARITY_NONE;
698 	config.stop_bits = UART_CFG_STOP_BITS_1;
699 
700 	uart_irq_rx_disable(uart_dev);
701 	uart_irq_tx_disable(uart_dev);
702 	fw_upload_read_to_clear();
703 	err = uart_configure(uart_dev, &config);
704 	uart_irq_rx_enable(uart_dev);
705 
706 	return err;
707 }
708 
fw_upload_change_speed(uint8_t hdr)709 static int fw_upload_change_speed(uint8_t hdr)
710 {
711 	int err;
712 	uint32_t hdr_len;
713 	bool load_payload = false;
714 	bool recovery = false;
715 	uint16_t len_to_send;
716 	uint32_t crc;
717 
718 	err = fw_upload_change_speed_config(
719 		(struct change_speed_config *)fw_upload.change_speed_buffer,
720 		uart_dev_data.secondary_speed);
721 	if (err) {
722 		return err;
723 	}
724 
725 	hdr_len = sizeof(fw_upload.change_speed_buffer);
726 
727 	fw_upload_gen_crc32_table();
728 	crc = sys_cpu_to_le32(hdr_len);
729 	memcpy(cmd5_hdrData + 8, &crc, 4);
730 	crc = fw_upload_update_crc32(0, (char *)cmd5_hdrData, 12);
731 	crc = sys_cpu_to_be32(crc);
732 	memcpy(cmd5_hdrData + 12, &crc, CRC32_LEN);
733 	crc = fw_upload_update_crc32(0, (char *)fw_upload.change_speed_buffer,
734 				  (int)sizeof(struct change_speed_config));
735 	crc = sys_cpu_to_be32(crc);
736 	memcpy(&fw_upload.change_speed_buffer[sizeof(struct change_speed_config)], &crc, CRC32_LEN);
737 
738 	while (true) {
739 		err = fw_upload_wait_for_hdr_sig();
740 
741 		if (hdr && (err == 0)) {
742 			if (load_payload) {
743 				if (fw_upload.version == VER3) {
744 					fw_upload.change_speed_buffer_len =
745 						CMD_HDR_LEN + fw_upload.length;
746 				}
747 				return 0;
748 			}
749 		} else {
750 			if (recovery) {
751 				return -ETIME;
752 			}
753 
754 			if (load_payload) {
755 				LOG_ERR("HDR cannot be received by using second speed. receovery "
756 					"speed");
757 
758 				err = fw_upload_uart_reconfig(uart_dev_data.primary_speed,
759 							      uart_dev_data.primary_flowcontrol);
760 				if (err) {
761 					return err;
762 				}
763 
764 				load_payload = false;
765 				recovery = true;
766 				continue;
767 			}
768 		}
769 
770 		if (fw_upload.version == VER1) {
771 			len_to_send = fw_upload_wait_length(0);
772 			if (len_to_send == V1_START_INDICATION) {
773 				return -EINVAL;
774 			} else if (len_to_send == 0) {
775 				continue;
776 			} else if (len_to_send == CMD_HDR_LEN) {
777 				memcpy(fw_upload.send_buffer, cmd5_hdrData, CMD_HDR_LEN);
778 				memcpy(&fw_upload.send_buffer[CMD_HDR_LEN],
779 				       fw_upload.change_speed_buffer, hdr_len);
780 
781 				err = fw_upload_write_hdr_and_payload(len_to_send,
782 								   fw_upload.send_buffer, true);
783 				if (err < 0) {
784 					return err;
785 				}
786 
787 				LOG_DBG("Change speed to %d", uart_dev_data.secondary_speed);
788 
789 				err = fw_upload_uart_reconfig(uart_dev_data.secondary_speed,
790 							      uart_dev_data.secondary_flowcontrol);
791 				if (err) {
792 					return err;
793 				}
794 				load_payload = true;
795 			} else {
796 				fw_upload_write_data(fw_upload.change_speed_buffer, hdr_len);
797 
798 				LOG_DBG("Change speed to %d", uart_dev_data.secondary_speed);
799 
800 				err = fw_upload_uart_reconfig(uart_dev_data.secondary_speed,
801 							      uart_dev_data.secondary_flowcontrol);
802 				if (err) {
803 					return err;
804 				}
805 				load_payload = true;
806 			}
807 		} else if (fw_upload.version == VER3) {
808 			err = fw_upload_wait_req(true);
809 			if (!(!hdr || (err == 0))) {
810 				continue;
811 			}
812 			if (fw_upload.length && (fw_upload.hdr_sig == V3_HEADER_DATA_REQ)) {
813 				if (fw_upload.error != 0) {
814 					fw_upload_send_ack(V3_TIMEOUT_ACK);
815 					continue;
816 				}
817 
818 				fw_upload_send_ack(V3_REQUEST_ACK);
819 				hdr = true;
820 
821 				if (fw_upload.length == CMD_HDR_LEN) {
822 					LOG_DBG("Send CMD5");
823 					fw_upload_write_data(cmd5_hdrData, fw_upload.length);
824 					fw_upload.last_offset = fw_upload.offset;
825 				} else {
826 					LOG_DBG("Send UA RT config");
827 					fw_upload_write_data(fw_upload.change_speed_buffer,
828 							     fw_upload.length);
829 
830 					LOG_DBG("Change speed to %d",
831 						uart_dev_data.secondary_speed);
832 
833 					err = fw_upload_uart_reconfig(
834 						uart_dev_data.secondary_speed,
835 						uart_dev_data.secondary_flowcontrol);
836 					if (err) {
837 						return err;
838 					}
839 					load_payload = true;
840 				}
841 			}
842 		}
843 	}
844 
845 	return 0;
846 }
847 
fw_upload_v1_send_data(uint16_t len)848 static int fw_upload_v1_send_data(uint16_t len)
849 {
850 	uint32_t cmd;
851 	uint32_t data_len;
852 	int ret_len;
853 
854 	memset(fw_upload.send_buffer, 0, sizeof(fw_upload.send_buffer));
855 
856 	fw_upload.is_cmd7_req = false;
857 	fw_upload.is_entry_point_req = false;
858 
859 	if ((fw_upload.fw_length - fw_upload.current_length) < len) {
860 		len = fw_upload.fw_length - fw_upload.current_length;
861 	}
862 
863 	memcpy(fw_upload.send_buffer, fw_upload.fw + fw_upload.current_length, len);
864 	fw_upload.current_length += len;
865 	cmd = sys_get_le32(fw_upload.send_buffer);
866 	if (cmd == CMD7) {
867 		fw_upload.is_cmd7_req = true;
868 		data_len = 0;
869 	} else {
870 		data_len = fw_upload_get_payload_length(fw_upload.send_buffer);
871 		if ((data_len > (sizeof(fw_upload.send_buffer) - len)) ||
872 		    ((data_len + fw_upload.current_length) > fw_upload.fw_length)) {
873 			LOG_ERR("Invalid FW at %d/%d", fw_upload.current_length,
874 				fw_upload.fw_length);
875 			return -EINVAL;
876 		}
877 		memcpy(&fw_upload.send_buffer[len], fw_upload.fw + fw_upload.current_length,
878 		       data_len);
879 		fw_upload.current_length += data_len;
880 		if ((fw_upload.current_length < fw_upload.fw_length) &&
881 		    ((cmd == CMD6) || (cmd == CMD4))) {
882 			fw_upload.is_entry_point_req = true;
883 		}
884 	}
885 
886 	ret_len = fw_upload_write_hdr_and_payload(len, fw_upload.send_buffer, false);
887 	LOG_DBG("FW upload %d/%d", fw_upload.current_length, fw_upload.fw_length);
888 
889 	return ret_len;
890 }
891 
fw_upload_v3_send_data(void)892 static int fw_upload_v3_send_data(void)
893 {
894 	uint32_t start;
895 
896 	LOG_DBG("Sending offset %d", fw_upload.offset);
897 	if (fw_upload.offset == fw_upload.last_offset) {
898 		LOG_WRN("Resending offset %d ...", fw_upload.offset);
899 		fw_upload_write_data(fw_upload.send_buffer, fw_upload.length);
900 		return fw_upload.length;
901 	}
902 	memset(fw_upload.send_buffer, 0, sizeof(fw_upload.send_buffer));
903 	start = fw_upload.offset - fw_upload.cmd7_change_timeout_len -
904 		fw_upload.change_speed_buffer_len;
905 	if (start >= fw_upload.fw_length) {
906 		LOG_ERR("Invalid fw offset");
907 		return -EINVAL;
908 	}
909 
910 	if ((fw_upload.length + start) > fw_upload.fw_length) {
911 		fw_upload.length = fw_upload.fw_length - start;
912 	}
913 	memcpy(fw_upload.send_buffer, fw_upload.fw + start, fw_upload.length);
914 	fw_upload.current_length = start + fw_upload.length;
915 
916 	fw_upload_write_data(fw_upload.send_buffer, fw_upload.length);
917 	fw_upload.last_offset = fw_upload.offset;
918 
919 	return fw_upload.length;
920 }
921 
fw_uploading(const uint8_t * fw,uint32_t fw_length)922 static int fw_uploading(const uint8_t *fw, uint32_t fw_length)
923 {
924 	int err;
925 	bool secondary_speed = false;
926 	uint16_t len_to_send;
927 
928 	fw_upload.wait_hdr_sig = true;
929 	fw_upload.is_hdr_data = false;
930 	fw_upload.is_error_case = false;
931 	fw_upload.is_cmd7_req = false;
932 	fw_upload.is_entry_point_req = false;
933 	fw_upload.last_offset = 0xFFFFU;
934 
935 	err = fw_upload_change_timeout();
936 	LOG_DBG("Change timeout hdr flag %d (err %d)", fw_upload.wait_hdr_sig, err);
937 	if (err) {
938 		return err;
939 	}
940 
941 	fw_upload_read_to_clear();
942 
943 	if (uart_dev_data.secondary_speed &&
944 	    (uart_dev_data.secondary_speed != uart_dev_data.primary_speed)) {
945 		LOG_DBG("Change speed to %d", uart_dev_data.secondary_speed);
946 		err = fw_upload_change_speed(fw_upload.wait_hdr_sig);
947 		if (err != 0) {
948 			LOG_ERR("Fail to change speed");
949 			return err;
950 		}
951 		secondary_speed = true;
952 	}
953 
954 	fw_upload.fw_length = fw_length;
955 	fw_upload.current_length = 0;
956 	fw_upload.fw = fw;
957 
958 	while (true) {
959 		err = fw_upload_wait_for_hdr_sig();
960 		if (secondary_speed && (err != 0)) {
961 			return -ETIME;
962 		}
963 
964 		secondary_speed = false;
965 
966 		if (fw_upload.version == VER1) {
967 			len_to_send = fw_upload_wait_length(true);
968 
969 			if (len_to_send == V1_START_INDICATION) {
970 				continue;
971 			}
972 			while (len_to_send > 0) {
973 				len_to_send = fw_upload_v1_send_data(len_to_send);
974 			}
975 			if (fw_upload.current_length >= fw_upload.fw_length) {
976 				LOG_DBG("FW download done");
977 				return 0;
978 			}
979 			LOG_ERR("FW download failed");
980 			return len_to_send;
981 		} else if (fw_upload.version == VER3) {
982 			if (fw_upload.hdr_sig == V3_START_INDICATION) {
983 				fw_upload_wait_req(false);
984 				continue;
985 			}
986 			err = fw_upload_wait_req(false);
987 			if (err) {
988 				LOG_ERR("Fail to wait req");
989 				return err;
990 			}
991 			if (fw_upload.length) {
992 				if (fw_upload.error == 0) {
993 					fw_upload_send_ack(V3_REQUEST_ACK);
994 					err = fw_upload_v3_send_data();
995 					if (err < 0) {
996 						LOG_ERR("FW download failed");
997 						return err;
998 					}
999 				} else {
1000 					LOG_DBG("Error occurs %d", fw_upload.error);
1001 					fw_upload_send_ack(V3_TIMEOUT_ACK);
1002 					if (fw_upload.error & BT_MIC_FAIL_BIT) {
1003 						fw_upload.change_speed_buffer_len = 0;
1004 						fw_upload.current_length = 0;
1005 						fw_upload.last_offset = 0;
1006 					}
1007 				}
1008 			} else {
1009 				if (fw_upload.error == 0) {
1010 					fw_upload_send_ack(V3_REQUEST_ACK);
1011 					LOG_DBG("FW download done");
1012 					return 0;
1013 				}
1014 				LOG_DBG("Error occurs %d", fw_upload.error);
1015 				fw_upload_send_ack(V3_TIMEOUT_ACK);
1016 				if (fw_upload.error & BT_MIC_FAIL_BIT) {
1017 					fw_upload.change_speed_buffer_len = 0;
1018 					fw_upload.current_length = 0;
1019 					fw_upload.last_offset = 0;
1020 				}
1021 			}
1022 		} else {
1023 			return -ENOTSUP;
1024 		}
1025 	}
1026 	return -EINVAL;
1027 }
1028 
bt_nxp_ctlr_uart_isr(const struct device * unused,void * user_data)1029 static void bt_nxp_ctlr_uart_isr(const struct device *unused, void *user_data)
1030 {
1031 	int err = 0;
1032 	int count = 0;
1033 
1034 	ARG_UNUSED(unused);
1035 	ARG_UNUSED(user_data);
1036 
1037 	while (uart_irq_update(uart_dev) && uart_irq_is_pending(uart_dev)) {
1038 		err = uart_poll_in(uart_dev, &fw_upload.rx.buffer[fw_upload.rx.head]);
1039 		if (err >= 0) {
1040 			fw_upload.rx.head++;
1041 			fw_upload.rx.head = fw_upload.rx.head % sizeof(fw_upload.rx.buffer);
1042 			count++;
1043 		}
1044 	}
1045 
1046 	while (count > 0) {
1047 		k_sem_give(&fw_upload.rx.sem);
1048 		count--;
1049 	}
1050 }
1051 
bt_nxp_ctlr_init(void)1052 static int bt_nxp_ctlr_init(void)
1053 {
1054 	int err;
1055 	uint32_t speed;
1056 	bool flowcontrol_of_hci;
1057 
1058 	if (!device_is_ready(uart_dev)) {
1059 		return -ENODEV;
1060 	}
1061 
1062 	speed = DT_PROP(DT_INST_GPARENT(0), current_speed);
1063 	uart_dev_data.primary_speed = DT_PROP_OR(DT_DRV_INST(0), fw_download_primary_speed, speed);
1064 	uart_dev_data.secondary_speed =
1065 		DT_PROP_OR(DT_DRV_INST(0), fw_download_secondary_speed, speed);
1066 
1067 	flowcontrol_of_hci = (bool)DT_PROP_OR(DT_DRV_INST(0), hw_flow_control, false);
1068 	uart_dev_data.primary_flowcontrol =
1069 		(bool)DT_PROP_OR(DT_DRV_INST(0), fw_download_primary_flowcontrol, false);
1070 	uart_dev_data.secondary_flowcontrol =
1071 		(bool)DT_PROP_OR(DT_DRV_INST(0), fw_download_secondary_flowcontrol, false);
1072 
1073 #if DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios) ||                                          \
1074 	DT_NODE_HAS_PROP(DT_DRV_INST(0), w_disable_gpios)
1075 #if DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios)
1076 	/* Check BT REG_ON gpio instance */
1077 	if (!gpio_is_ready_dt(&sdio_reset)) {
1078 		LOG_ERR("Error: failed to configure sdio_reset %s pin %d", sdio_reset.port->name,
1079 			sdio_reset.pin);
1080 		return -EIO;
1081 	}
1082 
1083 	/* Configure sdio_reset as output  */
1084 	err = gpio_pin_configure_dt(&sdio_reset, GPIO_OUTPUT);
1085 	if (err) {
1086 		LOG_ERR("Error %d: failed to configure sdio_reset %s pin %d", err,
1087 			sdio_reset.port->name, sdio_reset.pin);
1088 		return err;
1089 	}
1090 	err = gpio_pin_set_dt(&sdio_reset, 0);
1091 	if (err) {
1092 		return err;
1093 	}
1094 #endif /* DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios) */
1095 
1096 #if DT_NODE_HAS_PROP(DT_DRV_INST(0), w_disable_gpios)
1097 	/* Check BT REG_ON gpio instance */
1098 	if (!gpio_is_ready_dt(&w_disable)) {
1099 		LOG_ERR("Error: failed to configure w_disable %s pin %d", w_disable.port->name,
1100 			w_disable.pin);
1101 		return -EIO;
1102 	}
1103 
1104 	/* Configure w_disable as output  */
1105 	err = gpio_pin_configure_dt(&w_disable, GPIO_OUTPUT);
1106 	if (err) {
1107 		LOG_ERR("Error %d: failed to configure w_disable %s pin %d", err,
1108 			w_disable.port->name, w_disable.pin);
1109 		return err;
1110 	}
1111 	err = gpio_pin_set_dt(&w_disable, 0);
1112 	if (err) {
1113 		return err;
1114 	}
1115 #endif /* DT_NODE_HAS_PROP(DT_DRV_INST(0), w_disable_gpios) */
1116 
1117 	/* wait for reset done */
1118 	k_sleep(K_MSEC(100));
1119 
1120 #if DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios)
1121 	err = gpio_pin_set_dt(&sdio_reset, 1);
1122 	if (err) {
1123 		return err;
1124 	}
1125 #endif /* DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios) */
1126 
1127 #if DT_NODE_HAS_PROP(DT_DRV_INST(0), w_disable_gpios)
1128 	err = gpio_pin_set_dt(&w_disable, 1);
1129 	if (err) {
1130 		return err;
1131 	}
1132 #endif /* DT_NODE_HAS_PROP(DT_DRV_INST(0), w_disable_gpios) */
1133 #endif
1134 
1135 	uart_irq_rx_disable(uart_dev);
1136 	uart_irq_tx_disable(uart_dev);
1137 
1138 	fw_upload.rx.head = 0;
1139 	fw_upload.rx.tail = 0;
1140 
1141 	k_sem_init(&fw_upload.rx.sem, 0, sizeof(fw_upload.rx.buffer));
1142 
1143 	uart_irq_callback_set(uart_dev, bt_nxp_ctlr_uart_isr);
1144 
1145 	made_table = false;
1146 
1147 	err = fw_upload_uart_reconfig(uart_dev_data.primary_speed,
1148 				      uart_dev_data.primary_flowcontrol);
1149 	if (err) {
1150 		LOG_ERR("Fail to config uart");
1151 		return err;
1152 	}
1153 
1154 	uart_irq_rx_enable(uart_dev);
1155 
1156 	err = fw_uploading(bt_fw_bin, bt_fw_bin_len);
1157 
1158 	if (err) {
1159 		LOG_ERR("Fail to upload firmware");
1160 		return err;
1161 	}
1162 
1163 	(void)fw_upload_uart_reconfig(speed, flowcontrol_of_hci);
1164 
1165 	uart_irq_rx_disable(uart_dev);
1166 	uart_irq_tx_disable(uart_dev);
1167 
1168 	k_sleep(K_MSEC(CONFIG_BT_H4_NXP_CTLR_WAIT_TIME_AFTER_UPLOAD));
1169 
1170 	return 0;
1171 }
1172 
bt_hci_transport_setup(const struct device * dev)1173 int bt_hci_transport_setup(const struct device *dev)
1174 {
1175 	int ret = 0;
1176 	if (dev != uart_dev) {
1177 		return -EINVAL;
1178 	}
1179 
1180 	if (!fw_upload.is_setup_done) {
1181 		ret = bt_nxp_ctlr_init();
1182 	}
1183 	return ret;
1184 }
1185 
1186 #define BT_HCI_VSC_BAUDRATE_UPDATE_LENGTH 4
1187 #define BT_HCI_VSC_BAUDRATE_UPDATE_OPCODE BT_OP(BT_OGF_VS, 0x09)
1188 
bt_hci_baudrate_update(const struct device * dev,uint32_t baudrate)1189 static int bt_hci_baudrate_update(const struct device *dev, uint32_t baudrate)
1190 {
1191 	int err;
1192 	struct net_buf *buf;
1193 
1194 	buf = bt_hci_cmd_create(BT_HCI_VSC_BAUDRATE_UPDATE_OPCODE,
1195 				BT_HCI_VSC_BAUDRATE_UPDATE_LENGTH);
1196 	if (!buf) {
1197 		LOG_ERR("Fail to allocate buffer");
1198 		return -ENOBUFS;
1199 	}
1200 
1201 	/* Add new baudrate to the buffer */
1202 	net_buf_add_le32(buf, baudrate);
1203 
1204 	err = bt_hci_cmd_send_sync(BT_HCI_VSC_BAUDRATE_UPDATE_OPCODE, buf, NULL);
1205 	if (err) {
1206 		LOG_ERR("Fail to send baudrate update cmd");
1207 		return err;
1208 	}
1209 
1210 	return 0;
1211 }
1212 
bt_h4_vnd_setup(const struct device * dev)1213 int bt_h4_vnd_setup(const struct device *dev)
1214 {
1215 	int err;
1216 	uint32_t default_speed;
1217 	uint32_t operation_speed;
1218 	bool flowcontrol_of_hci;
1219 
1220 	if (dev != uart_dev) {
1221 		return -EINVAL;
1222 	}
1223 
1224 	if (!device_is_ready(uart_dev)) {
1225 		return -ENODEV;
1226 	}
1227 
1228 	default_speed = DT_PROP(DT_INST_GPARENT(0), current_speed);
1229 	operation_speed = DT_PROP_OR(DT_DRV_INST(0), hci_operation_speed, default_speed);
1230 	flowcontrol_of_hci = (bool)DT_PROP_OR(DT_DRV_INST(0), hw_flow_control, false);
1231 
1232 	if (operation_speed == default_speed) {
1233 		return 0;
1234 	}
1235 
1236 	if (!fw_upload.is_setup_done) {
1237 		err = bt_hci_baudrate_update(dev, operation_speed);
1238 		if (err) {
1239 			return err;
1240 		}
1241 
1242 		/* BT waiting time after controller bandrate updated */
1243 		(void)k_msleep(CONFIG_BT_H4_NXP_CTLR_WAIT_TIME_AFTER_BAUDRATE_UPDATE);
1244 	}
1245 
1246 	err = fw_upload_uart_reconfig(operation_speed, flowcontrol_of_hci);
1247 	if (err) {
1248 		LOG_ERR("Fail to update uart bandrate");
1249 		return err;
1250 	}
1251 
1252 	fw_upload.is_setup_done = true;
1253 
1254 	return 0;
1255 }
1256