aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/hci.h6
-rw-r--r--include/net/bluetooth/hci_core.h1
-rw-r--r--net/bluetooth/hci_event.c20
3 files changed, 27 insertions, 0 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 45eee08157bb..521eefa033e7 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -943,6 +943,12 @@ struct hci_rp_le_read_buffer_size {
943 __u8 le_max_pkt; 943 __u8 le_max_pkt;
944} __packed; 944} __packed;
945 945
946#define HCI_OP_LE_READ_LOCAL_FEATURES 0x2003
947struct hci_rp_le_read_local_features {
948 __u8 status;
949 __u8 features[8];
950} __packed;
951
946#define HCI_OP_LE_READ_ADV_TX_POWER 0x2007 952#define HCI_OP_LE_READ_ADV_TX_POWER 0x2007
947struct hci_rp_le_read_adv_tx_power { 953struct hci_rp_le_read_adv_tx_power {
948 __u8 status; 954 __u8 status;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 769a740c104c..3f607c94e213 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -152,6 +152,7 @@ struct hci_dev {
152 __u8 minor_class; 152 __u8 minor_class;
153 __u8 features[8]; 153 __u8 features[8];
154 __u8 host_features[8]; 154 __u8 host_features[8];
155 __u8 le_features[8];
155 __u8 commands[64]; 156 __u8 commands[64];
156 __u8 hci_ver; 157 __u8 hci_ver;
157 __u16 hci_rev; 158 __u16 hci_rev;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 705078a0cc39..07c8c79a9fd1 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -609,6 +609,9 @@ static void le_setup(struct hci_dev *hdev)
609 /* Read LE Buffer Size */ 609 /* Read LE Buffer Size */
610 hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); 610 hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
611 611
612 /* Read LE Local Supported Features */
613 hci_send_cmd(hdev, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
614
612 /* Read LE Advertising Channel TX Power */ 615 /* Read LE Advertising Channel TX Power */
613 hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); 616 hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
614} 617}
@@ -1090,6 +1093,19 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
1090 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); 1093 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
1091} 1094}
1092 1095
1096static void hci_cc_le_read_local_features(struct hci_dev *hdev,
1097 struct sk_buff *skb)
1098{
1099 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
1100
1101 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1102
1103 if (!rp->status)
1104 memcpy(hdev->le_features, rp->features, 8);
1105
1106 hci_req_complete(hdev, HCI_OP_LE_READ_LOCAL_FEATURES, rp->status);
1107}
1108
1093static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, 1109static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
1094 struct sk_buff *skb) 1110 struct sk_buff *skb)
1095{ 1111{
@@ -2628,6 +2644,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2628 hci_cc_le_read_buffer_size(hdev, skb); 2644 hci_cc_le_read_buffer_size(hdev, skb);
2629 break; 2645 break;
2630 2646
2647 case HCI_OP_LE_READ_LOCAL_FEATURES:
2648 hci_cc_le_read_local_features(hdev, skb);
2649 break;
2650
2631 case HCI_OP_LE_READ_ADV_TX_POWER: 2651 case HCI_OP_LE_READ_ADV_TX_POWER:
2632 hci_cc_le_read_adv_tx_power(hdev, skb); 2652 hci_cc_le_read_adv_tx_power(hdev, skb);
2633 break; 2653 break;