]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/bluetooth/hci_core.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
[mirror_ubuntu-bionic-kernel.git] / net / bluetooth / hci_core.c
index 92a857e3786d173273986ba179f7e9bac1856af7..a8962382f9c55646538f1071c9cf6f539ceac1c2 100644 (file)
@@ -83,6 +83,7 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
         */
        if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) {
                struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
+               u16 opcode = __le16_to_cpu(sent->opcode);
                struct sk_buff *skb;
 
                /* Some CSR based controllers generate a spontaneous
@@ -92,7 +93,7 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
                 * command.
                 */
 
-               if (cmd != HCI_OP_RESET || sent->opcode == HCI_OP_RESET)
+               if (cmd != HCI_OP_RESET || opcode == HCI_OP_RESET)
                        return;
 
                skb = skb_clone(hdev->sent_cmd, GFP_ATOMIC);
@@ -251,6 +252,9 @@ static void amp_init(struct hci_dev *hdev)
 
        /* Read Local Version */
        hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
+
+       /* Read Local AMP Info */
+       hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
 }
 
 static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
@@ -384,7 +388,6 @@ void hci_discovery_set_state(struct hci_dev *hdev, int state)
        case DISCOVERY_STOPPED:
                if (hdev->discovery.state != DISCOVERY_STARTING)
                        mgmt_discovering(hdev, 0);
-               hdev->discovery.type = 0;
                break;
        case DISCOVERY_STARTING:
                break;
@@ -1089,32 +1092,6 @@ static const struct rfkill_ops hci_rfkill_ops = {
        .set_block = hci_rfkill_set_block,
 };
 
-/* Alloc HCI device */
-struct hci_dev *hci_alloc_dev(void)
-{
-       struct hci_dev *hdev;
-
-       hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
-       if (!hdev)
-               return NULL;
-
-       hci_init_sysfs(hdev);
-       skb_queue_head_init(&hdev->driver_init);
-
-       return hdev;
-}
-EXPORT_SYMBOL(hci_alloc_dev);
-
-/* Free HCI device */
-void hci_free_dev(struct hci_dev *hdev)
-{
-       skb_queue_purge(&hdev->driver_init);
-
-       /* will free via device release */
-       put_device(&hdev->dev);
-}
-EXPORT_SYMBOL(hci_free_dev);
-
 static void hci_power_on(struct work_struct *work)
 {
        struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
@@ -1215,40 +1192,40 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
        return NULL;
 }
 
-static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
+static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
                                                u8 key_type, u8 old_key_type)
 {
        /* Legacy key */
        if (key_type < 0x03)
-               return 1;
+               return true;
 
        /* Debug keys are insecure so don't store them persistently */
        if (key_type == HCI_LK_DEBUG_COMBINATION)
-               return 0;
+               return false;
 
        /* Changed combination key and there's no previous one */
        if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
-               return 0;
+               return false;
 
        /* Security mode 3 case */
        if (!conn)
-               return 1;
+               return true;
 
        /* Neither local nor remote side had no-bonding as requirement */
        if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
-               return 1;
+               return true;
 
        /* Local side had dedicated bonding as requirement */
        if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
-               return 1;
+               return true;
 
        /* Remote side had dedicated bonding as requirement */
        if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
-               return 1;
+               return true;
 
        /* If none of the above criteria match, then don't store the key
         * persistently */
-       return 0;
+       return false;
 }
 
 struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
@@ -1285,7 +1262,8 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
                     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
 {
        struct link_key *key, *old_key;
-       u8 old_key_type, persistent;
+       u8 old_key_type;
+       bool persistent;
 
        old_key = hci_find_link_key(hdev, bdaddr);
        if (old_key) {
@@ -1328,16 +1306,14 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
 
        mgmt_new_link_key(hdev, key, persistent);
 
-       if (!persistent) {
-               list_del(&key->list);
-               kfree(key);
-       }
+       if (conn)
+               conn->flush_key = !persistent;
 
        return 0;
 }
 
 int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
-               int new_key, u8 authenticated, u8 tk[16], u8 enc_size, u16
+               int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
                ediv, u8 rand[8])
 {
        struct smp_ltk *key, *old_key;
@@ -1545,75 +1521,6 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
        return mgmt_device_unblocked(hdev, bdaddr, type);
 }
 
-static void hci_clear_adv_cache(struct work_struct *work)
-{
-       struct hci_dev *hdev = container_of(work, struct hci_dev,
-                                           adv_work.work);
-
-       hci_dev_lock(hdev);
-
-       hci_adv_entries_clear(hdev);
-
-       hci_dev_unlock(hdev);
-}
-
-int hci_adv_entries_clear(struct hci_dev *hdev)
-{
-       struct adv_entry *entry, *tmp;
-
-       list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) {
-               list_del(&entry->list);
-               kfree(entry);
-       }
-
-       BT_DBG("%s adv cache cleared", hdev->name);
-
-       return 0;
-}
-
-struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
-{
-       struct adv_entry *entry;
-
-       list_for_each_entry(entry, &hdev->adv_entries, list)
-               if (bacmp(bdaddr, &entry->bdaddr) == 0)
-                       return entry;
-
-       return NULL;
-}
-
-static inline int is_connectable_adv(u8 evt_type)
-{
-       if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND)
-               return 1;
-
-       return 0;
-}
-
-int hci_add_adv_entry(struct hci_dev *hdev,
-                                       struct hci_ev_le_advertising_info *ev) { struct adv_entry *entry; if (!is_connectable_adv(ev->evt_type))
-               return -EINVAL;
-
-       /* Only new entries should be added to adv_entries. So, if
-        * bdaddr was found, don't add it. */
-       if (hci_find_adv_entry(hdev, &ev->bdaddr))
-               return 0;
-
-       entry = kzalloc(sizeof(*entry), GFP_KERNEL);
-       if (!entry)
-               return -ENOMEM;
-
-       bacpy(&entry->bdaddr, &ev->bdaddr);
-       entry->bdaddr_type = ev->bdaddr_type;
-
-       list_add(&entry->list, &hdev->adv_entries);
-
-       BT_DBG("%s adv entry added: address %s type %u", hdev->name,
-                               batostr(&entry->bdaddr), entry->bdaddr_type);
-
-       return 0;
-}
-
 static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt)
 {
        struct le_scan_params *param =  (struct le_scan_params *) opt;
@@ -1671,6 +1578,24 @@ static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
        return 0;
 }
 
+int hci_cancel_le_scan(struct hci_dev *hdev)
+{
+       BT_DBG("%s", hdev->name);
+
+       if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
+               return -EALREADY;
+
+       if (cancel_delayed_work(&hdev->le_scan_disable)) {
+               struct hci_cp_le_set_scan_enable cp;
+
+               /* Send HCI command to disable LE Scan */
+               memset(&cp, 0, sizeof(cp));
+               hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
+       }
+
+       return 0;
+}
+
 static void le_scan_disable_work(struct work_struct *work)
 {
        struct hci_dev *hdev = container_of(work, struct hci_dev,
@@ -1715,95 +1640,103 @@ int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
        return 0;
 }
 
-/* Register HCI device */
-int hci_register_dev(struct hci_dev *hdev)
+/* Alloc HCI device */
+struct hci_dev *hci_alloc_dev(void)
 {
-       struct list_head *head = &hci_dev_list, *p;
-       int i, id, error;
-
-       BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
-
-       if (!hdev->open || !hdev->close)
-               return -EINVAL;
-
-       /* Do not allow HCI_AMP devices to register at index 0,
-        * so the index can be used as the AMP controller ID.
-        */
-       id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
-
-       write_lock(&hci_dev_list_lock);
-
-       /* Find first available device id */
-       list_for_each(p, &hci_dev_list) {
-               if (list_entry(p, struct hci_dev, list)->id != id)
-                       break;
-               head = p; id++;
-       }
-
-       sprintf(hdev->name, "hci%d", id);
-       hdev->id = id;
-       list_add_tail(&hdev->list, head);
+       struct hci_dev *hdev;
 
-       mutex_init(&hdev->lock);
+       hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
+       if (!hdev)
+               return NULL;
 
-       hdev->flags = 0;
-       hdev->dev_flags = 0;
        hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
        hdev->esco_type = (ESCO_HV1);
        hdev->link_mode = (HCI_LM_ACCEPT);
        hdev->io_capability = 0x03; /* No Input No Output */
 
-       hdev->idle_timeout = 0;
        hdev->sniff_max_interval = 800;
        hdev->sniff_min_interval = 80;
 
+       mutex_init(&hdev->lock);
+       mutex_init(&hdev->req_lock);
+
+       INIT_LIST_HEAD(&hdev->mgmt_pending);
+       INIT_LIST_HEAD(&hdev->blacklist);
+       INIT_LIST_HEAD(&hdev->uuids);
+       INIT_LIST_HEAD(&hdev->link_keys);
+       INIT_LIST_HEAD(&hdev->long_term_keys);
+       INIT_LIST_HEAD(&hdev->remote_oob_data);
+
        INIT_WORK(&hdev->rx_work, hci_rx_work);
        INIT_WORK(&hdev->cmd_work, hci_cmd_work);
        INIT_WORK(&hdev->tx_work, hci_tx_work);
+       INIT_WORK(&hdev->power_on, hci_power_on);
+       INIT_WORK(&hdev->le_scan, le_scan_work);
 
+       INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
+       INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
+       INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
 
+       skb_queue_head_init(&hdev->driver_init);
        skb_queue_head_init(&hdev->rx_q);
        skb_queue_head_init(&hdev->cmd_q);
        skb_queue_head_init(&hdev->raw_q);
 
-       setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);
-
-       for (i = 0; i < NUM_REASSEMBLY; i++)
-               hdev->reassembly[i] = NULL;
-
        init_waitqueue_head(&hdev->req_wait_q);
-       mutex_init(&hdev->req_lock);
 
-       discovery_init(hdev);
+       setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);
 
+       hci_init_sysfs(hdev);
+       discovery_init(hdev);
        hci_conn_hash_init(hdev);
 
-       INIT_LIST_HEAD(&hdev->mgmt_pending);
-
-       INIT_LIST_HEAD(&hdev->blacklist);
+       return hdev;
+}
+EXPORT_SYMBOL(hci_alloc_dev);
 
-       INIT_LIST_HEAD(&hdev->uuids);
+/* Free HCI device */
+void hci_free_dev(struct hci_dev *hdev)
+{
+       skb_queue_purge(&hdev->driver_init);
 
-       INIT_LIST_HEAD(&hdev->link_keys);
-       INIT_LIST_HEAD(&hdev->long_term_keys);
+       /* will free via device release */
+       put_device(&hdev->dev);
+}
+EXPORT_SYMBOL(hci_free_dev);
 
-       INIT_LIST_HEAD(&hdev->remote_oob_data);
+/* Register HCI device */
+int hci_register_dev(struct hci_dev *hdev)
+{
+       struct list_head *head, *p;
+       int id, error;
 
-       INIT_LIST_HEAD(&hdev->adv_entries);
+       if (!hdev->open || !hdev->close)
+               return -EINVAL;
 
-       INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache);
-       INIT_WORK(&hdev->power_on, hci_power_on);
-       INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
+       write_lock(&hci_dev_list_lock);
 
-       INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
+       /* Do not allow HCI_AMP devices to register at index 0,
+        * so the index can be used as the AMP controller ID.
+        */
+       id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
+       head = &hci_dev_list;
 
-       memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
+       /* Find first available device id */
+       list_for_each(p, &hci_dev_list) {
+               int nid = list_entry(p, struct hci_dev, list)->id;
+               if (nid > id)
+                       break;
+               if (nid == id)
+                       id++;
+               head = p;
+       }
 
-       atomic_set(&hdev->promisc, 0);
+       sprintf(hdev->name, "hci%d", id);
+       hdev->id = id;
 
-       INIT_WORK(&hdev->le_scan, le_scan_work);
+       BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
 
-       INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
+       list_add(&hdev->list, head);
 
        write_unlock(&hci_dev_list_lock);
 
@@ -1885,8 +1818,6 @@ void hci_unregister_dev(struct hci_dev *hdev)
 
        hci_del_sysfs(hdev);
 
-       cancel_delayed_work_sync(&hdev->adv_work);
-
        destroy_workqueue(hdev->workqueue);
 
        hci_dev_lock(hdev);
@@ -1895,7 +1826,6 @@ void hci_unregister_dev(struct hci_dev *hdev)
        hci_link_keys_clear(hdev);
        hci_smp_ltks_clear(hdev);
        hci_remote_oob_data_clear(hdev);
-       hci_adv_entries_clear(hdev);
        hci_dev_unlock(hdev);
 
        hci_dev_put(hdev);
@@ -2314,7 +2244,7 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
 {
        struct hci_conn_hash *h = &hdev->conn_hash;
        struct hci_conn *conn = NULL, *c;
-       int num = 0, min = ~0;
+       unsigned int num = 0, min = ~0;
 
        /* We don't have to lock device here. Connections are always
         * added and removed with TX task disabled. */
@@ -2395,7 +2325,7 @@ static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
 {
        struct hci_conn_hash *h = &hdev->conn_hash;
        struct hci_chan *chan = NULL;
-       int num = 0, min = ~0, cur_prio = 0;
+       unsigned int num = 0, min = ~0, cur_prio = 0;
        struct hci_conn *conn;
        int cnt, q, conn_num = 0;
 
@@ -2785,6 +2715,14 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
        if (conn) {
                hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
 
+               hci_dev_lock(hdev);
+               if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
+                   !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
+                       mgmt_device_connected(hdev, &conn->dst, conn->type,
+                                             conn->dst_type, 0, NULL, 0,
+                                             conn->dev_class);
+               hci_dev_unlock(hdev);
+
                /* Send to upper protocol */
                l2cap_recv_acldata(conn, skb, flags);
                return;
@@ -2938,7 +2876,19 @@ int hci_cancel_inquiry(struct hci_dev *hdev)
        BT_DBG("%s", hdev->name);
 
        if (!test_bit(HCI_INQUIRY, &hdev->flags))
-               return -EPERM;
+               return -EALREADY;
 
        return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
 }
+
+u8 bdaddr_to_le(u8 bdaddr_type)
+{
+       switch (bdaddr_type) {
+       case BDADDR_LE_PUBLIC:
+               return ADDR_LE_DEV_PUBLIC;
+
+       default:
+               /* Fallback to LE Random address type */
+               return ADDR_LE_DEV_RANDOM;
+       }
+}