diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index c055d16cfb8e..cad6ed5d8e51 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3015,8 +3015,25 @@ static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status) hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); - if (conn && conn->state == BT_CONFIG) + if (conn && conn->state == BT_CONFIG) { + /* If the local controller supports peripheral-initiated + * features exchange, but the remote controller does not, + * then the controller may already return the error code + * 0x1a for unsupported remote feature in the command + * status. + * + * Handle it as hci_le_remote_feat_complete_evt() does and + * allow the connection to transition into connected state. + */ + if (!conn->out && + status == HCI_ERROR_UNSUPPORTED_REMOTE_FEATURE && + (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES)) { + conn->state = BT_CONNECTED; + status = 0x00; + } + hci_connect_cfm(conn, status); + } hci_dev_unlock(hdev); } @@ -4113,8 +4130,17 @@ static void hci_cs_le_read_all_remote_features(struct hci_dev *hdev, u8 status) hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); - if (conn && conn->state == BT_CONFIG) + if (conn && conn->state == BT_CONFIG) { + /* See hci_cs_le_read_remote_features() */ + if (!conn->out && + status == HCI_ERROR_UNSUPPORTED_REMOTE_FEATURE && + (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES)) { + conn->state = BT_CONNECTED; + status = 0x00; + } + hci_connect_cfm(conn, status); + } hci_dev_unlock(hdev); }