IB/hfi1: Use struct_size()
[platform/kernel/linux-starfive.git] / net / bluetooth / hci_event.c
index 09ba6d8..95816a9 100644 (file)
@@ -3812,7 +3812,8 @@ static u8 hci_cc_le_set_cig_params(struct hci_dev *hdev, void *data,
        bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
 
        cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_CIG_PARAMS);
-       if (!cp || rp->num_handles != cp->num_cis || rp->cig_id != cp->cig_id) {
+       if (!rp->status && (!cp || rp->num_handles != cp->num_cis ||
+                           rp->cig_id != cp->cig_id)) {
                bt_dev_err(hdev, "unexpected Set CIG Parameters response data");
                status = HCI_ERROR_UNSPECIFIED;
        }
@@ -6316,23 +6317,18 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
                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_SCAN_RSP)
-               flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
+               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
@@ -6790,6 +6786,7 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
 {
        struct hci_evt_le_cis_established *ev = data;
        struct hci_conn *conn;
+       struct bt_iso_qos *qos;
        u16 handle = __le16_to_cpu(ev->handle);
 
        bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
@@ -6811,21 +6808,39 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
                goto unlock;
        }
 
-       if (conn->role == HCI_ROLE_SLAVE) {
-               __le32 interval;
-
-               memset(&interval, 0, sizeof(interval));
-
-               memcpy(&interval, ev->c_latency, sizeof(ev->c_latency));
-               conn->iso_qos.ucast.in.interval = le32_to_cpu(interval);
-               memcpy(&interval, ev->p_latency, sizeof(ev->p_latency));
-               conn->iso_qos.ucast.out.interval = le32_to_cpu(interval);
-               conn->iso_qos.ucast.in.latency = le16_to_cpu(ev->interval);
-               conn->iso_qos.ucast.out.latency = le16_to_cpu(ev->interval);
-               conn->iso_qos.ucast.in.sdu = le16_to_cpu(ev->c_mtu);
-               conn->iso_qos.ucast.out.sdu = le16_to_cpu(ev->p_mtu);
-               conn->iso_qos.ucast.in.phy = ev->c_phy;
-               conn->iso_qos.ucast.out.phy = ev->p_phy;
+       qos = &conn->iso_qos;
+
+       /* Convert ISO Interval (1.25 ms slots) to SDU Interval (us) */
+       qos->ucast.in.interval = le16_to_cpu(ev->interval) * 1250;
+       qos->ucast.out.interval = qos->ucast.in.interval;
+
+       switch (conn->role) {
+       case HCI_ROLE_SLAVE:
+               /* Convert Transport Latency (us) to Latency (msec) */
+               qos->ucast.in.latency =
+                       DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
+                                         1000);
+               qos->ucast.out.latency =
+                       DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency),
+                                         1000);
+               qos->ucast.in.sdu = le16_to_cpu(ev->c_mtu);
+               qos->ucast.out.sdu = le16_to_cpu(ev->p_mtu);
+               qos->ucast.in.phy = ev->c_phy;
+               qos->ucast.out.phy = ev->p_phy;
+               break;
+       case HCI_ROLE_MASTER:
+               /* Convert Transport Latency (us) to Latency (msec) */
+               qos->ucast.out.latency =
+                       DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
+                                         1000);
+               qos->ucast.in.latency =
+                       DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency),
+                                         1000);
+               qos->ucast.out.sdu = le16_to_cpu(ev->c_mtu);
+               qos->ucast.in.sdu = le16_to_cpu(ev->p_mtu);
+               qos->ucast.out.phy = ev->c_phy;
+               qos->ucast.in.phy = ev->p_phy;
+               break;
        }
 
        if (!ev->status) {