Bluetooth: Add sockopts for LE Connection Params

Various LE profiles require very specific LE parameters for
both establishing and maintaining LE connections to remote
peripherals. These LE only parameters are encapsulated into
a single sockopts structure, and may be passed from user space.

CRs-Fixed: 335971
Change-Id: I408edb97ab0fa9717c7d3fe5fc8ad6ac179a2fff
Signed-off-by: Brian Gix <bgix@codeaurora.org>
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 7e9f5f4..d218fab 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -99,6 +99,28 @@
  */
 #define BT_AMP_POLICY_PREFER_AMP       2
 
+#define BT_LE_PARAMS	100
+
+#define BT_LE_SCAN_WINDOW_MIN		0x0004
+#define BT_LE_SCAN_WINDOW_MAX		0x4000
+#define BT_LE_SCAN_WINDOW_DEF		0x0004
+
+#define BT_LE_SCAN_INTERVAL_MIN		0x0004
+#define BT_LE_SCAN_INTERVAL_MAX		0x4000
+#define BT_LE_SCAN_INTERVAL_DEF		0x0008
+
+#define BT_LE_CONN_INTERVAL_MIN		0x0006
+#define BT_LE_CONN_INTERVAL_MAX		0x0C80
+#define BT_LE_CONN_INTERVAL_MIN_DEF	0x0008
+#define BT_LE_CONN_INTERVAL_MAX_DEF	0x0100
+
+#define BT_LE_LATENCY_MAX		0x01F4
+#define BT_LE_LATENCY_DEF		0x0000
+
+#define BT_LE_SUP_TO_MIN		0x000A
+#define BT_LE_SUP_TO_MAX		0x0C80
+#define BT_LE_SUP_TO_DEFAULT		0X03E8
+
 #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
 #define BT_ERR(fmt, arg...)  printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
 #define BT_DBG(fmt, arg...)  pr_debug("%s: " fmt "\n" , __func__ , ## arg)
@@ -142,6 +164,20 @@
 
 #define bt_sk(__sk) ((struct bt_sock *) __sk)
 
+struct bt_le_params {
+	__u8  prohibit_remote_chg;
+	__u8  filter_policy;
+	__u16 scan_interval;
+	__u16 scan_window;
+	__u16 interval_min;
+	__u16 interval_max;
+	__u16 latency;
+	__u16 supervision_timeout;
+	__u16 min_ce_len;
+	__u16 max_ce_len;
+	__u16 conn_timeout;
+};
+
 struct bt_sock {
 	struct sock sk;
 	bdaddr_t    src;
@@ -149,6 +185,7 @@
 	struct list_head accept_q;
 	struct sock *parent;
 	u32 defer_setup;
+	struct bt_le_params le_params;
 };
 
 struct bt_sock_list {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 5053bd8..5749293 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -304,6 +304,7 @@
 	__u8		auth_initiator;
 	__u8		power_save;
 	__u16		disc_timeout;
+	__u16		conn_timeout;
 	unsigned long	pend;
 
 	__u8		remote_cap;
@@ -597,6 +598,10 @@
 struct hci_conn *hci_connect(struct hci_dev *hdev, int type,
 					__u16 pkt_type, bdaddr_t *dst,
 					__u8 sec_level, __u8 auth_type);
+struct hci_conn *hci_le_connect(struct hci_dev *hdev, __u16 pkt_type,
+					bdaddr_t *dst, __u8 sec_level,
+					__u8 auth_type,
+					struct bt_le_params *le_params);
 int hci_conn_check_link_mode(struct hci_conn *conn);
 int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
 int hci_conn_change_link_key(struct hci_conn *conn);
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index b903c5c..a098f3e 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -685,6 +685,7 @@
 int l2cap_ertm_tx(struct sock *sk, struct bt_l2cap_control *control,
 			struct sk_buff_head *skbs, u8 event);
 
+int l2cap_sock_le_params_valid(struct bt_le_params *le_params);
 void l2cap_sock_set_timer(struct sock *sk, long timeout);
 void l2cap_sock_clear_timer(struct sock *sk);
 void __l2cap_sock_close(struct sock *sk, int reason);