Bluetooth: HCI: Invert LE State quirk to be opt-out rather then opt-in

This inverts the LE State quirk so by default we assume the controllers
would report valid states rather than invalid which is how quirks
normally behave, also this would result in HCI command failing it the LE
States are really broken thus exposing the controllers that are really
broken in this respect.

Link: https://github.com/bluez/bluez/issues/584
Fixes: 22091585 ("Bluetooth: Adding driver and quirk defs for multi-role LE")
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 9c5af2d7
...@@ -2945,9 +2945,6 @@ static int btintel_setup_combined(struct hci_dev *hdev) ...@@ -2945,9 +2945,6 @@ static int btintel_setup_combined(struct hci_dev *hdev)
INTEL_ROM_LEGACY_NO_WBS_SUPPORT)) INTEL_ROM_LEGACY_NO_WBS_SUPPORT))
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
&hdev->quirks); &hdev->quirks);
if (ver.hw_variant == 0x08 && ver.fw_variant == 0x22)
set_bit(HCI_QUIRK_VALID_LE_STATES,
&hdev->quirks);
err = btintel_legacy_rom_setup(hdev, &ver); err = btintel_legacy_rom_setup(hdev, &ver);
break; break;
...@@ -2956,7 +2953,6 @@ static int btintel_setup_combined(struct hci_dev *hdev) ...@@ -2956,7 +2953,6 @@ static int btintel_setup_combined(struct hci_dev *hdev)
case 0x12: /* ThP */ case 0x12: /* ThP */
case 0x13: /* HrP */ case 0x13: /* HrP */
case 0x14: /* CcP */ case 0x14: /* CcP */
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
fallthrough; fallthrough;
case 0x0c: /* WsP */ case 0x0c: /* WsP */
/* Apply the device specific HCI quirks /* Apply the device specific HCI quirks
...@@ -3048,9 +3044,6 @@ static int btintel_setup_combined(struct hci_dev *hdev) ...@@ -3048,9 +3044,6 @@ static int btintel_setup_combined(struct hci_dev *hdev)
/* These variants don't seem to support LE Coded PHY */ /* These variants don't seem to support LE Coded PHY */
set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks); set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks);
/* Set Valid LE States quirk */
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
/* Setup MSFT Extension support */ /* Setup MSFT Extension support */
btintel_set_msft_opcode(hdev, ver.hw_variant); btintel_set_msft_opcode(hdev, ver.hw_variant);
...@@ -3076,9 +3069,6 @@ static int btintel_setup_combined(struct hci_dev *hdev) ...@@ -3076,9 +3069,6 @@ static int btintel_setup_combined(struct hci_dev *hdev)
*/ */
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
/* Apply LE States quirk from solar onwards */
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
/* Setup MSFT Extension support */ /* Setup MSFT Extension support */
btintel_set_msft_opcode(hdev, btintel_set_msft_opcode(hdev,
INTEL_HW_VARIANT(ver_tlv.cnvi_bt)); INTEL_HW_VARIANT(ver_tlv.cnvi_bt));
......
...@@ -1180,9 +1180,6 @@ static int btintel_pcie_setup(struct hci_dev *hdev) ...@@ -1180,9 +1180,6 @@ static int btintel_pcie_setup(struct hci_dev *hdev)
*/ */
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
/* Apply LE States quirk from solar onwards */
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
/* Setup MSFT Extension support */ /* Setup MSFT Extension support */
btintel_set_msft_opcode(hdev, btintel_set_msft_opcode(hdev,
INTEL_HW_VARIANT(ver_tlv.cnvi_bt)); INTEL_HW_VARIANT(ver_tlv.cnvi_bt));
......
...@@ -1148,9 +1148,6 @@ static int btmtksdio_setup(struct hci_dev *hdev) ...@@ -1148,9 +1148,6 @@ static int btmtksdio_setup(struct hci_dev *hdev)
} }
} }
/* Valid LE States quirk for MediaTek 7921 */
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
break; break;
case 0x7663: case 0x7663:
case 0x7668: case 0x7668:
......
...@@ -1287,7 +1287,6 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev) ...@@ -1287,7 +1287,6 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
case CHIP_ID_8852C: case CHIP_ID_8852C:
case CHIP_ID_8851B: case CHIP_ID_8851B:
case CHIP_ID_8852BT: case CHIP_ID_8852BT:
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
/* RTL8852C needs to transmit mSBC data continuously without /* RTL8852C needs to transmit mSBC data continuously without
......
...@@ -3956,8 +3956,8 @@ static int btusb_probe(struct usb_interface *intf, ...@@ -3956,8 +3956,8 @@ static int btusb_probe(struct usb_interface *intf,
if (id->driver_info & BTUSB_WIDEBAND_SPEECH) if (id->driver_info & BTUSB_WIDEBAND_SPEECH)
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
if (id->driver_info & BTUSB_VALID_LE_STATES) if (!(id->driver_info & BTUSB_VALID_LE_STATES))
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); set_bit(HCI_QUIRK_BROKEN_LE_STATES, &hdev->quirks);
if (id->driver_info & BTUSB_DIGIANSWER) { if (id->driver_info & BTUSB_DIGIANSWER) {
data->cmdreq_type = USB_TYPE_VENDOR; data->cmdreq_type = USB_TYPE_VENDOR;
......
...@@ -2474,8 +2474,8 @@ static int qca_serdev_probe(struct serdev_device *serdev) ...@@ -2474,8 +2474,8 @@ static int qca_serdev_probe(struct serdev_device *serdev)
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
&hdev->quirks); &hdev->quirks);
if (data->capabilities & QCA_CAP_VALID_LE_STATES) if (!(data->capabilities & QCA_CAP_VALID_LE_STATES))
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); set_bit(HCI_QUIRK_BROKEN_LE_STATES, &hdev->quirks);
} }
return 0; return 0;
......
...@@ -425,8 +425,6 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode) ...@@ -425,8 +425,6 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
if (opcode & 0x80) if (opcode & 0x80)
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
if (hci_register_dev(hdev) < 0) { if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device"); BT_ERR("Can't register HCI device");
hci_free_dev(hdev); hci_free_dev(hdev);
......
...@@ -206,14 +206,17 @@ enum { ...@@ -206,14 +206,17 @@ enum {
*/ */
HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
/* When this quirk is set, the controller has validated that /* When this quirk is set, the LE states reported through the
* LE states reported through the HCI_LE_READ_SUPPORTED_STATES are * HCI_LE_READ_SUPPORTED_STATES are invalid/broken.
* valid. This mechanism is necessary as many controllers have *
* been seen has having trouble initiating a connectable * This mechanism is necessary as many controllers have been seen has
* advertisement despite the state combination being reported as * having trouble initiating a connectable advertisement despite the
* supported. * state combination being reported as supported.
*
* This quirk can be set before hci_register_dev is called or
* during the hdev->setup vendor callback.
*/ */
HCI_QUIRK_VALID_LE_STATES, HCI_QUIRK_BROKEN_LE_STATES,
/* When this quirk is set, then erroneous data reporting /* When this quirk is set, then erroneous data reporting
* is ignored. This is mainly due to the fact that the HCI * is ignored. This is mainly due to the fact that the HCI
......
...@@ -825,7 +825,7 @@ extern struct mutex hci_cb_list_lock; ...@@ -825,7 +825,7 @@ extern struct mutex hci_cb_list_lock;
} while (0) } while (0)
#define hci_dev_le_state_simultaneous(hdev) \ #define hci_dev_le_state_simultaneous(hdev) \
(test_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks) && \ (!test_bit(HCI_QUIRK_BROKEN_LE_STATES, &hdev->quirks) && \
(hdev->le_states[4] & 0x08) && /* Central */ \ (hdev->le_states[4] & 0x08) && /* Central */ \
(hdev->le_states[4] & 0x40) && /* Peripheral */ \ (hdev->le_states[4] & 0x40) && /* Peripheral */ \
(hdev->le_states[3] & 0x10)) /* Simultaneous */ (hdev->le_states[3] & 0x10)) /* Simultaneous */
......
...@@ -5920,7 +5920,7 @@ static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev, ...@@ -5920,7 +5920,7 @@ static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
* while we have an existing one in peripheral role. * while we have an existing one in peripheral role.
*/ */
if (hdev->conn_hash.le_num_peripheral > 0 && if (hdev->conn_hash.le_num_peripheral > 0 &&
(!test_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks) || (test_bit(HCI_QUIRK_BROKEN_LE_STATES, &hdev->quirks) ||
!(hdev->le_states[3] & 0x10))) !(hdev->le_states[3] & 0x10)))
return NULL; return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment