From nobody Thu Nov 24 23:17:42 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4NJDRp4bCNz4jPWM; Thu, 24 Nov 2022 23:17:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4NJDRp3k2sz4B7V; Thu, 24 Nov 2022 23:17:42 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1669331862; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=GV2A3sIRzadhUj7im14ZpZ87BsthaJBAJhYoLuNeDDE=; b=UoryMGiQD55Co5+tfyrn6cY08py8cY/Ch2Yu6Jm3HWXUwFe0zY74S6WV9dDY7FLBmSvMsl sKDxj2vPcpMKl9rwgy5/e22jUkbyX0EzvGbxxvJNSWA54sVHyttMygYdvJ9VOZoTZ67xIB WaUDaCj/VV4ScquT65UE11P7ZinZrpoZiRs/ur8QOue816ckQ/04LStonYOAxq0np3OYLI +Q86OxFTRZVHpWN1xrBPRU9RRIiHReVr2xOnACiBKprfC9SjQZ5adZ0HvEexX02B68R3F5 RKiS7+EgoXaffbEenwHIQenO3Co9Hsg3egaXW3cq12/uF1grCHJnv17njvkDrg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1669331862; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=GV2A3sIRzadhUj7im14ZpZ87BsthaJBAJhYoLuNeDDE=; b=ZnXBcpqjhmT6DbyyUSkd+jYybk6NNnS8ewdrsxIGAX0czwRR+QpkswRLKJhMnxnyobE5K3 4j37ql2z5fIIaseqwmbM9LoVynABu86Q6RXcuP/mHFNQ2whL227AmPjcIm3IeCD3fSnodI N8BpjWKD8OCYbQFymfTcuW8PrJVwtmfre+hAUPETI3bu6ergQ4k+hkchhitzvbTMMIDMkd ZKDYkLYAuSKiH9vo3fraY3/ZHtoOAeWZIMxPAA/RxiOlOvg7XZdintBRP5pNjdfgNqsqUA 0+jKgyq1gRCD7Km/iE1s3igXVbRDNP2zPb++v75xGJbdAoDRJ9hdBm+q9T/wWQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1669331862; a=rsa-sha256; cv=none; b=LfXCLkMn7qSJeIC1HrFgv0fS53kBUkWc4mUEG5q0cagcVUDyvNIPGezSGZNeqLQnHSNq9e za+KNFSE7b+nd4RZ81CHsSpd0FTTnBC5rdbn68YJnKKF1Zr0Mr6VfQOgcm5rjyB1mpz16u bOBBDQO7JNNR3x/T6Rc/0Cy9Rlh9MlxemdI1IdrEH7wqPZVNnXp88V5J/XwMc7o8MZcwZ9 yrW6ZRPbzT6J71ENbsFi7nI42OnGzzTK8P3k8FcRIImwv9uRz9lKsk0KJKz7nppcylpicF Jy4WfppQSigoonEyxtyOycD+hNO4sFIKynXJfVtieqBsDZdH/KxcUPktN6KUcA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4NJDRp2nd6zJtw; Thu, 24 Nov 2022 23:17:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 2AONHgmT007096; Thu, 24 Nov 2022 23:17:42 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 2AONHg4l007095; Thu, 24 Nov 2022 23:17:42 GMT (envelope-from git) Date: Thu, 24 Nov 2022 23:17:42 GMT Message-Id: <202211242317.2AONHg4l007095@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Vladimir Kondratyev Subject: git: d95de59e943e - stable/12 - iwmbtfw(8): Improve Intel 7260/7265 adaptors handling List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: wulf X-Git-Repository: src X-Git-Refname: refs/heads/stable/12 X-Git-Reftype: branch X-Git-Commit: d95de59e943e2c07e35880d04467e822c234c3db Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/12 has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=d95de59e943e2c07e35880d04467e822c234c3db commit d95de59e943e2c07e35880d04467e822c234c3db Author: Vladimir Kondratyev AuthorDate: 2021-05-31 19:32:08 +0000 Commit: Vladimir Kondratyev CommitDate: 2022-11-24 23:16:08 +0000 iwmbtfw(8): Improve Intel 7260/7265 adaptors handling - Allow firmware downloading for hw_variant #8; - Enter manufacturer mode for setting of event mask; - Handle multi-event response on HCI commands for 7260; This allows to remove kludge with skipping of 0xfc2f opcode. - Disable patch and exit manufacturer mode on downloading failure; - Use default firmware if correct firmware file is not found; Reviewed by: Philippe Michaud-Boudreault MFC after: 1 week Tested by: arrowd Differential revision: https://reviews.freebsd.org/D30543 (cherry picked from commit da93a73f834612b659b37b513c8296e1178d249b) --- usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c | 14 ++++ usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c | 116 ++++++++++++++++++++-------------- usr.sbin/bluetooth/iwmbtfw/main.c | 9 ++- 3 files changed, 91 insertions(+), 48 deletions(-) diff --git a/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c b/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c index fc93ce094adc..963d5d5d9008 100644 --- a/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c +++ b/usr.sbin/bluetooth/iwmbtfw/iwmbt_fw.c @@ -116,10 +116,12 @@ char * iwmbt_get_fwname(struct iwmbt_version *ver, struct iwmbt_boot_params *params, const char *prefix, const char *suffix) { + struct stat sb; char *fwname; switch (ver->hw_variant) { case 0x07: /* 7260 */ + case 0x08: /* 7265 */ asprintf(&fwname, "%s/ibt-hw-%x.%x.%x-fw-%x.%x.%x.%x.%x.%s", prefix, le16toh(ver->hw_platform), @@ -131,6 +133,18 @@ iwmbt_get_fwname(struct iwmbt_version *ver, struct iwmbt_boot_params *params, le16toh(ver->fw_build_ww), le16toh(ver->fw_build_yy), suffix); + /* + * Fallback to the default firmware patch if + * the correct firmware patch file is not found. + */ + if (stat(fwname, &sb) != 0 && errno == ENOENT) { + free(fwname); + asprintf(&fwname, "%s/ibt-hw-%x.%x.%s", + prefix, + le16toh(ver->hw_platform), + le16toh(ver->hw_variant), + suffix); + } break; case 0x0b: /* 8260 */ diff --git a/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c b/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c index f4272548d560..218fd28b74a2 100644 --- a/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c +++ b/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c @@ -134,17 +134,18 @@ iwmbt_patch_fwfile(struct libusb_device_handle *hdl, struct iwmbt_firmware fw_job = *fw; uint16_t cmd_opcode; uint8_t cmd_length; - uint8_t cmd_buf[IWMBT_HCI_MAX_CMD_SIZE]; + struct iwmbt_hci_cmd *cmd_buf; uint8_t evt_code; uint8_t evt_length; uint8_t evt_buf[IWMBT_HCI_MAX_EVENT_SIZE]; - int skip_patch = 0; + int activate_patch = 0; - for (;;) { - skip_patch = 0; - - if (fw_job.len < 4) - break; + while (fw_job.len > 0) { + if (fw_job.len < 4) { + iwmbt_err("Invalid firmware, unexpected EOF in HCI " + "command header. Remains=%d", fw_job.len); + return (-1); + } if (fw_job.buf[0] != 0x01) { iwmbt_err("Invalid firmware, expected HCI command (%d)", @@ -159,47 +160,61 @@ iwmbt_patch_fwfile(struct libusb_device_handle *hdl, /* 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); + cmd_buf = (struct iwmbt_hci_cmd *)fw_job.buf; 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; + /* + * If there is a command that loads a patch in the + * firmware file, then activate the patch upon success, + * otherwise just disable the manufacturer mode. + */ + if (cmd_opcode == 0xfc8e) + activate_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)); + if (fw_job.len < cmd_length) { + iwmbt_err("Invalid firmware, unexpected EOF in HCI " + "command data. len=%d, remains=%d", + cmd_length, fw_job.len); + return (-1); + } /* Advance by data length. */ fw_job.buf += cmd_length; fw_job.len -= cmd_length; + ret = libusb_control_transfer(hdl, + LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE, + 0, + 0, + 0, + (uint8_t *)cmd_buf, + IWMBT_HCI_CMD_SIZE(cmd_buf), + IWMBT_HCI_CMD_TIMEOUT); + + if (ret < 0) { + iwmbt_err("libusb_control_transfer() failed: err=%s", + libusb_strerror(ret)); + return (-1); + } + /* * 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 (;;) { + while (fw_job.len > 0 && fw_job.buf[0] == 0x02) { /* Is this the end of the file? */ - if (fw_job.len < 3) - break; - - if (fw_job.buf[0] != 0x02) - break; + if (fw_job.len < 3) { + iwmbt_err("Invalid firmware, unexpected EOF in" + "event header. remains=%d", fw_job.len); + return (-1); + } /* Advance by one. */ fw_job.buf++; @@ -219,30 +234,39 @@ iwmbt_patch_fwfile(struct libusb_device_handle *hdl, iwmbt_debug("event=%04x, len=%02x", evt_code, evt_length); + if (fw_job.len < evt_length) { + iwmbt_err("Invalid firmware, unexpected EOF in" + " event data. len=%d, remains=%d", + evt_length, fw_job.len); + return (-1); + } + + ret = libusb_interrupt_transfer(hdl, + IWMBT_INTERRUPT_ENDPOINT_ADDR, + evt_buf, + IWMBT_HCI_MAX_EVENT_SIZE, + &transferred, + IWMBT_HCI_CMD_TIMEOUT); + + if (ret < 0) { + iwmbt_err("libusb_interrupt_transfer() failed:" + " err=%s", libusb_strerror(ret)); + return (-1); + } + + if ((int)evt_length + 2 != transferred || + memcmp(evt_buf + 2, fw_job.buf, evt_length) != 0) { + iwmbt_err("event does not match firmware"); + return (-1); + } + /* 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); + return (activate_patch); } int diff --git a/usr.sbin/bluetooth/iwmbtfw/main.c b/usr.sbin/bluetooth/iwmbtfw/main.c index 3476e3fcd613..202894740805 100644 --- a/usr.sbin/bluetooth/iwmbtfw/main.c +++ b/usr.sbin/bluetooth/iwmbtfw/main.c @@ -441,13 +441,15 @@ main(int argc, char *argv[]) /* Download firmware and parse it for magic Intel Reset parameter */ r = iwmbt_patch_firmware(hdl, firmware_path); free(firmware_path); - if (r < 0) + if (r < 0) { + (void)iwmbt_exit_manufacturer(hdl, 0x01); goto shutdown; + } iwmbt_info("Firmware download complete"); /* Exit manufacturer mode */ - r = iwmbt_exit_manufacturer(hdl, 0x02); + r = iwmbt_exit_manufacturer(hdl, r == 0 ? 0x00 : 0x02); if (r < 0) { iwmbt_debug("iwmbt_exit_manufacturer() failed code %d", r); goto shutdown; @@ -462,9 +464,12 @@ main(int argc, char *argv[]) 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 {