1 /*
2 * Copyright (C) 2018 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holders nor the names of
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * 4. Any redistribution, use, or modification is done solely for
17 * personal benefit and not for any commercial purpose or for
18 * monetary gain.
19 *
20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Please inquire about commercial licensing options at
34 * [email protected]
35 *
36 */
37
38 #define BTSTACK_FILE__ "btstack_chipset_intel_firmware.c"
39
40 #include <fcntl.h>
41 #include <stdio.h>
42 #include <inttypes.h>
43
44 #include "btstack_chipset_intel_firmware.h"
45
46 #include "bluetooth.h"
47 #include "btstack_debug.h"
48 #include "btstack_event.h"
49 #include "btstack_run_loop.h"
50 #include "btstack_util.h"
51 #include "hci.h"
52 #include "hci_cmd.h"
53 #include "hci_dump.h"
54
55 #ifdef _MSC_VER
56 // ignore deprecated warning for fopen
57 #pragma warning(disable : 4996)
58 #endif
59
60 // assert outgoing and incoming hci packet buffers can hold max hci command resp. event packet
61 #if HCI_OUTGOING_PACKET_BUFFER_SIZE < (HCI_CMD_HEADER_SIZE + 255)
62 #error "HCI_OUTGOING_PACKET_BUFFER_SIZE to small. Outgoing HCI packet buffer to small for largest HCI Command packet. Please set HCI_ACL_PAYLOAD_SIZE to 258 or higher."
63 #endif
64 #if HCI_INCOMING_PACKET_BUFFER_SIZE < (HCI_EVENT_HEADER_SIZE_HEADER_SIZE + 255)
65 #error "HCI_INCOMING_PACKET_BUFFER_SIZE to small. Incoming HCI packet buffer to small for largest HCI Event packet. Please set HCI_ACL_PAYLOAD_SIZE to 257 or higher."
66 #endif
67
68 // Vendor specific structs
69
70 typedef struct {
71 uint8_t status;
72 uint8_t hw_platform;
73 uint8_t hw_variant;
74 uint8_t hw_revision;
75 uint8_t fw_variant;
76 uint8_t fw_revision;
77 uint8_t fw_build_num;
78 uint8_t fw_build_ww;
79 uint8_t fw_build_yy;
80 uint8_t fw_patch_num;
81 } intel_version_t;
82
83 typedef struct {
84 uint8_t status;
85 uint8_t otp_format;
86 uint8_t otp_content;
87 uint8_t otp_patch;
88 uint16_t dev_revid;
89 uint8_t secure_boot;
90 uint8_t key_from_hdr;
91 uint8_t key_type;
92 uint8_t otp_lock;
93 uint8_t api_lock;
94 uint8_t debug_lock;
95 bd_addr_t otp_bdaddr;
96 uint8_t min_fw_build_nn;
97 uint8_t min_fw_build_cw;
98 uint8_t min_fw_build_yy;
99 uint8_t limited_cce;
100 uint8_t unlocked_state;
101 } intel_boot_params_t;
102
103 typedef enum {
104 INTEL_CONTROLLER_LEGACY,
105 INTEL_CONTROLLER_TLV,
106 } intel_controller_mode_t;
107
108 typedef enum {
109 STATE_INITIAL = 0,
110 STATE_HANDLE_HCI_RESET = 1,
111 STATE_HANDLE_READ_VERSION_1 = 2,
112 STATE_HANDLE_READ_SECURE_BOOT_PARAMS = 3,
113 STATE_SEND_PUBLIC_KEY_1 = 4,
114 STATE_SEND_PUBLIC_KEY_2 = 5,
115 STATE_SEND_SIGNATURE_PART_1 = 6,
116 STATE_SEND_SIGNATURE_PART_2 = 7,
117 STATE_SEND_FIRMWARE_CHUNK = 8,
118 STATE_HANDLE_FIRMWARE_CHUNKS_SENT = 9,
119 STATE_HANDLE_VENDOR_SPECIFIC_EVENT_02 = 10,
120 STATE_HANDLE_READ_VERSION_2 = 11,
121 STATE_SEND_DDC = 12,
122 STATE_DONE = 15
123 } state_t;
124
125 // Vendor specific commands
126
127 static const hci_cmd_t hci_intel_read_version = {
128 0xfc05, "1"
129 };
130 static const hci_cmd_t hci_intel_read_secure_boot_params = {
131 0xfc0d, ""
132 };
133
134 static const hci_cmd_t hci_intel_reset_param = {
135 0xfc01, "11111111"
136 };
137
138 static const hci_cmd_t hci_intel_set_event_mask = {
139 0xfc52, "11111111"
140 };
141
142 // state
143
144 const char * firmware_folder_path = ".";
145
146 static intel_version_t intel_version;
147 static intel_boot_params_t intel_boot_params;
148
149 static intel_controller_mode_t controller_mode;
150
151 const hci_transport_t * transport;
152
153 static state_t state;
154
155 static int vendor_firmware_complete_received;
156 static int waiting_for_command_complete;
157
158 static uint8_t hci_outgoing[300];
159 static uint8_t fw_buffer[300];
160
161 static FILE * fw_file;
162 static size_t fw_offset;
163
164 static void (*done)(int result);
165
166 // protogtypes
167
168 static void state_machine(uint8_t *packet, uint16_t size);
169
170 // functions
171
intel_get_dev_revid(intel_boot_params_t * boot_params)172 static uint16_t intel_get_dev_revid(intel_boot_params_t * boot_params){
173 return little_endian_read_16((uint8_t*)&intel_boot_params.dev_revid, 0);
174 }
175
dump_intel_version(intel_version_t * version)176 static void dump_intel_version(intel_version_t * version){
177 log_info("status 0x%02x", version->status);
178 log_info("hw_platform 0x%02x", version->hw_platform);
179 log_info("hw_variant 0x%02x", version->hw_variant);
180 log_info("hw_revision 0x%02x", version->hw_revision);
181 log_info("fw_variant 0x%02x", version->fw_variant);
182 log_info("fw_revision 0x%02x", version->fw_revision);
183 log_info("fw_build_num 0x%02x", version->fw_build_num);
184 log_info("fw_build_ww 0x%02x", version->fw_build_ww);
185 log_info("fw_build_yy 0x%02x", version->fw_build_yy);
186 log_info("fw_patch_num 0x%02x", version->fw_patch_num);
187 }
188
dump_intel_boot_params(intel_boot_params_t * boot_params)189 static void dump_intel_boot_params(intel_boot_params_t * boot_params){
190 bd_addr_t addr;
191 reverse_bd_addr(boot_params->otp_bdaddr, addr);
192 log_info("Device revision: %u", intel_get_dev_revid(boot_params));
193 log_info("Secure Boot: %s", boot_params->secure_boot ? "enabled" : "disabled");
194 log_info("OTP lock: %s", boot_params->otp_lock ? "enabled" : "disabled");
195 log_info("API lock: %s", boot_params->api_lock ? "enabled" : "disabled");
196 log_info("Debug lock: %s", boot_params->debug_lock ? "enabled" : "disabled");
197 log_info("Minimum firmware build %u week %u %u", boot_params->min_fw_build_nn, boot_params->min_fw_build_cw, 2000 + boot_params->min_fw_build_yy);
198 log_info("OTC BD_ADDR: %s", bd_addr_to_str(addr));
199 }
200
intel_get_firmware_name(intel_version_t * version,intel_boot_params_t * boot_params,const char * folder_path,const char * suffix,char * firmware_path,size_t firmware_path_len)201 static int intel_get_firmware_name(intel_version_t *version, intel_boot_params_t *boot_params, const char *folder_path,
202 const char *suffix, char *firmware_path, size_t firmware_path_len) {
203 switch (version->hw_variant)
204 {
205 case 0x0b: /* SfP */
206 case 0x0c: /* WsP */
207 snprintf(firmware_path, firmware_path_len, "%s/ibt-%u-%u.%s",
208 folder_path,
209 version->hw_variant,
210 intel_get_dev_revid(boot_params),
211 suffix);
212 break;
213 case 0x11: /* JfP */
214 case 0x12: /* ThP */
215 case 0x13: /* HrP */
216 case 0x14: /* CcP */
217 snprintf(firmware_path, firmware_path_len, "%s/ibt-%u-%u-%u.%s",
218 folder_path,
219 version->hw_variant,
220 version->hw_revision,
221 version->fw_revision,
222 suffix);
223 break;
224 default:
225 printf("Unsupported Intel hardware variant (%u)\n", version->hw_variant);
226 break;
227 }
228
229 return 0;
230 }
231
transport_send_packet(uint8_t packet_type,const uint8_t * packet,uint16_t size)232 static int transport_send_packet(uint8_t packet_type, const uint8_t * packet, uint16_t size){
233 hci_dump_packet(HCI_COMMAND_DATA_PACKET, 0, (uint8_t*) packet, size);
234 return transport->send_packet(packet_type, (uint8_t *) packet, size);
235 }
236
transport_send_cmd_va_arg(const hci_cmd_t * cmd,va_list argptr)237 static int transport_send_cmd_va_arg(const hci_cmd_t *cmd, va_list argptr){
238 uint8_t * packet = hci_outgoing;
239 uint16_t size = hci_cmd_create_from_template(packet, cmd, argptr);
240 return transport_send_packet(HCI_COMMAND_DATA_PACKET, packet, size);
241 }
242
transport_send_cmd(const hci_cmd_t * cmd,...)243 static int transport_send_cmd(const hci_cmd_t *cmd, ...){
244 va_list argptr;
245 va_start(argptr, cmd);
246 int res = transport_send_cmd_va_arg(cmd, argptr);
247 va_end(argptr);
248 return res;
249 }
250
transport_send_intel_secure(uint8_t fragment_type,const uint8_t * data,uint8_t len)251 static int transport_send_intel_secure(uint8_t fragment_type, const uint8_t * data, uint8_t len){
252 little_endian_store_16(hci_outgoing, 0, 0xfc09);
253 hci_outgoing[2] = 1 + len;
254 hci_outgoing[3] = fragment_type;
255 memcpy(&hci_outgoing[4], data, len);
256 uint16_t size = 3 + 1 + len;
257 return transport_send_packet(HCI_ACL_DATA_PACKET, hci_outgoing, size);
258 }
259
transport_send_intel_ddc(const uint8_t * data,uint8_t len)260 static int transport_send_intel_ddc(const uint8_t * data, uint8_t len){
261 little_endian_store_16(hci_outgoing, 0, 0xfc8b);
262 hci_outgoing[2] = len;
263 memcpy(&hci_outgoing[3], data, len);
264 uint16_t size = 3 + len;
265 return transport_send_packet(HCI_COMMAND_DATA_PACKET, hci_outgoing, size);
266 }
267
268 // read data from fw file and send it via intel_secure + update state
intel_send_fragment(uint8_t fragment_type,uint8_t len)269 static int intel_send_fragment(uint8_t fragment_type, uint8_t len){
270 size_t res = fread(fw_buffer, 1, len, fw_file);
271 log_info("offset %6" PRId32 ", read %3u -> res %" PRId32 "", (int32_t)fw_offset, len, (int32_t)res);
272 fw_offset += res;
273 return transport_send_intel_secure(fragment_type, fw_buffer, len);
274 }
275
276 // read data from ddc file and send iva intel ddc command
277 // @returns -1 on eof
intel_send_ddc(void)278 static int intel_send_ddc(void){
279 size_t res;
280 // read len
281 res = fread(fw_buffer, 1, 1, fw_file);
282 log_info("offset %6" PRId32 ", read 1 -> res %" PRId32 "", (int32_t)fw_offset, (int32_t)res);
283 if (res == 0) return -1;
284 uint8_t len = fw_buffer[0];
285 fw_offset += 1;
286 res = fread(&fw_buffer[1], 1, len, fw_file);
287 log_info("offset %6" PRId32 ", read %u -> res %" PRId32 "", (int32_t)fw_offset, 1, (int32_t)res);
288 return transport_send_intel_ddc(fw_buffer, 1 + len);
289 }
290
state_machine(uint8_t * packet,uint16_t size)291 static void state_machine(uint8_t *packet, uint16_t size) {
292 size_t res;
293 size_t buffer_offset;
294 bd_addr_t addr;
295 char fw_path[300];
296
297 if (packet){
298 // firmware upload complete event?
299 if (packet[0] == 0xff && packet[2] == 0x06) {
300 vendor_firmware_complete_received = 1;
301 }
302
303 // command complete
304 if (packet[0] == 0x0e){
305 waiting_for_command_complete = 0;
306 }
307 }
308
309 switch (state){
310 case STATE_INITIAL:
311 controller_mode = INTEL_CONTROLLER_LEGACY;
312 state = STATE_HANDLE_HCI_RESET;
313 transport_send_cmd(&hci_reset);
314 break;
315 case STATE_HANDLE_HCI_RESET:
316 // check if HCI Reset was supported
317 if (packet[0] == 0x0e && packet[1] == 0x04 && packet[3] == 0x03 && packet[4] == 0x0c && packet[5] == 0x00){
318 log_info("HCI Reset was successful, no need for firmware upload / or not an Intel chipset");
319 (*done)(0);
320 break;
321 }
322
323 // Read Intel Version
324 state = STATE_HANDLE_READ_VERSION_1;
325 transport_send_cmd(&hci_intel_read_version, 0xff);
326 break;
327 case STATE_HANDLE_READ_VERSION_1:
328 // detect legacy vs. new TLV mode based on Read Version response
329 if ((size == sizeof(intel_version_t)) || (packet[1] != 0x037)){
330 controller_mode = INTEL_CONTROLLER_TLV;
331 printf("\nERROR: Intel Controller uses new TLV mode. TLV mode is not supported yet\n");
332 printf("Details: https://github.com/torvalds/linux/blob/master/drivers/bluetooth/btintel.c\n\n");
333 log_error("TLV mode not supported");
334 (*done)(1);
335 break;
336 }
337
338 // legacy mode
339 intel_version = *(intel_version_t*) hci_event_command_complete_get_return_parameters(packet);
340 dump_intel_version(&intel_version);
341
342 // fw_variant = 0x06 bootloader mode / 0x23 operational mode
343 if (intel_version.fw_variant == 0x23) {
344 (*done)(0);
345 break;
346 }
347
348 if (intel_version.fw_variant != 0x06){
349 log_error("unknown fw_variant 0x%02x", intel_version.fw_variant);
350 break;
351 }
352
353 // Read Intel Secure Boot Params
354 state = STATE_HANDLE_READ_SECURE_BOOT_PARAMS;
355 transport_send_cmd(&hci_intel_read_secure_boot_params);
356 break;
357 case STATE_HANDLE_READ_SECURE_BOOT_PARAMS:
358 intel_boot_params = *(intel_boot_params_t *) hci_event_command_complete_get_return_parameters(packet);
359 dump_intel_boot_params(&intel_boot_params);
360
361 reverse_bd_addr(intel_boot_params.otp_bdaddr, addr);
362
363 // assert command complete is required
364 if (intel_boot_params.limited_cce != 0) break;
365
366 // firmware file
367 intel_get_firmware_name(&intel_version, &intel_boot_params, firmware_folder_path,
368 "sfi", fw_path, sizeof(fw_path));
369 log_info("Open firmware %s", fw_path);
370 printf("Firmware %s\n", fw_path);
371
372 // open firmware file
373 fw_offset = 0;
374 fw_file = fopen(fw_path, "rb");
375 if (!fw_file){
376 log_error("can't open file %s", fw_path);
377 (*done)(1);
378 return;
379 }
380
381 vendor_firmware_complete_received = 0;
382
383 // send CCS segment - offset 0
384 state = STATE_SEND_PUBLIC_KEY_1;
385 intel_send_fragment(0x00, 128);
386 break;
387 case STATE_SEND_PUBLIC_KEY_1:
388 // send public key / part 1 - offset 128
389 state = STATE_SEND_PUBLIC_KEY_2;
390 intel_send_fragment(0x03, 128);
391 break;
392 case STATE_SEND_PUBLIC_KEY_2:
393 // send public key / part 2 - offset 384
394 state = STATE_SEND_SIGNATURE_PART_1;
395 intel_send_fragment(0x03, 128);
396 break;
397 case STATE_SEND_SIGNATURE_PART_1:
398 // skip 4 bytes
399 res = fread(fw_buffer, 1, 4, fw_file);
400 log_info("read res %d", (int)res);
401 fw_offset += res;
402
403 // send signature / part 1 - offset 388
404 state = STATE_SEND_SIGNATURE_PART_2;
405 intel_send_fragment(0x02, 128);
406 break;
407 case STATE_SEND_SIGNATURE_PART_2:
408 // send signature / part 2 - offset 516
409 state = STATE_SEND_FIRMWARE_CHUNK;
410 intel_send_fragment(0x02, 128);
411 break;
412 case STATE_SEND_FIRMWARE_CHUNK:
413 // send firmware chunks - offset 644
414 // chunk len must be 4 byte aligned
415 // multiple commands can be combined
416 buffer_offset = 0;
417 do {
418 res = fread(&fw_buffer[buffer_offset], 1, 3, fw_file);
419 log_info("fw_offset %6" PRId32 ", buffer_offset %" PRId32 ", read %3u -> res %" PRId32 "", (int32_t)fw_offset, (int32_t)buffer_offset, 3, (int32_t)res);
420 fw_offset += res;
421 if (res == 0 ){
422 // EOF
423 log_info("End of file");
424 fclose(fw_file);
425 fw_file = NULL;
426 state = STATE_HANDLE_FIRMWARE_CHUNKS_SENT;
427 break;
428 }
429 int param_len = fw_buffer[buffer_offset + 2];
430 buffer_offset += 3;
431 if (param_len){
432 res = fread(&fw_buffer[buffer_offset], 1, param_len, fw_file);
433 fw_offset += res;
434 buffer_offset += res;
435 }
436 } while ((buffer_offset & 3) != 0);
437
438 if (buffer_offset == 0) break;
439
440 waiting_for_command_complete = 1;
441 transport_send_intel_secure(0x01, fw_buffer, (uint8_t) buffer_offset);
442 break;
443
444 case STATE_HANDLE_FIRMWARE_CHUNKS_SENT:
445 // expect Vendor Specific Event 0x06
446 if (!vendor_firmware_complete_received) break;
447
448 printf("Firmware upload complete\n");
449 log_info("Vendor Event 0x06 - firmware complete");
450
451 // Reset Params - constants from Windows Intel driver
452 state = STATE_HANDLE_VENDOR_SPECIFIC_EVENT_02;
453 transport_send_cmd(&hci_intel_reset_param, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x04, 0x00);
454 break;
455
456 case STATE_HANDLE_VENDOR_SPECIFIC_EVENT_02:
457 // expect Vendor Specific Event 0x02
458 if (packet[0] != 0xff) break;
459 if (packet[2] != 0x02) break;
460
461 printf("Firmware operational\n");
462 log_info("Vendor Event 0x02 - firmware operational");
463
464 // Read Intel Version
465 state = STATE_HANDLE_READ_VERSION_2;
466 transport_send_cmd(&hci_intel_read_version);
467 break;
468
469 case STATE_HANDLE_READ_VERSION_2:
470 intel_version = *(intel_version_t*) hci_event_command_complete_get_return_parameters(packet);
471 dump_intel_version(&intel_version);
472
473 // ddc config
474 intel_get_firmware_name(&intel_version, &intel_boot_params, firmware_folder_path,
475 "ddc", fw_path, sizeof(fw_path));
476 log_info("Open DDC %s", fw_path);
477
478 // open ddc file
479 fw_offset = 0;
480 fw_file = fopen(fw_path, "rb");
481 if (!fw_file){
482 log_error("can't open file %s", fw_path);
483
484 (*done)(1);
485 return;
486 }
487
488 // load ddc
489 state = STATE_SEND_DDC;
490
491 /* fall through */
492
493 case STATE_SEND_DDC:
494 res = intel_send_ddc();
495 if (res == 0) break;
496
497 // DDC download complete
498 log_info("Load DDC Complete");
499
500 // TODO: check if we need to wait for HCI Command Complete, resp. add another state here
501
502 // Set Intel event mask 0xfc52
503 state = STATE_DONE;
504 transport_send_cmd(&hci_intel_set_event_mask, 0x87, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
505 break;
506
507 case STATE_DONE:
508 (*done)(0);
509 break;
510
511 default:
512 break;
513 }
514 }
515
transport_packet_handler(uint8_t packet_type,uint8_t * packet,uint16_t size)516 static void transport_packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){
517 UNUSED(packet_type);
518 // we also get events with packet_type ACL from the controller
519 hci_dump_packet(HCI_EVENT_PACKET, 1, packet, size);
520 switch (hci_event_packet_get_type(packet)){
521 case HCI_EVENT_COMMAND_COMPLETE:
522 case HCI_EVENT_VENDOR_SPECIFIC:
523 state_machine(packet, size);
524 break;
525 default:
526 break;
527 }
528 }
529
btstack_chipset_intel_set_firmware_path(const char * path)530 void btstack_chipset_intel_set_firmware_path(const char * path){
531 firmware_folder_path = path;
532 }
533
btstack_chipset_intel_download_firmware(const hci_transport_t * hci_transport,void (* callback)(int result))534 void btstack_chipset_intel_download_firmware(const hci_transport_t * hci_transport, void (*callback)(int result)){
535
536 done = callback;
537
538 transport = hci_transport;;
539 transport->register_packet_handler(&transport_packet_handler);
540 transport->open();
541
542 // get started
543 state = STATE_INITIAL;
544 state_machine(NULL, 0);
545 }
546