Bluetooth: Add LE SecMgr and mgmtops support

Enabled ECB Block encoding for Low Energy pairing
Implemented missing components of MGMTOPS interface
Differentiated as needed between BR/EDR pairing and LE pairing

Signed-off-by: Brian Gix <bgix@codeaurora.org>

Conflicts:

	net/bluetooth/mgmt.c
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b095e99..65af37f 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -60,7 +60,7 @@
 
 static DEFINE_RWLOCK(hci_task_lock);
 
-static int enable_smp;
+static int enable_smp = 1;
 
 /* HCI device list */
 LIST_HEAD(hci_dev_list);
@@ -962,7 +962,7 @@
 
 	BT_DBG("%s", hdev->name);
 
-	if (hci_dev_open(hdev->id) < 0)
+	if (hci_dev_open(hdev->id) < 0 && !test_bit(HCI_UP, &hdev->flags))
 		return;
 
 	if (test_bit(HCI_AUTO_OFF, &hdev->flags))
@@ -1097,7 +1097,9 @@
 						u8 *val, u8 type, u8 pin_len)
 {
 	struct link_key *key, *old_key;
+	struct hci_conn *conn;
 	u8 old_key_type;
+	u8 bonded = 0;
 
 	old_key = hci_find_link_key(hdev, bdaddr);
 	if (old_key) {
@@ -1115,11 +1117,17 @@
 
 	bacpy(&key->bdaddr, bdaddr);
 	memcpy(key->val, val, 16);
+	key->auth = 0x01;
 	key->type = type;
 	key->pin_len = pin_len;
 
+	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, bdaddr);
+
+	if (conn && (conn->auth_type > 0x01 || conn->remote_auth > 0x01))
+		bonded = 1;
+
 	if (new_key)
-		mgmt_new_key(hdev->id, key, old_key_type);
+		mgmt_new_key(hdev->id, key, bonded);
 
 	if (type == 0x06)
 		key->type = old_key_type;
@@ -1128,24 +1136,22 @@
 }
 
 int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
-			u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16])
+			u8 key_size, u8 auth, __le16 ediv, u8 rand[8],
+			u8 ltk[16])
 {
 	struct link_key *key, *old_key;
 	struct key_master_id *id;
-	u8 old_key_type;
 
-	BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
+	BT_DBG("%s Auth: %2.2X addr %s", hdev->name, auth, batostr(bdaddr));
 
 	old_key = hci_find_link_key_type(hdev, bdaddr, KEY_TYPE_LTK);
 	if (old_key) {
 		key = old_key;
-		old_key_type = old_key->type;
 	} else {
 		key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
 		if (!key)
 			return -ENOMEM;
 		list_add(&key->list, &hdev->link_keys);
-		old_key_type = 0xff;
 	}
 
 	key->dlen = sizeof(*id);
@@ -1154,13 +1160,14 @@
 	memcpy(key->val, ltk, sizeof(key->val));
 	key->type = KEY_TYPE_LTK;
 	key->pin_len = key_size;
+	key->auth = auth;
 
 	id = (void *) &key->data;
 	id->ediv = ediv;
 	memcpy(id->rand, rand, sizeof(id->rand));
 
 	if (new_key)
-		mgmt_new_key(hdev->id, key, old_key_type);
+		mgmt_new_key(hdev->id, key, auth & 0x01);
 
 	return 0;
 }
@@ -1243,6 +1250,7 @@
 {
 	struct list_head *p, *n;
 
+	BT_DBG("");
 	write_lock_bh(&hdev->adv_entries_lock);
 
 	list_for_each_safe(p, n, &hdev->adv_entries) {
@@ -1264,6 +1272,7 @@
 	struct list_head *p;
 	struct adv_entry *res = NULL;
 
+	BT_DBG("");
 	read_lock_bh(&hdev->adv_entries_lock);
 
 	list_for_each(p, &hdev->adv_entries) {
@@ -1318,6 +1327,8 @@
 {
 	struct adv_entry *entry;
 
+	BT_DBG("");
+
 	if (!is_connectable_adv(ev->evt_type))
 		return -EINVAL;