Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / net / bluetooth / hci_event.c
index ed4ecd930a715394f8bd4565e735ff3ccc1dbe9c..138580745c2ce2679e04475b86131c3f34effca9 100644 (file)
@@ -223,9 +223,6 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
                memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
 
        hci_dev_unlock(hdev);
-
-       if (!status && !test_bit(HCI_INIT, &hdev->flags))
-               hci_update_ad(hdev);
 }
 
 static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
@@ -604,6 +601,65 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
                bacpy(&hdev->bdaddr, &rp->bdaddr);
 }
 
+static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
+                                          struct sk_buff *skb)
+{
+       struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
+
+       BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
+
+       if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
+               hdev->page_scan_interval = __le16_to_cpu(rp->interval);
+               hdev->page_scan_window = __le16_to_cpu(rp->window);
+       }
+}
+
+static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
+                                           struct sk_buff *skb)
+{
+       u8 status = *((u8 *) skb->data);
+       struct hci_cp_write_page_scan_activity *sent;
+
+       BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+       if (status)
+               return;
+
+       sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
+       if (!sent)
+               return;
+
+       hdev->page_scan_interval = __le16_to_cpu(sent->interval);
+       hdev->page_scan_window = __le16_to_cpu(sent->window);
+}
+
+static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
+                                          struct sk_buff *skb)
+{
+       struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
+
+       BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
+
+       if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
+               hdev->page_scan_type = rp->type;
+}
+
+static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
+                                       struct sk_buff *skb)
+{
+       u8 status = *((u8 *) skb->data);
+       u8 *type;
+
+       BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+       if (status)
+               return;
+
+       type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
+       if (type)
+               hdev->page_scan_type = *type;
+}
+
 static void hci_cc_read_data_block_size(struct hci_dev *hdev,
                                        struct sk_buff *skb)
 {
@@ -776,11 +832,8 @@ static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
 
        BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
-       if (!rp->status) {
+       if (!rp->status)
                hdev->adv_tx_power = rp->tx_power;
-               if (!test_bit(HCI_INIT, &hdev->flags))
-                       hci_update_ad(hdev);
-       }
 }
 
 static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
@@ -877,10 +930,15 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
                        clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
        }
 
-       hci_dev_unlock(hdev);
+       if (!test_bit(HCI_INIT, &hdev->flags)) {
+               struct hci_request req;
+
+               hci_req_init(&req, hdev);
+               hci_update_ad(&req);
+               hci_req_run(&req, NULL);
+       }
 
-       if (!test_bit(HCI_INIT, &hdev->flags))
-               hci_update_ad(hdev);
+       hci_dev_unlock(hdev);
 }
 
 static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
@@ -2205,6 +2263,22 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
                hci_cc_read_bd_addr(hdev, skb);
                break;
 
+       case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
+               hci_cc_read_page_scan_activity(hdev, skb);
+               break;
+
+       case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
+               hci_cc_write_page_scan_activity(hdev, skb);
+               break;
+
+       case HCI_OP_READ_PAGE_SCAN_TYPE:
+               hci_cc_read_page_scan_type(hdev, skb);
+               break;
+
+       case HCI_OP_WRITE_PAGE_SCAN_TYPE:
+               hci_cc_write_page_scan_type(hdev, skb);
+               break;
+
        case HCI_OP_READ_DATA_BLOCK_SIZE:
                hci_cc_read_data_block_size(hdev, skb);
                break;