The branch stable/14 has been updated by wulf:

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

commit 5ce844d3daa29ba0358e455d3723226d127a28af
Author:     Vladimir Kondratyev <w...@freebsd.org>
AuthorDate: 2024-11-06 23:25:56 +0000
Commit:     Vladimir Kondratyev <w...@freebsd.org>
CommitDate: 2024-12-22 03:34:24 +0000

    ng_ubt_intel: Allow to attach to 9260 bluetooth adaptors
    
    with operational mode firmware.
    
    Sponsored by:   Future Crew LLC
    MFC after:      1 month
    Reviewed by:    bz
    Differential Revision:  https://reviews.freebsd.org/D46734
    
    (cherry picked from commit 19a577ea5cae1238065106de9080cb6f3e66034d)
---
 sys/netgraph/bluetooth/drivers/ubt/ng_ubt_intel.c | 69 ++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)

diff --git a/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_intel.c 
b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_intel.c
index ad71cae5fa83..f93b74b264ad 100644
--- a/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_intel.c
+++ b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_intel.c
@@ -6,6 +6,7 @@
  * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2019, 2021 Vladimir Kondratyev <w...@freebsd.org>
+ * Copyright (c) 2023 Future Crew LLC.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,9 +57,13 @@
 #include <netgraph/bluetooth/include/ng_ubt.h>
 #include <netgraph/bluetooth/drivers/ubt/ng_ubt_var.h>
 
+#define        UBT_INTEL_HCICMD_TIMEOUT        2000    /* ms */
+#define        UBT_INTEL_TLV_IMAGE_TYPE        0x1c
+
 enum {
        UBT_INTEL_DEVICE_7260,
        UBT_INTEL_DEVICE_8260,
+       UBT_INTEL_DEVICE_9260,
 };
 
 struct ubt_intel_version_rp {
@@ -93,6 +98,9 @@ static const STRUCT_USB_HOST_ID ubt_intel_devs[] =
        { USB_VPI(USB_VENDOR_INTEL2, 0x0025, UBT_INTEL_DEVICE_8260) },
        { USB_VPI(USB_VENDOR_INTEL2, 0x0026, UBT_INTEL_DEVICE_8260) },
        { USB_VPI(USB_VENDOR_INTEL2, 0x0029, UBT_INTEL_DEVICE_8260) },
+       /* Intel Wireless 9260/9560 and successors */
+       { USB_VPI(USB_VENDOR_INTEL2, 0x0032, UBT_INTEL_DEVICE_9260) },
+       { USB_VPI(USB_VENDOR_INTEL2, 0x0033, UBT_INTEL_DEVICE_9260) },
 };
 
 /*
@@ -103,7 +111,6 @@ static usb_error_t
 ubt_intel_do_hci_request(struct usb_device *udev, uint16_t opcode,
     void *resp, uint8_t resp_len)
 {
-#define        UBT_INTEL_HCICMD_TIMEOUT        2000    /* ms */
        struct ubt_hci_event_command_compl *evt;
        struct ubt_hci_cmd cmd;
        usb_error_t error;
@@ -128,6 +135,53 @@ exit:
        return (error);
 }
 
+static uint8_t
+ubt_intel_get_img_type(struct usb_device *udev)
+{
+#define        UBT_INTEL_MAX_EVT_SIZE          256
+       static struct ubt_hci_cmd cmd = {
+           .opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_VENDOR, 0x05)),
+           .length = 1,
+           .data = { 0xff },
+       };
+       struct ubt_hci_event_command_compl *evt;
+       usb_error_t error;
+       uint8_t status, datalen, type, len, img_type = 0;
+       uint8_t *data;
+
+       evt = malloc(UBT_INTEL_MAX_EVT_SIZE, M_TEMP, M_ZERO | M_WAITOK);
+       evt->header.length =
+           UBT_INTEL_MAX_EVT_SIZE - sizeof(struct ubt_hci_evhdr);
+
+       error = ubt_do_hci_request(udev, &cmd, evt, UBT_INTEL_HCICMD_TIMEOUT);
+       if (error != USB_ERR_NORMAL_COMPLETION)
+               goto exit;
+
+       datalen = evt->header.length - UBT_HCI_EVENT_COMPL_HEAD_SIZE;
+       data = evt->data;
+       status = *data++;
+       if (status != 0)
+               goto exit;
+       datalen--;
+
+       while (datalen >= 2) {
+               type = *data++;
+               len = *data++;
+               datalen -= 2;
+               if (datalen < len)
+                       break;
+               if (type == UBT_INTEL_TLV_IMAGE_TYPE && len == 1) {
+                       img_type = *data;
+                       break;
+               }
+               datalen -= len;
+               data += len;
+       }
+exit:
+       free(evt, M_TEMP);
+       return (img_type);
+}
+
 /*
  * Probe for a Intel Wireless Bluetooth device.
  */
@@ -139,6 +193,7 @@ ubt_intel_probe(device_t dev)
        struct ubt_intel_version_rp version;
        ng_hci_reset_rp reset;
        int error;
+       uint8_t img_type;
 
        if (uaa->usb_mode != USB_MODE_HOST)
                return (ENXIO);
@@ -193,6 +248,18 @@ ubt_intel_probe(device_t dev)
                        return (ENXIO);
                break;
 
+       case UBT_INTEL_DEVICE_9260:
+               /*
+                * Find if the Intel Wireless 9260/9560 device is in bootloader
+                * mode or is running operational firmware with checking of
+                * image type byte of "Intel version" HCI command response.
+                * The value 0x03 identifies the operational firmware.
+                */
+               img_type = ubt_intel_get_img_type(uaa->device);
+               if (img_type != 0x03)
+                       return (ENXIO);
+               break;
+
        default:
                KASSERT(0 == 1, ("Unknown DRIVER_INFO"));
        }

Reply via email to