Bluetooth: Add hardware error MGMT event
[platform/kernel/linux-starfive.git] / net / bluetooth / hci_event.c
index 6643c9c..db3a2ea 100644 (file)
@@ -712,6 +712,47 @@ static u8 hci_cc_read_local_version(struct hci_dev *hdev, void *data,
        return rp->status;
 }
 
+static u8 hci_cc_read_enc_key_size(struct hci_dev *hdev, void *data,
+                                  struct sk_buff *skb)
+{
+       struct hci_rp_read_enc_key_size *rp = data;
+       struct hci_conn *conn;
+       u16 handle;
+       u8 status = rp->status;
+
+       bt_dev_dbg(hdev, "status 0x%2.2x", status);
+
+       handle = le16_to_cpu(rp->handle);
+
+       hci_dev_lock(hdev);
+
+       conn = hci_conn_hash_lookup_handle(hdev, handle);
+       if (!conn) {
+               status = 0xFF;
+               goto done;
+       }
+
+       /* While unexpected, the read_enc_key_size command may fail. The most
+        * secure approach is to then assume the key size is 0 to force a
+        * disconnection.
+        */
+       if (status) {
+               bt_dev_err(hdev, "failed to read key size for handle %u",
+                          handle);
+               conn->enc_key_size = 0;
+       } else {
+               conn->enc_key_size = rp->key_size;
+               status = 0;
+       }
+
+       hci_encrypt_cfm(conn, 0);
+
+done:
+       hci_dev_unlock(hdev);
+
+       return status;
+}
+
 static u8 hci_cc_read_local_commands(struct hci_dev *hdev, void *data,
                                     struct sk_buff *skb)
 {
@@ -840,8 +881,13 @@ static u8 hci_cc_read_local_ext_features(struct hci_dev *hdev, void *data,
        if (rp->status)
                return rp->status;
 
-       if (hdev->max_page < rp->max_page)
-               hdev->max_page = rp->max_page;
+       if (hdev->max_page < rp->max_page) {
+               if (test_bit(HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2,
+                            &hdev->quirks))
+                       bt_dev_warn(hdev, "broken local ext features page 2");
+               else
+                       hdev->max_page = rp->max_page;
+       }
 
        if (rp->page < HCI_MAX_PAGES)
                memcpy(hdev->features[rp->page], rp->features, 8);
@@ -1715,6 +1761,8 @@ static void le_set_scan_enable_complete(struct hci_dev *hdev, u8 enable)
                hci_dev_set_flag(hdev, HCI_LE_SCAN);
                if (hdev->le_scan_type == LE_SCAN_ACTIVE)
                        clear_pending_adv_report(hdev);
+               if (hci_dev_test_flag(hdev, HCI_MESH))
+                       hci_discovery_set_state(hdev, DISCOVERY_FINDING);
                break;
 
        case LE_SCAN_DISABLE:
@@ -1729,7 +1777,7 @@ static void le_set_scan_enable_complete(struct hci_dev *hdev, u8 enable)
                                          d->last_adv_addr_type, NULL,
                                          d->last_adv_rssi, d->last_adv_flags,
                                          d->last_adv_data,
-                                         d->last_adv_data_len, NULL, 0);
+                                         d->last_adv_data_len, NULL, 0, 0);
                }
 
                /* Cancel this timer so that we don't try to disable scanning
@@ -1744,7 +1792,14 @@ static void le_set_scan_enable_complete(struct hci_dev *hdev, u8 enable)
                 * therefore discovery as stopped.
                 */
                if (hci_dev_test_and_clear_flag(hdev, HCI_LE_SCAN_INTERRUPTED))
+#ifndef TIZEN_BT /* The below line is kernel bug. */
                        hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+#else
+                       hci_le_discovery_set_state(hdev, DISCOVERY_STOPPED);
+#endif
+               else if (!hci_dev_test_flag(hdev, HCI_LE_ADV) &&
+                        hdev->discovery.state == DISCOVERY_FINDING)
+                       queue_work(hdev->workqueue, &hdev->reenable_adv_work);
 
                break;
 
@@ -2152,13 +2207,86 @@ static u8 hci_cc_set_ext_adv_param(struct hci_dev *hdev, void *data,
                        adv_instance->tx_power = rp->tx_power;
        }
        /* Update adv data as tx power is known now */
-       hci_req_update_adv_data(hdev, cp->handle);
+       hci_update_adv_data(hdev, cp->handle);
 
        hci_dev_unlock(hdev);
 
        return rp->status;
 }
 
+#ifdef TIZEN_BT
+static u8 hci_cc_enable_rssi(struct hci_dev *hdev, void *data,
+                            struct sk_buff *skb)
+{
+       struct hci_cc_rsp_enable_rssi *rp = data;
+
+       BT_DBG("hci_cc_enable_rssi - %s status 0x%2.2x Event_LE_ext_Opcode 0x%2.2x",
+              hdev->name, rp->status, rp->le_ext_opcode);
+
+       mgmt_enable_rssi_cc(hdev, rp, rp->status);
+
+       return rp->status;
+}
+
+static u8 hci_cc_get_raw_rssi(struct hci_dev *hdev, void *data,
+                             struct sk_buff *skb)
+{
+       struct hci_cc_rp_get_raw_rssi *rp = data;
+
+       BT_DBG("hci_cc_get_raw_rssi- %s Get Raw Rssi Response[%2.2x %4.4x %2.2X]",
+              hdev->name, rp->status, rp->conn_handle, rp->rssi_dbm);
+
+       mgmt_raw_rssi_response(hdev, rp, rp->status);
+
+       return rp->status;
+}
+
+static void hci_vendor_specific_group_ext_evt(struct hci_dev *hdev,
+                                             struct sk_buff *skb)
+{
+       struct hci_ev_ext_vendor_specific *ev = (void *)skb->data;
+       __u8 event_le_ext_sub_code;
+
+       BT_DBG("RSSI event LE_META_VENDOR_SPECIFIC_GROUP_EVENT: %X",
+              LE_META_VENDOR_SPECIFIC_GROUP_EVENT);
+
+       skb_pull(skb, sizeof(*ev));
+       event_le_ext_sub_code = ev->event_le_ext_sub_code;
+
+       switch (event_le_ext_sub_code) {
+       case LE_RSSI_LINK_ALERT:
+               BT_DBG("RSSI event LE_RSSI_LINK_ALERT %X",
+                      LE_RSSI_LINK_ALERT);
+               mgmt_rssi_alert_evt(hdev, skb);
+               break;
+
+       default:
+               break;
+       }
+}
+
+static void hci_vendor_specific_evt(struct hci_dev *hdev, void *data,
+                                   struct sk_buff *skb)
+{
+       struct hci_ev_vendor_specific *ev = (void *)skb->data;
+       __u8 event_sub_code;
+
+       BT_DBG("hci_vendor_specific_evt");
+
+       skb_pull(skb, sizeof(*ev));
+       event_sub_code = ev->event_sub_code;
+
+       switch (event_sub_code) {
+       case LE_META_VENDOR_SPECIFIC_GROUP_EVENT:
+               hci_vendor_specific_group_ext_evt(hdev, skb);
+               break;
+
+       default:
+               break;
+       }
+}
+#endif
+
 static u8 hci_cc_read_rssi(struct hci_dev *hdev, void *data,
                           struct sk_buff *skb)
 {
@@ -2443,15 +2571,25 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
        struct discovery_state *discov = &hdev->discovery;
        struct inquiry_entry *e;
 
+#ifdef TIZEN_BT
        /* Update the mgmt connected state if necessary. Be careful with
         * conn objects that exist but are not (yet) connected however.
         * Only those in BT_CONFIG or BT_CONNECTED states can be
         * considered connected.
         */
        if (conn &&
+           (conn->state == BT_CONFIG || conn->state == BT_CONNECTED)) {
+               if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
+                       mgmt_device_connected(hdev, conn, 0, name, name_len);
+               else
+                       mgmt_device_name_update(hdev, bdaddr, name, name_len);
+       }
+#else
+       if (conn &&
            (conn->state == BT_CONFIG || conn->state == BT_CONNECTED) &&
            !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
                mgmt_device_connected(hdev, conn, name, name_len);
+#endif
 
        if (discov->state == DISCOVERY_STOPPED)
                return;
@@ -2830,16 +2968,6 @@ static void cs_le_create_conn(struct hci_dev *hdev, bdaddr_t *peer_addr,
 
        conn->resp_addr_type = peer_addr_type;
        bacpy(&conn->resp_addr, peer_addr);
-
-       /* We don't want the connection attempt to stick around
-        * indefinitely since LE doesn't have a page timeout concept
-        * like BR/EDR. Set a timer for any connection that doesn't use
-        * the accept list for connecting.
-        */
-       if (filter_policy == HCI_LE_USE_PEER_ADDR)
-               queue_delayed_work(conn->hdev->workqueue,
-                                  &conn->le_conn_timeout,
-                                  conn->conn_timeout);
 }
 
 static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
@@ -3071,7 +3199,7 @@ static void hci_inquiry_result_evt(struct hci_dev *hdev, void *edata,
 
                mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
                                  info->dev_class, HCI_RSSI_INVALID,
-                                 flags, NULL, 0, NULL, 0);
+                                 flags, NULL, 0, NULL, 0, 0);
        }
 
        hci_dev_unlock(hdev);
@@ -3534,47 +3662,6 @@ unlock:
        hci_dev_unlock(hdev);
 }
 
-static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status,
-                                      u16 opcode, struct sk_buff *skb)
-{
-       const struct hci_rp_read_enc_key_size *rp;
-       struct hci_conn *conn;
-       u16 handle;
-
-       BT_DBG("%s status 0x%02x", hdev->name, status);
-
-       if (!skb || skb->len < sizeof(*rp)) {
-               bt_dev_err(hdev, "invalid read key size response");
-               return;
-       }
-
-       rp = (void *)skb->data;
-       handle = le16_to_cpu(rp->handle);
-
-       hci_dev_lock(hdev);
-
-       conn = hci_conn_hash_lookup_handle(hdev, handle);
-       if (!conn)
-               goto unlock;
-
-       /* While unexpected, the read_enc_key_size command may fail. The most
-        * secure approach is to then assume the key size is 0 to force a
-        * disconnection.
-        */
-       if (rp->status) {
-               bt_dev_err(hdev, "failed to read key size for handle %u",
-                          handle);
-               conn->enc_key_size = 0;
-       } else {
-               conn->enc_key_size = rp->key_size;
-       }
-
-       hci_encrypt_cfm(conn, 0);
-
-unlock:
-       hci_dev_unlock(hdev);
-}
-
 static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
                                   struct sk_buff *skb)
 {
@@ -3639,7 +3726,6 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
        /* Try reading the encryption key size for encrypted ACL links */
        if (!ev->status && ev->encrypt && conn->type == ACL_LINK) {
                struct hci_cp_read_enc_key_size cp;
-               struct hci_request req;
 
                /* Only send HCI_Read_Encryption_Key_Size if the
                 * controller really supports it. If it doesn't, assume
@@ -3650,12 +3736,9 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
                        goto notify;
                }
 
-               hci_req_init(&req, hdev);
-
                cp.handle = cpu_to_le16(conn->handle);
-               hci_req_add(&req, HCI_OP_READ_ENC_KEY_SIZE, sizeof(cp), &cp);
-
-               if (hci_req_run_skb(&req, read_enc_key_size_complete)) {
+               if (hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE,
+                                sizeof(cp), &cp)) {
                        bt_dev_err(hdev, "sending read key size failed");
                        conn->enc_key_size = HCI_LINK_KEY_SIZE;
                        goto notify;
@@ -3766,16 +3849,18 @@ static inline void handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd)
 {
        cancel_delayed_work(&hdev->cmd_timer);
 
+       rcu_read_lock();
        if (!test_bit(HCI_RESET, &hdev->flags)) {
                if (ncmd) {
                        cancel_delayed_work(&hdev->ncmd_timer);
                        atomic_set(&hdev->cmd_cnt, 1);
                } else {
                        if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
-                               schedule_delayed_work(&hdev->ncmd_timer,
-                                                     HCI_NCMD_TIMEOUT);
+                               queue_delayed_work(hdev->workqueue, &hdev->ncmd_timer,
+                                                  HCI_NCMD_TIMEOUT);
                }
        }
+       rcu_read_unlock();
 }
 
 static u8 hci_cc_le_read_buffer_size_v2(struct hci_dev *hdev, void *data,
@@ -3835,8 +3920,11 @@ static u8 hci_cc_le_set_cig_params(struct hci_dev *hdev, void *data,
                           conn->handle, conn->link);
 
                /* Create CIS if LE is already connected */
-               if (conn->link && conn->link->state == BT_CONNECTED)
+               if (conn->link && conn->link->state == BT_CONNECTED) {
+                       rcu_read_unlock();
                        hci_le_create_cis(conn->link);
+                       rcu_read_lock();
+               }
 
                if (i == rp->num_handles)
                        break;
@@ -4037,6 +4125,8 @@ static const struct hci_cc {
               sizeof(struct hci_rp_read_local_amp_info)),
        HCI_CC(HCI_OP_READ_CLOCK, hci_cc_read_clock,
               sizeof(struct hci_rp_read_clock)),
+       HCI_CC(HCI_OP_READ_ENC_KEY_SIZE, hci_cc_read_enc_key_size,
+              sizeof(struct hci_rp_read_enc_key_size)),
        HCI_CC(HCI_OP_READ_INQ_RSP_TX_POWER, hci_cc_read_inq_rsp_tx_power,
               sizeof(struct hci_rp_read_inq_rsp_tx_power)),
        HCI_CC(HCI_OP_READ_DEF_ERR_DATA_REPORTING,
@@ -4125,6 +4215,12 @@ static const struct hci_cc {
                      hci_cc_le_set_per_adv_enable),
        HCI_CC(HCI_OP_LE_READ_TRANSMIT_POWER, hci_cc_le_read_transmit_power,
               sizeof(struct hci_rp_le_read_transmit_power)),
+#ifdef TIZEN_BT
+       HCI_CC(HCI_OP_ENABLE_RSSI, hci_cc_enable_rssi,
+              sizeof(struct hci_cc_rsp_enable_rssi)),
+       HCI_CC(HCI_OP_GET_RAW_RSSI, hci_cc_get_raw_rssi,
+              sizeof(struct hci_cc_rp_get_raw_rssi)),
+#endif
        HCI_CC_STATUS(HCI_OP_LE_SET_PRIVACY_MODE, hci_cc_le_set_privacy_mode),
        HCI_CC(HCI_OP_LE_READ_BUFFER_SIZE_V2, hci_cc_le_read_buffer_size_v2,
               sizeof(struct hci_rp_le_read_buffer_size_v2)),
@@ -4322,6 +4418,11 @@ static void hci_hardware_error_evt(struct hci_dev *hdev, void *data,
 
        bt_dev_dbg(hdev, "code 0x%2.2x", ev->code);
 
+#ifdef TIZEN_BT
+       hci_dev_lock(hdev);
+       mgmt_hardware_error(hdev, ev->code);
+       hci_dev_unlock(hdev);
+#endif
        hdev->hw_error_code = ev->code;
 
        queue_work(hdev->req_workqueue, &hdev->error_reset);
@@ -4829,7 +4930,7 @@ static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, void *edata,
 
                        mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
                                          info->dev_class, info->rssi,
-                                         flags, NULL, 0, NULL, 0);
+                                         flags, NULL, 0, NULL, 0, 0);
                }
        } else if (skb->len == array_size(ev->num,
                                          sizeof(struct inquiry_info_rssi))) {
@@ -4860,7 +4961,7 @@ static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, void *edata,
 
                        mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
                                          info->dev_class, info->rssi,
-                                         flags, NULL, 0, NULL, 0);
+                                         flags, NULL, 0, NULL, 0, 0);
                }
        } else {
                bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x",
@@ -5116,7 +5217,7 @@ static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, void *edata,
 
                mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
                                  info->dev_class, info->rssi,
-                                 flags, info->data, eir_len, NULL, 0);
+                                 flags, info->data, eir_len, NULL, 0, 0);
        }
 
        hci_dev_unlock(hdev);
@@ -5884,6 +5985,12 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
        if (status)
                goto unlock;
 
+       /* Drop the connection if it has been aborted */
+       if (test_bit(HCI_CONN_CANCEL, &conn->flags)) {
+               hci_conn_drop(conn);
+               goto unlock;
+       }
+
        if (conn->dst_type == ADDR_LE_DEV_PUBLIC)
                addr_type = BDADDR_LE_PUBLIC;
        else
@@ -6069,12 +6176,26 @@ static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, void *data,
 
        conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
        if (conn) {
+#ifdef TIZEN_BT
+               if (ev->status) {
+                       hci_dev_unlock(hdev);
+                       mgmt_le_conn_update_failed(hdev, &conn->dst,
+                               conn->type, conn->dst_type, ev->status);
+                       return;
+               }
+#endif
                conn->le_conn_interval = le16_to_cpu(ev->interval);
                conn->le_conn_latency = le16_to_cpu(ev->latency);
                conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
        }
 
        hci_dev_unlock(hdev);
+
+#ifdef TIZEN_BT
+       mgmt_le_conn_updated(hdev, &conn->dst, conn->type,
+                               conn->dst_type, conn->le_conn_interval,
+                               conn->le_conn_latency, conn->le_supv_timeout);
+#endif
 }
 
 /* This function requires the caller holds hdev->lock */
@@ -6172,7 +6293,7 @@ static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
 static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
                               u8 bdaddr_type, bdaddr_t *direct_addr,
                               u8 direct_addr_type, s8 rssi, u8 *data, u8 len,
-                              bool ext_adv)
+                              bool ext_adv, bool ctl_time, u64 instant)
 {
        struct discovery_state *d = &hdev->discovery;
        struct smp_irk *irk;
@@ -6220,7 +6341,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
         * important to see if the address is matching the local
         * controller address.
         */
-       if (direct_addr) {
+       if (!hci_dev_test_flag(hdev, HCI_MESH) && direct_addr) {
                direct_addr_type = ev_bdaddr_type(hdev, direct_addr_type,
                                                  &bdaddr_resolved);
 
@@ -6268,6 +6389,18 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
                conn->le_adv_data_len = len;
        }
 
+       if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND)
+               flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
+       else
+               flags = 0;
+
+       /* All scan results should be sent up for Mesh systems */
+       if (hci_dev_test_flag(hdev, HCI_MESH)) {
+               mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
+                                 rssi, flags, data, len, NULL, 0, instant);
+               return;
+       }
+
        /* Passive scanning shouldn't trigger any device found events,
         * except for devices marked as CONN_REPORT for which we do send
         * device found events, or advertisement monitoring requested.
@@ -6281,35 +6414,23 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
                    idr_is_empty(&hdev->adv_monitors_idr))
                        return;
 
-               if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND)
-                       flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
-               else
-                       flags = 0;
                mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
-                                 rssi, flags, data, len, NULL, 0);
+                                 rssi, flags, data, len, NULL, 0, 0);
                return;
        }
 
-       /* When receiving non-connectable or scannable undirected
-        * advertising reports, this means that the remote device is
-        * not connectable and then clearly indicate this in the
-        * device found event.
-        *
-        * When receiving a scan response, then there is no way to
+       /* When receiving a scan response, then there is no way to
         * know if the remote device is connectable or not. However
         * since scan responses are merged with a previously seen
         * advertising report, the flags field from that report
         * will be used.
         *
-        * In the really unlikely case that a controller get confused
-        * and just sends a scan response event, then it is marked as
-        * not connectable as well.
+        * In the unlikely case that a controller just sends a scan
+        * response event that doesn't match the pending report, then
+        * it is marked as a standalone SCAN_RSP.
         */
-       if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND ||
-           type == LE_ADV_SCAN_RSP)
-               flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
-       else
-               flags = 0;
+       if (type == LE_ADV_SCAN_RSP)
+               flags = MGMT_DEV_FOUND_SCAN_RSP;
 
        /* If there's nothing pending either store the data from this
         * event or send an immediate device found event if the data
@@ -6326,7 +6447,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
                }
 
                mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
-                                 rssi, flags, data, len, NULL, 0);
+                                 rssi, flags, data, len, NULL, 0, 0);
                return;
        }
 
@@ -6345,7 +6466,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
                                          d->last_adv_addr_type, NULL,
                                          d->last_adv_rssi, d->last_adv_flags,
                                          d->last_adv_data,
-                                         d->last_adv_data_len, NULL, 0);
+                                         d->last_adv_data_len, NULL, 0, 0);
 
                /* If the new report will trigger a SCAN_REQ store it for
                 * later merging.
@@ -6362,7 +6483,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
                 */
                clear_pending_adv_report(hdev);
                mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
-                                 rssi, flags, data, len, NULL, 0);
+                                 rssi, flags, data, len, NULL, 0, 0);
                return;
        }
 
@@ -6372,7 +6493,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
         */
        mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
                          d->last_adv_addr_type, NULL, rssi, d->last_adv_flags,
-                         d->last_adv_data, d->last_adv_data_len, data, len);
+                         d->last_adv_data, d->last_adv_data_len, data, len, 0);
        clear_pending_adv_report(hdev);
 }
 
@@ -6380,6 +6501,7 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data,
                                  struct sk_buff *skb)
 {
        struct hci_ev_le_advertising_report *ev = data;
+       u64 instant = jiffies;
 
        if (!ev->num)
                return;
@@ -6404,7 +6526,8 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data,
                        rssi = info->data[info->length];
                        process_adv_report(hdev, info->type, &info->bdaddr,
                                           info->bdaddr_type, NULL, 0, rssi,
-                                          info->data, info->length, false);
+                                          info->data, info->length, false,
+                                          false, instant);
                } else {
                        bt_dev_err(hdev, "Dropping invalid advertising data");
                }
@@ -6461,6 +6584,7 @@ static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
                                      struct sk_buff *skb)
 {
        struct hci_ev_le_ext_adv_report *ev = data;
+       u64 instant = jiffies;
 
        if (!ev->num)
                return;
@@ -6487,7 +6611,8 @@ static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
                        process_adv_report(hdev, legacy_evt_type, &info->bdaddr,
                                           info->bdaddr_type, NULL, 0,
                                           info->rssi, info->data, info->length,
-                                          !(evt_type & LE_EXT_ADV_LEGACY_PDU));
+                                          !(evt_type & LE_EXT_ADV_LEGACY_PDU),
+                                          false, instant);
                }
        }
 
@@ -6710,6 +6835,7 @@ static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, void *data,
                                         struct sk_buff *skb)
 {
        struct hci_ev_le_direct_adv_report *ev = data;
+       u64 instant = jiffies;
        int i;
 
        if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_DIRECT_ADV_REPORT,
@@ -6727,7 +6853,7 @@ static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, void *data,
                process_adv_report(hdev, info->type, &info->bdaddr,
                                   info->bdaddr_type, &info->direct_addr,
                                   info->direct_addr_type, info->rssi, NULL, 0,
-                                  false);
+                                  false, false, instant);
        }
 
        hci_dev_unlock(hdev);
@@ -6776,6 +6902,13 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
                goto unlock;
        }
 
+       if (conn->type != ISO_LINK) {
+               bt_dev_err(hdev,
+                          "Invalid connection link type handle 0x%4.4x",
+                          handle);
+               goto unlock;
+       }
+
        if (conn->role == HCI_ROLE_SLAVE) {
                __le32 interval;
 
@@ -6896,6 +7029,13 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
        if (!conn)
                goto unlock;
 
+       if (conn->type != ISO_LINK) {
+               bt_dev_err(hdev,
+                          "Invalid connection link type handle 0x%2.2x",
+                          ev->handle);
+               goto unlock;
+       }
+
        if (ev->num_bis)
                conn->handle = __le16_to_cpu(ev->bis_handle[0]);
 
@@ -6953,7 +7093,7 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
                bis->iso_qos.in.latency = le16_to_cpu(ev->interval) * 125 / 100;
                bis->iso_qos.in.sdu = le16_to_cpu(ev->max_pdu);
 
-               hci_connect_cfm(bis, ev->status);
+               hci_iso_setup_path(bis);
        }
 
        hci_dev_unlock(hdev);
@@ -7402,8 +7542,14 @@ static const struct hci_ev {
        /* [0x48 = HCI_EV_NUM_COMP_BLOCKS] */
        HCI_EV(HCI_EV_NUM_COMP_BLOCKS, hci_num_comp_blocks_evt,
               sizeof(struct hci_ev_num_comp_blocks)),
+#ifdef TIZEN_BT
+       /* [0xFF = HCI_EV_VENDOR_SPECIFIC] */
+       HCI_EV(HCI_EV_VENDOR_SPECIFIC, hci_vendor_specific_evt,
+              sizeof(struct hci_ev_vendor_specific)),
+#else
        /* [0xff = HCI_EV_VENDOR] */
        HCI_EV_VL(HCI_EV_VENDOR, msft_vendor_evt, 0, HCI_MAX_EVENT_SIZE),
+#endif
 };
 
 static void hci_event_func(struct hci_dev *hdev, u8 event, struct sk_buff *skb,