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