The branch main has been updated by wulf:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=fe70d7b26d7a98b17e315bc3455bee267c618b4e

commit fe70d7b26d7a98b17e315bc3455bee267c618b4e
Author:     Philippe Michaud-Boudreault <[email protected]>
AuthorDate: 2021-05-04 23:48:21 +0000
Commit:     Vladimir Kondratyev <[email protected]>
CommitDate: 2021-05-04 23:50:32 +0000

    iwmbtfw(8): Add support for Intel 7260/7265 bluetooth adapter firmwares
    
    To use it comms/iwmbt-firmware port should be updated to 20210315 version.
    
    Submitted by:   Philippe Michaud-Boudreault <[email protected]>
    Tested by:      Helge Oldach <[email protected]>
    Reviewed by:    wulf
    PR:             228787
    MFC after:      2 weeks
---
 usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c   |  14 ++
 usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c   | 189 +++++++++++++++++++++++-
 usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h   |   5 +
 usr.sbin/bluetooth/iwmbtfw/iwmbtfw.8    |  10 +-
 usr.sbin/bluetooth/iwmbtfw/iwmbtfw.conf |   2 +-
 usr.sbin/bluetooth/iwmbtfw/main.c       | 253 +++++++++++++++++++++++---------
 6 files changed, 401 insertions(+), 72 deletions(-)

diff --git a/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c 
b/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c
index 7764f8bc4ac3..fc93ce094adc 100644
--- a/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c
+++ b/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c
@@ -119,6 +119,20 @@ iwmbt_get_fwname(struct iwmbt_version *ver, struct 
iwmbt_boot_params *params,
        char *fwname;
 
        switch (ver->hw_variant) {
+       case 0x07:      /* 7260 */
+               asprintf(&fwname, "%s/ibt-hw-%x.%x.%x-fw-%x.%x.%x.%x.%x.%s",
+                   prefix,
+                   le16toh(ver->hw_platform),
+                   le16toh(ver->hw_variant),
+                   le16toh(ver->hw_revision),
+                   le16toh(ver->fw_variant),
+                   le16toh(ver->fw_revision),
+                   le16toh(ver->fw_build_num),
+                   le16toh(ver->fw_build_ww),
+                   le16toh(ver->fw_build_yy),
+                   suffix);
+               break;
+
        case 0x0b:      /* 8260 */
        case 0x0c:      /* 8265 */
                asprintf(&fwname, "%s/ibt-%u-%u.%s",
diff --git a/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c 
b/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c
index af48e038340f..f4272548d560 100644
--- a/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c
+++ b/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c
@@ -27,7 +27,7 @@
  * $FreeBSD$
  */
 
-#include <sys/types.h>
+#include <sys/param.h>
 #include <sys/endian.h>
 #include <sys/stat.h>
 
@@ -126,6 +126,125 @@ iwmbt_hci_command(struct libusb_device_handle *hdl, 
struct iwmbt_hci_cmd *cmd,
        return (ret);
 }
 
+int
+iwmbt_patch_fwfile(struct libusb_device_handle *hdl,
+    const struct iwmbt_firmware *fw)
+{
+       int ret, transferred;
+       struct iwmbt_firmware fw_job = *fw;
+       uint16_t cmd_opcode;
+       uint8_t cmd_length;
+       uint8_t cmd_buf[IWMBT_HCI_MAX_CMD_SIZE];
+       uint8_t evt_code;
+       uint8_t evt_length;
+       uint8_t evt_buf[IWMBT_HCI_MAX_EVENT_SIZE];
+       int skip_patch = 0;
+
+       for (;;) {
+               skip_patch = 0;
+
+               if (fw_job.len < 4)
+                       break;
+
+               if (fw_job.buf[0] != 0x01) {
+                       iwmbt_err("Invalid firmware, expected HCI command (%d)",
+                                       fw_job.buf[0]);
+                       return (-1);
+               }
+
+               /* Advance by one. */
+               fw_job.buf++;
+               fw_job.len--;
+
+               /* Load in the HCI command to perform. */
+               cmd_opcode = le16dec(fw_job.buf);
+               cmd_length = fw_job.buf[2];
+               memcpy(cmd_buf, fw_job.buf, 3);
+
+               iwmbt_debug("opcode=%04x, len=%02x", cmd_opcode, cmd_length);
+
+               /* For some reason the command 0xfc2f hangs up my card. */
+               if (cmd_opcode == 0xfc2f)
+                       skip_patch = 1;
+
+               /* Advance by three. */
+               fw_job.buf += 3;
+               fw_job.len -= 3;
+
+               if (fw_job.len < cmd_length)
+                       cmd_length = fw_job.len;
+
+               /* Copy data to HCI command buffer. */
+               memcpy(cmd_buf + 3, fw_job.buf,
+                   MIN(cmd_length, IWMBT_HCI_MAX_CMD_SIZE - 3));
+
+               /* Advance by data length. */
+               fw_job.buf += cmd_length;
+               fw_job.len -= cmd_length;
+
+               /*
+                * Every command has its associated event: data must match
+                * what is recorded in the firmware file. Perform that check
+                * now.
+                *
+                * Some commands are mapped to more than one event sequence,
+                * in that case we can drop the non-patch commands, as we
+                * probably don't need them for operation of the card.
+                *
+                */
+
+               for (;;) {
+                       /* Is this the end of the file? */
+                       if (fw_job.len < 3)
+                               break;
+
+                       if (fw_job.buf[0] != 0x02)
+                               break;
+
+                       /* Advance by one. */
+                       fw_job.buf++;
+                       fw_job.len--;
+
+                       /* Load in the HCI event. */
+                       evt_code = fw_job.buf[0];
+                       evt_length = fw_job.buf[1];
+
+                       /* Advance by two. */
+                       fw_job.buf += 2;
+                       fw_job.len -= 2;
+
+                       /* Prepare HCI event buffer. */
+                       memset(evt_buf, 0, IWMBT_HCI_MAX_EVENT_SIZE);
+
+                       iwmbt_debug("event=%04x, len=%02x",
+                                       evt_code, evt_length);
+
+                       /* Advance by data length. */
+                       fw_job.buf += evt_length;
+                       fw_job.len -= evt_length;
+
+                       if (skip_patch == 0) {
+                               ret = iwmbt_hci_command(hdl,
+                                   (struct iwmbt_hci_cmd *)cmd_buf,
+                                   evt_buf,
+                                   IWMBT_HCI_MAX_EVENT_SIZE,
+                                   &transferred,
+                                   IWMBT_HCI_CMD_TIMEOUT);
+
+                               if (ret < 0) {
+                                       iwmbt_debug("Can't send patch: "
+                                           "code=%d, size=%d",
+                                           ret,
+                                           transferred);
+                                        return (-1);
+                               }
+                       }
+               }
+       }
+
+       return (0);
+}
+
 int
 iwmbt_load_fwfile(struct libusb_device_handle *hdl,
     const struct iwmbt_firmware *fw, uint32_t *boot_param)
@@ -217,6 +336,74 @@ iwmbt_load_fwfile(struct libusb_device_handle *hdl,
        return (0);
 }
 
+int
+iwmbt_enter_manufacturer(struct libusb_device_handle *hdl)
+{
+       int ret, transferred;
+       static struct iwmbt_hci_cmd cmd = {
+               .opcode = htole16(0xfc11),
+               .length = 2,
+               .data = { 0x01, 0x00 },
+       };
+       uint8_t buf[IWMBT_HCI_MAX_EVENT_SIZE];
+
+       ret = iwmbt_hci_command(hdl,
+           &cmd,
+           buf,
+           sizeof(buf),
+           &transferred,
+           IWMBT_HCI_CMD_TIMEOUT);
+
+       if (ret < 0) {
+                iwmbt_debug("Can't enter manufacturer mode: code=%d, size=%d",
+                    ret,
+                    transferred);
+                return (-1);
+       }
+
+       return (0);
+}
+
+int
+iwmbt_exit_manufacturer(struct libusb_device_handle *hdl, int mode)
+{
+       int ret, transferred;
+       static struct iwmbt_hci_cmd cmd = {
+               .opcode = htole16(0xfc11),
+               .length = 2,
+               .data = { 0x00, 0x00 },
+       };
+       uint8_t buf[IWMBT_HCI_MAX_EVENT_SIZE];
+
+       /*
+        * The mode sets the type of reset we want to perform:
+        * 0x00: simply exit manufacturer mode without a reset.
+        * 0x01: exit manufacturer mode with a reset and patches disabled
+        * 0x02: exit manufacturer mode with a reset and patches enabled
+        */
+       if (mode > 2) {
+               iwmbt_debug("iwmbt_exit_manufacturer(): unknown mode (%d)",
+                               mode);
+       }
+       cmd.data[1] = mode;
+
+       ret = iwmbt_hci_command(hdl,
+           &cmd,
+           buf,
+           sizeof(buf),
+           &transferred,
+           IWMBT_HCI_CMD_TIMEOUT);
+
+       if (ret < 0) {
+                iwmbt_debug("Can't exit manufacturer mode: code=%d, size=%d",
+                    ret,
+                    transferred);
+                return (-1);
+       }
+
+       return (0);
+}
+
 int
 iwmbt_get_version(struct libusb_device_handle *hdl,
     struct iwmbt_version *version)
diff --git a/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h 
b/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h
index 6a87f499fa26..5bc1d15181cd 100644
--- a/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h
+++ b/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h
@@ -73,8 +73,13 @@ struct iwmbt_hci_event_cmd_compl {
 #define        IWMBT_HCI_CMD_TIMEOUT           2000    /* ms */
 #define        IWMBT_LOADCMPL_TIMEOUT          5000    /* ms */
 
+extern int iwmbt_patch_fwfile(struct libusb_device_handle *hdl,
+           const struct iwmbt_firmware *fw);
 extern int iwmbt_load_fwfile(struct libusb_device_handle *hdl,
            const struct iwmbt_firmware *fw, uint32_t *boot_param);
+extern int iwmbt_enter_manufacturer(struct libusb_device_handle *hdl);
+extern int iwmbt_exit_manufacturer(struct libusb_device_handle *hdl,
+           int mode);
 extern int iwmbt_get_version(struct libusb_device_handle *hdl,
            struct iwmbt_version *version);
 extern int iwmbt_get_boot_params(struct libusb_device_handle *hdl,
diff --git a/usr.sbin/bluetooth/iwmbtfw/iwmbtfw.8 
b/usr.sbin/bluetooth/iwmbtfw/iwmbtfw.8
index 3afbf54793f9..10e68040e0e4 100644
--- a/usr.sbin/bluetooth/iwmbtfw/iwmbtfw.8
+++ b/usr.sbin/bluetooth/iwmbtfw/iwmbtfw.8
@@ -1,5 +1,6 @@
 .\" Copyright (c) 2013, 2016 Adrian Chadd <[email protected]>
 .\" Copyright (c) 2019 Vladimir Kondratyev <[email protected]>
+.\" Copyright (c) 2021 Philippe Michaud-Boudreault <[email protected]>
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -24,12 +25,12 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 4, 2019
+.Dd May 3, 2021
 .Dt IWMBTFW 8
 .Os
 .Sh NAME
 .Nm iwmbtfw
-.Nd firmware download utility for Intel Wireless 8260/8265 chip based Bluetooth
+.Nd firmware download utility for Intel Wireless 7260/8260/8265 chip based 
Bluetooth
 USB devices
 .Sh SYNOPSIS
 .Nm
@@ -46,7 +47,7 @@ device.
 .Pp
 This utility will
 .Em only
-work with Intel Wireless 8260/8265 chip based Bluetooth USB devices and some of
+work with Intel Wireless 7260/8260/8265 chip based Bluetooth USB devices and 
some of
 their successors.
 The identification is currently based on USB vendor ID/product ID pair.
 The vendor ID should be 0x8087
@@ -91,6 +92,9 @@ utility used as firmware downloader template and on Linux 
btintel driver
 source code.
 It is written by
 .An Vladimir Kondratyev Aq Mt [email protected] .
+.Pp
+Support for the 7260 card added by
+.An Philippe Michaud-Boudreault Aq Mt [email protected] .
 .Sh BUGS
 Most likely.
 Please report if found.
diff --git a/usr.sbin/bluetooth/iwmbtfw/iwmbtfw.conf 
b/usr.sbin/bluetooth/iwmbtfw/iwmbtfw.conf
index 4bd1f020237c..6b417089c68b 100644
--- a/usr.sbin/bluetooth/iwmbtfw/iwmbtfw.conf
+++ b/usr.sbin/bluetooth/iwmbtfw/iwmbtfw.conf
@@ -7,6 +7,6 @@ notify 100 {
        match "subsystem"       "DEVICE";
        match "type"            "ATTACH";
        match "vendor"          "0x8087";
-       match "product"         "(0x0a2b|0x0aaa|0x0025|0x0026|0x0029)";
+       match "product"         
"(0x07dc|0x0a2a|0x0aa7|0x0a2b|0x0aaa|0x0025|0x0026|0x0029)";
        action "/usr/sbin/iwmbtfw -d $cdev -f /usr/local/share/iwmbt-firmware";
 };
diff --git a/usr.sbin/bluetooth/iwmbtfw/main.c 
b/usr.sbin/bluetooth/iwmbtfw/main.c
index ecd9d226b91f..3476e3fcd613 100644
--- a/usr.sbin/bluetooth/iwmbtfw/main.c
+++ b/usr.sbin/bluetooth/iwmbtfw/main.c
@@ -57,7 +57,15 @@ struct iwmbt_devid {
        uint16_t vendor_id;
 };
 
-static struct iwmbt_devid iwmbt_list[] = {
+static struct iwmbt_devid iwmbt_list_72xx[] = {
+
+       /* Intel Wireless 7260/7265 and successors */
+       { .vendor_id = 0x8087, .product_id = 0x07dc },
+       { .vendor_id = 0x8087, .product_id = 0x0a2a },
+       { .vendor_id = 0x8087, .product_id = 0x0aa7 },
+};
+
+static struct iwmbt_devid iwmbt_list_82xx[] = {
 
        /* Intel Wireless 8260/8265 and successors */
        { .vendor_id = 0x8087, .product_id = 0x0a2b },
@@ -67,15 +75,33 @@ static struct iwmbt_devid iwmbt_list[] = {
        { .vendor_id = 0x8087, .product_id = 0x0029 },
 };
 
+static int
+iwmbt_is_7260(struct libusb_device_descriptor *d)
+{
+       int i;
+
+       /* Search looking for whether it's an 7260/7265 */
+       for (i = 0; i < (int) nitems(iwmbt_list_72xx); i++) {
+               if ((iwmbt_list_72xx[i].product_id == d->idProduct) &&
+                   (iwmbt_list_72xx[i].vendor_id == d->idVendor)) {
+                       iwmbt_info("found 7260/7265");
+                       return (1);
+               }
+       }
+
+       /* Not found */
+       return (0);
+}
+
 static int
 iwmbt_is_8260(struct libusb_device_descriptor *d)
 {
        int i;
 
        /* Search looking for whether it's an 8260/8265 */
-       for (i = 0; i < (int) nitems(iwmbt_list); i++) {
-               if ((iwmbt_list[i].product_id == d->idProduct) &&
-                   (iwmbt_list[i].vendor_id == d->idVendor)) {
+       for (i = 0; i < (int) nitems(iwmbt_list_82xx); i++) {
+               if ((iwmbt_list_82xx[i].product_id == d->idProduct) &&
+                   (iwmbt_list_82xx[i].vendor_id == d->idVendor)) {
                        iwmbt_info("found 8260/8265");
                        return (1);
                }
@@ -86,7 +112,8 @@ iwmbt_is_8260(struct libusb_device_descriptor *d)
 }
 
 static libusb_device *
-iwmbt_find_device(libusb_context *ctx, int bus_id, int dev_id)
+iwmbt_find_device(libusb_context *ctx, int bus_id, int dev_id,
+    int *iwmbt_use_old_method)
 {
        libusb_device **list, *dev = NULL, *found = NULL;
        struct libusb_device_descriptor d;
@@ -116,11 +143,20 @@ iwmbt_find_device(libusb_context *ctx, int bus_id, int 
dev_id)
                        }
 
                        /* Match on the vendor/product id */
+                       if (iwmbt_is_7260(&d)) {
+                               /*
+                                * Take a reference so it's not freed later on.
+                                */
+                               found = libusb_ref_device(dev);
+                               *iwmbt_use_old_method = 1;
+                               break;
+                       } else
                        if (iwmbt_is_8260(&d)) {
                                /*
                                 * Take a reference so it's not freed later on.
                                 */
                                found = libusb_ref_device(dev);
+                               *iwmbt_use_old_method = 0;
                                break;
                        }
                }
@@ -166,6 +202,31 @@ iwmbt_dump_boot_params(struct iwmbt_boot_params *params)
            params->otp_bdaddr[0]);
 }
 
+static int
+iwmbt_patch_firmware(libusb_device_handle *hdl, const char *firmware_path)
+{
+       struct iwmbt_firmware fw;
+       int ret;
+
+       iwmbt_debug("loading %s", firmware_path);
+
+       /* Read in the firmware */
+       if (iwmbt_fw_read(&fw, firmware_path) <= 0) {
+               iwmbt_debug("iwmbt_fw_read() failed");
+               return (-1);
+       }
+
+       /* Load in the firmware */
+       ret = iwmbt_patch_fwfile(hdl, &fw);
+       if (ret < 0)
+               iwmbt_debug("Loading firmware file failed");
+
+       /* free it */
+       iwmbt_fw_free(&fw);
+
+       return (ret);
+}
+
 static int
 iwmbt_init_firmware(libusb_device_handle *hdl, const char *firmware_path,
     uint32_t *boot_param)
@@ -268,6 +329,7 @@ main(int argc, char *argv[])
        char *firmware_dir = NULL;
        char *firmware_path = NULL;
        int retcode = 1;
+       int iwmbt_use_old_method = 0;
 
        /* Parse command line arguments */
        while ((n = getopt(argc, argv, "Dd:f:hIm:p:v:")) != -1) {
@@ -312,7 +374,7 @@ main(int argc, char *argv[])
        iwmbt_debug("opening dev %d.%d", (int) bus_id, (int) dev_id);
 
        /* Find a device based on the bus/dev id */
-       dev = iwmbt_find_device(ctx, bus_id, dev_id);
+       dev = iwmbt_find_device(ctx, bus_id, dev_id, &iwmbt_use_old_method);
        if (dev == NULL) {
                iwmbt_err("device not found");
                goto shutdown;
@@ -344,87 +406,144 @@ main(int argc, char *argv[])
        /* Get Intel version */
        r = iwmbt_get_version(hdl, &ver);
        if (r < 0) {
-               iwmbt_debug("iwmbt_get_version() failedL code %d", r);
+               iwmbt_debug("iwmbt_get_version() failed code %d", r);
                goto shutdown;
        }
        iwmbt_dump_version(&ver);
        iwmbt_debug("fw_variant=0x%02x", (int) ver.fw_variant);
 
-       /* fw_variant = 0x06 bootloader mode / 0x23 operational mode */
-       if (ver.fw_variant == 0x23) {
-               iwmbt_info("Firmware has already been downloaded");
+       if (iwmbt_use_old_method) {
+
+               /* fw_patch_num = >0 operational mode */
+               if (ver.fw_patch_num > 0x00) {
+                       iwmbt_info("Firmware has already been downloaded");
+                       retcode = 0;
+                       goto reset;
+               }
+
+               /* Default the firmware path */
+               if (firmware_dir == NULL)
+                       firmware_dir = strdup(_DEFAULT_IWMBT_FIRMWARE_PATH);
+
+               firmware_path = iwmbt_get_fwname(&ver, &params, firmware_dir, 
"bseq");
+               if (firmware_path == NULL)
+                       goto shutdown;
+
+               iwmbt_debug("firmware_path = %s", firmware_path);
+
+               /* Enter manufacturer mode */
+               r = iwmbt_enter_manufacturer(hdl);
+               if (r < 0) {
+                       iwmbt_debug("iwmbt_enter_manufacturer() failed code 
%d", r);
+                       goto shutdown;
+               }
+
+               /* Download firmware and parse it for magic Intel Reset 
parameter */
+               r = iwmbt_patch_firmware(hdl, firmware_path);
+               free(firmware_path);
+               if (r < 0)
+                       goto shutdown;
+
+               iwmbt_info("Firmware download complete");
+
+               /* Exit manufacturer mode */
+               r = iwmbt_exit_manufacturer(hdl, 0x02);
+               if (r < 0) {
+                       iwmbt_debug("iwmbt_exit_manufacturer() failed code %d", 
r);
+                       goto shutdown;
+               }
+
+               /* Once device is running in operational mode we can ignore 
failures */
                retcode = 0;
-               goto reset;
-       }
 
-       if (ver.fw_variant != 0x06){
-               iwmbt_err("unknown fw_variant 0x%02x", (int) ver.fw_variant);
-               goto shutdown;
-       }
+               /* Execute Read Intel Version one more time */
+               r = iwmbt_get_version(hdl, &ver);
+               if (r == 0)
+                       iwmbt_dump_version(&ver);
 
-       /* Read Intel Secure Boot Params */
-       r = iwmbt_get_boot_params(hdl, &params);
-       if (r < 0) {
-               iwmbt_debug("iwmbt_get_boot_params() failed!");
-               goto shutdown;
-       }
-       iwmbt_dump_boot_params(&params);
+               /* Set Intel Event mask */
+               r = iwmbt_set_event_mask(hdl);
+               if (r == 0)
+                       iwmbt_info("Intel Event Mask is set");
 
-       /* Check if firmware fragments are ACKed with a cmd complete event */
-       if (params.limited_cce != 0x00) {
-               iwmbt_err("Unsupported Intel firmware loading method (%u)",
-                  params.limited_cce);
-               goto shutdown;
-       }
+       } else {
 
-       /* Default the firmware path */
-       if (firmware_dir == NULL)
-               firmware_dir = strdup(_DEFAULT_IWMBT_FIRMWARE_PATH);
+               /* fw_variant = 0x06 bootloader mode / 0x23 operational mode */
+               if (ver.fw_variant == 0x23) {
+                       iwmbt_info("Firmware has already been downloaded");
+                       retcode = 0;
+                       goto reset;
+               }
 
-       firmware_path = iwmbt_get_fwname(&ver, &params, firmware_dir, "sfi");
-       if (firmware_path == NULL)
-               goto shutdown;
+               if (ver.fw_variant != 0x06){
+                       iwmbt_err("unknown fw_variant 0x%02x", (int) 
ver.fw_variant);
+                       goto shutdown;
+               }
 
-       iwmbt_debug("firmware_path = %s", firmware_path);
+               /* Read Intel Secure Boot Params */
+               r = iwmbt_get_boot_params(hdl, &params);
+               if (r < 0) {
+                       iwmbt_debug("iwmbt_get_boot_params() failed!");
+                       goto shutdown;
+               }
+               iwmbt_dump_boot_params(&params);
 
-       /* Download firmware and parse it for magic Intel Reset parameter */
-       r = iwmbt_init_firmware(hdl, firmware_path, &boot_param);
-       free(firmware_path);
-       if (r < 0)
-               goto shutdown;
+               /* Check if firmware fragments are ACKed with a cmd complete 
event */
+               if (params.limited_cce != 0x00) {
+                       iwmbt_err("Unsupported Intel firmware loading method 
(%u)",
+                          params.limited_cce);
+                       goto shutdown;
+               }
 
-       iwmbt_info("Firmware download complete");
+               /* Default the firmware path */
+               if (firmware_dir == NULL)
+                       firmware_dir = strdup(_DEFAULT_IWMBT_FIRMWARE_PATH);
 
-       r = iwmbt_intel_reset(hdl, boot_param);
-       if (r < 0) {
-               iwmbt_debug("iwmbt_intel_reset() failed!");
-               goto shutdown;
-       }
+               firmware_path = iwmbt_get_fwname(&ver, &params, firmware_dir, 
"sfi");
+               if (firmware_path == NULL)
+                       goto shutdown;
 
-       iwmbt_info("Firmware operational");
+               iwmbt_debug("firmware_path = %s", firmware_path);
 
-       /* Once device is running in operational mode we can ignore failures */
-       retcode = 0;
+               /* Download firmware and parse it for magic Intel Reset 
parameter */
+               r = iwmbt_init_firmware(hdl, firmware_path, &boot_param);
+               free(firmware_path);
+               if (r < 0)
+                       goto shutdown;
 
-       /* Execute Read Intel Version one more time */
-       r = iwmbt_get_version(hdl, &ver);
-       if (r == 0)
-               iwmbt_dump_version(&ver);
-
-       /* Apply the device configuration (DDC) parameters */
-       firmware_path = iwmbt_get_fwname(&ver, &params, firmware_dir, "ddc");
-       iwmbt_debug("ddc_path = %s", firmware_path);
-       if (firmware_path != NULL) {
-               r = iwmbt_init_ddc(hdl, firmware_path);
+               iwmbt_info("Firmware download complete");
+
+               r = iwmbt_intel_reset(hdl, boot_param);
+               if (r < 0) {
+                       iwmbt_debug("iwmbt_intel_reset() failed!");
+                       goto shutdown;
+               }
+
+               iwmbt_info("Firmware operational");
+
+               /* Once device is running in operational mode we can ignore 
failures */
+               retcode = 0;
+
+               /* Execute Read Intel Version one more time */
+               r = iwmbt_get_version(hdl, &ver);
                if (r == 0)
-                       iwmbt_info("DDC download complete");
-               free(firmware_path);
-       }
+                       iwmbt_dump_version(&ver);
+
+               /* Apply the device configuration (DDC) parameters */
+               firmware_path = iwmbt_get_fwname(&ver, &params, firmware_dir, 
"ddc");
+               iwmbt_debug("ddc_path = %s", firmware_path);
+               if (firmware_path != NULL) {
+                       r = iwmbt_init_ddc(hdl, firmware_path);
+                       if (r == 0)
+                               iwmbt_info("DDC download complete");
+                       free(firmware_path);
+               }
 
-       /* Set Intel Event mask */
-       r = iwmbt_set_event_mask(hdl);
-       if (r == 0)
-               iwmbt_info("Intel Event Mask is set");
+               /* Set Intel Event mask */
+               r = iwmbt_set_event_mask(hdl);
+               if (r == 0)
+                       iwmbt_info("Intel Event Mask is set");
+       }
 
 reset:
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to