intel.c 38 KB

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