Bluetooth Connection Issues on Nvidia Jetson Orin Devices

Issue Overview

Users of Nvidia Jetson Orin devices (including Orin Nano, NX, and AGX) are experiencing severe issues when attempting to connect Bluetooth devices, particularly low-energy (BLE) devices. The problem manifests as system freezes, kernel panics, and automatic reboots when trying to pair or connect certain Bluetooth peripherals. This issue has been reported across multiple Jetpack versions, including 5.0.1, 5.0.2, 5.1.1, and 5.1.2, affecting a wide range of users and impeding the use of Bluetooth functionality on these devices.

Possible Causes

  1. Kernel-level bug: The primary cause appears to be a bug in the kernel’s Elliptic Curve Cryptography (ECC) implementation, specifically related to the NIST P256 curve used in Bluetooth pairing.

  2. Uninitialized data structures: The curve struct in the kernel’s ECC implementation is partially uninitialized, leading to NULL pointers for curve->a and curve->b.

  3. Incomplete code migration: When separating ECC and ECDH code, Nvidia developers failed to include the updated NIST P256 curve parameters (a and b) in their modified code.

  4. Device-specific incompatibilities: Some users report issues with specific devices like Logitech MX Master 3S mouse, Logitech MX Keys keyboard, and gaming controllers (Xbox, Stadia).

  5. Low-energy (BLE) device sensitivity: The issue seems more prevalent with BLE devices, possibly due to the CONFIG_BT_LE flag not being set in the kernel build.

Troubleshooting Steps, Solutions & Fixes

  1. Apply the kernel patch:
    The most effective solution is to apply a patch to the kernel’s ECC implementation. Here’s how to do it:

    a. Locate the file crypto/ecc.c in your kernel source.
    b. Apply the following patch:

    diff --git a/crypto/ecc.c b/crypto/ecc.c
    index ee0e044403f6..6ee23f0bee32 100644
    --- a/crypto/ecc.c
    +++ b/crypto/ecc.c
    @@ -50,6 +50,10 @@ static u64 nist_p192_p[] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFEull,
                                    0xFFFFFFFFFFFFFFFFull };
     static u64 nist_p192_n[] = { 0x146BC9B1B4D22831ull, 0xFFFFFFFF99DEF836ull,
                                    0xFFFFFFFFFFFFFFFFull };
    +static u64 nist_p192_a[] = { 0xFFFFFFFFFFFFFFFCull, 0xFFFFFFFFFFFFFFFEull,
    +                               0xFFFFFFFFFFFFFFFFull };
    +static u64 nist_p192_b[] = { 0xFEB8DEECC146B9B1ull, 0x0FA7E9AB72243049ull,
    +                               0x64210519E59C80E7ull };
     static struct ecc_curve nist_p192 = {
            .name = "nist_192",
            .g = {
    @@ -58,7 +62,9 @@ static struct ecc_curve nist_p192 = {
                    .ndigits = 3,
            },
            .p = nist_p192_p,
    -       .n = nist_p192_n
    +       .n = nist_p192_n,
    +       .a = nist_p192_a,
    +       .b = nist_p192_b
     };
     
     /* NIST P-256 */
    @@ -70,6 +76,10 @@ static u64 nist_p256_p[] = { 0xFFFFFFFFFFFFFFFFull, 0x00000000FFFFFFFFull,
                                    0x0000000000000000ull, 0xFFFFFFFF00000001ull };
     static u64 nist_p256_n[] = { 0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull,
                                    0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00000000ull };
    +static u64 nist_p256_a[] = { 0xFFFFFFFFFFFFFFFCull, 0x00000000FFFFFFFFull,
    +                               0x0000000000000000ull, 0xFFFFFFFF00000001ull };
    +static u64 nist_p256_b[] = { 0x3BCE3C3E27D2604Bull, 0x651D06B0CC53B0F6ull,
    +                               0xB3EBBD55769886BCull, 0x5AC635D8AA3A93E7ull };
     static struct ecc_curve nist_p256 = {
            .name = "nist_256",
            .g = {
    @@ -78,7 +88,9 @@ static struct ecc_curve nist_p256 = {
                    .ndigits = 4,
            },
            .p = nist_p256_p,
    -       .n = nist_p256_n
    +       .n = nist_p256_n,
    +       .a = nist_p256_a,
    +       .b = nist_p256_b
     };
     
     /* BrainPool P-256 */
    

    c. Rebuild the kernel.
    d. Copy the new Image file to /boot.
    e. Reboot the device.

  2. Temporary workaround (not recommended for production):
    If you can’t immediately patch and rebuild the kernel, you can add a check in the ecc_is_pubkey_valid_partial function to prevent kernel crashes:

    int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
                                    struct ecc_point *pk)
    {
        if (!curve->p || !pk->x || !pk->y || !curve->a || !curve->b)
        {
            pr_err("NULL pointer within data structures passed to ecc_is_pubkey_valid_partial: curve->p=%p, pk->x=%p, pk->y=%p, curve->a=%p, curve->b=%p\n",
            curve->p, pk->x, pk->y, curve->a, curve->b);
            return -EINVAL;
        }
        // ... rest of the function
    }
    
  3. Test with different Bluetooth adapters:
    Some users reported success using external USB Bluetooth adapters. Try using a different adapter to isolate whether the issue is specific to the onboard Bluetooth.

  4. Update to the latest Jetpack version:
    Ensure you’re running the latest available Jetpack version for your Jetson Orin device. While this may not solve the issue entirely, it could potentially include other bug fixes or improvements.

  5. Collect diagnostic information:
    If you’re still experiencing issues after applying the patch, collect the following information to assist in further troubleshooting:

    • Kernel logs (use dmesg or journalctl)
    • Bluetooth controller logs (use btmon)
    • List of Bluetooth devices that cause the issue
    • Jetpack version and kernel version
  6. Report the issue:
    If the problem persists after applying the patch, report it to Nvidia’s developer forums with the collected diagnostic information. This will help the Nvidia team to further investigate and potentially provide additional fixes.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *