xref: /btstack/chipset/intel/btstack_chipset_intel_firmware.c (revision f4b0d900598300cdbb7abb5bd00c3cc75d4a1d3e)
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 // Vendor specific commands
109 
110 static const hci_cmd_t hci_intel_read_version = {
111     0xfc05, "1"
112 };
113 static const hci_cmd_t hci_intel_read_secure_boot_params = {
114     0xfc0d, ""
115 };
116 
117 static const hci_cmd_t hci_intel_reset_param = {
118     0xfc01, "11111111"
119 };
120 
121 static const hci_cmd_t hci_intel_set_event_mask = {
122     0xfc52, "11111111"
123 };
124 
125 static const hci_cmd_t hci_intel_fc9f = {
126     0xfc9f, "1"
127 };
128 
129 // state
130 
131 const char * firmware_path = ".";
132 
133 static intel_controller_mode_t controller_mode;
134 
135 const hci_transport_t * transport;
136 
137 static int state = 0;
138 
139 static uint8_t hci_outgoing[300];
140 static uint8_t fw_buffer[300];
141 
142 static uint8_t  hw_variant;
143 static uint16_t dev_revid;
144 
145 static FILE *   fw_file;
146 static size_t   fw_offset;
147 
148 static void (*done)(int result);
149 
150 // functions
151 
152 static int transport_send_packet(uint8_t packet_type, const uint8_t * packet, uint16_t size){
153     hci_dump_packet(HCI_COMMAND_DATA_PACKET, 0, (uint8_t*) packet, size);
154     return transport->send_packet(packet_type, (uint8_t *) packet, size);
155 }
156 
157 static int transport_send_cmd_va_arg(const hci_cmd_t *cmd, va_list argptr){
158     uint8_t * packet = hci_outgoing;
159     uint16_t size = hci_cmd_create_from_template(packet, cmd, argptr);
160     return transport_send_packet(HCI_COMMAND_DATA_PACKET, packet, size);
161 }
162 
163 static int transport_send_cmd(const hci_cmd_t *cmd, ...){
164     va_list argptr;
165     va_start(argptr, cmd);
166     int res = transport_send_cmd_va_arg(cmd, argptr);
167     va_end(argptr);
168     return res;
169 }
170 
171 static int transport_send_intel_secure(uint8_t fragment_type, const uint8_t * data, uint8_t len){
172     little_endian_store_16(hci_outgoing, 0, 0xfc09);
173     hci_outgoing[2] = 1 + len;
174     hci_outgoing[3] = fragment_type;
175     memcpy(&hci_outgoing[4], data, len);
176     uint16_t size = 3 +  1 + len;
177     return transport_send_packet(HCI_ACL_DATA_PACKET, hci_outgoing, size);
178 }
179 
180 static int transport_send_intel_ddc(const uint8_t * data, uint8_t len){
181     little_endian_store_16(hci_outgoing, 0, 0xfc8b);
182     hci_outgoing[2] = len;
183     memcpy(&hci_outgoing[3], data, len);
184     uint16_t size = 3 +  len;
185     return transport_send_packet(HCI_COMMAND_DATA_PACKET, hci_outgoing, size);
186 }
187 
188 static void state_machine(uint8_t *packet, uint16_t size);
189 
190 // read data from fw file and send it via intel_secure + update state
191 static int intel_send_fragment(uint8_t fragment_type, uint8_t len){
192     size_t res = fread(fw_buffer, 1, len, fw_file);
193     log_info("offset %6" PRId32 ", read %3u -> res %" PRId32 "", (int32_t)fw_offset, len, (int32_t)res);
194     fw_offset += res;
195     state++;
196     return transport_send_intel_secure(fragment_type, fw_buffer, len);
197 }
198 
199 // read data from  ddc file and send iva intel ddc command
200 // @returns -1 on eof
201 static int intel_send_ddc(void){
202     size_t res;
203     // read len
204     res = fread(fw_buffer, 1, 1, fw_file);
205     log_info("offset %6" PRId32 ", read 1 -> res %" PRId32 "", (int32_t)fw_offset, (int32_t)res);
206     if (res == 0) return -1;
207     uint8_t len = fw_buffer[0];
208     fw_offset += 1;
209     res = fread(&fw_buffer[1], 1, len, fw_file);
210     log_info("offset %6" PRId32 ", read %u -> res %" PRId32 "", (int32_t)fw_offset, 1, (int32_t)res);
211     return transport_send_intel_ddc(fw_buffer, 1 + len);
212 }
213 
214 static void dump_intel_version(intel_version_t     * version){
215     log_info("status       0x%02x", version->status);
216     log_info("hw_platform  0x%02x", version->hw_platform);
217     log_info("hw_variant   0x%02x", version->hw_variant);
218     log_info("hw_revision  0x%02x", version->hw_revision);
219     log_info("fw_variant   0x%02x", version->fw_variant);
220     log_info("fw_revision  0x%02x", version->fw_revision);
221     log_info("fw_build_num 0x%02x", version->fw_build_num);
222     log_info("fw_build_ww  0x%02x", version->fw_build_ww);
223     log_info("fw_build_yy  0x%02x", version->fw_build_yy);
224     log_info("fw_patch_num 0x%02x", version->fw_patch_num);
225 }
226 
227 static void dump_intel_boot_params(intel_boot_params_t * boot_params){
228     bd_addr_t addr;
229     reverse_bd_addr(boot_params->otp_bdaddr, addr);
230     log_info("Device revision: %u", dev_revid);
231     log_info("Secure Boot:  %s", boot_params->secure_boot ? "enabled" : "disabled");
232     log_info("OTP lock:     %s", boot_params->otp_lock    ? "enabled" : "disabled");
233     log_info("API lock:     %s", boot_params->api_lock    ? "enabled" : "disabled");
234     log_info("Debug lock:   %s", boot_params->debug_lock  ? "enabled" : "disabled");
235     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);
236     log_info("OTC BD_ADDR:  %s", bd_addr_to_str(addr));
237 }
238 
239 static int vendor_firmware_complete_received;
240 static int waiting_for_command_complete;
241 
242 static void state_machine(uint8_t *packet, uint16_t size) {
243     intel_version_t     * version;
244     intel_boot_params_t * boot_params;
245     size_t res;
246     size_t buffer_offset;
247     bd_addr_t addr;
248     char    fw_path[300];
249 
250     if (packet){
251         // firmware upload complete event?
252         if (packet[0] == 0xff && packet[2] == 0x06) {
253             vendor_firmware_complete_received = 1;
254         }
255 
256         // command complete
257         if (packet[0] == 0x0e){
258             waiting_for_command_complete = 0;
259         }
260     }
261 
262     switch (state){
263         case 0:
264             controller_mode = INTEL_CONTROLLER_LEGACY;
265             state++;
266             transport_send_cmd(&hci_reset);
267             break;
268         case 1:
269             // check if HCI Reset was supported
270             if (packet[0] == 0x0e && packet[1] == 0x04 && packet[3] == 0x03 && packet[4] == 0x0c && packet[5] == 0x00){
271                 log_info("HCI Reset was successful, no need for firmware upload / or not an Intel chipset");
272                 (*done)(0);
273                 break;
274             }
275 
276             // Read Intel Version
277             state++;
278             transport_send_cmd(&hci_intel_read_version, 0xff);
279             break;
280         case 2:
281             // detect legacy vs. new TLV mode
282             if ((size == sizeof(intel_version_t)) || (packet[1] != 0x037)){
283                 controller_mode = INTEL_CONTROLLER_TLV;
284                 printf("\nERROR: Intel Controller uses new TLV mode. TLV mode is not supported yet\n");
285                 printf("Details: https://github.com/torvalds/linux/blob/master/drivers/bluetooth/btintel.c\n\n");
286                 log_error("TLV mode not supported");
287                 (*done)(1);
288                 break;
289             }
290 
291             // legacy mode
292             version = (intel_version_t*) hci_event_command_complete_get_return_parameters(packet);
293             dump_intel_version(version);
294 
295             hw_variant = version->hw_variant;
296 
297             // fw_variant = 0x06 bootloader mode / 0x23 operational mode
298             if (version->fw_variant == 0x23) {
299                 (*done)(0);
300                 break;
301             }
302 
303             if (version->fw_variant != 0x06){
304                 log_error("unknown fw_variant 0x%02x", version->fw_variant);
305                 break;
306             }
307 
308             // Read Intel Secure Boot Params
309             state++;
310             transport_send_cmd(&hci_intel_read_secure_boot_params);
311             break;
312         case 3:
313             boot_params = (intel_boot_params_t *) hci_event_command_complete_get_return_parameters(packet);
314             dump_intel_boot_params(boot_params);
315 
316             reverse_bd_addr(boot_params->otp_bdaddr, addr);
317             dev_revid = little_endian_read_16((uint8_t*)&boot_params->dev_revid, 0);
318 
319             // assert commmand complete is required
320             if (boot_params->limited_cce != 0) break;
321 
322             // firmware file
323             snprintf(fw_path, sizeof(fw_path), "%s/ibt-%u-%u.sfi", firmware_path, hw_variant, dev_revid);
324             log_info("Open firmware %s", fw_path);
325             printf("Firwmare %s\n", fw_path);
326 
327             // open firmware file
328             fw_offset = 0;
329             fw_file = fopen(fw_path, "rb");
330             if (!fw_file){
331                 log_error("can't open file %s", fw_path);
332                 (*done)(1);
333                 return;
334             }
335 
336             vendor_firmware_complete_received = 0;
337 
338             // send CCS segment - offset 0
339             intel_send_fragment(0x00, 128);
340             break;
341         case 4:
342             // send public key / part 1 - offset 128
343             intel_send_fragment(0x03, 128);
344             break;
345         case 5:
346             // send public key / part 2 - offset 384
347             intel_send_fragment(0x03, 128);
348             break;
349         case 6:
350             // skip 4 bytes
351             res = fread(fw_buffer, 1, 4, fw_file);
352             log_info("read res %d", (int)res);
353             fw_offset += res;
354 
355             // send signature / part 1 - offset 388
356             intel_send_fragment(0x02, 128);
357             break;
358         case 7:
359             // send signature / part 2 - offset 516
360             intel_send_fragment(0x02, 128);
361             break;
362         case 8:
363             // send firmware chunks - offset 644
364             // chunk len must be 4 byte aligned
365             // multiple commands can be combined
366             buffer_offset = 0;
367             do {
368                 res = fread(&fw_buffer[buffer_offset], 1, 3, fw_file);
369                 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);
370                 fw_offset += res;
371                 if (res == 0 ){
372                     // EOF
373                     log_info("End of file");
374                     fclose(fw_file);
375                     fw_file = NULL;
376                     state++;
377                     break;
378                 }
379                 int param_len = fw_buffer[buffer_offset + 2];
380                 buffer_offset += 3;
381                 if (param_len){
382                     res = fread(&fw_buffer[buffer_offset], 1, param_len, fw_file);
383                     fw_offset     += res;
384                     buffer_offset += res;
385                 }
386             } while ((buffer_offset & 3) != 0);
387 
388             if (buffer_offset == 0) break;
389 
390             waiting_for_command_complete = 1;
391             transport_send_intel_secure(0x01, fw_buffer, (uint8_t) buffer_offset);
392             break;
393 
394         case 9:
395             // expect Vendor Specific Event 0x06
396             if (!vendor_firmware_complete_received) break;
397 
398             printf("Firmware upload complete\n");
399             log_info("Vendor Event 0x06 - firmware complete");
400 
401             // Reset Params - constants from Windows Intel driver
402             state++;
403             transport_send_cmd(&hci_intel_reset_param, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x04, 0x00);
404             break;
405 
406         case 10:
407             // expect Vendor Specific Event 0x02
408             if (packet[0] != 0xff) break;
409             if (packet[2] != 0x02) break;
410 
411             printf("Firmware operational\n");
412             log_info("Vendor Event 0x02 - firmware operational");
413 
414             // Read Intel Version
415             state++;
416             transport_send_cmd(&hci_intel_read_version);
417             break;
418 
419         case 11:
420             version = (intel_version_t*) hci_event_command_complete_get_return_parameters(packet);
421             dump_intel_version(version);
422 
423             // ddc config
424             snprintf(fw_path, sizeof(fw_path), "%s/ibt-%u-%u.ddc", firmware_path, hw_variant, dev_revid);
425             log_info("Open DDC %s", fw_path);
426 
427             // open ddc file
428             fw_offset = 0;
429             fw_file = fopen(fw_path, "rb");
430             if (!fw_file){
431                 log_error("can't open file %s", fw_path);
432 
433                 (*done)(1);
434                 return;
435             }
436 
437             // load ddc
438             state++;
439 
440             /* fall through */
441 
442         case 12:
443             res = intel_send_ddc();
444             if (res == 0) break;
445 
446             // DDC download complete
447             state++;
448             log_info("Load DDC Complete");
449 
450 
451             // Set Intel event mask 0xfc52
452             state++;
453             transport_send_cmd(&hci_intel_set_event_mask, 0x87, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
454             break;
455 
456         case 13:
457             // 9F FC 01 00
458             state++;
459             transport_send_cmd(&hci_intel_fc9f, 0x00);
460             break;
461 
462         case 14:
463             (*done)(0);
464             break;
465 
466         default:
467             break;
468     }
469 }
470 
471 static void transport_packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){
472     UNUSED(packet_type);
473     // we also get events with packet_type ACL from the controller
474     hci_dump_packet(HCI_EVENT_PACKET, 1, packet, size);
475     switch (hci_event_packet_get_type(packet)){
476         case HCI_EVENT_COMMAND_COMPLETE:
477         case HCI_EVENT_VENDOR_SPECIFIC:
478             state_machine(packet, size);
479             break;
480         default:
481             break;
482     }
483 }
484 
485 void btstack_chipset_intel_set_firmware_path(const char * path){
486     firmware_path = path;
487 }
488 
489 void btstack_chipset_intel_download_firmware(const hci_transport_t * hci_transport, void (*callback)(int result)){
490 
491     done = callback;
492 
493 	transport = hci_transport;;
494     // transport->init(NULL);
495     transport->register_packet_handler(&transport_packet_handler);
496     transport->open();
497 
498     // get started
499     state = 0;
500     state_machine(NULL, 0);
501 }
502