These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / net / bluetooth / hci_conn.c
index ee5e598..24e9410 100644 (file)
@@ -59,9 +59,126 @@ static const struct sco_param esco_param_msbc[] = {
        { EDR_ESCO_MASK | ESCO_EV3,   0x0008,   0x02 }, /* T1 */
 };
 
-static void hci_le_create_connection_cancel(struct hci_conn *conn)
+/* This function requires the caller holds hdev->lock */
+static void hci_connect_le_scan_cleanup(struct hci_conn *conn)
+{
+       struct hci_conn_params *params;
+       struct hci_dev *hdev = conn->hdev;
+       struct smp_irk *irk;
+       bdaddr_t *bdaddr;
+       u8 bdaddr_type;
+
+       bdaddr = &conn->dst;
+       bdaddr_type = conn->dst_type;
+
+       /* Check if we need to convert to identity address */
+       irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
+       if (irk) {
+               bdaddr = &irk->bdaddr;
+               bdaddr_type = irk->addr_type;
+       }
+
+       params = hci_pend_le_action_lookup(&hdev->pend_le_conns, bdaddr,
+                                          bdaddr_type);
+       if (!params || !params->explicit_connect)
+               return;
+
+       /* The connection attempt was doing scan for new RPA, and is
+        * in scan phase. If params are not associated with any other
+        * autoconnect action, remove them completely. If they are, just unmark
+        * them as waiting for connection, by clearing explicit_connect field.
+        */
+       params->explicit_connect = false;
+
+       list_del_init(&params->action);
+
+       switch (params->auto_connect) {
+       case HCI_AUTO_CONN_EXPLICIT:
+               hci_conn_params_del(hdev, bdaddr, bdaddr_type);
+               /* return instead of break to avoid duplicate scan update */
+               return;
+       case HCI_AUTO_CONN_DIRECT:
+       case HCI_AUTO_CONN_ALWAYS:
+               list_add(&params->action, &hdev->pend_le_conns);
+               break;
+       case HCI_AUTO_CONN_REPORT:
+               list_add(&params->action, &hdev->pend_le_reports);
+               break;
+       default:
+               break;
+       }
+
+       hci_update_background_scan(hdev);
+}
+
+static void hci_conn_cleanup(struct hci_conn *conn)
+{
+       struct hci_dev *hdev = conn->hdev;
+
+       if (test_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags))
+               hci_conn_params_del(conn->hdev, &conn->dst, conn->dst_type);
+
+       hci_chan_list_flush(conn);
+
+       hci_conn_hash_del(hdev, conn);
+
+       if (hdev->notify)
+               hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
+
+       hci_conn_del_sysfs(conn);
+
+       debugfs_remove_recursive(conn->debugfs);
+
+       hci_dev_put(hdev);
+
+       hci_conn_put(conn);
+}
+
+static void le_scan_cleanup(struct work_struct *work)
+{
+       struct hci_conn *conn = container_of(work, struct hci_conn,
+                                            le_scan_cleanup);
+       struct hci_dev *hdev = conn->hdev;
+       struct hci_conn *c = NULL;
+
+       BT_DBG("%s hcon %p", hdev->name, conn);
+
+       hci_dev_lock(hdev);
+
+       /* Check that the hci_conn is still around */
+       rcu_read_lock();
+       list_for_each_entry_rcu(c, &hdev->conn_hash.list, list) {
+               if (c == conn)
+                       break;
+       }
+       rcu_read_unlock();
+
+       if (c == conn) {
+               hci_connect_le_scan_cleanup(conn);
+               hci_conn_cleanup(conn);
+       }
+
+       hci_dev_unlock(hdev);
+       hci_dev_put(hdev);
+       hci_conn_put(conn);
+}
+
+static void hci_connect_le_scan_remove(struct hci_conn *conn)
 {
-       hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL);
+       BT_DBG("%s hcon %p", conn->hdev->name, conn);
+
+       /* We can't call hci_conn_del/hci_conn_cleanup here since that
+        * could deadlock with another hci_conn_del() call that's holding
+        * hci_dev_lock and doing cancel_delayed_work_sync(&conn->disc_work).
+        * Instead, grab temporary extra references to the hci_dev and
+        * hci_conn and perform the necessary cleanup in a separate work
+        * callback.
+        */
+
+       hci_dev_hold(conn->hdev);
+       hci_conn_get(conn);
+
+       schedule_work(&conn->le_scan_cleanup);
 }
 
 static void hci_acl_create_connection(struct hci_conn *conn)
@@ -107,33 +224,8 @@ static void hci_acl_create_connection(struct hci_conn *conn)
        hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp);
 }
 
-static void hci_acl_create_connection_cancel(struct hci_conn *conn)
-{
-       struct hci_cp_create_conn_cancel cp;
-
-       BT_DBG("hcon %p", conn);
-
-       if (conn->hdev->hci_ver < BLUETOOTH_VER_1_2)
-               return;
-
-       bacpy(&cp.bdaddr, &conn->dst);
-       hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
-}
-
-static void hci_reject_sco(struct hci_conn *conn)
-{
-       struct hci_cp_reject_sync_conn_req cp;
-
-       cp.reason = HCI_ERROR_REJ_LIMITED_RESOURCES;
-       bacpy(&cp.bdaddr, &conn->dst);
-
-       hci_send_cmd(conn->hdev, HCI_OP_REJECT_SYNC_CONN_REQ, sizeof(cp), &cp);
-}
-
 int hci_disconnect(struct hci_conn *conn, __u8 reason)
 {
-       struct hci_cp_disconnect cp;
-
        BT_DBG("hcon %p", conn);
 
        /* When we are master of an established connection and it enters
@@ -141,7 +233,8 @@ int hci_disconnect(struct hci_conn *conn, __u8 reason)
         * current clock offset.  Processing of the result is done
         * within the event handling and hci_clock_offset_evt function.
         */
-       if (conn->type == ACL_LINK && conn->role == HCI_ROLE_MASTER) {
+       if (conn->type == ACL_LINK && conn->role == HCI_ROLE_MASTER &&
+           (conn->state == BT_CONNECTED || conn->state == BT_CONFIG)) {
                struct hci_dev *hdev = conn->hdev;
                struct hci_cp_read_clock_offset clkoff_cp;
 
@@ -150,25 +243,7 @@ int hci_disconnect(struct hci_conn *conn, __u8 reason)
                             &clkoff_cp);
        }
 
-       conn->state = BT_DISCONN;
-
-       cp.handle = cpu_to_le16(conn->handle);
-       cp.reason = reason;
-       return hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp);
-}
-
-static void hci_amp_disconn(struct hci_conn *conn)
-{
-       struct hci_cp_disconn_phy_link cp;
-
-       BT_DBG("hcon %p", conn);
-
-       conn->state = BT_DISCONN;
-
-       cp.phy_handle = HCI_PHY_HANDLE(conn->handle);
-       cp.reason = hci_proto_disconn_ind(conn);
-       hci_send_cmd(conn->hdev, HCI_OP_DISCONN_PHY_LINK,
-                    sizeof(cp), &cp);
+       return hci_abort_conn(conn, reason);
 }
 
 static void hci_add_sco(struct hci_conn *conn, __u16 handle)
@@ -276,7 +351,7 @@ u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
 }
 
 void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
-                     __u8 ltk[16])
+                     __u8 ltk[16], __u8 key_size)
 {
        struct hci_dev *hdev = conn->hdev;
        struct hci_cp_le_start_enc cp;
@@ -288,7 +363,7 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
        cp.handle = cpu_to_le16(conn->handle);
        cp.rand = rand;
        cp.ediv = ediv;
-       memcpy(cp.ltk, ltk, sizeof(cp.ltk));
+       memcpy(cp.ltk, ltk, key_size);
 
        hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp);
 }
@@ -334,31 +409,14 @@ static void hci_conn_timeout(struct work_struct *work)
        if (refcnt > 0)
                return;
 
-       switch (conn->state) {
-       case BT_CONNECT:
-       case BT_CONNECT2:
-               if (conn->out) {
-                       if (conn->type == ACL_LINK)
-                               hci_acl_create_connection_cancel(conn);
-                       else if (conn->type == LE_LINK)
-                               hci_le_create_connection_cancel(conn);
-               } else if (conn->type == SCO_LINK || conn->type == ESCO_LINK) {
-                       hci_reject_sco(conn);
-               }
-               break;
-       case BT_CONFIG:
-       case BT_CONNECTED:
-               if (conn->type == AMP_LINK) {
-                       hci_amp_disconn(conn);
-               } else {
-                       __u8 reason = hci_proto_disconn_ind(conn);
-                       hci_disconnect(conn, reason);
-               }
-               break;
-       default:
-               conn->state = BT_CLOSED;
-               break;
+       /* LE connections in scanning state need special handling */
+       if (conn->state == BT_CONNECT && conn->type == LE_LINK &&
+           test_bit(HCI_CONN_SCANNING, &conn->flags)) {
+               hci_connect_le_scan_remove(conn);
+               return;
        }
+
+       hci_abort_conn(conn, hci_proto_disconn_ind(conn));
 }
 
 /* Enter sniff mode */
@@ -426,7 +484,7 @@ static void le_conn_timeout(struct work_struct *work)
                return;
        }
 
-       hci_le_create_connection_cancel(conn);
+       hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
 }
 
 struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
@@ -489,6 +547,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
        INIT_DELAYED_WORK(&conn->auto_accept_work, hci_conn_auto_accept);
        INIT_DELAYED_WORK(&conn->idle_work, hci_conn_idle);
        INIT_DELAYED_WORK(&conn->le_conn_timeout, le_conn_timeout);
+       INIT_WORK(&conn->le_scan_cleanup, le_scan_cleanup);
 
        atomic_set(&conn->refcnt, 0);
 
@@ -535,27 +594,17 @@ int hci_conn_del(struct hci_conn *conn)
                }
        }
 
-       hci_chan_list_flush(conn);
-
        if (conn->amp_mgr)
                amp_mgr_put(conn->amp_mgr);
 
-       hci_conn_hash_del(hdev, conn);
-       if (hdev->notify)
-               hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
-
        skb_queue_purge(&conn->data_q);
 
-       hci_conn_del_sysfs(conn);
-
-       debugfs_remove_recursive(conn->debugfs);
-
-       if (test_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags))
-               hci_conn_params_del(conn->hdev, &conn->dst, conn->dst_type);
-
-       hci_dev_put(hdev);
-
-       hci_conn_put(conn);
+       /* Remove the connection from the list and cleanup its remaining
+        * state. This is a separate function since for some cases like
+        * BT_CONNECT_SCAN we *only* want the cleanup part without the
+        * rest of hci_conn_del.
+        */
+       hci_conn_cleanup(conn);
 
        return 0;
 }
@@ -637,15 +686,18 @@ static void create_le_conn_complete(struct hci_dev *hdev, u8 status, u16 opcode)
 {
        struct hci_conn *conn;
 
-       if (status == 0)
-               return;
+       hci_dev_lock(hdev);
+
+       conn = hci_lookup_le_connect(hdev);
+
+       if (!status) {
+               hci_connect_le_scan_cleanup(conn);
+               goto done;
+       }
 
        BT_ERR("HCI request failed to create LE connection: status 0x%2.2x",
               status);
 
-       hci_dev_lock(hdev);
-
-       conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
        if (!conn)
                goto done;
 
@@ -670,8 +722,12 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
        if (hci_update_random_address(req, false, &own_addr_type))
                return;
 
+       /* Set window to be the same value as the interval to enable
+        * continuous scanning.
+        */
        cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
-       cp.scan_window = cpu_to_le16(hdev->le_scan_window);
+       cp.scan_window = cp.scan_interval;
+
        bacpy(&cp.peer_addr, &conn->dst);
        cp.peer_addr_type = conn->dst_type;
        cp.own_address_type = own_addr_type;
@@ -685,6 +741,7 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
        hci_req_add(req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
 
        conn->state = BT_CONNECT;
+       clear_bit(HCI_CONN_SCANNING, &conn->flags);
 }
 
 static void hci_req_directed_advertising(struct hci_request *req,
@@ -728,7 +785,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
                                u8 role)
 {
        struct hci_conn_params *params;
-       struct hci_conn *conn;
+       struct hci_conn *conn, *conn_unfinished;
        struct smp_irk *irk;
        struct hci_request req;
        int err;
@@ -750,27 +807,30 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
         * attempt, we simply update pending_sec_level and auth_type fields
         * and return the object found.
         */
-       conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
+       conn = hci_conn_hash_lookup_le(hdev, dst, dst_type);
+       conn_unfinished = NULL;
        if (conn) {
-               conn->pending_sec_level = sec_level;
-               goto done;
+               if (conn->state == BT_CONNECT &&
+                   test_bit(HCI_CONN_SCANNING, &conn->flags)) {
+                       BT_DBG("will continue unfinished conn %pMR", dst);
+                       conn_unfinished = conn;
+               } else {
+                       if (conn->pending_sec_level < sec_level)
+                               conn->pending_sec_level = sec_level;
+                       goto done;
+               }
        }
 
        /* Since the controller supports only one LE connection attempt at a
         * time, we return -EBUSY if there is any connection attempt running.
         */
-       conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
-       if (conn)
+       if (hci_lookup_le_connect(hdev))
                return ERR_PTR(-EBUSY);
 
        /* When given an identity address with existing identity
         * resolving key, the connection needs to be established
         * to a resolvable random address.
         *
-        * This uses the cached random resolvable address from
-        * a previous scan. When no cached address is available,
-        * try connecting to the identity address instead.
-        *
         * Storing the resolvable random address is required here
         * to handle connection failures. The address will later
         * be resolved back into the original identity address
@@ -782,15 +842,23 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
                dst_type = ADDR_LE_DEV_RANDOM;
        }
 
-       conn = hci_conn_add(hdev, LE_LINK, dst, role);
+       if (conn_unfinished) {
+               conn = conn_unfinished;
+               bacpy(&conn->dst, dst);
+       } else {
+               conn = hci_conn_add(hdev, LE_LINK, dst, role);
+       }
+
        if (!conn)
                return ERR_PTR(-ENOMEM);
 
        conn->dst_type = dst_type;
        conn->sec_level = BT_SECURITY_LOW;
-       conn->pending_sec_level = sec_level;
        conn->conn_timeout = conn_timeout;
 
+       if (!conn_unfinished)
+               conn->pending_sec_level = sec_level;
+
        hci_req_init(&req, hdev);
 
        /* Disable advertising if we're active. For master role
@@ -854,6 +922,149 @@ create_conn:
                return ERR_PTR(err);
        }
 
+done:
+       /* If this is continuation of connect started by hci_connect_le_scan,
+        * it already called hci_conn_hold and calling it again would mess the
+        * counter.
+        */
+       if (!conn_unfinished)
+               hci_conn_hold(conn);
+
+       return conn;
+}
+
+static void hci_connect_le_scan_complete(struct hci_dev *hdev, u8 status,
+                                        u16 opcode)
+{
+       struct hci_conn *conn;
+
+       if (!status)
+               return;
+
+       BT_ERR("Failed to add device to auto conn whitelist: status 0x%2.2x",
+              status);
+
+       hci_dev_lock(hdev);
+
+       conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
+       if (conn)
+               hci_le_conn_failed(conn, status);
+
+       hci_dev_unlock(hdev);
+}
+
+static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type)
+{
+       struct hci_conn *conn;
+
+       conn = hci_conn_hash_lookup_le(hdev, addr, type);
+       if (!conn)
+               return false;
+
+       if (conn->state != BT_CONNECTED)
+               return false;
+
+       return true;
+}
+
+/* This function requires the caller holds hdev->lock */
+static int hci_explicit_conn_params_set(struct hci_request *req,
+                                       bdaddr_t *addr, u8 addr_type)
+{
+       struct hci_dev *hdev = req->hdev;
+       struct hci_conn_params *params;
+
+       if (is_connected(hdev, addr, addr_type))
+               return -EISCONN;
+
+       params = hci_conn_params_lookup(hdev, addr, addr_type);
+       if (!params) {
+               params = hci_conn_params_add(hdev, addr, addr_type);
+               if (!params)
+                       return -ENOMEM;
+
+               /* If we created new params, mark them to be deleted in
+                * hci_connect_le_scan_cleanup. It's different case than
+                * existing disabled params, those will stay after cleanup.
+                */
+               params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
+       }
+
+       /* We're trying to connect, so make sure params are at pend_le_conns */
+       if (params->auto_connect == HCI_AUTO_CONN_DISABLED ||
+           params->auto_connect == HCI_AUTO_CONN_REPORT ||
+           params->auto_connect == HCI_AUTO_CONN_EXPLICIT) {
+               list_del_init(&params->action);
+               list_add(&params->action, &hdev->pend_le_conns);
+       }
+
+       params->explicit_connect = true;
+       __hci_update_background_scan(req);
+
+       BT_DBG("addr %pMR (type %u) auto_connect %u", addr, addr_type,
+              params->auto_connect);
+
+       return 0;
+}
+
+/* This function requires the caller holds hdev->lock */
+struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
+                                    u8 dst_type, u8 sec_level,
+                                    u16 conn_timeout, u8 role)
+{
+       struct hci_conn *conn;
+       struct hci_request req;
+       int err;
+
+       /* Let's make sure that le is enabled.*/
+       if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
+               if (lmp_le_capable(hdev))
+                       return ERR_PTR(-ECONNREFUSED);
+
+               return ERR_PTR(-EOPNOTSUPP);
+       }
+
+       /* Some devices send ATT messages as soon as the physical link is
+        * established. To be able to handle these ATT messages, the user-
+        * space first establishes the connection and then starts the pairing
+        * process.
+        *
+        * So if a hci_conn object already exists for the following connection
+        * attempt, we simply update pending_sec_level and auth_type fields
+        * and return the object found.
+        */
+       conn = hci_conn_hash_lookup_le(hdev, dst, dst_type);
+       if (conn) {
+               if (conn->pending_sec_level < sec_level)
+                       conn->pending_sec_level = sec_level;
+               goto done;
+       }
+
+       BT_DBG("requesting refresh of dst_addr");
+
+       conn = hci_conn_add(hdev, LE_LINK, dst, role);
+       if (!conn)
+               return ERR_PTR(-ENOMEM);
+
+       hci_req_init(&req, hdev);
+
+       if (hci_explicit_conn_params_set(&req, dst, dst_type) < 0)
+               return ERR_PTR(-EBUSY);
+
+       conn->state = BT_CONNECT;
+       set_bit(HCI_CONN_SCANNING, &conn->flags);
+
+       err = hci_req_run(&req, hci_connect_le_scan_complete);
+       if (err && err != -ENODATA) {
+               hci_conn_del(conn);
+               return ERR_PTR(err);
+       }
+
+       conn->dst_type = dst_type;
+       conn->sec_level = BT_SECURITY_LOW;
+       conn->pending_sec_level = sec_level;
+       conn->conn_timeout = conn_timeout;
+
 done:
        hci_conn_hold(conn);
        return conn;