summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMuhammad Saheed <muhammad.saheed.iam@gmail.com>2026-08-05 01:40:51 +0530
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2026-08-07 15:40:28 -0400
commit75722cde87ee24029e93e4e32d85309989f55991 (patch)
tree84f9746d44f6ab798a78d81179e7a3a428e01e63
parente3643fbddb257c928c075cab05bbd929106b56ee (diff)
downloadlinux-75722cde87ee24029e93e4e32d85309989f55991.tar.gz
linux-75722cde87ee24029e93e4e32d85309989f55991.zip
Bluetooth: hci_sync: Disable legacy instance's ext adv before setup snapshot
hci_setup_ext_adv_instance_sync(...) only disabled HCI_OP_LE_SET_EXT_ADV_ENABLE before setup snapshot in case of non-legacy instances (instance > 0) and never disabled the same for legacy instance (instance == 0). This would lead to failure in setting ext adv params with HCI_ERROR_COMMAND_DISALLOWED (0x0c) error like below, when toggling the discoverable/connectable property of a controller with advertising enabled. ``` $ btmgmt advertising off hci0 Set Advertising complete, settings: powered ssp br/edr le secure-conn wide-band-speech cis-central cis-peripheral $ btmgmt connectable on hci0 Set Connectable complete, settings: powered connectable ssp br/edr le secure-conn wide-band-speech cis-central cis-peripheral $ btmgmt connectable off hci0 Set Connectable complete, settings: powered ssp br/edr le secure-conn wide-band-speech cis-central cis-peripheral $ btmgmt advertising on hci0 Set Advertising complete, settings: powered connectable ssp br/edr le advertising secure-conn wide-band-speech cis-central cis-peripheral $ btmgmt connectable on Set Connectable for hci0 failed with status 0x0a (Busy) $ btmgmt connectable off Set Connectable for hci0 failed with status 0x0a (Busy) $ dmesg ... [ 21.970527] hci0: Opcode 0x2036 [ 21.970529] hci0: opcode 0x2036 plen 25 [ 21.970537] hci0: skb len 28 [ 21.970539] hci0: length 1 [ 21.976099] hci0: result 0x0c [ 21.976105] hci0: end: err -16 [ 21.976114] Bluetooth: hci0: Opcode 0x2036 failed: -16 ``` Signed-off-by: Muhammad Saheed <muhammad.saheed.iam@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
-rw-r--r--net/bluetooth/hci_sync.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index df2d037970f9..b5897545d795 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -1150,6 +1150,32 @@ int hci_update_random_address_sync(struct hci_dev *hdev, bool require_privacy,
return 0;
}
+static int hci_disable_ext_adv_legacy_instance_sync(struct hci_dev *hdev)
+{
+ struct hci_cp_le_set_ext_adv_enable *cp;
+ struct hci_cp_ext_adv_set *set;
+ u8 data[sizeof(*cp) + sizeof(*set) * 1];
+ u8 size;
+
+ if (!hci_dev_test_flag(hdev, HCI_LE_ADV_0))
+ return 0;
+
+ memset(data, 0, sizeof(data));
+
+ cp = (void *)data;
+ set = (void *)cp->data;
+
+ cp->num_of_sets = 0x01;
+ cp->enable = 0x00;
+
+ set->handle = 0x00;
+
+ size = sizeof(*cp) + sizeof(*set) * cp->num_of_sets;
+
+ return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE,
+ size, data, HCI_CMD_TIMEOUT);
+}
+
static int hci_disable_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
{
struct hci_cp_le_set_ext_adv_enable *cp;
@@ -1375,6 +1401,10 @@ int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
return -EINVAL;
}
} else {
+ err = hci_disable_ext_adv_legacy_instance_sync(hdev);
+ if (err)
+ return err;
+
adv = NULL;
}