aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEygene Ryabinkin <rea@FreeBSD.org>2025-01-29 21:56:40 +0000
committerVladimir Kondratyev <wulf@FreeBSD.org>2025-01-29 21:56:40 +0000
commit06969db312022277729dd144e3655a90007306ef (patch)
tree201b7c3cbbb62f677200d31207fc0dd1f1b8d86c
parentf466ba4ca479ec500b927deadaba104469662994 (diff)
Refactor iwmbtfw: modularize and de-constify
- Move logic for firmware download into different adapter types to the own functions to allow main() to be simpler - Use enums/typedefs for exit modes, image types, etc - Purge most obvious comments: functions are named properly, so most of their invocations self-document the code. Signed-off-by: Eygene Ryabinkin <rea@FreeBSD.org> Reviewed by: wulf MFC after: 1 month
-rw-r--r--usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c1
-rw-r--r--usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.h8
-rw-r--r--usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c15
-rw-r--r--usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h14
-rw-r--r--usr.sbin/bluetooth/iwmbtfw/main.c526
5 files changed, 298 insertions, 266 deletions
diff --git a/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c b/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c
index 815b40982d5b..3a5cd9d42658 100644
--- a/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c
+++ b/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c
@@ -119,6 +119,7 @@ iwmbt_get_fwname(struct iwmbt_version *ver, struct iwmbt_boot_params *params,
switch (ver->hw_variant) {
case 0x07: /* 7260 */
case 0x08: /* 7265 */
+ // NB: don't use params, they are NULL for 7xxx
asprintf(&fwname, "%s/ibt-hw-%x.%x.%x-fw-%x.%x.%x.%x.%x.%s",
prefix,
le16toh(ver->hw_platform),
diff --git a/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.h b/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.h
index 2666d123c8f0..eb6909a1f91d 100644
--- a/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.h
+++ b/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.h
@@ -52,6 +52,10 @@ struct iwmbt_version {
uint8_t fw_patch_num;
} __attribute__ ((packed));
+/* Known values for fw_variant */
+#define FW_VARIANT_BOOTLOADER 0x06 /* Bootloader mode */
+#define FW_VARIANT_OPERATIONAL 0x23 /* Operational mode */
+
struct iwmbt_boot_params {
uint8_t status;
uint8_t otp_format;
@@ -131,6 +135,10 @@ struct iwmbt_version_tlv {
bdaddr_t otp_bd_addr;
};
+/* Known TLV img_type values */
+#define TLV_IMG_TYPE_BOOTLOADER 0x01 /* Bootloader mode */
+#define TLV_IMG_TYPE_OPERATIONAL 0x03 /* Operational mode */
+
struct iwmbt_firmware {
char *fwname;
int len;
diff --git a/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c b/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c
index 1efd24ecf9f6..255181b8f4bc 100644
--- a/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c
+++ b/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c
@@ -437,7 +437,8 @@ iwmbt_enter_manufacturer(struct libusb_device_handle *hdl)
}
int
-iwmbt_exit_manufacturer(struct libusb_device_handle *hdl, int mode)
+iwmbt_exit_manufacturer(struct libusb_device_handle *hdl,
+ enum iwmbt_mm_exit mode)
{
int ret, transferred;
static struct iwmbt_hci_cmd cmd = {
@@ -447,17 +448,7 @@ iwmbt_exit_manufacturer(struct libusb_device_handle *hdl, int mode)
};
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;
+ cmd.data[1] = (uint8_t)mode;
ret = iwmbt_hci_command(hdl,
&cmd,
diff --git a/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h b/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h
index 89ee344fe587..aac885dfd153 100644
--- a/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h
+++ b/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h
@@ -58,6 +58,18 @@ struct iwmbt_hci_event_cmd_compl {
uint8_t data[];
} __attribute__ ((packed));
+/*
+ * Manufacturer mode exit type: selects reset type,
+ * 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
+ */
+enum iwmbt_mm_exit {
+ IWMBT_MM_EXIT_ONLY = 0x00,
+ IWMBT_MM_EXIT_COLD_RESET = 0x01,
+ IWMBT_MM_EXIT_WARM_RESET = 0x02,
+};
+
#define IWMBT_HCI_EVT_COMPL_SIZE(payload) \
(offsetof(struct iwmbt_hci_event_cmd_compl, data) + sizeof(payload))
#define IWMBT_HCI_EVENT_COMPL_HEAD_SIZE \
@@ -91,7 +103,7 @@ extern int iwmbt_load_fwfile(struct libusb_device_handle *hdl,
const struct iwmbt_firmware *fw, uint32_t *boot_param, int offset);
extern int iwmbt_enter_manufacturer(struct libusb_device_handle *hdl);
extern int iwmbt_exit_manufacturer(struct libusb_device_handle *hdl,
- int mode);
+ enum iwmbt_mm_exit mode);
extern int iwmbt_get_version(struct libusb_device_handle *hdl,
struct iwmbt_version *version);
extern int iwmbt_get_version_tlv(struct libusb_device_handle *hdl,
diff --git a/usr.sbin/bluetooth/iwmbtfw/main.c b/usr.sbin/bluetooth/iwmbtfw/main.c
index e4bb22af0e8a..497edcb254cf 100644
--- a/usr.sbin/bluetooth/iwmbtfw/main.c
+++ b/usr.sbin/bluetooth/iwmbtfw/main.c
@@ -215,9 +215,11 @@ iwmbt_dump_version_tlv(struct iwmbt_version_tlv *ver)
ver->otp_bd_addr.b[2],
ver->otp_bd_addr.b[1],
ver->otp_bd_addr.b[0]);
- if (ver->img_type == 0x01 || ver->img_type == 0x03)
+ if (ver->img_type == TLV_IMG_TYPE_BOOTLOADER ||
+ ver->img_type == TLV_IMG_TYPE_OPERATIONAL)
iwmbt_info("%s timestamp %u.%u buildtype %u build %u",
- ver->img_type == 0x01 ? "Bootloader" : "Firmware",
+ (ver->img_type == TLV_IMG_TYPE_BOOTLOADER ?
+ "Bootloader" : "Firmware"),
2000 + (ver->timestamp >> 8),
ver->timestamp & 0xff,
ver->build_type,
@@ -399,22 +401,266 @@ usage(void)
exit(127);
}
+
+/*
+ * Returns 0 on success.
+ */
+static int
+handle_7260(libusb_device_handle *hdl, char *firmware_dir)
+{
+ int r;
+ struct iwmbt_version ver;
+ char *firmware_path = NULL;
+
+ r = iwmbt_get_version(hdl, &ver);
+ if (r < 0) {
+ iwmbt_debug("iwmbt_get_version() failed code %d", r);
+ return 1;
+ }
+ iwmbt_dump_version(&ver);
+ iwmbt_debug("fw_patch_num=0x%02x", (int) ver.fw_patch_num);
+
+ /* fw_patch_num = >0 operational mode */
+ if (ver.fw_patch_num > 0x00) {
+ iwmbt_info("Firmware has already been downloaded");
+ return 0;
+ }
+
+ firmware_path = iwmbt_get_fwname(&ver, NULL, firmware_dir, "bseq");
+ if (firmware_path == NULL)
+ return 1;
+ iwmbt_debug("firmware_path = %s", firmware_path);
+
+ r = iwmbt_enter_manufacturer(hdl);
+ if (r < 0) {
+ iwmbt_debug("iwmbt_enter_manufacturer() failed code %d", r);
+ return 1;
+ }
+
+ /* Download firmware */
+ r = iwmbt_patch_firmware(hdl, firmware_path);
+ free(firmware_path);
+ if (r < 0) {
+ (void)iwmbt_exit_manufacturer(hdl, IWMBT_MM_EXIT_COLD_RESET);
+ return 1;
+ }
+
+ iwmbt_info("Firmware download complete");
+
+ r = iwmbt_exit_manufacturer(hdl,
+ (r == 0 ? IWMBT_MM_EXIT_ONLY : IWMBT_MM_EXIT_WARM_RESET));
+ if (r < 0) {
+ iwmbt_debug("iwmbt_exit_manufacturer() failed code %d", r);
+ return 1;
+ }
+
+ /* Once device is running in operational mode we can ignore failures */
+
+ /* Dump actual controller version */
+ r = iwmbt_get_version(hdl, &ver);
+ if (r == 0)
+ iwmbt_dump_version(&ver);
+
+ if (iwmbt_enter_manufacturer(hdl) < 0)
+ return 0;
+ r = iwmbt_set_event_mask(hdl);
+ if (r == 0)
+ iwmbt_info("Intel Event Mask is set");
+ (void)iwmbt_exit_manufacturer(hdl, IWMBT_MM_EXIT_ONLY);
+
+ return 0;
+}
+
+
+/*
+ * Returns 0 on success.
+ */
+static int
+handle_8260(libusb_device_handle *hdl, char *firmware_dir)
+{
+ int r;
+ uint32_t boot_param;
+ struct iwmbt_version ver;
+ struct iwmbt_boot_params params;
+ char *firmware_path = NULL;
+
+ r = iwmbt_get_version(hdl, &ver);
+ if (r < 0) {
+ iwmbt_debug("iwmbt_get_version() failed code %d", r);
+ return 1;
+ }
+ iwmbt_dump_version(&ver);
+ iwmbt_debug("fw_variant=0x%02x", (int) ver.fw_variant);
+
+ if (ver.fw_variant == FW_VARIANT_OPERATIONAL) {
+ iwmbt_info("Firmware has already been downloaded");
+ return 0;
+ }
+
+ if (ver.fw_variant != FW_VARIANT_BOOTLOADER){
+ iwmbt_err("unknown fw_variant 0x%02x", (int) ver.fw_variant);
+ return 1;
+ }
+
+ /* Read Intel Secure Boot Params */
+ r = iwmbt_get_boot_params(hdl, &params);
+ if (r < 0) {
+ iwmbt_debug("iwmbt_get_boot_params() failed!");
+ return 1;
+ }
+ iwmbt_dump_boot_params(&params);
+
+ /* 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);
+ return 1;
+ }
+
+ firmware_path = iwmbt_get_fwname(&ver, &params, firmware_dir, "sfi");
+ if (firmware_path == NULL)
+ return 1;
+ iwmbt_debug("firmware_path = %s", firmware_path);
+
+ /* Download firmware and parse it for magic Intel Reset parameter */
+ r = iwmbt_init_firmware(hdl, firmware_path, &boot_param, 0, 0);
+ free(firmware_path);
+ if (r < 0)
+ return 1;
+
+ iwmbt_info("Firmware download complete");
+
+ r = iwmbt_intel_reset(hdl, boot_param);
+ if (r < 0) {
+ iwmbt_debug("iwmbt_intel_reset() failed!");
+ return 1;
+ }
+
+ iwmbt_info("Firmware operational");
+
+ /* Once device is running in operational mode we can ignore failures */
+
+ /* Dump actual controller version */
+ 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);
+ if (r == 0)
+ iwmbt_info("DDC download complete");
+ free(firmware_path);
+ }
+
+ r = iwmbt_set_event_mask(hdl);
+ if (r == 0)
+ iwmbt_info("Intel Event Mask is set");
+
+ return 0;
+}
+
+
+static int
+handle_9260(libusb_device_handle *hdl, char *firmware_dir)
+{
+ int r;
+ uint32_t boot_param;
+ struct iwmbt_version vl;
+ struct iwmbt_version_tlv vt;
+ char *firmware_path = NULL;
+
+ r = iwmbt_get_version_tlv(hdl, &vt);
+ if (r < 0) {
+ iwmbt_debug("iwmbt_get_version_tlv() failed code %d", r);
+ return 1;
+ }
+ iwmbt_dump_version_tlv(&vt);
+ iwmbt_debug("img_type=0x%02x", (int) vt.img_type);
+
+ if (vt.img_type == TLV_IMG_TYPE_OPERATIONAL) {
+ iwmbt_info("Firmware has already been downloaded");
+ return 0;
+ }
+
+ if (vt.img_type != TLV_IMG_TYPE_BOOTLOADER) {
+ iwmbt_err("unknown img_type 0x%02x", (int) vt.img_type);
+ return 1;
+ }
+
+ /* Check if firmware fragments are ACKed with a cmd complete event */
+ if (vt.limited_cce != 0x00) {
+ iwmbt_err("Unsupported Intel firmware loading method (%u)",
+ vt.limited_cce);
+ return 1;
+ }
+
+ /* Check if secure boot engine is supported: 1 (ECDSA) or 0 (RSA) */
+ if (vt.sbe_type > 0x01) {
+ iwmbt_err("Unsupported secure boot engine (%u)",
+ vt.sbe_type);
+ return 1;
+ }
+
+ firmware_path = iwmbt_get_fwname_tlv(&vt, firmware_dir, "sfi");
+ if (firmware_path == NULL)
+ return 1;
+ iwmbt_debug("firmware_path = %s", firmware_path);
+
+ /* Download firmware and parse it for magic Intel Reset parameter */
+ r = iwmbt_init_firmware(hdl, firmware_path, &boot_param,
+ vt.cnvi_bt >> 16 & 0x3f, vt.sbe_type);
+ free(firmware_path);
+ if (r < 0)
+ return 1;
+
+ iwmbt_info("Firmware download complete");
+
+ r = iwmbt_intel_reset(hdl, boot_param);
+ if (r < 0) {
+ iwmbt_debug("iwmbt_intel_reset() failed!");
+ return 1;
+ }
+
+ iwmbt_info("Firmware operational");
+
+ /* Once device is running in operational mode we can ignore failures */
+
+ r = iwmbt_get_version(hdl, &vl);
+ if (r == 0)
+ iwmbt_dump_version(&vl);
+
+ /* Apply the device configuration (DDC) parameters */
+ firmware_path = iwmbt_get_fwname_tlv(&vt, 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);
+ }
+
+ r = iwmbt_set_event_mask(hdl);
+ if (r == 0)
+ iwmbt_info("Intel Event Mask is set");
+
+ return 0;
+}
+
+
int
main(int argc, char *argv[])
{
libusb_context *ctx = NULL;
libusb_device *dev = NULL;
libusb_device_handle *hdl = NULL;
- static struct iwmbt_version ver;
- static struct iwmbt_version_tlv ver_tlv;
- static struct iwmbt_boot_params params;
- uint32_t boot_param;
int r;
uint8_t bus_id = 0, dev_id = 0;
int devid_set = 0;
int n;
char *firmware_dir = NULL;
- char *firmware_path = NULL;
int retcode = 1;
enum iwmbt_device iwmbt_device;
@@ -494,256 +740,30 @@ main(int argc, char *argv[])
goto shutdown;
}
- if (iwmbt_device == IWMBT_DEVICE_7260) {
-
- /* Get Intel version */
- r = iwmbt_get_version(hdl, &ver);
- if (r < 0) {
- iwmbt_debug("iwmbt_get_version() failed code %d", r);
- goto shutdown;
- }
- iwmbt_dump_version(&ver);
- iwmbt_debug("fw_patch_num=0x%02x", (int) ver.fw_patch_num);
-
- /* fw_patch_num = >0 operational mode */
- if (ver.fw_patch_num > 0x00) {
- iwmbt_info("Firmware has already been downloaded");
- retcode = 0;
- goto reset;
- }
-
- firmware_path = iwmbt_get_fwname(&ver, &params, firmware_dir, "bseq");
- if (firmware_path == NULL)
- goto shutdown;
-
- iwmbt_debug("firmware_path = %s", firmware_path);
-
- /* Check firmware file exists before changing HW mode */
- r = access(firmware_path, R_OK);
- if (r) {
- perror("Failed to open firmware");
- goto shutdown;
- }
-
- /* 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) {
- (void)iwmbt_exit_manufacturer(hdl, 0x01);
- goto shutdown;
- }
-
- iwmbt_info("Firmware download complete");
-
- /* Exit manufacturer mode */
- r = iwmbt_exit_manufacturer(hdl, r == 0 ? 0x00 : 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;
-
- /* Execute Read Intel Version one more time */
- r = iwmbt_get_version(hdl, &ver);
- if (r == 0)
- iwmbt_dump_version(&ver);
-
- /* Set Intel Event mask */
- if (iwmbt_enter_manufacturer(hdl) < 0)
- goto reset;
- r = iwmbt_set_event_mask(hdl);
- if (r == 0)
- iwmbt_info("Intel Event Mask is set");
- (void)iwmbt_exit_manufacturer(hdl, 0x00);
-
- } else if (iwmbt_device == IWMBT_DEVICE_8260) {
-
- /* Get Intel version */
- r = iwmbt_get_version(hdl, &ver);
- if (r < 0) {
- 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");
- retcode = 0;
- goto reset;
- }
-
- if (ver.fw_variant != 0x06){
- iwmbt_err("unknown fw_variant 0x%02x", (int) ver.fw_variant);
- goto shutdown;
- }
-
- /* 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);
-
- /* 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;
- }
-
- firmware_path = iwmbt_get_fwname(&ver, &params, firmware_dir, "sfi");
- if (firmware_path == NULL)
- goto shutdown;
-
- iwmbt_debug("firmware_path = %s", firmware_path);
-
- /* Download firmware and parse it for magic Intel Reset parameter */
- r = iwmbt_init_firmware(hdl, firmware_path, &boot_param, 0, 0);
- free(firmware_path);
- if (r < 0)
- goto shutdown;
-
- 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_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");
-
- } else {
-
- /* Get Intel version */
- r = iwmbt_get_version_tlv(hdl, &ver_tlv);
- if (r < 0) {
- iwmbt_debug("iwmbt_get_version_tlv() failed code %d", r);
- goto shutdown;
- }
- iwmbt_dump_version_tlv(&ver_tlv);
- iwmbt_debug("img_type=0x%02x", (int) ver_tlv.img_type);
-
- /* img_type = 0x01 bootloader mode / 0x03 operational mode */
- if (ver_tlv.img_type == 0x03) {
- iwmbt_info("Firmware has already been downloaded");
- retcode = 0;
- goto reset;
- }
-
- if (ver_tlv.img_type != 0x01){
- iwmbt_err("unknown img_type 0x%02x", (int) ver_tlv.img_type);
- goto shutdown;
- }
-
- /* Check if firmware fragments are ACKed with a cmd complete event */
- if (ver_tlv.limited_cce != 0x00) {
- iwmbt_err("Unsupported Intel firmware loading method (%u)",
- ver_tlv.limited_cce);
- goto shutdown;
- }
-
- /* Check if secure boot engine is supported: 1 (ECDSA) or 0 (RSA) */
- if (ver_tlv.sbe_type > 0x01) {
- iwmbt_err("Unsupported secure boot engine (%u)",
- ver_tlv.sbe_type);
- goto shutdown;
- }
-
- firmware_path = iwmbt_get_fwname_tlv(&ver_tlv, firmware_dir, "sfi");
- if (firmware_path == NULL)
- goto shutdown;
-
- iwmbt_debug("firmware_path = %s", firmware_path);
-
- /* Download firmware and parse it for magic Intel Reset parameter */
- r = iwmbt_init_firmware(hdl, firmware_path, &boot_param,
- ver_tlv.cnvi_bt >> 16 & 0x3f, ver_tlv.sbe_type);
- free(firmware_path);
- if (r < 0)
- goto shutdown;
-
- 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_dump_version(&ver);
-
- /* Apply the device configuration (DDC) parameters */
- firmware_path = iwmbt_get_fwname_tlv(&ver_tlv, 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");
-
- iwmbt_info("Firmware download complete");
+ switch(iwmbt_device) {
+ case IWMBT_DEVICE_7260:
+ retcode = handle_7260(hdl, firmware_dir);
+ break;
+ case IWMBT_DEVICE_8260:
+ retcode = handle_8260(hdl, firmware_dir);
+ break;
+ case IWMBT_DEVICE_9260:
+ retcode = handle_9260(hdl, firmware_dir);
+ break;
+ default:
+ iwmbt_err("FIXME: unknown iwmbt type %d", (int)iwmbt_device);
+ retcode = 1;
}
-reset:
-
- /* Ask kernel driver to probe and attach device again */
- r = libusb_reset_device(hdl);
- if (r != 0)
- iwmbt_err("libusb_reset_device() failed: %s",
- libusb_strerror(r));
+ if (retcode == 0) {
+ /* Ask kernel driver to probe and attach device again */
+ r = libusb_reset_device(hdl);
+ if (r != 0)
+ iwmbt_err("libusb_reset_device() failed: %s",
+ libusb_strerror(r));
+ }
shutdown:
-
- /* Shutdown */
-
if (hdl != NULL)
libusb_close(hdl);