Lines 57-63
struct iwmbt_devid {
Link Here
|
57 |
uint16_t vendor_id; |
57 |
uint16_t vendor_id; |
58 |
}; |
58 |
}; |
59 |
|
59 |
|
60 |
static struct iwmbt_devid iwmbt_list[] = { |
60 |
static struct iwmbt_devid iwmbt_list_72xx[] = { |
|
|
61 |
|
62 |
/* Intel Wireless 7260/7265 and successors */ |
63 |
{ .vendor_id = 0x8087, .product_id = 0x07dc }, |
64 |
{ .vendor_id = 0x8087, .product_id = 0x0a2a }, |
65 |
{ .vendor_id = 0x8087, .product_id = 0x0aa7 }, |
66 |
}; |
67 |
|
68 |
static struct iwmbt_devid iwmbt_list_82xx[] = { |
61 |
|
69 |
|
62 |
/* Intel Wireless 8260/8265 and successors */ |
70 |
/* Intel Wireless 8260/8265 and successors */ |
63 |
{ .vendor_id = 0x8087, .product_id = 0x0a2b }, |
71 |
{ .vendor_id = 0x8087, .product_id = 0x0a2b }, |
Lines 67-81
static struct iwmbt_devid iwmbt_list[] = {
Link Here
|
67 |
{ .vendor_id = 0x8087, .product_id = 0x0029 }, |
75 |
{ .vendor_id = 0x8087, .product_id = 0x0029 }, |
68 |
}; |
76 |
}; |
69 |
|
77 |
|
|
|
78 |
static int |
79 |
iwmbt_is_7260(struct libusb_device_descriptor *d) |
80 |
{ |
81 |
int i; |
82 |
|
83 |
/* Search looking for whether it's an 7260/7265 */ |
84 |
for (i = 0; i < (int) nitems(iwmbt_list_72xx); i++) { |
85 |
if ((iwmbt_list_72xx[i].product_id == d->idProduct) && |
86 |
(iwmbt_list_72xx[i].vendor_id == d->idVendor)) { |
87 |
iwmbt_info("found 7260/7265"); |
88 |
return (1); |
89 |
} |
90 |
} |
91 |
|
92 |
/* Not found */ |
93 |
return (0); |
94 |
} |
95 |
|
70 |
static int |
96 |
static int |
71 |
iwmbt_is_8260(struct libusb_device_descriptor *d) |
97 |
iwmbt_is_8260(struct libusb_device_descriptor *d) |
72 |
{ |
98 |
{ |
73 |
int i; |
99 |
int i; |
74 |
|
100 |
|
75 |
/* Search looking for whether it's an 8260/8265 */ |
101 |
/* Search looking for whether it's an 8260/8265 */ |
76 |
for (i = 0; i < (int) nitems(iwmbt_list); i++) { |
102 |
for (i = 0; i < (int) nitems(iwmbt_list_82xx); i++) { |
77 |
if ((iwmbt_list[i].product_id == d->idProduct) && |
103 |
if ((iwmbt_list_82xx[i].product_id == d->idProduct) && |
78 |
(iwmbt_list[i].vendor_id == d->idVendor)) { |
104 |
(iwmbt_list_82xx[i].vendor_id == d->idVendor)) { |
79 |
iwmbt_info("found 8260/8265"); |
105 |
iwmbt_info("found 8260/8265"); |
80 |
return (1); |
106 |
return (1); |
81 |
} |
107 |
} |
Lines 86-92
iwmbt_is_8260(struct libusb_device_descriptor *d)
Link Here
|
86 |
} |
112 |
} |
87 |
|
113 |
|
88 |
static libusb_device * |
114 |
static libusb_device * |
89 |
iwmbt_find_device(libusb_context *ctx, int bus_id, int dev_id) |
115 |
iwmbt_find_device(libusb_context *ctx, int bus_id, int dev_id, |
|
|
116 |
int *iwmbt_use_old_method) |
90 |
{ |
117 |
{ |
91 |
libusb_device **list, *dev = NULL, *found = NULL; |
118 |
libusb_device **list, *dev = NULL, *found = NULL; |
92 |
struct libusb_device_descriptor d; |
119 |
struct libusb_device_descriptor d; |
Lines 116-126
iwmbt_find_device(libusb_context *ctx, int bus_id, int dev_id)
Link Here
|
116 |
} |
143 |
} |
117 |
|
144 |
|
118 |
/* Match on the vendor/product id */ |
145 |
/* Match on the vendor/product id */ |
|
|
146 |
if (iwmbt_is_7260(&d)) { |
147 |
/* |
148 |
* Take a reference so it's not freed later on. |
149 |
*/ |
150 |
found = libusb_ref_device(dev); |
151 |
*iwmbt_use_old_method = 1; |
152 |
break; |
153 |
} else |
119 |
if (iwmbt_is_8260(&d)) { |
154 |
if (iwmbt_is_8260(&d)) { |
120 |
/* |
155 |
/* |
121 |
* Take a reference so it's not freed later on. |
156 |
* Take a reference so it's not freed later on. |
122 |
*/ |
157 |
*/ |
123 |
found = libusb_ref_device(dev); |
158 |
found = libusb_ref_device(dev); |
|
|
159 |
*iwmbt_use_old_method = 0; |
124 |
break; |
160 |
break; |
125 |
} |
161 |
} |
126 |
} |
162 |
} |
Lines 166-171
iwmbt_dump_boot_params(struct iwmbt_boot_params *params)
Link Here
|
166 |
params->otp_bdaddr[0]); |
202 |
params->otp_bdaddr[0]); |
167 |
} |
203 |
} |
168 |
|
204 |
|
|
|
205 |
static int |
206 |
iwmbt_patch_firmware(libusb_device_handle *hdl, const char *firmware_path) |
207 |
{ |
208 |
struct iwmbt_firmware fw; |
209 |
int ret; |
210 |
|
211 |
iwmbt_debug("loading %s", firmware_path); |
212 |
|
213 |
/* Read in the firmware */ |
214 |
if (iwmbt_fw_read(&fw, firmware_path) <= 0) { |
215 |
iwmbt_debug("iwmbt_fw_read() failed"); |
216 |
return (-1); |
217 |
} |
218 |
|
219 |
/* Load in the firmware */ |
220 |
ret = iwmbt_patch_fwfile(hdl, &fw); |
221 |
if (ret < 0) |
222 |
iwmbt_debug("Loading firmware file failed"); |
223 |
|
224 |
/* free it */ |
225 |
iwmbt_fw_free(&fw); |
226 |
|
227 |
return (ret); |
228 |
} |
229 |
|
169 |
static int |
230 |
static int |
170 |
iwmbt_init_firmware(libusb_device_handle *hdl, const char *firmware_path, |
231 |
iwmbt_init_firmware(libusb_device_handle *hdl, const char *firmware_path, |
171 |
uint32_t *boot_param) |
232 |
uint32_t *boot_param) |
Lines 268-273
main(int argc, char *argv[])
Link Here
|
268 |
char *firmware_dir = NULL; |
329 |
char *firmware_dir = NULL; |
269 |
char *firmware_path = NULL; |
330 |
char *firmware_path = NULL; |
270 |
int retcode = 1; |
331 |
int retcode = 1; |
|
|
332 |
int iwmbt_use_old_method = 0; |
271 |
|
333 |
|
272 |
/* Parse command line arguments */ |
334 |
/* Parse command line arguments */ |
273 |
while ((n = getopt(argc, argv, "Dd:f:hIm:p:v:")) != -1) { |
335 |
while ((n = getopt(argc, argv, "Dd:f:hIm:p:v:")) != -1) { |
Lines 312-318
main(int argc, char *argv[])
Link Here
|
312 |
iwmbt_debug("opening dev %d.%d", (int) bus_id, (int) dev_id); |
374 |
iwmbt_debug("opening dev %d.%d", (int) bus_id, (int) dev_id); |
313 |
|
375 |
|
314 |
/* Find a device based on the bus/dev id */ |
376 |
/* Find a device based on the bus/dev id */ |
315 |
dev = iwmbt_find_device(ctx, bus_id, dev_id); |
377 |
dev = iwmbt_find_device(ctx, bus_id, dev_id, &iwmbt_use_old_method); |
316 |
if (dev == NULL) { |
378 |
if (dev == NULL) { |
317 |
iwmbt_err("device not found"); |
379 |
iwmbt_err("device not found"); |
318 |
goto shutdown; |
380 |
goto shutdown; |
Lines 344-430
main(int argc, char *argv[])
Link Here
|
344 |
/* Get Intel version */ |
406 |
/* Get Intel version */ |
345 |
r = iwmbt_get_version(hdl, &ver); |
407 |
r = iwmbt_get_version(hdl, &ver); |
346 |
if (r < 0) { |
408 |
if (r < 0) { |
347 |
iwmbt_debug("iwmbt_get_version() failedL code %d", r); |
409 |
iwmbt_debug("iwmbt_get_version() failed code %d", r); |
348 |
goto shutdown; |
410 |
goto shutdown; |
349 |
} |
411 |
} |
350 |
iwmbt_dump_version(&ver); |
412 |
iwmbt_dump_version(&ver); |
351 |
iwmbt_debug("fw_variant=0x%02x", (int) ver.fw_variant); |
413 |
iwmbt_debug("fw_variant=0x%02x", (int) ver.fw_variant); |
352 |
|
414 |
|
353 |
/* fw_variant = 0x06 bootloader mode / 0x23 operational mode */ |
415 |
if (iwmbt_use_old_method) { |
354 |
if (ver.fw_variant == 0x23) { |
416 |
|
355 |
iwmbt_info("Firmware has already been downloaded"); |
417 |
/* fw_patch_num = >0 operational mode */ |
|
|
418 |
if (ver.fw_patch_num > 0x00) { |
419 |
iwmbt_info("Firmware has already been downloaded"); |
420 |
retcode = 0; |
421 |
goto reset; |
422 |
} |
423 |
|
424 |
/* Default the firmware path */ |
425 |
if (firmware_dir == NULL) |
426 |
firmware_dir = strdup(_DEFAULT_IWMBT_FIRMWARE_PATH); |
427 |
|
428 |
firmware_path = iwmbt_get_fwname(&ver, ¶ms, firmware_dir, "bseq"); |
429 |
if (firmware_path == NULL) |
430 |
goto shutdown; |
431 |
|
432 |
iwmbt_debug("firmware_path = %s", firmware_path); |
433 |
|
434 |
/* Enter manufacturer mode */ |
435 |
r = iwmbt_enter_manufacturer(hdl); |
436 |
if (r < 0) { |
437 |
iwmbt_debug("iwmbt_enter_manufacturer() failed code %d", r); |
438 |
goto shutdown; |
439 |
} |
440 |
|
441 |
/* Download firmware and parse it for magic Intel Reset parameter */ |
442 |
r = iwmbt_patch_firmware(hdl, firmware_path); |
443 |
free(firmware_path); |
444 |
if (r < 0) |
445 |
goto shutdown; |
446 |
|
447 |
iwmbt_info("Firmware download complete"); |
448 |
|
449 |
/* Exit manufacturer mode */ |
450 |
r = iwmbt_exit_manufacturer(hdl, 0x02); |
451 |
if (r < 0) { |
452 |
iwmbt_debug("iwmbt_exit_manufacturer() failed code %d", r); |
453 |
goto shutdown; |
454 |
} |
455 |
|
456 |
/* Once device is running in operational mode we can ignore failures */ |
356 |
retcode = 0; |
457 |
retcode = 0; |
357 |
goto reset; |
|
|
358 |
} |
359 |
|
458 |
|
360 |
if (ver.fw_variant != 0x06){ |
459 |
/* Execute Read Intel Version one more time */ |
361 |
iwmbt_err("unknown fw_variant 0x%02x", (int) ver.fw_variant); |
460 |
r = iwmbt_get_version(hdl, &ver); |
362 |
goto shutdown; |
461 |
if (r == 0) |
363 |
} |
462 |
iwmbt_dump_version(&ver); |
364 |
|
463 |
|
365 |
/* Read Intel Secure Boot Params */ |
464 |
/* Set Intel Event mask */ |
366 |
r = iwmbt_get_boot_params(hdl, ¶ms); |
465 |
r = iwmbt_set_event_mask(hdl); |
367 |
if (r < 0) { |
466 |
if (r == 0) |
368 |
iwmbt_debug("iwmbt_get_boot_params() failed!"); |
467 |
iwmbt_info("Intel Event Mask is set"); |
369 |
goto shutdown; |
|
|
370 |
} |
371 |
iwmbt_dump_boot_params(¶ms); |
372 |
|
468 |
|
373 |
/* Check if firmware fragments are ACKed with a cmd complete event */ |
469 |
} else { |
374 |
if (params.limited_cce != 0x00) { |
|
|
375 |
iwmbt_err("Unsupported Intel firmware loading method (%u)", |
376 |
params.limited_cce); |
377 |
goto shutdown; |
378 |
} |
379 |
|
470 |
|
380 |
/* Default the firmware path */ |
471 |
/* fw_variant = 0x06 bootloader mode / 0x23 operational mode */ |
381 |
if (firmware_dir == NULL) |
472 |
if (ver.fw_variant == 0x23) { |
382 |
firmware_dir = strdup(_DEFAULT_IWMBT_FIRMWARE_PATH); |
473 |
iwmbt_info("Firmware has already been downloaded"); |
|
|
474 |
retcode = 0; |
475 |
goto reset; |
476 |
} |
383 |
|
477 |
|
384 |
firmware_path = iwmbt_get_fwname(&ver, ¶ms, firmware_dir, "sfi"); |
478 |
if (ver.fw_variant != 0x06){ |
385 |
if (firmware_path == NULL) |
479 |
iwmbt_err("unknown fw_variant 0x%02x", (int) ver.fw_variant); |
386 |
goto shutdown; |
480 |
goto shutdown; |
|
|
481 |
} |
387 |
|
482 |
|
388 |
iwmbt_debug("firmware_path = %s", firmware_path); |
483 |
/* Read Intel Secure Boot Params */ |
|
|
484 |
r = iwmbt_get_boot_params(hdl, ¶ms); |
485 |
if (r < 0) { |
486 |
iwmbt_debug("iwmbt_get_boot_params() failed!"); |
487 |
goto shutdown; |
488 |
} |
489 |
iwmbt_dump_boot_params(¶ms); |
389 |
|
490 |
|
390 |
/* Download firmware and parse it for magic Intel Reset parameter */ |
491 |
/* Check if firmware fragments are ACKed with a cmd complete event */ |
391 |
r = iwmbt_init_firmware(hdl, firmware_path, &boot_param); |
492 |
if (params.limited_cce != 0x00) { |
392 |
free(firmware_path); |
493 |
iwmbt_err("Unsupported Intel firmware loading method (%u)", |
393 |
if (r < 0) |
494 |
params.limited_cce); |
394 |
goto shutdown; |
495 |
goto shutdown; |
|
|
496 |
} |
395 |
|
497 |
|
396 |
iwmbt_info("Firmware download complete"); |
498 |
/* Default the firmware path */ |
|
|
499 |
if (firmware_dir == NULL) |
500 |
firmware_dir = strdup(_DEFAULT_IWMBT_FIRMWARE_PATH); |
397 |
|
501 |
|
398 |
r = iwmbt_intel_reset(hdl, boot_param); |
502 |
firmware_path = iwmbt_get_fwname(&ver, ¶ms, firmware_dir, "sfi"); |
399 |
if (r < 0) { |
503 |
if (firmware_path == NULL) |
400 |
iwmbt_debug("iwmbt_intel_reset() failed!"); |
504 |
goto shutdown; |
401 |
goto shutdown; |
|
|
402 |
} |
403 |
|
505 |
|
404 |
iwmbt_info("Firmware operational"); |
506 |
iwmbt_debug("firmware_path = %s", firmware_path); |
405 |
|
507 |
|
406 |
/* Once device is running in operational mode we can ignore failures */ |
508 |
/* Download firmware and parse it for magic Intel Reset parameter */ |
407 |
retcode = 0; |
509 |
r = iwmbt_init_firmware(hdl, firmware_path, &boot_param); |
|
|
510 |
free(firmware_path); |
511 |
if (r < 0) |
512 |
goto shutdown; |
408 |
|
513 |
|
409 |
/* Execute Read Intel Version one more time */ |
514 |
iwmbt_info("Firmware download complete"); |
410 |
r = iwmbt_get_version(hdl, &ver); |
515 |
|
411 |
if (r == 0) |
516 |
r = iwmbt_intel_reset(hdl, boot_param); |
412 |
iwmbt_dump_version(&ver); |
517 |
if (r < 0) { |
413 |
|
518 |
iwmbt_debug("iwmbt_intel_reset() failed!"); |
414 |
/* Apply the device configuration (DDC) parameters */ |
519 |
goto shutdown; |
415 |
firmware_path = iwmbt_get_fwname(&ver, ¶ms, firmware_dir, "ddc"); |
520 |
} |
416 |
iwmbt_debug("ddc_path = %s", firmware_path); |
521 |
|
417 |
if (firmware_path != NULL) { |
522 |
iwmbt_info("Firmware operational"); |
418 |
r = iwmbt_init_ddc(hdl, firmware_path); |
523 |
|
|
|
524 |
/* Once device is running in operational mode we can ignore failures */ |
525 |
retcode = 0; |
526 |
|
527 |
/* Execute Read Intel Version one more time */ |
528 |
r = iwmbt_get_version(hdl, &ver); |
419 |
if (r == 0) |
529 |
if (r == 0) |
420 |
iwmbt_info("DDC download complete"); |
530 |
iwmbt_dump_version(&ver); |
421 |
free(firmware_path); |
531 |
|
422 |
} |
532 |
/* Apply the device configuration (DDC) parameters */ |
|
|
533 |
firmware_path = iwmbt_get_fwname(&ver, ¶ms, firmware_dir, "ddc"); |
534 |
iwmbt_debug("ddc_path = %s", firmware_path); |
535 |
if (firmware_path != NULL) { |
536 |
r = iwmbt_init_ddc(hdl, firmware_path); |
537 |
if (r == 0) |
538 |
iwmbt_info("DDC download complete"); |
539 |
free(firmware_path); |
540 |
} |
423 |
|
541 |
|
424 |
/* Set Intel Event mask */ |
542 |
/* Set Intel Event mask */ |
425 |
r = iwmbt_set_event_mask(hdl); |
543 |
r = iwmbt_set_event_mask(hdl); |
426 |
if (r == 0) |
544 |
if (r == 0) |
427 |
iwmbt_info("Intel Event Mask is set"); |
545 |
iwmbt_info("Intel Event Mask is set"); |
|
|
546 |
} |
428 |
|
547 |
|
429 |
reset: |
548 |
reset: |
430 |
|
549 |
|