diff options
-rw-r--r-- | include/net/bluetooth/hci.h | 6 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 1 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 20 |
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 | ||
947 | struct 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 |
947 | struct hci_rp_le_read_adv_tx_power { | 953 | struct 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 | ||
1096 | static 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 | |||
1093 | static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, | 1109 | static 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; |