Merge "Add avtest to test rpm" into tizen
[platform/upstream/bluez.git] / monitor / intel.c
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 /*
3  *
4  *  BlueZ - Bluetooth protocol stack for Linux
5  *
6  *  Copyright (C) 2011-2014  Intel Corporation
7  *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
8  *
9  *
10  */
11
12 #ifdef HAVE_CONFIG_H
13 #include <config.h>
14 #endif
15
16 #include <stdio.h>
17 #include <inttypes.h>
18
19 #include "lib/bluetooth.h"
20 #include "lib/hci.h"
21
22 #include "src/shared/util.h"
23 #include "display.h"
24 #include "packet.h"
25 #include "lmp.h"
26 #include "ll.h"
27 #include "vendor.h"
28 #include "intel.h"
29
30 #define COLOR_UNKNOWN_EVENT_MASK        COLOR_WHITE_BG
31 #define COLOR_UNKNOWN_SCAN_STATUS       COLOR_WHITE_BG
32 #define COLOR_UNKNOWN_EXT_EVENT         COLOR_WHITE_BG
33
34 static void print_status(uint8_t status)
35 {
36         packet_print_error("Status", status);
37 }
38
39 static void print_module(uint8_t module)
40 {
41         const char *str;
42
43         switch (module) {
44         case 0x01:
45                 str = "BC";
46                 break;
47         case 0x02:
48                 str = "HCI";
49                 break;
50         case 0x03:
51                 str = "LLC";
52                 break;
53         case 0x04:
54                 str = "OS";
55                 break;
56         case 0x05:
57                 str = "LM";
58                 break;
59         case 0x06:
60                 str = "SC";
61                 break;
62         case 0x07:
63                 str = "SP";
64                 break;
65         case 0x08:
66                 str = "OSAL";
67                 break;
68         case 0x09:
69                 str = "LC";
70                 break;
71         case 0x0a:
72                 str = "APP";
73                 break;
74         case 0x0b:
75                 str = "TLD";
76                 break;
77         case 0xf0:
78                 str = "Debug";
79                 break;
80         default:
81                 str = "Reserved";
82                 break;
83         }
84
85         print_field("Module: %s (0x%2.2x)", str, module);
86 }
87
88 static void null_cmd(const void *data, uint8_t size)
89 {
90 }
91
92 static void status_rsp(const void *data, uint8_t size)
93 {
94         uint8_t status = get_u8(data);
95
96         print_status(status);
97 }
98
99 static void reset_cmd(const void *data, uint8_t size)
100 {
101         uint8_t reset_type = get_u8(data);
102         uint8_t patch_enable = get_u8(data + 1);
103         uint8_t ddc_reload = get_u8(data + 2);
104         uint8_t boot_option = get_u8(data + 3);
105         uint32_t boot_addr = get_le32(data + 4);
106         const char *str;
107
108         switch (reset_type) {
109         case 0x00:
110                 str = "Soft software reset";
111                 break;
112         case 0x01:
113                 str = "Hard software reset";
114                 break;
115         default:
116                 str = "Reserved";
117                 break;
118         }
119
120         print_field("Reset type: %s (0x%2.2x)", str, reset_type);
121
122         switch (patch_enable) {
123         case 0x00:
124                 str = "Do not enable";
125                 break;
126         case 0x01:
127                 str = "Enable";
128                 break;
129         default:
130                 str = "Reserved";
131                 break;
132         }
133
134         print_field("Patch vectors: %s (0x%2.2x)", str, patch_enable);
135
136         switch (ddc_reload) {
137         case 0x00:
138                 str = "Do not reload";
139                 break;
140         case 0x01:
141                 str = "Reload from OTP";
142                 break;
143         default:
144                 str = "Reserved";
145                 break;
146         }
147
148         print_field("DDC parameters: %s (0x%2.2x)", str, ddc_reload);
149
150         switch (boot_option) {
151         case 0x00:
152                 str = "Current image";
153                 break;
154         case 0x01:
155                 str = "Specified address";
156                 break;
157         default:
158                 str = "Reserved";
159                 break;
160         }
161
162         print_field("Boot option: %s (0x%2.2x)", str, boot_option);
163         print_field("Boot address: 0x%8.8x", boot_addr);
164 }
165
166 struct intel_version_tlv {
167         uint8_t type;
168         uint8_t len;
169         uint8_t val[];
170 };
171
172 static void print_version_tlv_u32(const struct intel_version_tlv *tlv,
173                                   char *type_str)
174 {
175         print_field("%s(%u): 0x%8.8x", type_str, tlv->type, get_le32(tlv->val));
176 }
177
178 static void print_version_tlv_u16(const struct intel_version_tlv *tlv,
179                                   char *type_str)
180 {
181         print_field("%s(%u): 0x%4.4x", type_str, tlv->type, get_le16(tlv->val));
182 }
183
184 static void print_version_tlv_u8(const struct intel_version_tlv *tlv,
185                                  char *type_str)
186 {
187         print_field("%s(%u): 0x%2.2x", type_str, tlv->type, get_u8(tlv->val));
188 }
189
190 static void print_version_tlv_enabled(const struct intel_version_tlv *tlv,
191                                       char *type_str)
192 {
193         print_field("%s(%u): %s(%u)", type_str, tlv->type,
194                                         tlv->val[0] ? "Enabled" : "Disabled",
195                                         tlv->val[0]);
196 }
197
198 static void print_version_tlv_img_type(const struct intel_version_tlv *tlv,
199                                        char *type_str)
200 {
201         const char *str;
202
203         switch (get_u8(tlv->val)) {
204         case 0x01:
205                 str = "Bootloader";
206                 break;
207         case 0x03:
208                 str = "Firmware";
209                 break;
210         default:
211                 str = "Unknown";
212                 break;
213         }
214         print_field("%s(%u): %s(0x%2.2x)", type_str, tlv->type, str,
215                                                         get_u8(tlv->val));
216 }
217
218 static void print_version_tlv_timestamp(const struct intel_version_tlv *tlv,
219                                         char *type_str)
220 {
221         print_field("%s(%u): %u-%u", type_str, tlv->type,
222                                 tlv->val[1], tlv->val[0]);
223 }
224
225 static void print_version_tlv_min_fw(const struct intel_version_tlv *tlv,
226                                      char *type_str)
227 {
228         print_field("%s(%u): %u-%u.%u", type_str, tlv->type,
229                                 tlv->val[0], tlv->val[1], 2000 + tlv->val[2]);
230 }
231
232 static void print_version_tlv_otp_bdaddr(const struct intel_version_tlv *tlv,
233                                          char *type_str)
234 {
235         packet_print_addr(type_str, tlv->val, 0x00);
236 }
237
238 static void print_version_tlv_unknown(const struct intel_version_tlv *tlv,
239                                       char *type_str)
240 {
241         print_field("%s(%u): ", type_str, tlv->type);
242         packet_hexdump(tlv->val, tlv->len);
243 }
244
245 static void print_version_tlv_mfg(const struct intel_version_tlv *tlv,
246                                          char *type_str)
247 {
248         uint16_t mfg_id = get_le16(tlv->val);
249
250         print_field("%s(%u): %s (%u)", type_str, tlv->type,
251                                                 bt_compidtostr(mfg_id), mfg_id);
252 }
253
254 static const struct intel_version_tlv_desc {
255         uint8_t type;
256         char *type_str;
257         void (*func)(const struct intel_version_tlv *tlv, char *type_str);
258 } intel_version_tlv_table[] = {
259         { 16, "CNVi TOP", print_version_tlv_u32 },
260         { 17, "CNVr TOP", print_version_tlv_u32 },
261         { 18, "CNVi BT", print_version_tlv_u32 },
262         { 19, "CNVr BT", print_version_tlv_u32 },
263         { 20, "CNVi OTP", print_version_tlv_u16 },
264         { 21, "CNVr OTP", print_version_tlv_u16 },
265         { 22, "Device Rev ID", print_version_tlv_u16 },
266         { 23, "USB VID", print_version_tlv_u16 },
267         { 24, "USB PID", print_version_tlv_u16 },
268         { 25, "PCIE VID", print_version_tlv_u16 },
269         { 26, "PCIe DID", print_version_tlv_u16 },
270         { 27, "PCIe Subsystem ID", print_version_tlv_u16 },
271         { 28, "Image Type", print_version_tlv_img_type },
272         { 29, "Time Stamp", print_version_tlv_timestamp },
273         { 30, "Build Type", print_version_tlv_u8 },
274         { 31, "Build Num", print_version_tlv_u32 },
275         { 32, "FW Build Product", print_version_tlv_u8 },
276         { 33, "FW Build HW", print_version_tlv_u8 },
277         { 34, "FW Build Step", print_version_tlv_u8 },
278         { 35, "BT Spec", print_version_tlv_u8 },
279         { 36, "Manufacturer", print_version_tlv_mfg },
280         { 37, "HCI Revision", print_version_tlv_u16 },
281         { 38, "LMP SubVersion", print_version_tlv_u16 },
282         { 39, "OTP Patch Version", print_version_tlv_u8 },
283         { 40, "Secure Boot", print_version_tlv_enabled },
284         { 41, "Key From Header", print_version_tlv_enabled },
285         { 42, "OTP Lock", print_version_tlv_enabled },
286         { 43, "API Lock", print_version_tlv_enabled },
287         { 44, "Debug Lock", print_version_tlv_enabled },
288         { 45, "Minimum FW", print_version_tlv_min_fw },
289         { 46, "Limited CCE", print_version_tlv_enabled },
290         { 47, "SBE Type", print_version_tlv_u8 },
291         { 48, "OTP BDADDR", print_version_tlv_otp_bdaddr },
292         { 49, "Unlocked State", print_version_tlv_enabled },
293         { 0, NULL, NULL },
294 };
295
296 static void read_version_tlv_rsp(const void *data, uint8_t size)
297 {
298         uint8_t status = get_u8(data);
299
300         print_status(status);
301
302         /* Consume the status */
303         data++;
304         size--;
305
306         while (size > 0) {
307                 const struct intel_version_tlv *tlv = data;
308                 const struct intel_version_tlv_desc *desc = NULL;
309                 int i;
310
311                 for (i = 0; intel_version_tlv_table[i].type > 0; i++) {
312                         if (intel_version_tlv_table[i].type == tlv->type) {
313                                 desc = &intel_version_tlv_table[i];
314                                 break;
315                         }
316                 }
317
318                 if (desc)
319                         desc->func(tlv, desc->type_str);
320                 else
321                         print_version_tlv_unknown(tlv, "Unknown Type");
322
323                 data += sizeof(*tlv) + tlv->len;
324                 size -= sizeof(*tlv) + tlv->len;
325         }
326 }
327
328 static void read_version_rsp(const void *data, uint8_t size)
329 {
330         uint8_t status = get_u8(data);
331         uint8_t hw_platform = get_u8(data + 1);
332         uint8_t hw_variant = get_u8(data + 2);
333         uint8_t hw_revision = get_u8(data + 3);
334         uint8_t fw_variant = get_u8(data + 4);
335         uint8_t fw_revision = get_u8(data + 5);
336         uint8_t fw_build_nn = get_u8(data + 6);
337         uint8_t fw_build_cw = get_u8(data + 7);
338         uint8_t fw_build_yy = get_u8(data + 8);
339         uint8_t fw_patch = get_u8(data + 9);
340
341         /* There are two different formats of the response for the
342          * HCI_Intel_Read_version command depends on the command parameters
343          * If the size is fixed to 10 and hw_platform is 0x37, then it is the
344          * legacy format, otherwise use the tlv based format.
345          */
346         if (size != 10 && hw_platform != 0x37) {
347                 read_version_tlv_rsp(data, size);
348                 return;
349         }
350
351         print_status(status);
352         print_field("Hardware platform: 0x%2.2x", hw_platform);
353         print_field("Hardware variant: 0x%2.2x", hw_variant);
354         print_field("Hardware revision: %u.%u", hw_revision >> 4,
355                                                 hw_revision & 0x0f);
356         print_field("Firmware variant: 0x%2.2x", fw_variant);
357         print_field("Firmware revision: %u.%u", fw_revision >> 4,
358                                                 fw_revision & 0x0f);
359
360         print_field("Firmware build: %u-%u.%u", fw_build_nn,
361                                         fw_build_cw, 2000 + fw_build_yy);
362         print_field("Firmware patch: %u", fw_patch);
363 }
364
365 static void read_version_cmd(const void *data, uint8_t size)
366 {
367         char *str;
368         uint8_t type;
369
370         /* This is the legacy read version command format and no further action
371          * is needed
372          */
373         if (size == 0)
374                 return;
375
376         print_field("Requested Type:");
377
378         while (size > 0) {
379                 const struct intel_version_tlv_desc *desc = NULL;
380                 int i;
381
382                 type = get_u8(data);
383
384                 /* Get all supported types */
385                 if (type == 0xff)
386                         str = "All Supported Types";
387                 else {
388                         for (i = 0; intel_version_tlv_table[i].type > 0; i++) {
389                                 if (intel_version_tlv_table[i].type == type) {
390                                         desc = &intel_version_tlv_table[i];
391                                         break;
392                                 }
393                         }
394
395                         if (desc)
396                                 str = desc->type_str;
397                         else
398                                 str = "Unknown Type";
399                 }
400
401                 print_field("  %s(0x%2.2x)", str, type);
402
403                 data += sizeof(type);
404                 size -= sizeof(type);
405         }
406 }
407
408 static void set_uart_baudrate_cmd(const void *data, uint8_t size)
409 {
410         uint8_t baudrate = get_u8(data);
411         const char *str;
412
413         switch (baudrate) {
414         case 0x00:
415                 str = "9600 Baud";
416                 break;
417         case 0x01:
418                 str = "19200 Baud";
419                 break;
420         case 0x02:
421                 str = "38400 Baud";
422                 break;
423         case 0x03:
424                 str = "57600 Baud";
425                 break;
426         case 0x04:
427                 str = "115200 Baud";
428                 break;
429         case 0x05:
430                 str = "230400 Baud";
431                 break;
432         case 0x06:
433                 str = "460800 Baud";
434                 break;
435         case 0x07:
436                 str = "921600 Baud";
437                 break;
438         case 0x08:
439                 str = "1843200 Baud";
440                 break;
441         case 0x09:
442                 str = "3250000 baud";
443                 break;
444         case 0x0a:
445                 str = "2000000 baud";
446                 break;
447         case 0x0b:
448                 str = "3000000 baud";
449                 break;
450         case 0x0c:
451                 str = "3714286 baud";
452                 break;
453         case 0x0d:
454                 str = "4333333 baud";
455                 break;
456         case 0x0e:
457                 str = "6500000 baud";
458                 break;
459         default:
460                 str = "Reserved";
461                 break;
462         }
463
464         print_field("Baudrate: %s (0x%2.2x)", str, baudrate);
465 }
466
467 static void secure_send_cmd(const void *data, uint8_t size)
468 {
469         uint8_t type = get_u8(data);
470         const char *str;
471
472         switch (type) {
473         case 0x00:
474                 str = "Init";
475                 break;
476         case 0x01:
477                 str = "Data";
478                 break;
479         case 0x02:
480                 str = "Sign";
481                 break;
482         case 0x03:
483                 str = "PKey";
484                 break;
485         default:
486                 str = "Reserved";
487                 break;
488         }
489
490         print_field("Type: %s fragment (0x%2.2x)", str, type);
491
492         packet_hexdump(data + 1, size - 1);
493 }
494
495 static void manufacturer_mode_cmd(const void *data, uint8_t size)
496 {
497         uint8_t mode = get_u8(data);
498         uint8_t reset = get_u8(data + 1);
499         const char *str;
500
501         switch (mode) {
502         case 0x00:
503                 str = "Disabled";
504                 break;
505         case 0x01:
506                 str = "Enabled";
507                 break;
508         default:
509                 str = "Reserved";
510                 break;
511         }
512
513         print_field("Mode switch: %s (0x%2.2x)", str, mode);
514
515         switch (reset) {
516         case 0x00:
517                 str = "No reset";
518                 break;
519         case 0x01:
520                 str = "Reset and deactivate patches";
521                 break;
522         case 0x02:
523                 str = "Reset and activate patches";
524                 break;
525         default:
526                 str = "Reserved";
527                 break;
528         }
529
530         print_field("Reset behavior: %s (0x%2.2x)", str, reset);
531 }
532
533 static void write_bd_data_cmd(const void *data, uint8_t size)
534 {
535         uint8_t features[8];
536
537         packet_print_addr("Address", data, 0x00);
538         packet_hexdump(data + 6, 6);
539
540         memcpy(features, data + 12, 8);
541         packet_print_features_lmp(features, 0);
542
543         memcpy(features, data + 20, 1);
544         memset(features + 1, 0, 7);
545         packet_print_features_ll(features);
546
547         packet_hexdump(data + 21, size - 21);
548 }
549
550 static void read_bd_data_rsp(const void *data, uint8_t size)
551 {
552         uint8_t status = get_u8(data);
553
554         print_status(status);
555         packet_print_addr("Address", data + 1, 0x00);
556         packet_hexdump(data + 7, size - 7);
557 }
558
559 static void write_bd_address_cmd(const void *data, uint8_t size)
560 {
561         packet_print_addr("Address", data, 0x00);
562 }
563
564 static void act_deact_traces_cmd(const void *data, uint8_t size)
565 {
566         uint8_t tx = get_u8(data);
567         uint8_t tx_arq = get_u8(data + 1);
568         uint8_t rx = get_u8(data + 2);
569
570         print_field("Transmit traces: 0x%2.2x", tx);
571         print_field("Transmit ARQ: 0x%2.2x", tx_arq);
572         print_field("Receive traces: 0x%2.2x", rx);
573 }
574
575 static void stimulate_exception_cmd(const void *data, uint8_t size)
576 {
577         uint8_t type = get_u8(data);
578         const char *str;
579
580         switch (type) {
581         case 0x00:
582                 str = "Fatal Exception";
583                 break;
584         case 0x01:
585                 str = "Debug Exception";
586                 break;
587         default:
588                 str = "Reserved";
589                 break;
590         }
591
592         print_field("Type: %s (0x%2.2x)", str, type);
593 }
594
595 static const struct {
596         uint8_t bit;
597         const char *str;
598 } events_table[] = {
599         {  0, "Bootup"                  },
600         {  1, "SCO Rejected via LMP"    },
601         {  2, "PTT Switch Notification" },
602         {  7, "Scan Status"             },
603         {  9, "Debug Exception"         },
604         { 10, "Fatal Exception"         },
605         { 11, "System Exception"        },
606         { 13, "LE Link Established"     },
607         { 14, "FW Trace String"         },
608         { }
609 };
610
611 static void set_event_mask_cmd(const void *data, uint8_t size)
612 {
613         const uint8_t *events_array = data;
614         uint64_t mask, events = 0;
615         int i;
616
617         for (i = 0; i < 8; i++)
618                 events |= ((uint64_t) events_array[i]) << (i * 8);
619
620         print_field("Mask: 0x%16.16" PRIx64, events);
621
622         mask = events;
623
624         for (i = 0; events_table[i].str; i++) {
625                 if (events & (((uint64_t) 1) << events_table[i].bit)) {
626                         print_field("  %s", events_table[i].str);
627                         mask &= ~(((uint64_t) 1) << events_table[i].bit);
628                 }
629         }
630
631         if (mask)
632                 print_text(COLOR_UNKNOWN_EVENT_MASK, "  Unknown mask "
633                                                 "(0x%16.16" PRIx64 ")", mask);
634 }
635
636 static void ddc_config_write_cmd(const void *data, uint8_t size)
637 {
638         while (size > 0) {
639                 uint8_t param_len = get_u8(data);
640                 uint16_t param_id = get_le16(data + 1);
641
642                 print_field("Identifier: 0x%4.4x", param_id);
643                 packet_hexdump(data + 3, param_len - 2);
644
645                 data += param_len + 1;
646                 size -= param_len + 1;
647         }
648 }
649
650 static void ddc_config_write_rsp(const void *data, uint8_t size)
651 {
652         uint8_t status = get_u8(data);
653         uint16_t param_id = get_le16(data + 1);
654
655         print_status(status);
656         print_field("Identifier: 0x%4.4x", param_id);
657 }
658
659 static void memory_write_cmd(const void *data, uint8_t size)
660 {
661         uint32_t addr = get_le32(data);
662         uint8_t mode = get_u8(data + 4);
663         uint8_t length = get_u8(data + 5);
664         const char *str;
665
666         print_field("Address: 0x%8.8x", addr);
667
668         switch (mode) {
669         case 0x00:
670                 str = "Byte access";
671                 break;
672         case 0x01:
673                 str = "Half word access";
674                 break;
675         case 0x02:
676                 str = "Word access";
677                 break;
678         default:
679                 str = "Reserved";
680                 break;
681         }
682
683         print_field("Mode: %s (0x%2.2x)", str, mode);
684         print_field("Length: %u", length);
685
686         packet_hexdump(data + 6, size - 6);
687 }
688
689 static void read_supported_features_cmd(const void *data, uint8_t size)
690 {
691         uint8_t page = get_u8(data);
692
693         print_field("Page: 0x%2.2x", page);
694 }
695
696 static void read_supported_features_rsp(const void *data, uint8_t size)
697 {
698         uint8_t status = get_u8(data);
699         uint8_t page = get_u8(data + 1);
700         uint8_t max_pages = get_u8(data + 2);
701
702         print_status(status);
703         print_field("Page: 0x%2.2x", page);
704         print_field("Max Pages: 0x%2.2x", max_pages);
705         print_field("Supported Features:");
706         packet_hexdump(data + 3, size - 3);
707 }
708
709 static const struct vendor_ocf vendor_ocf_table[] = {
710         { 0x001, "Reset",
711                         reset_cmd, 8, true,
712                         status_rsp, 1, true },
713         { 0x002, "No Operation" },
714         { 0x005, "Read Version",
715                         read_version_cmd, 0, false,
716                         read_version_rsp, 1, false },
717         { 0x006, "Set UART Baudrate",
718                         set_uart_baudrate_cmd, 1, true,
719                         status_rsp, 1, true },
720         { 0x007, "Enable LPM" },
721         { 0x008, "PCM Write Configuration" },
722         { 0x009, "Secure Send",
723                         secure_send_cmd, 1, false,
724                         status_rsp, 1, true },
725         { 0x00d, "Read Secure Boot Params",
726                         null_cmd, 0, true },
727         { 0x00e, "Write Secure Boot Params" },
728         { 0x00f, "Unlock" },
729         { 0x010, "Change UART Baudrate" },
730         { 0x011, "Manufacturer Mode",
731                         manufacturer_mode_cmd, 2, true,
732                         status_rsp, 1, true },
733         { 0x012, "Read Link RSSI" },
734         { 0x022, "Get Exception Info" },
735         { 0x024, "Clear Exception Info" },
736         { 0x02f, "Write BD Data",
737                         write_bd_data_cmd, 6, false },
738         { 0x030, "Read BD Data",
739                         null_cmd, 0, true,
740                         read_bd_data_rsp, 7, false },
741         { 0x031, "Write BD Address",
742                         write_bd_address_cmd, 6, true,
743                         status_rsp, 1, true },
744         { 0x032, "Flow Specification" },
745         { 0x034, "Read Secure ID" },
746         { 0x038, "Set Synchronous USB Interface Type" },
747         { 0x039, "Config Synchronous Interface" },
748         { 0x03f, "SW RF Kill",
749                         null_cmd, 0, true,
750                         status_rsp, 1, true },
751         { 0x043, "Activate Deactivate Traces",
752                         act_deact_traces_cmd, 3, true },
753         { 0x04d, "Stimulate Exception",
754                         stimulate_exception_cmd, 1, true,
755                         status_rsp, 1, true },
756         { 0x050, "Read HW Version" },
757         { 0x052, "Set Event Mask",
758                         set_event_mask_cmd, 8, true,
759                         status_rsp, 1, true },
760         { 0x053, "Config_Link_Controller" },
761         { 0x089, "DDC Write" },
762         { 0x08a, "DDC Read" },
763         { 0x08b, "DDC Config Write",
764                         ddc_config_write_cmd, 3, false,
765                         ddc_config_write_rsp, 3, true },
766         { 0x08c, "DDC Config Read" },
767         { 0x08d, "Memory Read" },
768         { 0x08e, "Memory Write",
769                         memory_write_cmd, 6, false,
770                         status_rsp, 1, true },
771         { 0x0a6, "Read Supported Features",
772                         read_supported_features_cmd, 1, true,
773                         read_supported_features_rsp, 19, true },
774
775         { }
776 };
777
778 const struct vendor_ocf *intel_vendor_ocf(uint16_t ocf)
779 {
780         int i;
781
782         for (i = 0; vendor_ocf_table[i].str; i++) {
783                 if (vendor_ocf_table[i].ocf == ocf)
784                         return &vendor_ocf_table[i];
785         }
786
787         return NULL;
788 }
789
790 static void startup_evt(const void *data, uint8_t size)
791 {
792 }
793
794 static void fatal_exception_evt(const void *data, uint8_t size)
795 {
796         uint16_t line = get_le16(data);
797         uint8_t module = get_u8(data + 2);
798         uint8_t reason = get_u8(data + 3);
799
800         print_field("Line: %u", line);
801         print_module(module);
802         print_field("Reason: 0x%2.2x", reason);
803 }
804
805 static void bootup_evt(const void *data, uint8_t size)
806 {
807         uint8_t zero = get_u8(data);
808         uint8_t num_packets = get_u8(data + 1);
809         uint8_t source = get_u8(data + 2);
810         uint8_t reset_type = get_u8(data + 3);
811         uint8_t reset_reason = get_u8(data + 4);
812         uint8_t ddc_status = get_u8(data + 5);
813         const char *str;
814
815         print_field("Zero: 0x%2.2x", zero);
816         print_field("Number of packets: %d", num_packets);
817
818         switch (source) {
819         case 0x00:
820                 str = "Bootloader";
821                 break;
822         case 0x01:
823                 str = "Operational firmware";
824                 break;
825         case 0x02:
826                 str = "Self test firmware";
827                 break;
828         default:
829                 str = "Reserved";
830                 break;
831         }
832
833         print_field("Source: %s (0x%2.2x)", str, source);
834
835         switch (reset_type) {
836         case 0x00:
837                 str = "Hardware reset";
838                 break;
839         case 0x01:
840                 str = "Soft watchdog reset";
841                 break;
842         case 0x02:
843                 str = "Soft software reset";
844                 break;
845         case 0x03:
846                 str = "Hard watchdog reset";
847                 break;
848         case 0x04:
849                 str = "Hard software reset";
850                 break;
851         default:
852                 str = "Reserved";
853                 break;
854         }
855
856         print_field("Reset type: %s (0x%2.2x)", str, reset_type);
857
858         switch (reset_reason) {
859         case 0x00:
860                 str = "Power on";
861                 break;
862         case 0x01:
863                 str = "Reset command";
864                 break;
865         case 0x02:
866                 str = "Intel reset command";
867                 break;
868         case 0x03:
869                 str = "Watchdog";
870                 break;
871         case 0x04:
872                 str = "Fatal exception";
873                 break;
874         case 0x05:
875                 str = "System exception";
876                 break;
877         case 0xff:
878                 str = "Unknown";
879                 break;
880         default:
881                 str = "Reserved";
882                 break;
883         }
884
885         print_field("Reset reason: %s (0x%2.2x)", str, reset_reason);
886
887         switch (ddc_status) {
888         case 0x00:
889                 str = "Firmware default";
890                 break;
891         case 0x01:
892                 str = "Firmware default plus OTP";
893                 break;
894         case 0x02:
895                 str = "Persistent RAM";
896                 break;
897         case 0x03:
898                 str = "Not used";
899                 break;
900         default:
901                 str = "Reserved";
902                 break;
903         }
904
905         print_field("DDC status: %s (0x%2.2x)", str, ddc_status);
906 }
907
908 static void default_bd_data_evt(const void *data, uint8_t size)
909 {
910         uint8_t mem_status = get_u8(data);
911         const char *str;
912
913         switch (mem_status) {
914         case 0x02:
915                 str = "Invalid manufacturing data";
916                 break;
917         default:
918                 str = "Reserved";
919                 break;
920         }
921
922         print_field("Memory status: %s (0x%2.2x)", str, mem_status);
923 }
924
925 static void secure_send_commands_result_evt(const void *data, uint8_t size)
926 {
927         uint8_t result = get_u8(data);
928         uint16_t opcode = get_le16(data + 1);
929         uint16_t ogf = cmd_opcode_ogf(opcode);
930         uint16_t ocf = cmd_opcode_ocf(opcode);
931         uint8_t status = get_u8(data + 3);
932         const char *str;
933
934         switch (result) {
935         case 0x00:
936                 str = "Success";
937                 break;
938         case 0x01:
939                 str = "General failure";
940                 break;
941         case 0x02:
942                 str = "Hardware failure";
943                 break;
944         case 0x03:
945                 str = "Signature verification failed";
946                 break;
947         case 0x04:
948                 str = "Parsing error of command buffer";
949                 break;
950         case 0x05:
951                 str = "Command execution failure";
952                 break;
953         case 0x06:
954                 str = "Command parameters error";
955                 break;
956         case 0x07:
957                 str = "Command missing";
958                 break;
959         default:
960                 str = "Reserved";
961                 break;
962         }
963
964         print_field("Result: %s (0x%2.2x)", str, result);
965         print_field("Opcode: 0x%4.4x (0x%2.2x|0x%4.4x)", opcode, ogf, ocf);
966         print_status(status);
967 }
968
969 static void debug_exception_evt(const void *data, uint8_t size)
970 {
971         uint16_t line = get_le16(data);
972         uint8_t module = get_u8(data + 2);
973         uint8_t reason = get_u8(data + 3);
974
975         print_field("Line: %u", line);
976         print_module(module);
977         print_field("Reason: 0x%2.2x", reason);
978 }
979
980 static void le_link_established_evt(const void *data, uint8_t size)
981 {
982         uint16_t handle = get_le16(data);
983         uint32_t access_addr = get_le32(data + 10);
984
985         print_field("Handle: %u", handle);
986
987         packet_hexdump(data + 2, 8);
988
989         print_field("Access address: 0x%8.8x", access_addr);
990
991         packet_hexdump(data + 14, size - 14);
992 }
993
994 static void scan_status_evt(const void *data, uint8_t size)
995 {
996         uint8_t enable = get_u8(data);
997
998         print_field("Inquiry scan: %s",
999                                 (enable & 0x01) ? "Enabled" : "Disabled");
1000         print_field("Page scan: %s",
1001                                 (enable & 0x02) ? "Enabled" : "Disabled");
1002
1003         if (enable & 0xfc)
1004                 print_text(COLOR_UNKNOWN_SCAN_STATUS,
1005                                 "  Unknown status (0x%2.2x)", enable & 0xfc);
1006
1007 }
1008
1009 static void act_deact_traces_complete_evt(const void *data, uint8_t size)
1010 {
1011         uint8_t status = get_u8(data);
1012
1013         print_status(status);
1014 }
1015
1016 static void lmp_pdu_trace_evt(const void *data, uint8_t size)
1017 {
1018         uint8_t type, len, id;
1019         uint16_t handle, count;
1020         uint32_t clock;
1021         const char *str;
1022
1023         type = get_u8(data);
1024         handle = get_le16(data + 1);
1025
1026         switch (type) {
1027         case 0x00:
1028                 str = "RX LMP";
1029                 break;
1030         case 0x01:
1031                 str = "TX LMP";
1032                 break;
1033         case 0x02:
1034                 str = "ACK LMP";
1035                 break;
1036         case 0x03:
1037                 str = "RX LL";
1038                 break;
1039         case 0x04:
1040                 str = "TX LL";
1041                 break;
1042         case 0x05:
1043                 str = "ACK LL";
1044                 break;
1045         default:
1046                 str = "Unknown";
1047                 break;
1048         }
1049
1050         print_field("Type: %s (0x%2.2x)", str, type);
1051         print_field("Handle: %u", handle);
1052
1053         switch (type) {
1054         case 0x00:
1055                 len = size - 8;
1056                 clock = get_le32(data + 4 + len);
1057
1058                 packet_hexdump(data + 3, 1);
1059                 lmp_packet(data + 4, len, false);
1060                 print_field("Clock: 0x%8.8x", clock);
1061                 break;
1062         case 0x01:
1063                 len = size - 9;
1064                 clock = get_le32(data + 4 + len);
1065                 id = get_u8(data + 4 + len + 4);
1066
1067                 packet_hexdump(data + 3, 1);
1068                 lmp_packet(data + 4, len, false);
1069                 print_field("Clock: 0x%8.8x", clock);
1070                 print_field("ID: 0x%2.2x", id);
1071                 break;
1072         case 0x02:
1073                 clock = get_le32(data + 3);
1074                 id = get_u8(data + 3 + 4);
1075
1076                 print_field("Clock: 0x%8.8x", clock);
1077                 print_field("ID: 0x%2.2x", id);
1078                 break;
1079         case 0x03:
1080                 len = size - 8;
1081                 count = get_le16(data + 3);
1082
1083                 print_field("Count: 0x%4.4x", count);
1084                 packet_hexdump(data + 3 + 2 + 1, 2);
1085                 llcp_packet(data + 8, len, false);
1086                 break;
1087         case 0x04:
1088                 len = size - 8;
1089                 count = get_le16(data + 3);
1090                 id = get_u8(data + 3 + 2);
1091
1092                 print_field("Count: 0x%4.4x", count);
1093                 print_field("ID: 0x%2.2x", id);
1094                 packet_hexdump(data + 3 + 2 + 1, 2);
1095                 llcp_packet(data + 8, len, false);
1096                 break;
1097         case 0x05:
1098                 count = get_le16(data + 3);
1099                 id = get_u8(data + 3 + 2);
1100
1101                 print_field("Count: 0x%4.4x", count);
1102                 print_field("ID: 0x%2.2x", id);
1103                 break;
1104         default:
1105                 packet_hexdump(data + 3, size - 3);
1106                 break;
1107         }
1108 }
1109
1110 static void write_bd_data_complete_evt(const void *data, uint8_t size)
1111 {
1112         uint8_t status = get_u8(data);
1113
1114         print_status(status);
1115 }
1116
1117 static void sco_rejected_via_lmp_evt(const void *data, uint8_t size)
1118 {
1119         uint8_t reason = get_u8(data + 6);
1120
1121         packet_print_addr("Address", data, 0x00);
1122         packet_print_error("Reason", reason);
1123 }
1124
1125 static void ptt_switch_notification_evt(const void *data, uint8_t size)
1126 {
1127         uint16_t handle = get_le16(data);
1128         uint8_t table = get_u8(data + 2);
1129         const char *str;
1130
1131         print_field("Handle: %u", handle);
1132
1133         switch (table) {
1134         case 0x00:
1135                 str = "Basic rate";
1136                 break;
1137         case 0x01:
1138                 str = "Enhanced data rate";
1139                 break;
1140         default:
1141                 str = "Reserved";
1142                 break;
1143         }
1144
1145         print_field("Packet type table: %s (0x%2.2x)", str, table);
1146 }
1147
1148 static void system_exception_evt(const void *data, uint8_t size)
1149 {
1150         uint8_t type = get_u8(data);
1151         const char *str;
1152
1153         switch (type) {
1154         case 0x00:
1155                 str = "No Exception";
1156                 break;
1157         case 0x01:
1158                 str = "Undefined Instruction";
1159                 break;
1160         case 0x02:
1161                 str = "Prefetch abort";
1162                 break;
1163         case 0x03:
1164                 str = "Data abort";
1165                 break;
1166         default:
1167                 str = "Reserved";
1168                 break;
1169         }
1170
1171         print_field("Type: %s (0x%2.2x)", str, type);
1172
1173         packet_hexdump(data + 1, size - 1);
1174 }
1175
1176 static const struct vendor_evt vendor_evt_table[] = {
1177         { 0x00, "Startup",
1178                         startup_evt, 0, true },
1179         { 0x01, "Fatal Exception",
1180                         fatal_exception_evt, 4, true },
1181         { 0x02, "Bootup",
1182                         bootup_evt, 6, true },
1183         { 0x05, "Default BD Data",
1184                         default_bd_data_evt, 1, true },
1185         { 0x06, "Secure Send Commands Result",
1186                         secure_send_commands_result_evt, 4, true },
1187         { 0x08, "Debug Exception",
1188                         debug_exception_evt, 4, true },
1189         { 0x0f, "LE Link Established",
1190                         le_link_established_evt, 26, true },
1191         { 0x11, "Scan Status",
1192                         scan_status_evt, 1, true },
1193         { 0x16, "Activate Deactivate Traces Complete",
1194                         act_deact_traces_complete_evt, 1, true },
1195         { 0x17, "LMP PDU Trace",
1196                         lmp_pdu_trace_evt, 3, false },
1197         { 0x19, "Write BD Data Complete",
1198                         write_bd_data_complete_evt, 1, true },
1199         { 0x25, "SCO Rejected via LMP",
1200                         sco_rejected_via_lmp_evt, 7, true },
1201         { 0x26, "PTT Switch Notification",
1202                         ptt_switch_notification_evt, 3, true },
1203         { 0x29, "System Exception",
1204                         system_exception_evt, 133, true },
1205         { 0x2c, "FW Trace String" },
1206         { 0x2e, "FW Trace Binary" },
1207         { }
1208 };
1209
1210 /*
1211  * An Intel telemetry subevent is of the TLV format.
1212  * - Type: takes 1 byte. This is the subevent_id.
1213  * - Length: takes 1 byte.
1214  * - Value: takes |Length| bytes.
1215  */
1216 struct intel_tlv {
1217         uint8_t subevent_id;
1218         uint8_t length;
1219         uint8_t value[];
1220 };
1221
1222 #define TLV_SIZE(tlv) (*((const uint8_t *) tlv + 1) + 2 * sizeof(uint8_t))
1223 #define NEXT_TLV(tlv) (const struct intel_tlv *) \
1224                                         ((const uint8_t *) tlv + TLV_SIZE(tlv))
1225
1226 static void ext_evt_type(const struct intel_tlv *tlv)
1227 {
1228         uint8_t evt_type = get_u8(tlv->value);
1229         const char *str;
1230
1231         switch (evt_type) {
1232         case 0x00:
1233                 str = "System Exception";
1234                 break;
1235         case 0x01:
1236                 str = "Fatal Exception";
1237                 break;
1238         case 0x02:
1239                 str = "Debug Exception";
1240                 break;
1241         case 0x03:
1242                 str = "Connection Event for BR/EDR Link Type";
1243                 break;
1244         case 0x04:
1245                 str = "Disconnection Event";
1246                 break;
1247         case 0x05:
1248                 str = "Audio Link Quality Report Type";
1249                 break;
1250         case 0x06:
1251                 str = "Stats for BR/EDR Link Type";
1252                 break;
1253         default:
1254                 print_text(COLOR_UNKNOWN_EXT_EVENT,
1255                         "Unknown extended telemetry event type (0x%2.2x)",
1256                         evt_type);
1257                 packet_hexdump((const void *) tlv,
1258                                         tlv->length + 2 * sizeof(uint8_t));
1259                 return;
1260         }
1261
1262         print_field("Extended event type (0x%2.2x): %s (0x%2.2x)",
1263                         tlv->subevent_id, str, evt_type);
1264 }
1265
1266 static void ext_acl_evt_conn_handle(const struct intel_tlv *tlv)
1267 {
1268         uint16_t conn_handle = get_le16(tlv->value);
1269
1270         print_field("ACL connection handle (0x%2.2x): 0x%4.4x",
1271                         tlv->subevent_id, conn_handle);
1272 }
1273
1274 static void ext_acl_evt_hec_errors(const struct intel_tlv *tlv)
1275 {
1276         uint32_t num = get_le32(tlv->value);
1277
1278         print_field("Rx HEC errors (0x%2.2x): %d", tlv->subevent_id, num);
1279 }
1280
1281 static void ext_acl_evt_crc_errors(const struct intel_tlv *tlv)
1282 {
1283         uint32_t num = get_le32(tlv->value);
1284
1285         print_field("Rx CRC errors (0x%2.2x): %d", tlv->subevent_id, num);
1286 }
1287
1288 static void ext_acl_evt_num_pkt_from_host(const struct intel_tlv *tlv)
1289 {
1290         uint32_t num = get_le32(tlv->value);
1291
1292         print_field("Packets from host (0x%2.2x): %d",
1293                         tlv->subevent_id, num);
1294 }
1295
1296 static void ext_acl_evt_num_tx_pkt_to_air(const struct intel_tlv *tlv)
1297 {
1298         uint32_t num = get_le32(tlv->value);
1299
1300         print_field("Tx packets (0x%2.2x): %d", tlv->subevent_id, num);
1301 }
1302
1303 static void ext_acl_evt_num_tx_pkt_retry(const struct intel_tlv *tlv)
1304 {
1305         char *subevent_str;
1306         uint32_t num = get_le32(tlv->value);
1307
1308         switch (tlv->subevent_id) {
1309         case 0x4f:
1310                 subevent_str = "Tx packets 0 retries";
1311                 break;
1312         case 0x50:
1313                 subevent_str = "Tx packets 1 retries";
1314                 break;
1315         case 0x51:
1316                 subevent_str = "Tx packets 2 retries";
1317                 break;
1318         case 0x52:
1319                 subevent_str = "Tx packets 3 retries";
1320                 break;
1321         case 0x53:
1322                 subevent_str = "Tx packets 4 retries and more";
1323                 break;
1324         default:
1325                 subevent_str = "Unknown";
1326                 break;
1327         }
1328
1329         print_field("%s (0x%2.2x): %d", subevent_str, tlv->subevent_id, num);
1330 }
1331
1332 static void ext_acl_evt_num_tx_pkt_type(const struct intel_tlv *tlv)
1333 {
1334         char *packet_type_str;
1335         uint32_t num = get_le32(tlv->value);
1336
1337         switch (tlv->subevent_id) {
1338         case 0x54:
1339                 packet_type_str = "DH1";
1340                 break;
1341         case 0x55:
1342                 packet_type_str = "DH3";
1343                 break;
1344         case 0x56:
1345                 packet_type_str = "DH5";
1346                 break;
1347         case 0x57:
1348                 packet_type_str = "2DH1";
1349                 break;
1350         case 0x58:
1351                 packet_type_str = "2DH3";
1352                 break;
1353         case 0x59:
1354                 packet_type_str = "2DH5";
1355                 break;
1356         case 0x5a:
1357                 packet_type_str = "3DH1";
1358                 break;
1359         case 0x5b:
1360                 packet_type_str = "3DH3";
1361                 break;
1362         case 0x5c:
1363                 packet_type_str = "3DH5";
1364                 break;
1365         default:
1366                 packet_type_str = "Unknown";
1367                 break;
1368         }
1369
1370         print_field("Tx %s packets (0x%2.2x): %d",
1371                         packet_type_str, tlv->subevent_id, num);
1372 }
1373
1374 static void ext_acl_evt_num_rx_pkt_from_air(const struct intel_tlv *tlv)
1375 {
1376         uint32_t num = get_le32(tlv->value);
1377
1378         print_field("Rx packets (0x%2.2x): %d",
1379                         tlv->subevent_id, num);
1380 }
1381
1382 static void ext_acl_evt_link_throughput(const struct intel_tlv *tlv)
1383 {
1384         uint32_t num = get_le32(tlv->value);
1385
1386         print_field("ACL link throughput (KBps) (0x%2.2x): %d",
1387                         tlv->subevent_id, num);
1388 }
1389
1390 static void ext_acl_evt_max_packet_latency(const struct intel_tlv *tlv)
1391 {
1392         uint32_t num = get_le32(tlv->value);
1393
1394         print_field("ACL max packet latency (ms) (0x%2.2x): %d",
1395                         tlv->subevent_id, num);
1396 }
1397
1398 static void ext_acl_evt_avg_packet_latency(const struct intel_tlv *tlv)
1399 {
1400         uint32_t num = get_le32(tlv->value);
1401
1402         print_field("ACL avg packet latency (ms) (0x%2.2x): %d",
1403                         tlv->subevent_id, num);
1404 }
1405
1406 static void ext_sco_evt_conn_handle(const struct intel_tlv *tlv)
1407 {
1408         uint16_t conn_handle = get_le16(tlv->value);
1409
1410         print_field("SCO/eSCO connection handle (0x%2.2x): 0x%4.4x",
1411                         tlv->subevent_id, conn_handle);
1412 }
1413
1414 static void ext_sco_evt_num_rx_pkt_from_air(const struct intel_tlv *tlv)
1415 {
1416         uint32_t num = get_le32(tlv->value);
1417
1418         print_field("Packets from host (0x%2.2x): %d", tlv->subevent_id, num);
1419 }
1420
1421 static void ext_sco_evt_num_tx_pkt_to_air(const struct intel_tlv *tlv)
1422 {
1423         uint32_t num = get_le32(tlv->value);
1424
1425         print_field("Tx packets (0x%2.2x): %d", tlv->subevent_id, num);
1426 }
1427
1428 static void ext_sco_evt_num_rx_payloads_lost(const struct intel_tlv *tlv)
1429 {
1430         uint32_t num = get_le32(tlv->value);
1431
1432         print_field("Rx payload lost (0x%2.2x): %d", tlv->subevent_id, num);
1433 }
1434
1435 static void ext_sco_evt_num_tx_payloads_lost(const struct intel_tlv *tlv)
1436 {
1437
1438         uint32_t num = get_le32(tlv->value);
1439
1440         print_field("Tx payload lost (0x%2.2x): %d", tlv->subevent_id, num);
1441 }
1442
1443 static void slots_errors(const struct intel_tlv *tlv, const char *type_str)
1444 {
1445         /* The subevent has 5 slots where each slot is of the uint32_t type. */
1446         uint32_t num[5];
1447         const uint8_t *data = tlv->value;
1448         int i;
1449
1450         if (tlv->length != 5 * sizeof(uint32_t)) {
1451                 print_text(COLOR_UNKNOWN_EXT_EVENT,
1452                                 "  Invalid subevent length (%d)", tlv->length);
1453                 return;
1454         }
1455
1456         for (i = 0; i < 5; i++) {
1457                 num[i] = get_le32(data);
1458                 data += sizeof(uint32_t);
1459         }
1460
1461         print_field("%s (0x%2.2x): %d %d %d %d %d", type_str, tlv->subevent_id,
1462                         num[0], num[1], num[2], num[3], num[4]);
1463 }
1464
1465 static void ext_sco_evt_num_no_sync_errors(const struct intel_tlv *tlv)
1466 {
1467         slots_errors(tlv, "Rx No SYNC errors");
1468 }
1469
1470 static void ext_sco_evt_num_hec_errors(const struct intel_tlv *tlv)
1471 {
1472         slots_errors(tlv, "Rx HEC errors");
1473 }
1474
1475 static void ext_sco_evt_num_crc_errors(const struct intel_tlv *tlv)
1476 {
1477         slots_errors(tlv, "Rx CRC errors");
1478 }
1479
1480 static void ext_sco_evt_num_naks(const struct intel_tlv *tlv)
1481 {
1482         slots_errors(tlv, "Rx NAK errors");
1483 }
1484
1485 static void ext_sco_evt_num_failed_tx_by_wifi(const struct intel_tlv *tlv)
1486 {
1487         slots_errors(tlv, "Failed Tx due to Wifi coex");
1488 }
1489
1490 static void ext_sco_evt_num_failed_rx_by_wifi(const struct intel_tlv *tlv)
1491 {
1492         slots_errors(tlv, "Failed Rx due to Wifi coex");
1493 }
1494
1495 static void ext_sco_evt_samples_inserted(const struct intel_tlv *tlv)
1496 {
1497         uint32_t num = get_le32(tlv->value);
1498
1499         print_field("Late samples inserted based on CDC (0x%2.2x): %d",
1500                         tlv->subevent_id, num);
1501 }
1502
1503 static void ext_sco_evt_samples_dropped(const struct intel_tlv *tlv)
1504 {
1505         uint32_t num = get_le32(tlv->value);
1506
1507         print_field("Samples dropped (0x%2.2x): %d", tlv->subevent_id, num);
1508 }
1509
1510 static void ext_sco_evt_mute_samples(const struct intel_tlv *tlv)
1511 {
1512         uint32_t num = get_le32(tlv->value);
1513
1514         print_field("Mute samples sent at initial connection (0x%2.2x): %d",
1515                         tlv->subevent_id, num);
1516 }
1517
1518 static void ext_sco_evt_plc_injection_data(const struct intel_tlv *tlv)
1519 {
1520         uint32_t num = get_le32(tlv->value);
1521
1522         print_field("PLC injection data (0x%2.2x): %d", tlv->subevent_id, num);
1523 }
1524
1525 static const struct intel_ext_subevent {
1526         uint8_t subevent_id;
1527         uint8_t length;
1528         void (*func)(const struct intel_tlv *tlv);
1529 } intel_ext_subevent_table[] = {
1530         { 0x01, 1, ext_evt_type },
1531
1532         /* ACL audio link quality subevents */
1533         { 0x4a, 2, ext_acl_evt_conn_handle },
1534         { 0x4b, 4, ext_acl_evt_hec_errors },
1535         { 0x4c, 4, ext_acl_evt_crc_errors },
1536         { 0x4d, 4, ext_acl_evt_num_pkt_from_host },
1537         { 0x4e, 4, ext_acl_evt_num_tx_pkt_to_air },
1538         { 0x4f, 4, ext_acl_evt_num_tx_pkt_retry },
1539         { 0x50, 4, ext_acl_evt_num_tx_pkt_retry },
1540         { 0x51, 4, ext_acl_evt_num_tx_pkt_retry },
1541         { 0x52, 4, ext_acl_evt_num_tx_pkt_retry },
1542         { 0x53, 4, ext_acl_evt_num_tx_pkt_retry },
1543         { 0x54, 4, ext_acl_evt_num_tx_pkt_type },
1544         { 0x55, 4, ext_acl_evt_num_tx_pkt_type },
1545         { 0x56, 4, ext_acl_evt_num_tx_pkt_type },
1546         { 0x57, 4, ext_acl_evt_num_tx_pkt_type },
1547         { 0x58, 4, ext_acl_evt_num_tx_pkt_type },
1548         { 0x59, 4, ext_acl_evt_num_tx_pkt_type },
1549         { 0x5a, 4, ext_acl_evt_num_tx_pkt_type },
1550         { 0x5b, 4, ext_acl_evt_num_tx_pkt_type },
1551         { 0x5c, 4, ext_acl_evt_num_tx_pkt_type },
1552         { 0x5d, 4, ext_acl_evt_num_rx_pkt_from_air },
1553         { 0x5e, 4, ext_acl_evt_link_throughput },
1554         { 0x5f, 4, ext_acl_evt_max_packet_latency },
1555         { 0x60, 4, ext_acl_evt_avg_packet_latency },
1556
1557         /* SCO/eSCO audio link quality subevents */
1558         { 0x6a, 2, ext_sco_evt_conn_handle },
1559         { 0x6b, 4, ext_sco_evt_num_rx_pkt_from_air },
1560         { 0x6c, 4, ext_sco_evt_num_tx_pkt_to_air },
1561         { 0x6d, 4, ext_sco_evt_num_rx_payloads_lost },
1562         { 0x6e, 4, ext_sco_evt_num_tx_payloads_lost },
1563         { 0x6f, 20, ext_sco_evt_num_no_sync_errors },
1564         { 0x70, 20, ext_sco_evt_num_hec_errors },
1565         { 0x71, 20, ext_sco_evt_num_crc_errors },
1566         { 0x72, 20, ext_sco_evt_num_naks },
1567         { 0x73, 20, ext_sco_evt_num_failed_tx_by_wifi },
1568         { 0x74, 20, ext_sco_evt_num_failed_rx_by_wifi },
1569         { 0x75, 4, ext_sco_evt_samples_inserted },
1570         { 0x76, 4, ext_sco_evt_samples_dropped },
1571         { 0x77, 4, ext_sco_evt_mute_samples },
1572         { 0x78, 4, ext_sco_evt_plc_injection_data },
1573
1574         /* end */
1575         { 0x0, 0}
1576 };
1577
1578 static const struct intel_tlv *process_ext_subevent(const struct intel_tlv *tlv,
1579                                         const struct intel_tlv *last_tlv)
1580 {
1581         const struct intel_tlv *next_tlv = NEXT_TLV(tlv);
1582         const struct intel_ext_subevent *subevent = NULL;
1583         int i;
1584
1585         for (i = 0; intel_ext_subevent_table[i].length > 0; i++) {
1586                 if (intel_ext_subevent_table[i].subevent_id ==
1587                                                         tlv->subevent_id) {
1588                         subevent = &intel_ext_subevent_table[i];
1589                         break;
1590                 }
1591         }
1592
1593         if (!subevent) {
1594                 print_text(COLOR_UNKNOWN_EXT_EVENT,
1595                                 "Unknown extended subevent 0x%2.2x",
1596                                 tlv->subevent_id);
1597                 return NULL;
1598         }
1599
1600         if (tlv->length != subevent->length) {
1601                 print_text(COLOR_ERROR, "Invalid length %d of subevent 0x%2.2x",
1602                                 tlv->length, tlv->subevent_id);
1603                 return NULL;
1604         }
1605
1606         if (next_tlv > last_tlv) {
1607                 print_text(COLOR_ERROR, "Subevent exceeds the buffer size.");
1608                 return NULL;
1609         }
1610
1611         subevent->func(tlv);
1612
1613         return next_tlv;
1614 }
1615
1616 static void intel_vendor_ext_evt(const void *data, uint8_t size)
1617 {
1618         /* The data pointer points to a number of tlv.*/
1619         const struct intel_tlv *tlv = data;
1620         const struct intel_tlv *last_tlv = data + size;
1621
1622         /* Process every tlv subevent until reaching last_tlv.
1623          * The decoding process terminates normally when tlv == last_tlv.
1624          */
1625         while (tlv && tlv < last_tlv)
1626                 tlv = process_ext_subevent(tlv, last_tlv);
1627
1628         /* If an error occurs in decoding the subevents, hexdump the packet. */
1629         if (!tlv)
1630                 packet_hexdump(data, size);
1631 }
1632
1633 /* Vendor extended events with a vendor prefix. */
1634 static const struct vendor_evt vendor_prefix_evt_table[] = {
1635         { 0x03, "Extended Telemetry", intel_vendor_ext_evt },
1636         { }
1637 };
1638
1639 const uint8_t intel_vendor_prefix[] = {0x87, 0x80};
1640 #define INTEL_VENDOR_PREFIX_SIZE sizeof(intel_vendor_prefix)
1641
1642 /*
1643  * The vendor event with Intel vendor prefix.
1644  * Its format looks like
1645  *   0xff <length> <vendor_prefix> <subopcode> <data>
1646  *   where Intel's <vendor_prefix> is 0x8780.
1647  *
1648  *   When <subopcode> == 0x03, it is a telemetry event; and
1649  *   <data> is a number of tlv data.
1650  */
1651 struct vendor_prefix_evt {
1652         uint8_t prefix_data[INTEL_VENDOR_PREFIX_SIZE];
1653         uint8_t subopcode;
1654 };
1655
1656 static const struct vendor_evt *intel_vendor_prefix_evt(const void *data,
1657                                                         int *consumed_size)
1658 {
1659         unsigned int i;
1660         const struct vendor_prefix_evt *vnd = data;
1661         char prefix_string[INTEL_VENDOR_PREFIX_SIZE * 2 + 1] = { 0 };
1662
1663         /* Check if the vendor prefix matches. */
1664         for (i = 0; i < INTEL_VENDOR_PREFIX_SIZE; i++) {
1665                 if (vnd->prefix_data[i] != intel_vendor_prefix[i])
1666                         return NULL;
1667                 sprintf(prefix_string + i * 2, "%02x", vnd->prefix_data[i]);
1668         }
1669         print_field("Vendor Prefix (0x%s)", prefix_string);
1670
1671         /*
1672          * Handle the vendor event with a vendor prefix.
1673          *   0xff <length> <vendor_prefix> <subopcode> <data>
1674          * This loop checks whether the <subopcode> exists in the
1675          * vendor_prefix_evt_table.
1676          */
1677         for (i = 0; vendor_prefix_evt_table[i].str; i++) {
1678                 if (vendor_prefix_evt_table[i].evt == vnd->subopcode) {
1679                         *consumed_size = sizeof(struct vendor_prefix_evt);
1680                         return &vendor_prefix_evt_table[i];
1681                 }
1682         }
1683
1684         return NULL;
1685 }
1686
1687 const struct vendor_evt *intel_vendor_evt(const void *data, int *consumed_size)
1688 {
1689         uint8_t evt = *((const uint8_t *) data);
1690         int i;
1691
1692         /*
1693          * Handle the vendor event without a vendor prefix.
1694          *   0xff <length> <evt> <data>
1695          * This loop checks whether the <evt> exists in the vendor_evt_table.
1696          */
1697         for (i = 0; vendor_evt_table[i].str; i++) {
1698                 if (vendor_evt_table[i].evt == evt)
1699                         return &vendor_evt_table[i];
1700         }
1701
1702         /*
1703          * It is not a regular event. Check whether it is a vendor extended
1704          * event that comes with a vendor prefix followed by a subopcode.
1705          */
1706         return intel_vendor_prefix_evt(data, consumed_size);
1707 }