diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hci_core.c | 101 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 87 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 216 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 69 | ||||
-rw-r--r-- | net/bluetooth/lib.c | 23 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 148 | ||||
-rw-r--r-- | net/bluetooth/sco.c | 4 | ||||
-rw-r--r-- | net/bluetooth/smp.c | 208 | ||||
-rw-r--r-- | net/mac80211/aes_ccm.c | 37 | ||||
-rw-r--r-- | net/mac80211/aes_ccm.h | 2 | ||||
-rw-r--r-- | net/mac80211/aes_cmac.c | 10 | ||||
-rw-r--r-- | net/mac80211/aes_cmac.h | 2 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 27 | ||||
-rw-r--r-- | net/mac80211/debugfs_key.c | 13 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 8 | ||||
-rw-r--r-- | net/mac80211/driver-trace.h | 46 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 27 | ||||
-rw-r--r-- | net/mac80211/iface.c | 7 | ||||
-rw-r--r-- | net/mac80211/key.c | 75 | ||||
-rw-r--r-- | net/mac80211/key.h | 32 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 58 | ||||
-rw-r--r-- | net/mac80211/rx.c | 36 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 3 | ||||
-rw-r--r-- | net/mac80211/tkip.c | 108 | ||||
-rw-r--r-- | net/mac80211/tkip.h | 8 | ||||
-rw-r--r-- | net/mac80211/tx.c | 3 | ||||
-rw-r--r-- | net/mac80211/util.c | 67 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 94 | ||||
-rw-r--r-- | net/wireless/scan.c | 2 |
29 files changed, 1077 insertions, 444 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index b18db5628275..ec0bc3f60f2e 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -60,8 +60,6 @@ static void hci_tx_task(unsigned long arg); | |||
60 | 60 | ||
61 | static DEFINE_RWLOCK(hci_task_lock); | 61 | static DEFINE_RWLOCK(hci_task_lock); |
62 | 62 | ||
63 | static int enable_smp; | ||
64 | |||
65 | /* HCI device list */ | 63 | /* HCI device list */ |
66 | LIST_HEAD(hci_dev_list); | 64 | LIST_HEAD(hci_dev_list); |
67 | DEFINE_RWLOCK(hci_dev_list_lock); | 65 | DEFINE_RWLOCK(hci_dev_list_lock); |
@@ -148,7 +146,7 @@ static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, | |||
148 | 146 | ||
149 | switch (hdev->req_status) { | 147 | switch (hdev->req_status) { |
150 | case HCI_REQ_DONE: | 148 | case HCI_REQ_DONE: |
151 | err = -bt_err(hdev->req_result); | 149 | err = -bt_to_errno(hdev->req_result); |
152 | break; | 150 | break; |
153 | 151 | ||
154 | case HCI_REQ_CANCELED: | 152 | case HCI_REQ_CANCELED: |
@@ -542,7 +540,7 @@ int hci_dev_open(__u16 dev) | |||
542 | ret = __hci_request(hdev, hci_init_req, 0, | 540 | ret = __hci_request(hdev, hci_init_req, 0, |
543 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | 541 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); |
544 | 542 | ||
545 | if (lmp_le_capable(hdev)) | 543 | if (lmp_host_le_capable(hdev)) |
546 | ret = __hci_request(hdev, hci_le_init_req, 0, | 544 | ret = __hci_request(hdev, hci_le_init_req, 0, |
547 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | 545 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); |
548 | 546 | ||
@@ -1059,6 +1057,42 @@ static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, | |||
1059 | return 0; | 1057 | return 0; |
1060 | } | 1058 | } |
1061 | 1059 | ||
1060 | struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) | ||
1061 | { | ||
1062 | struct link_key *k; | ||
1063 | |||
1064 | list_for_each_entry(k, &hdev->link_keys, list) { | ||
1065 | struct key_master_id *id; | ||
1066 | |||
1067 | if (k->type != HCI_LK_SMP_LTK) | ||
1068 | continue; | ||
1069 | |||
1070 | if (k->dlen != sizeof(*id)) | ||
1071 | continue; | ||
1072 | |||
1073 | id = (void *) &k->data; | ||
1074 | if (id->ediv == ediv && | ||
1075 | (memcmp(rand, id->rand, sizeof(id->rand)) == 0)) | ||
1076 | return k; | ||
1077 | } | ||
1078 | |||
1079 | return NULL; | ||
1080 | } | ||
1081 | EXPORT_SYMBOL(hci_find_ltk); | ||
1082 | |||
1083 | struct link_key *hci_find_link_key_type(struct hci_dev *hdev, | ||
1084 | bdaddr_t *bdaddr, u8 type) | ||
1085 | { | ||
1086 | struct link_key *k; | ||
1087 | |||
1088 | list_for_each_entry(k, &hdev->link_keys, list) | ||
1089 | if (k->type == type && bacmp(bdaddr, &k->bdaddr) == 0) | ||
1090 | return k; | ||
1091 | |||
1092 | return NULL; | ||
1093 | } | ||
1094 | EXPORT_SYMBOL(hci_find_link_key_type); | ||
1095 | |||
1062 | int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, | 1096 | int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, |
1063 | bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) | 1097 | bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) |
1064 | { | 1098 | { |
@@ -1114,6 +1148,44 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, | |||
1114 | return 0; | 1148 | return 0; |
1115 | } | 1149 | } |
1116 | 1150 | ||
1151 | int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, | ||
1152 | u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]) | ||
1153 | { | ||
1154 | struct link_key *key, *old_key; | ||
1155 | struct key_master_id *id; | ||
1156 | u8 old_key_type; | ||
1157 | |||
1158 | BT_DBG("%s addr %s", hdev->name, batostr(bdaddr)); | ||
1159 | |||
1160 | old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK); | ||
1161 | if (old_key) { | ||
1162 | key = old_key; | ||
1163 | old_key_type = old_key->type; | ||
1164 | } else { | ||
1165 | key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC); | ||
1166 | if (!key) | ||
1167 | return -ENOMEM; | ||
1168 | list_add(&key->list, &hdev->link_keys); | ||
1169 | old_key_type = 0xff; | ||
1170 | } | ||
1171 | |||
1172 | key->dlen = sizeof(*id); | ||
1173 | |||
1174 | bacpy(&key->bdaddr, bdaddr); | ||
1175 | memcpy(key->val, ltk, sizeof(key->val)); | ||
1176 | key->type = HCI_LK_SMP_LTK; | ||
1177 | key->pin_len = key_size; | ||
1178 | |||
1179 | id = (void *) &key->data; | ||
1180 | id->ediv = ediv; | ||
1181 | memcpy(id->rand, rand, sizeof(id->rand)); | ||
1182 | |||
1183 | if (new_key) | ||
1184 | mgmt_new_key(hdev->id, key, old_key_type); | ||
1185 | |||
1186 | return 0; | ||
1187 | } | ||
1188 | |||
1117 | int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) | 1189 | int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) |
1118 | { | 1190 | { |
1119 | struct link_key *key; | 1191 | struct link_key *key; |
@@ -1246,7 +1318,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1246 | if (bacmp(bdaddr, BDADDR_ANY) == 0) | 1318 | if (bacmp(bdaddr, BDADDR_ANY) == 0) |
1247 | return -EBADF; | 1319 | return -EBADF; |
1248 | 1320 | ||
1249 | hci_dev_lock(hdev); | 1321 | hci_dev_lock_bh(hdev); |
1250 | 1322 | ||
1251 | if (hci_blacklist_lookup(hdev, bdaddr)) { | 1323 | if (hci_blacklist_lookup(hdev, bdaddr)) { |
1252 | err = -EEXIST; | 1324 | err = -EEXIST; |
@@ -1266,7 +1338,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1266 | err = 0; | 1338 | err = 0; |
1267 | 1339 | ||
1268 | err: | 1340 | err: |
1269 | hci_dev_unlock(hdev); | 1341 | hci_dev_unlock_bh(hdev); |
1270 | return err; | 1342 | return err; |
1271 | } | 1343 | } |
1272 | 1344 | ||
@@ -1275,7 +1347,7 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1275 | struct bdaddr_list *entry; | 1347 | struct bdaddr_list *entry; |
1276 | int err = 0; | 1348 | int err = 0; |
1277 | 1349 | ||
1278 | hci_dev_lock(hdev); | 1350 | hci_dev_lock_bh(hdev); |
1279 | 1351 | ||
1280 | if (bacmp(bdaddr, BDADDR_ANY) == 0) { | 1352 | if (bacmp(bdaddr, BDADDR_ANY) == 0) { |
1281 | hci_blacklist_clear(hdev); | 1353 | hci_blacklist_clear(hdev); |
@@ -1292,7 +1364,7 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1292 | kfree(entry); | 1364 | kfree(entry); |
1293 | 1365 | ||
1294 | done: | 1366 | done: |
1295 | hci_dev_unlock(hdev); | 1367 | hci_dev_unlock_bh(hdev); |
1296 | return err; | 1368 | return err; |
1297 | } | 1369 | } |
1298 | 1370 | ||
@@ -1368,14 +1440,6 @@ int hci_add_adv_entry(struct hci_dev *hdev, | |||
1368 | return 0; | 1440 | return 0; |
1369 | } | 1441 | } |
1370 | 1442 | ||
1371 | static struct crypto_blkcipher *alloc_cypher(void) | ||
1372 | { | ||
1373 | if (enable_smp) | ||
1374 | return crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); | ||
1375 | |||
1376 | return ERR_PTR(-ENOTSUPP); | ||
1377 | } | ||
1378 | |||
1379 | /* Register HCI device */ | 1443 | /* Register HCI device */ |
1380 | int hci_register_dev(struct hci_dev *hdev) | 1444 | int hci_register_dev(struct hci_dev *hdev) |
1381 | { | 1445 | { |
@@ -1460,7 +1524,7 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1460 | if (!hdev->workqueue) | 1524 | if (!hdev->workqueue) |
1461 | goto nomem; | 1525 | goto nomem; |
1462 | 1526 | ||
1463 | hdev->tfm = alloc_cypher(); | 1527 | hdev->tfm = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); |
1464 | if (IS_ERR(hdev->tfm)) | 1528 | if (IS_ERR(hdev->tfm)) |
1465 | BT_INFO("Failed to load transform for ecb(aes): %ld", | 1529 | BT_INFO("Failed to load transform for ecb(aes): %ld", |
1466 | PTR_ERR(hdev->tfm)); | 1530 | PTR_ERR(hdev->tfm)); |
@@ -2352,6 +2416,3 @@ static void hci_cmd_task(unsigned long arg) | |||
2352 | } | 2416 | } |
2353 | } | 2417 | } |
2354 | } | 2418 | } |
2355 | |||
2356 | module_param(enable_smp, bool, 0644); | ||
2357 | MODULE_PARM_DESC(enable_smp, "Enable SMP support (LE only)"); | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index ac2c5e89617c..a40170e022e8 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -45,6 +45,8 @@ | |||
45 | #include <net/bluetooth/bluetooth.h> | 45 | #include <net/bluetooth/bluetooth.h> |
46 | #include <net/bluetooth/hci_core.h> | 46 | #include <net/bluetooth/hci_core.h> |
47 | 47 | ||
48 | static int enable_le; | ||
49 | |||
48 | /* Handle HCI Event packets */ | 50 | /* Handle HCI Event packets */ |
49 | 51 | ||
50 | static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) | 52 | static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -525,6 +527,20 @@ static void hci_setup_event_mask(struct hci_dev *hdev) | |||
525 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); | 527 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); |
526 | } | 528 | } |
527 | 529 | ||
530 | static void hci_set_le_support(struct hci_dev *hdev) | ||
531 | { | ||
532 | struct hci_cp_write_le_host_supported cp; | ||
533 | |||
534 | memset(&cp, 0, sizeof(cp)); | ||
535 | |||
536 | if (enable_le) { | ||
537 | cp.le = 1; | ||
538 | cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); | ||
539 | } | ||
540 | |||
541 | hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp); | ||
542 | } | ||
543 | |||
528 | static void hci_setup(struct hci_dev *hdev) | 544 | static void hci_setup(struct hci_dev *hdev) |
529 | { | 545 | { |
530 | hci_setup_event_mask(hdev); | 546 | hci_setup_event_mask(hdev); |
@@ -542,6 +558,17 @@ static void hci_setup(struct hci_dev *hdev) | |||
542 | 558 | ||
543 | if (hdev->features[7] & LMP_INQ_TX_PWR) | 559 | if (hdev->features[7] & LMP_INQ_TX_PWR) |
544 | hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); | 560 | hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); |
561 | |||
562 | if (hdev->features[7] & LMP_EXTFEATURES) { | ||
563 | struct hci_cp_read_local_ext_features cp; | ||
564 | |||
565 | cp.page = 0x01; | ||
566 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, | ||
567 | sizeof(cp), &cp); | ||
568 | } | ||
569 | |||
570 | if (hdev->features[4] & LMP_LE) | ||
571 | hci_set_le_support(hdev); | ||
545 | } | 572 | } |
546 | 573 | ||
547 | static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) | 574 | static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -658,6 +685,21 @@ static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb | |||
658 | hdev->features[6], hdev->features[7]); | 685 | hdev->features[6], hdev->features[7]); |
659 | } | 686 | } |
660 | 687 | ||
688 | static void hci_cc_read_local_ext_features(struct hci_dev *hdev, | ||
689 | struct sk_buff *skb) | ||
690 | { | ||
691 | struct hci_rp_read_local_ext_features *rp = (void *) skb->data; | ||
692 | |||
693 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
694 | |||
695 | if (rp->status) | ||
696 | return; | ||
697 | |||
698 | memcpy(hdev->extfeatures, rp->features, 8); | ||
699 | |||
700 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status); | ||
701 | } | ||
702 | |||
661 | static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) | 703 | static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) |
662 | { | 704 | { |
663 | struct hci_rp_read_buffer_size *rp = (void *) skb->data; | 705 | struct hci_rp_read_buffer_size *rp = (void *) skb->data; |
@@ -892,6 +934,21 @@ static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
892 | hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status); | 934 | hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status); |
893 | } | 935 | } |
894 | 936 | ||
937 | static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev, | ||
938 | struct sk_buff *skb) | ||
939 | { | ||
940 | struct hci_cp_read_local_ext_features cp; | ||
941 | __u8 status = *((__u8 *) skb->data); | ||
942 | |||
943 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
944 | |||
945 | if (status) | ||
946 | return; | ||
947 | |||
948 | cp.page = 0x01; | ||
949 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp); | ||
950 | } | ||
951 | |||
895 | static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | 952 | static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) |
896 | { | 953 | { |
897 | BT_DBG("%s status 0x%x", hdev->name, status); | 954 | BT_DBG("%s status 0x%x", hdev->name, status); |
@@ -1826,6 +1883,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1826 | hci_cc_read_local_features(hdev, skb); | 1883 | hci_cc_read_local_features(hdev, skb); |
1827 | break; | 1884 | break; |
1828 | 1885 | ||
1886 | case HCI_OP_READ_LOCAL_EXT_FEATURES: | ||
1887 | hci_cc_read_local_ext_features(hdev, skb); | ||
1888 | break; | ||
1889 | |||
1829 | case HCI_OP_READ_BUFFER_SIZE: | 1890 | case HCI_OP_READ_BUFFER_SIZE: |
1830 | hci_cc_read_buffer_size(hdev, skb); | 1891 | hci_cc_read_buffer_size(hdev, skb); |
1831 | break; | 1892 | break; |
@@ -1894,6 +1955,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1894 | hci_cc_le_ltk_neg_reply(hdev, skb); | 1955 | hci_cc_le_ltk_neg_reply(hdev, skb); |
1895 | break; | 1956 | break; |
1896 | 1957 | ||
1958 | case HCI_OP_WRITE_LE_HOST_SUPPORTED: | ||
1959 | hci_cc_write_le_host_supported(hdev, skb); | ||
1960 | break; | ||
1961 | |||
1897 | default: | 1962 | default: |
1898 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); | 1963 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); |
1899 | break; | 1964 | break; |
@@ -2793,21 +2858,36 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev, | |||
2793 | { | 2858 | { |
2794 | struct hci_ev_le_ltk_req *ev = (void *) skb->data; | 2859 | struct hci_ev_le_ltk_req *ev = (void *) skb->data; |
2795 | struct hci_cp_le_ltk_reply cp; | 2860 | struct hci_cp_le_ltk_reply cp; |
2861 | struct hci_cp_le_ltk_neg_reply neg; | ||
2796 | struct hci_conn *conn; | 2862 | struct hci_conn *conn; |
2863 | struct link_key *ltk; | ||
2797 | 2864 | ||
2798 | BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle)); | 2865 | BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle)); |
2799 | 2866 | ||
2800 | hci_dev_lock(hdev); | 2867 | hci_dev_lock(hdev); |
2801 | 2868 | ||
2802 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | 2869 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
2870 | if (conn == NULL) | ||
2871 | goto not_found; | ||
2803 | 2872 | ||
2804 | memset(&cp, 0, sizeof(cp)); | 2873 | ltk = hci_find_ltk(hdev, ev->ediv, ev->random); |
2874 | if (ltk == NULL) | ||
2875 | goto not_found; | ||
2876 | |||
2877 | memcpy(cp.ltk, ltk->val, sizeof(ltk->val)); | ||
2805 | cp.handle = cpu_to_le16(conn->handle); | 2878 | cp.handle = cpu_to_le16(conn->handle); |
2806 | memcpy(cp.ltk, conn->ltk, sizeof(conn->ltk)); | 2879 | conn->pin_length = ltk->pin_len; |
2807 | 2880 | ||
2808 | hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); | 2881 | hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); |
2809 | 2882 | ||
2810 | hci_dev_unlock(hdev); | 2883 | hci_dev_unlock(hdev); |
2884 | |||
2885 | return; | ||
2886 | |||
2887 | not_found: | ||
2888 | neg.handle = ev->handle; | ||
2889 | hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg); | ||
2890 | hci_dev_unlock(hdev); | ||
2811 | } | 2891 | } |
2812 | 2892 | ||
2813 | static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2893 | static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -3022,3 +3102,6 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data) | |||
3022 | hci_send_to_sock(hdev, skb, NULL); | 3102 | hci_send_to_sock(hdev, skb, NULL); |
3023 | kfree_skb(skb); | 3103 | kfree_skb(skb); |
3024 | } | 3104 | } |
3105 | |||
3106 | module_param(enable_le, bool, 0444); | ||
3107 | MODULE_PARM_DESC(enable_le, "Enable LE support"); | ||
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index fc219ec28711..f7f8e2cd3f70 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -61,13 +61,9 @@ int disable_ertm; | |||
61 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; | 61 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; |
62 | static u8 l2cap_fixed_chan[8] = { 0x02, }; | 62 | static u8 l2cap_fixed_chan[8] = { 0x02, }; |
63 | 63 | ||
64 | static struct workqueue_struct *_busy_wq; | ||
65 | |||
66 | static LIST_HEAD(chan_list); | 64 | static LIST_HEAD(chan_list); |
67 | static DEFINE_RWLOCK(chan_list_lock); | 65 | static DEFINE_RWLOCK(chan_list_lock); |
68 | 66 | ||
69 | static void l2cap_busy_work(struct work_struct *work); | ||
70 | |||
71 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, | 67 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, |
72 | u8 code, u8 ident, u16 dlen, void *data); | 68 | u8 code, u8 ident, u16 dlen, void *data); |
73 | static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, | 69 | static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, |
@@ -223,18 +219,18 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn) | |||
223 | 219 | ||
224 | static void l2cap_set_timer(struct l2cap_chan *chan, struct timer_list *timer, long timeout) | 220 | static void l2cap_set_timer(struct l2cap_chan *chan, struct timer_list *timer, long timeout) |
225 | { | 221 | { |
226 | BT_DBG("chan %p state %d timeout %ld", chan->sk, chan->state, timeout); | 222 | BT_DBG("chan %p state %d timeout %ld", chan->sk, chan->state, timeout); |
227 | 223 | ||
228 | if (!mod_timer(timer, jiffies + timeout)) | 224 | if (!mod_timer(timer, jiffies + msecs_to_jiffies(timeout))) |
229 | chan_hold(chan); | 225 | chan_hold(chan); |
230 | } | 226 | } |
231 | 227 | ||
232 | static void l2cap_clear_timer(struct l2cap_chan *chan, struct timer_list *timer) | 228 | static void l2cap_clear_timer(struct l2cap_chan *chan, struct timer_list *timer) |
233 | { | 229 | { |
234 | BT_DBG("chan %p state %d", chan, chan->state); | 230 | BT_DBG("chan %p state %d", chan, chan->state); |
235 | 231 | ||
236 | if (timer_pending(timer) && del_timer(timer)) | 232 | if (timer_pending(timer) && del_timer(timer)) |
237 | chan_put(chan); | 233 | chan_put(chan); |
238 | } | 234 | } |
239 | 235 | ||
240 | static void l2cap_state_change(struct l2cap_chan *chan, int state) | 236 | static void l2cap_state_change(struct l2cap_chan *chan, int state) |
@@ -395,7 +391,6 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
395 | __clear_ack_timer(chan); | 391 | __clear_ack_timer(chan); |
396 | 392 | ||
397 | skb_queue_purge(&chan->srej_q); | 393 | skb_queue_purge(&chan->srej_q); |
398 | skb_queue_purge(&chan->busy_q); | ||
399 | 394 | ||
400 | list_for_each_entry_safe(l, tmp, &chan->srej_l, list) { | 395 | list_for_each_entry_safe(l, tmp, &chan->srej_l, list) { |
401 | list_del(&l->list); | 396 | list_del(&l->list); |
@@ -741,9 +736,9 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
741 | &chan->conf_state)) { | 736 | &chan->conf_state)) { |
742 | /* l2cap_chan_close() calls list_del(chan) | 737 | /* l2cap_chan_close() calls list_del(chan) |
743 | * so release the lock */ | 738 | * so release the lock */ |
744 | read_unlock_bh(&conn->chan_lock); | 739 | read_unlock(&conn->chan_lock); |
745 | l2cap_chan_close(chan, ECONNRESET); | 740 | l2cap_chan_close(chan, ECONNRESET); |
746 | read_lock_bh(&conn->chan_lock); | 741 | read_lock(&conn->chan_lock); |
747 | bh_unlock_sock(sk); | 742 | bh_unlock_sock(sk); |
748 | continue; | 743 | continue; |
749 | } | 744 | } |
@@ -1873,11 +1868,9 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan) | |||
1873 | setup_timer(&chan->ack_timer, l2cap_ack_timeout, (unsigned long) chan); | 1868 | setup_timer(&chan->ack_timer, l2cap_ack_timeout, (unsigned long) chan); |
1874 | 1869 | ||
1875 | skb_queue_head_init(&chan->srej_q); | 1870 | skb_queue_head_init(&chan->srej_q); |
1876 | skb_queue_head_init(&chan->busy_q); | ||
1877 | 1871 | ||
1878 | INIT_LIST_HEAD(&chan->srej_l); | 1872 | INIT_LIST_HEAD(&chan->srej_l); |
1879 | 1873 | ||
1880 | INIT_WORK(&chan->busy_work, l2cap_busy_work); | ||
1881 | 1874 | ||
1882 | sk->sk_backlog_rcv = l2cap_ertm_data_rcv; | 1875 | sk->sk_backlog_rcv = l2cap_ertm_data_rcv; |
1883 | } | 1876 | } |
@@ -2284,9 +2277,9 @@ done: | |||
2284 | 2277 | ||
2285 | static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) | 2278 | static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) |
2286 | { | 2279 | { |
2287 | struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data; | 2280 | struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data; |
2288 | 2281 | ||
2289 | if (rej->reason != 0x0000) | 2282 | if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD) |
2290 | return 0; | 2283 | return 0; |
2291 | 2284 | ||
2292 | if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) && | 2285 | if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) && |
@@ -2532,9 +2525,12 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2532 | 2525 | ||
2533 | if ((bt_sk(sk)->defer_setup && chan->state != BT_CONNECT2) || | 2526 | if ((bt_sk(sk)->defer_setup && chan->state != BT_CONNECT2) || |
2534 | (!bt_sk(sk)->defer_setup && chan->state != BT_CONFIG)) { | 2527 | (!bt_sk(sk)->defer_setup && chan->state != BT_CONFIG)) { |
2535 | struct l2cap_cmd_rej rej; | 2528 | struct l2cap_cmd_rej_cid rej; |
2529 | |||
2530 | rej.reason = cpu_to_le16(L2CAP_REJ_INVALID_CID); | ||
2531 | rej.scid = cpu_to_le16(chan->scid); | ||
2532 | rej.dcid = cpu_to_le16(chan->dcid); | ||
2536 | 2533 | ||
2537 | rej.reason = cpu_to_le16(0x0002); | ||
2538 | l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, | 2534 | l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, |
2539 | sizeof(rej), &rej); | 2535 | sizeof(rej), &rej); |
2540 | goto unlock; | 2536 | goto unlock; |
@@ -3025,12 +3021,12 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, | |||
3025 | err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data); | 3021 | err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data); |
3026 | 3022 | ||
3027 | if (err) { | 3023 | if (err) { |
3028 | struct l2cap_cmd_rej rej; | 3024 | struct l2cap_cmd_rej_unk rej; |
3029 | 3025 | ||
3030 | BT_ERR("Wrong link type (%d)", err); | 3026 | BT_ERR("Wrong link type (%d)", err); |
3031 | 3027 | ||
3032 | /* FIXME: Map err to a valid reason */ | 3028 | /* FIXME: Map err to a valid reason */ |
3033 | rej.reason = cpu_to_le16(0); | 3029 | rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); |
3034 | l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); | 3030 | l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); |
3035 | } | 3031 | } |
3036 | 3032 | ||
@@ -3183,32 +3179,27 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk | |||
3183 | if (!chan->sdu) | 3179 | if (!chan->sdu) |
3184 | goto disconnect; | 3180 | goto disconnect; |
3185 | 3181 | ||
3186 | if (!test_bit(CONN_SAR_RETRY, &chan->conn_state)) { | 3182 | chan->partial_sdu_len += skb->len; |
3187 | chan->partial_sdu_len += skb->len; | ||
3188 | 3183 | ||
3189 | if (chan->partial_sdu_len > chan->imtu) | 3184 | if (chan->partial_sdu_len > chan->imtu) |
3190 | goto drop; | 3185 | goto drop; |
3191 | 3186 | ||
3192 | if (chan->partial_sdu_len != chan->sdu_len) | 3187 | if (chan->partial_sdu_len != chan->sdu_len) |
3193 | goto drop; | 3188 | goto drop; |
3194 | 3189 | ||
3195 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); | 3190 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); |
3196 | } | ||
3197 | 3191 | ||
3198 | _skb = skb_clone(chan->sdu, GFP_ATOMIC); | 3192 | _skb = skb_clone(chan->sdu, GFP_ATOMIC); |
3199 | if (!_skb) { | 3193 | if (!_skb) { |
3200 | set_bit(CONN_SAR_RETRY, &chan->conn_state); | ||
3201 | return -ENOMEM; | 3194 | return -ENOMEM; |
3202 | } | 3195 | } |
3203 | 3196 | ||
3204 | err = chan->ops->recv(chan->data, _skb); | 3197 | err = chan->ops->recv(chan->data, _skb); |
3205 | if (err < 0) { | 3198 | if (err < 0) { |
3206 | kfree_skb(_skb); | 3199 | kfree_skb(_skb); |
3207 | set_bit(CONN_SAR_RETRY, &chan->conn_state); | ||
3208 | return err; | 3200 | return err; |
3209 | } | 3201 | } |
3210 | 3202 | ||
3211 | clear_bit(CONN_SAR_RETRY, &chan->conn_state); | ||
3212 | clear_bit(CONN_SAR_SDU, &chan->conn_state); | 3203 | clear_bit(CONN_SAR_SDU, &chan->conn_state); |
3213 | 3204 | ||
3214 | kfree_skb(chan->sdu); | 3205 | kfree_skb(chan->sdu); |
@@ -3228,22 +3219,26 @@ disconnect: | |||
3228 | return 0; | 3219 | return 0; |
3229 | } | 3220 | } |
3230 | 3221 | ||
3231 | static int l2cap_try_push_rx_skb(struct l2cap_chan *chan) | 3222 | static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan) |
3232 | { | 3223 | { |
3233 | struct sk_buff *skb; | ||
3234 | u16 control; | 3224 | u16 control; |
3235 | int err; | ||
3236 | 3225 | ||
3237 | while ((skb = skb_dequeue(&chan->busy_q))) { | 3226 | BT_DBG("chan %p, Enter local busy", chan); |
3238 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; | ||
3239 | err = l2cap_ertm_reassembly_sdu(chan, skb, control); | ||
3240 | if (err < 0) { | ||
3241 | skb_queue_head(&chan->busy_q, skb); | ||
3242 | return -EBUSY; | ||
3243 | } | ||
3244 | 3227 | ||
3245 | chan->buffer_seq = (chan->buffer_seq + 1) % 64; | 3228 | set_bit(CONN_LOCAL_BUSY, &chan->conn_state); |
3246 | } | 3229 | |
3230 | control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | ||
3231 | control |= L2CAP_SUPER_RCV_NOT_READY; | ||
3232 | l2cap_send_sframe(chan, control); | ||
3233 | |||
3234 | set_bit(CONN_RNR_SENT, &chan->conn_state); | ||
3235 | |||
3236 | __clear_ack_timer(chan); | ||
3237 | } | ||
3238 | |||
3239 | static void l2cap_ertm_exit_local_busy(struct l2cap_chan *chan) | ||
3240 | { | ||
3241 | u16 control; | ||
3247 | 3242 | ||
3248 | if (!test_bit(CONN_RNR_SENT, &chan->conn_state)) | 3243 | if (!test_bit(CONN_RNR_SENT, &chan->conn_state)) |
3249 | goto done; | 3244 | goto done; |
@@ -3263,93 +3258,16 @@ done: | |||
3263 | clear_bit(CONN_RNR_SENT, &chan->conn_state); | 3258 | clear_bit(CONN_RNR_SENT, &chan->conn_state); |
3264 | 3259 | ||
3265 | BT_DBG("chan %p, Exit local busy", chan); | 3260 | BT_DBG("chan %p, Exit local busy", chan); |
3266 | |||
3267 | return 0; | ||
3268 | } | 3261 | } |
3269 | 3262 | ||
3270 | static void l2cap_busy_work(struct work_struct *work) | 3263 | void l2cap_chan_busy(struct l2cap_chan *chan, int busy) |
3271 | { | 3264 | { |
3272 | DECLARE_WAITQUEUE(wait, current); | 3265 | if (chan->mode == L2CAP_MODE_ERTM) { |
3273 | struct l2cap_chan *chan = | 3266 | if (busy) |
3274 | container_of(work, struct l2cap_chan, busy_work); | 3267 | l2cap_ertm_enter_local_busy(chan); |
3275 | struct sock *sk = chan->sk; | 3268 | else |
3276 | int n_tries = 0, timeo = HZ/5, err; | 3269 | l2cap_ertm_exit_local_busy(chan); |
3277 | struct sk_buff *skb; | ||
3278 | |||
3279 | lock_sock(sk); | ||
3280 | |||
3281 | add_wait_queue(sk_sleep(sk), &wait); | ||
3282 | while ((skb = skb_peek(&chan->busy_q))) { | ||
3283 | set_current_state(TASK_INTERRUPTIBLE); | ||
3284 | |||
3285 | if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) { | ||
3286 | err = -EBUSY; | ||
3287 | l2cap_send_disconn_req(chan->conn, chan, EBUSY); | ||
3288 | break; | ||
3289 | } | ||
3290 | |||
3291 | if (!timeo) | ||
3292 | timeo = HZ/5; | ||
3293 | |||
3294 | if (signal_pending(current)) { | ||
3295 | err = sock_intr_errno(timeo); | ||
3296 | break; | ||
3297 | } | ||
3298 | |||
3299 | release_sock(sk); | ||
3300 | timeo = schedule_timeout(timeo); | ||
3301 | lock_sock(sk); | ||
3302 | |||
3303 | err = sock_error(sk); | ||
3304 | if (err) | ||
3305 | break; | ||
3306 | |||
3307 | if (l2cap_try_push_rx_skb(chan) == 0) | ||
3308 | break; | ||
3309 | } | ||
3310 | |||
3311 | set_current_state(TASK_RUNNING); | ||
3312 | remove_wait_queue(sk_sleep(sk), &wait); | ||
3313 | |||
3314 | release_sock(sk); | ||
3315 | } | ||
3316 | |||
3317 | static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) | ||
3318 | { | ||
3319 | int sctrl, err; | ||
3320 | |||
3321 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { | ||
3322 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; | ||
3323 | __skb_queue_tail(&chan->busy_q, skb); | ||
3324 | return l2cap_try_push_rx_skb(chan); | ||
3325 | |||
3326 | |||
3327 | } | ||
3328 | |||
3329 | err = l2cap_ertm_reassembly_sdu(chan, skb, control); | ||
3330 | if (err >= 0) { | ||
3331 | chan->buffer_seq = (chan->buffer_seq + 1) % 64; | ||
3332 | return err; | ||
3333 | } | 3270 | } |
3334 | |||
3335 | /* Busy Condition */ | ||
3336 | BT_DBG("chan %p, Enter local busy", chan); | ||
3337 | |||
3338 | set_bit(CONN_LOCAL_BUSY, &chan->conn_state); | ||
3339 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; | ||
3340 | __skb_queue_tail(&chan->busy_q, skb); | ||
3341 | |||
3342 | sctrl = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | ||
3343 | sctrl |= L2CAP_SUPER_RCV_NOT_READY; | ||
3344 | l2cap_send_sframe(chan, sctrl); | ||
3345 | |||
3346 | set_bit(CONN_RNR_SENT, &chan->conn_state); | ||
3347 | |||
3348 | __clear_ack_timer(chan); | ||
3349 | |||
3350 | queue_work(_busy_wq, &chan->busy_work); | ||
3351 | |||
3352 | return err; | ||
3353 | } | 3271 | } |
3354 | 3272 | ||
3355 | static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) | 3273 | static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) |
@@ -3450,13 +3368,22 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) | |||
3450 | struct sk_buff *skb; | 3368 | struct sk_buff *skb; |
3451 | u16 control; | 3369 | u16 control; |
3452 | 3370 | ||
3453 | while ((skb = skb_peek(&chan->srej_q))) { | 3371 | while ((skb = skb_peek(&chan->srej_q)) && |
3372 | !test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { | ||
3373 | int err; | ||
3374 | |||
3454 | if (bt_cb(skb)->tx_seq != tx_seq) | 3375 | if (bt_cb(skb)->tx_seq != tx_seq) |
3455 | break; | 3376 | break; |
3456 | 3377 | ||
3457 | skb = skb_dequeue(&chan->srej_q); | 3378 | skb = skb_dequeue(&chan->srej_q); |
3458 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; | 3379 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; |
3459 | l2cap_ertm_reassembly_sdu(chan, skb, control); | 3380 | err = l2cap_ertm_reassembly_sdu(chan, skb, control); |
3381 | |||
3382 | if (err < 0) { | ||
3383 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | ||
3384 | break; | ||
3385 | } | ||
3386 | |||
3460 | chan->buffer_seq_srej = | 3387 | chan->buffer_seq_srej = |
3461 | (chan->buffer_seq_srej + 1) % 64; | 3388 | (chan->buffer_seq_srej + 1) % 64; |
3462 | tx_seq = (tx_seq + 1) % 64; | 3389 | tx_seq = (tx_seq + 1) % 64; |
@@ -3523,9 +3450,6 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3523 | chan->expected_ack_seq = req_seq; | 3450 | chan->expected_ack_seq = req_seq; |
3524 | l2cap_drop_acked_frames(chan); | 3451 | l2cap_drop_acked_frames(chan); |
3525 | 3452 | ||
3526 | if (tx_seq == chan->expected_tx_seq) | ||
3527 | goto expected; | ||
3528 | |||
3529 | tx_seq_offset = (tx_seq - chan->buffer_seq) % 64; | 3453 | tx_seq_offset = (tx_seq - chan->buffer_seq) % 64; |
3530 | if (tx_seq_offset < 0) | 3454 | if (tx_seq_offset < 0) |
3531 | tx_seq_offset += 64; | 3455 | tx_seq_offset += 64; |
@@ -3539,6 +3463,9 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3539 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) | 3463 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) |
3540 | goto drop; | 3464 | goto drop; |
3541 | 3465 | ||
3466 | if (tx_seq == chan->expected_tx_seq) | ||
3467 | goto expected; | ||
3468 | |||
3542 | if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { | 3469 | if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { |
3543 | struct srej_list *first; | 3470 | struct srej_list *first; |
3544 | 3471 | ||
@@ -3590,7 +3517,6 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3590 | chan->buffer_seq_srej = chan->buffer_seq; | 3517 | chan->buffer_seq_srej = chan->buffer_seq; |
3591 | 3518 | ||
3592 | __skb_queue_head_init(&chan->srej_q); | 3519 | __skb_queue_head_init(&chan->srej_q); |
3593 | __skb_queue_head_init(&chan->busy_q); | ||
3594 | l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); | 3520 | l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); |
3595 | 3521 | ||
3596 | set_bit(CONN_SEND_PBIT, &chan->conn_state); | 3522 | set_bit(CONN_SEND_PBIT, &chan->conn_state); |
@@ -3611,9 +3537,12 @@ expected: | |||
3611 | return 0; | 3537 | return 0; |
3612 | } | 3538 | } |
3613 | 3539 | ||
3614 | err = l2cap_push_rx_skb(chan, skb, rx_control); | 3540 | err = l2cap_ertm_reassembly_sdu(chan, skb, rx_control); |
3615 | if (err < 0) | 3541 | chan->buffer_seq = (chan->buffer_seq + 1) % 64; |
3616 | return 0; | 3542 | if (err < 0) { |
3543 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | ||
3544 | return err; | ||
3545 | } | ||
3617 | 3546 | ||
3618 | if (rx_control & L2CAP_CTRL_FINAL) { | 3547 | if (rx_control & L2CAP_CTRL_FINAL) { |
3619 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) | 3548 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) |
@@ -4108,7 +4037,7 @@ static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status) | |||
4108 | if (conn) | 4037 | if (conn) |
4109 | l2cap_conn_ready(conn); | 4038 | l2cap_conn_ready(conn); |
4110 | } else | 4039 | } else |
4111 | l2cap_conn_del(hcon, bt_err(status)); | 4040 | l2cap_conn_del(hcon, bt_to_errno(status)); |
4112 | 4041 | ||
4113 | return 0; | 4042 | return 0; |
4114 | } | 4043 | } |
@@ -4132,7 +4061,7 @@ static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) | |||
4132 | if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK)) | 4061 | if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK)) |
4133 | return -EINVAL; | 4062 | return -EINVAL; |
4134 | 4063 | ||
4135 | l2cap_conn_del(hcon, bt_err(reason)); | 4064 | l2cap_conn_del(hcon, bt_to_errno(reason)); |
4136 | 4065 | ||
4137 | return 0; | 4066 | return 0; |
4138 | } | 4067 | } |
@@ -4178,6 +4107,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
4178 | chan->sec_level = hcon->sec_level; | 4107 | chan->sec_level = hcon->sec_level; |
4179 | del_timer(&conn->security_timer); | 4108 | del_timer(&conn->security_timer); |
4180 | l2cap_chan_ready(sk); | 4109 | l2cap_chan_ready(sk); |
4110 | smp_distribute_keys(conn, 0); | ||
4181 | } | 4111 | } |
4182 | 4112 | ||
4183 | bh_unlock_sock(sk); | 4113 | bh_unlock_sock(sk); |
@@ -4415,12 +4345,6 @@ int __init l2cap_init(void) | |||
4415 | if (err < 0) | 4345 | if (err < 0) |
4416 | return err; | 4346 | return err; |
4417 | 4347 | ||
4418 | _busy_wq = create_singlethread_workqueue("l2cap"); | ||
4419 | if (!_busy_wq) { | ||
4420 | err = -ENOMEM; | ||
4421 | goto error; | ||
4422 | } | ||
4423 | |||
4424 | err = hci_register_proto(&l2cap_hci_proto); | 4348 | err = hci_register_proto(&l2cap_hci_proto); |
4425 | if (err < 0) { | 4349 | if (err < 0) { |
4426 | BT_ERR("L2CAP protocol registration failed"); | 4350 | BT_ERR("L2CAP protocol registration failed"); |
@@ -4438,7 +4362,6 @@ int __init l2cap_init(void) | |||
4438 | return 0; | 4362 | return 0; |
4439 | 4363 | ||
4440 | error: | 4364 | error: |
4441 | destroy_workqueue(_busy_wq); | ||
4442 | l2cap_cleanup_sockets(); | 4365 | l2cap_cleanup_sockets(); |
4443 | return err; | 4366 | return err; |
4444 | } | 4367 | } |
@@ -4447,9 +4370,6 @@ void l2cap_exit(void) | |||
4447 | { | 4370 | { |
4448 | debugfs_remove(l2cap_debugfs); | 4371 | debugfs_remove(l2cap_debugfs); |
4449 | 4372 | ||
4450 | flush_workqueue(_busy_wq); | ||
4451 | destroy_workqueue(_busy_wq); | ||
4452 | |||
4453 | if (hci_unregister_proto(&l2cap_hci_proto) < 0) | 4373 | if (hci_unregister_proto(&l2cap_hci_proto) < 0) |
4454 | BT_ERR("L2CAP protocol unregistration failed"); | 4374 | BT_ERR("L2CAP protocol unregistration failed"); |
4455 | 4375 | ||
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 39082d4e77ce..5c36b3e8739c 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -422,8 +422,12 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
422 | break; | 422 | break; |
423 | } | 423 | } |
424 | 424 | ||
425 | memset(&sec, 0, sizeof(sec)); | ||
425 | sec.level = chan->sec_level; | 426 | sec.level = chan->sec_level; |
426 | 427 | ||
428 | if (sk->sk_state == BT_CONNECTED) | ||
429 | sec.key_size = chan->conn->hcon->enc_key_size; | ||
430 | |||
427 | len = min_t(unsigned int, len, sizeof(sec)); | 431 | len = min_t(unsigned int, len, sizeof(sec)); |
428 | if (copy_to_user(optval, (char *) &sec, len)) | 432 | if (copy_to_user(optval, (char *) &sec, len)) |
429 | err = -EFAULT; | 433 | err = -EFAULT; |
@@ -711,13 +715,15 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
711 | static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags) | 715 | static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags) |
712 | { | 716 | { |
713 | struct sock *sk = sock->sk; | 717 | struct sock *sk = sock->sk; |
718 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
719 | int err; | ||
714 | 720 | ||
715 | lock_sock(sk); | 721 | lock_sock(sk); |
716 | 722 | ||
717 | if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { | 723 | if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { |
718 | sk->sk_state = BT_CONFIG; | 724 | sk->sk_state = BT_CONFIG; |
719 | 725 | ||
720 | __l2cap_connect_rsp_defer(l2cap_pi(sk)->chan); | 726 | __l2cap_connect_rsp_defer(pi->chan); |
721 | release_sock(sk); | 727 | release_sock(sk); |
722 | return 0; | 728 | return 0; |
723 | } | 729 | } |
@@ -725,9 +731,37 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
725 | release_sock(sk); | 731 | release_sock(sk); |
726 | 732 | ||
727 | if (sock->type == SOCK_STREAM) | 733 | if (sock->type == SOCK_STREAM) |
728 | return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags); | 734 | err = bt_sock_stream_recvmsg(iocb, sock, msg, len, flags); |
735 | else | ||
736 | err = bt_sock_recvmsg(iocb, sock, msg, len, flags); | ||
737 | |||
738 | if (pi->chan->mode != L2CAP_MODE_ERTM) | ||
739 | return err; | ||
740 | |||
741 | /* Attempt to put pending rx data in the socket buffer */ | ||
742 | |||
743 | lock_sock(sk); | ||
744 | |||
745 | if (!test_bit(CONN_LOCAL_BUSY, &pi->chan->conn_state)) | ||
746 | goto done; | ||
747 | |||
748 | if (pi->rx_busy_skb) { | ||
749 | if (!sock_queue_rcv_skb(sk, pi->rx_busy_skb)) | ||
750 | pi->rx_busy_skb = NULL; | ||
751 | else | ||
752 | goto done; | ||
753 | } | ||
729 | 754 | ||
730 | return bt_sock_recvmsg(iocb, sock, msg, len, flags); | 755 | /* Restore data flow when half of the receive buffer is |
756 | * available. This avoids resending large numbers of | ||
757 | * frames. | ||
758 | */ | ||
759 | if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf >> 1) | ||
760 | l2cap_chan_busy(pi->chan, 0); | ||
761 | |||
762 | done: | ||
763 | release_sock(sk); | ||
764 | return err; | ||
731 | } | 765 | } |
732 | 766 | ||
733 | /* Kill socket (only if zapped and orphan) | 767 | /* Kill socket (only if zapped and orphan) |
@@ -811,9 +845,31 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data) | |||
811 | 845 | ||
812 | static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb) | 846 | static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb) |
813 | { | 847 | { |
848 | int err; | ||
814 | struct sock *sk = data; | 849 | struct sock *sk = data; |
850 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
815 | 851 | ||
816 | return sock_queue_rcv_skb(sk, skb); | 852 | if (pi->rx_busy_skb) |
853 | return -ENOMEM; | ||
854 | |||
855 | err = sock_queue_rcv_skb(sk, skb); | ||
856 | |||
857 | /* For ERTM, handle one skb that doesn't fit into the recv | ||
858 | * buffer. This is important to do because the data frames | ||
859 | * have already been acked, so the skb cannot be discarded. | ||
860 | * | ||
861 | * Notify the l2cap core that the buffer is full, so the | ||
862 | * LOCAL_BUSY state is entered and no more frames are | ||
863 | * acked and reassembled until there is buffer space | ||
864 | * available. | ||
865 | */ | ||
866 | if (err < 0 && pi->chan->mode == L2CAP_MODE_ERTM) { | ||
867 | pi->rx_busy_skb = skb; | ||
868 | l2cap_chan_busy(pi->chan, 1); | ||
869 | err = 0; | ||
870 | } | ||
871 | |||
872 | return err; | ||
817 | } | 873 | } |
818 | 874 | ||
819 | static void l2cap_sock_close_cb(void *data) | 875 | static void l2cap_sock_close_cb(void *data) |
@@ -842,6 +898,11 @@ static void l2cap_sock_destruct(struct sock *sk) | |||
842 | { | 898 | { |
843 | BT_DBG("sk %p", sk); | 899 | BT_DBG("sk %p", sk); |
844 | 900 | ||
901 | if (l2cap_pi(sk)->rx_busy_skb) { | ||
902 | kfree_skb(l2cap_pi(sk)->rx_busy_skb); | ||
903 | l2cap_pi(sk)->rx_busy_skb = NULL; | ||
904 | } | ||
905 | |||
845 | skb_queue_purge(&sk->sk_receive_queue); | 906 | skb_queue_purge(&sk->sk_receive_queue); |
846 | skb_queue_purge(&sk->sk_write_queue); | 907 | skb_queue_purge(&sk->sk_write_queue); |
847 | } | 908 | } |
diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c index b826d1bf10df..86a6bed229df 100644 --- a/net/bluetooth/lib.c +++ b/net/bluetooth/lib.c | |||
@@ -59,7 +59,7 @@ char *batostr(bdaddr_t *ba) | |||
59 | EXPORT_SYMBOL(batostr); | 59 | EXPORT_SYMBOL(batostr); |
60 | 60 | ||
61 | /* Bluetooth error codes to Unix errno mapping */ | 61 | /* Bluetooth error codes to Unix errno mapping */ |
62 | int bt_err(__u16 code) | 62 | int bt_to_errno(__u16 code) |
63 | { | 63 | { |
64 | switch (code) { | 64 | switch (code) { |
65 | case 0: | 65 | case 0: |
@@ -149,4 +149,23 @@ int bt_err(__u16 code) | |||
149 | return ENOSYS; | 149 | return ENOSYS; |
150 | } | 150 | } |
151 | } | 151 | } |
152 | EXPORT_SYMBOL(bt_err); | 152 | EXPORT_SYMBOL(bt_to_errno); |
153 | |||
154 | int bt_printk(const char *level, const char *format, ...) | ||
155 | { | ||
156 | struct va_format vaf; | ||
157 | va_list args; | ||
158 | int r; | ||
159 | |||
160 | va_start(args, format); | ||
161 | |||
162 | vaf.fmt = format; | ||
163 | vaf.va = &args; | ||
164 | |||
165 | r = printk("%sBluetooth: %pV\n", level, &vaf); | ||
166 | |||
167 | va_end(args); | ||
168 | |||
169 | return r; | ||
170 | } | ||
171 | EXPORT_SYMBOL(bt_printk); | ||
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 64c0418a6221..53e109eb043e 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -179,7 +179,7 @@ static int read_controller_info(struct sock *sk, u16 index) | |||
179 | 179 | ||
180 | hci_del_off_timer(hdev); | 180 | hci_del_off_timer(hdev); |
181 | 181 | ||
182 | hci_dev_lock(hdev); | 182 | hci_dev_lock_bh(hdev); |
183 | 183 | ||
184 | set_bit(HCI_MGMT, &hdev->flags); | 184 | set_bit(HCI_MGMT, &hdev->flags); |
185 | 185 | ||
@@ -208,7 +208,7 @@ static int read_controller_info(struct sock *sk, u16 index) | |||
208 | 208 | ||
209 | memcpy(rp.name, hdev->dev_name, sizeof(hdev->dev_name)); | 209 | memcpy(rp.name, hdev->dev_name, sizeof(hdev->dev_name)); |
210 | 210 | ||
211 | hci_dev_unlock(hdev); | 211 | hci_dev_unlock_bh(hdev); |
212 | hci_dev_put(hdev); | 212 | hci_dev_put(hdev); |
213 | 213 | ||
214 | return cmd_complete(sk, index, MGMT_OP_READ_INFO, &rp, sizeof(rp)); | 214 | return cmd_complete(sk, index, MGMT_OP_READ_INFO, &rp, sizeof(rp)); |
@@ -316,7 +316,7 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
316 | if (!hdev) | 316 | if (!hdev) |
317 | return cmd_status(sk, index, MGMT_OP_SET_POWERED, ENODEV); | 317 | return cmd_status(sk, index, MGMT_OP_SET_POWERED, ENODEV); |
318 | 318 | ||
319 | hci_dev_lock(hdev); | 319 | hci_dev_lock_bh(hdev); |
320 | 320 | ||
321 | up = test_bit(HCI_UP, &hdev->flags); | 321 | up = test_bit(HCI_UP, &hdev->flags); |
322 | if ((cp->val && up) || (!cp->val && !up)) { | 322 | if ((cp->val && up) || (!cp->val && !up)) { |
@@ -343,7 +343,7 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
343 | err = 0; | 343 | err = 0; |
344 | 344 | ||
345 | failed: | 345 | failed: |
346 | hci_dev_unlock(hdev); | 346 | hci_dev_unlock_bh(hdev); |
347 | hci_dev_put(hdev); | 347 | hci_dev_put(hdev); |
348 | return err; | 348 | return err; |
349 | } | 349 | } |
@@ -368,7 +368,7 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | |||
368 | if (!hdev) | 368 | if (!hdev) |
369 | return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENODEV); | 369 | return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENODEV); |
370 | 370 | ||
371 | hci_dev_lock(hdev); | 371 | hci_dev_lock_bh(hdev); |
372 | 372 | ||
373 | if (!test_bit(HCI_UP, &hdev->flags)) { | 373 | if (!test_bit(HCI_UP, &hdev->flags)) { |
374 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENETDOWN); | 374 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENETDOWN); |
@@ -403,7 +403,7 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | |||
403 | mgmt_pending_remove(cmd); | 403 | mgmt_pending_remove(cmd); |
404 | 404 | ||
405 | failed: | 405 | failed: |
406 | hci_dev_unlock(hdev); | 406 | hci_dev_unlock_bh(hdev); |
407 | hci_dev_put(hdev); | 407 | hci_dev_put(hdev); |
408 | 408 | ||
409 | return err; | 409 | return err; |
@@ -429,7 +429,7 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data, | |||
429 | if (!hdev) | 429 | if (!hdev) |
430 | return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENODEV); | 430 | return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENODEV); |
431 | 431 | ||
432 | hci_dev_lock(hdev); | 432 | hci_dev_lock_bh(hdev); |
433 | 433 | ||
434 | if (!test_bit(HCI_UP, &hdev->flags)) { | 434 | if (!test_bit(HCI_UP, &hdev->flags)) { |
435 | err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENETDOWN); | 435 | err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENETDOWN); |
@@ -463,7 +463,7 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data, | |||
463 | mgmt_pending_remove(cmd); | 463 | mgmt_pending_remove(cmd); |
464 | 464 | ||
465 | failed: | 465 | failed: |
466 | hci_dev_unlock(hdev); | 466 | hci_dev_unlock_bh(hdev); |
467 | hci_dev_put(hdev); | 467 | hci_dev_put(hdev); |
468 | 468 | ||
469 | return err; | 469 | return err; |
@@ -522,7 +522,7 @@ static int set_pairable(struct sock *sk, u16 index, unsigned char *data, | |||
522 | if (!hdev) | 522 | if (!hdev) |
523 | return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, ENODEV); | 523 | return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, ENODEV); |
524 | 524 | ||
525 | hci_dev_lock(hdev); | 525 | hci_dev_lock_bh(hdev); |
526 | 526 | ||
527 | if (cp->val) | 527 | if (cp->val) |
528 | set_bit(HCI_PAIRABLE, &hdev->flags); | 528 | set_bit(HCI_PAIRABLE, &hdev->flags); |
@@ -538,7 +538,7 @@ static int set_pairable(struct sock *sk, u16 index, unsigned char *data, | |||
538 | err = mgmt_event(MGMT_EV_PAIRABLE, index, &ev, sizeof(ev), sk); | 538 | err = mgmt_event(MGMT_EV_PAIRABLE, index, &ev, sizeof(ev), sk); |
539 | 539 | ||
540 | failed: | 540 | failed: |
541 | hci_dev_unlock(hdev); | 541 | hci_dev_unlock_bh(hdev); |
542 | hci_dev_put(hdev); | 542 | hci_dev_put(hdev); |
543 | 543 | ||
544 | return err; | 544 | return err; |
@@ -739,7 +739,7 @@ static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
739 | if (!hdev) | 739 | if (!hdev) |
740 | return cmd_status(sk, index, MGMT_OP_ADD_UUID, ENODEV); | 740 | return cmd_status(sk, index, MGMT_OP_ADD_UUID, ENODEV); |
741 | 741 | ||
742 | hci_dev_lock(hdev); | 742 | hci_dev_lock_bh(hdev); |
743 | 743 | ||
744 | uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC); | 744 | uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC); |
745 | if (!uuid) { | 745 | if (!uuid) { |
@@ -763,7 +763,7 @@ static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
763 | err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0); | 763 | err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0); |
764 | 764 | ||
765 | failed: | 765 | failed: |
766 | hci_dev_unlock(hdev); | 766 | hci_dev_unlock_bh(hdev); |
767 | hci_dev_put(hdev); | 767 | hci_dev_put(hdev); |
768 | 768 | ||
769 | return err; | 769 | return err; |
@@ -788,7 +788,7 @@ static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
788 | if (!hdev) | 788 | if (!hdev) |
789 | return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENODEV); | 789 | return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENODEV); |
790 | 790 | ||
791 | hci_dev_lock(hdev); | 791 | hci_dev_lock_bh(hdev); |
792 | 792 | ||
793 | if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) { | 793 | if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) { |
794 | err = hci_uuids_clear(hdev); | 794 | err = hci_uuids_clear(hdev); |
@@ -823,7 +823,7 @@ static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
823 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0); | 823 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0); |
824 | 824 | ||
825 | unlock: | 825 | unlock: |
826 | hci_dev_unlock(hdev); | 826 | hci_dev_unlock_bh(hdev); |
827 | hci_dev_put(hdev); | 827 | hci_dev_put(hdev); |
828 | 828 | ||
829 | return err; | 829 | return err; |
@@ -847,7 +847,7 @@ static int set_dev_class(struct sock *sk, u16 index, unsigned char *data, | |||
847 | if (!hdev) | 847 | if (!hdev) |
848 | return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, ENODEV); | 848 | return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, ENODEV); |
849 | 849 | ||
850 | hci_dev_lock(hdev); | 850 | hci_dev_lock_bh(hdev); |
851 | 851 | ||
852 | hdev->major_class = cp->major; | 852 | hdev->major_class = cp->major; |
853 | hdev->minor_class = cp->minor; | 853 | hdev->minor_class = cp->minor; |
@@ -857,7 +857,7 @@ static int set_dev_class(struct sock *sk, u16 index, unsigned char *data, | |||
857 | if (err == 0) | 857 | if (err == 0) |
858 | err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, NULL, 0); | 858 | err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, NULL, 0); |
859 | 859 | ||
860 | hci_dev_unlock(hdev); | 860 | hci_dev_unlock_bh(hdev); |
861 | hci_dev_put(hdev); | 861 | hci_dev_put(hdev); |
862 | 862 | ||
863 | return err; | 863 | return err; |
@@ -879,7 +879,7 @@ static int set_service_cache(struct sock *sk, u16 index, unsigned char *data, | |||
879 | if (!hdev) | 879 | if (!hdev) |
880 | return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, ENODEV); | 880 | return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, ENODEV); |
881 | 881 | ||
882 | hci_dev_lock(hdev); | 882 | hci_dev_lock_bh(hdev); |
883 | 883 | ||
884 | BT_DBG("hci%u enable %d", index, cp->enable); | 884 | BT_DBG("hci%u enable %d", index, cp->enable); |
885 | 885 | ||
@@ -897,7 +897,7 @@ static int set_service_cache(struct sock *sk, u16 index, unsigned char *data, | |||
897 | err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL, | 897 | err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL, |
898 | 0); | 898 | 0); |
899 | 899 | ||
900 | hci_dev_unlock(hdev); | 900 | hci_dev_unlock_bh(hdev); |
901 | hci_dev_put(hdev); | 901 | hci_dev_put(hdev); |
902 | 902 | ||
903 | return err; | 903 | return err; |
@@ -908,7 +908,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
908 | struct hci_dev *hdev; | 908 | struct hci_dev *hdev; |
909 | struct mgmt_cp_load_keys *cp; | 909 | struct mgmt_cp_load_keys *cp; |
910 | u16 key_count, expected_len; | 910 | u16 key_count, expected_len; |
911 | int i; | 911 | int i, err; |
912 | 912 | ||
913 | cp = (void *) data; | 913 | cp = (void *) data; |
914 | 914 | ||
@@ -918,9 +918,9 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
918 | key_count = get_unaligned_le16(&cp->key_count); | 918 | key_count = get_unaligned_le16(&cp->key_count); |
919 | 919 | ||
920 | expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info); | 920 | expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info); |
921 | if (expected_len != len) { | 921 | if (expected_len > len) { |
922 | BT_ERR("load_keys: expected %u bytes, got %u bytes", | 922 | BT_ERR("load_keys: expected at least %u bytes, got %u bytes", |
923 | len, expected_len); | 923 | expected_len, len); |
924 | return -EINVAL; | 924 | return -EINVAL; |
925 | } | 925 | } |
926 | 926 | ||
@@ -931,7 +931,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
931 | BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys, | 931 | BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys, |
932 | key_count); | 932 | key_count); |
933 | 933 | ||
934 | hci_dev_lock(hdev); | 934 | hci_dev_lock_bh(hdev); |
935 | 935 | ||
936 | hci_link_keys_clear(hdev); | 936 | hci_link_keys_clear(hdev); |
937 | 937 | ||
@@ -942,17 +942,36 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
942 | else | 942 | else |
943 | clear_bit(HCI_DEBUG_KEYS, &hdev->flags); | 943 | clear_bit(HCI_DEBUG_KEYS, &hdev->flags); |
944 | 944 | ||
945 | for (i = 0; i < key_count; i++) { | 945 | len -= sizeof(*cp); |
946 | struct mgmt_key_info *key = &cp->keys[i]; | 946 | i = 0; |
947 | |||
948 | while (i < len) { | ||
949 | struct mgmt_key_info *key = (void *) cp->keys + i; | ||
950 | |||
951 | i += sizeof(*key) + key->dlen; | ||
952 | |||
953 | if (key->type == HCI_LK_SMP_LTK) { | ||
954 | struct key_master_id *id = (void *) key->data; | ||
955 | |||
956 | if (key->dlen != sizeof(struct key_master_id)) | ||
957 | continue; | ||
958 | |||
959 | hci_add_ltk(hdev, 0, &key->bdaddr, key->pin_len, | ||
960 | id->ediv, id->rand, key->val); | ||
961 | |||
962 | continue; | ||
963 | } | ||
947 | 964 | ||
948 | hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type, | 965 | hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type, |
949 | key->pin_len); | 966 | key->pin_len); |
950 | } | 967 | } |
951 | 968 | ||
952 | hci_dev_unlock(hdev); | 969 | err = cmd_complete(sk, index, MGMT_OP_LOAD_KEYS, NULL, 0); |
970 | |||
971 | hci_dev_unlock_bh(hdev); | ||
953 | hci_dev_put(hdev); | 972 | hci_dev_put(hdev); |
954 | 973 | ||
955 | return 0; | 974 | return err; |
956 | } | 975 | } |
957 | 976 | ||
958 | static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len) | 977 | static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len) |
@@ -971,7 +990,7 @@ static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
971 | if (!hdev) | 990 | if (!hdev) |
972 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV); | 991 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV); |
973 | 992 | ||
974 | hci_dev_lock(hdev); | 993 | hci_dev_lock_bh(hdev); |
975 | 994 | ||
976 | err = hci_remove_link_key(hdev, &cp->bdaddr); | 995 | err = hci_remove_link_key(hdev, &cp->bdaddr); |
977 | if (err < 0) { | 996 | if (err < 0) { |
@@ -994,7 +1013,7 @@ static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
994 | } | 1013 | } |
995 | 1014 | ||
996 | unlock: | 1015 | unlock: |
997 | hci_dev_unlock(hdev); | 1016 | hci_dev_unlock_bh(hdev); |
998 | hci_dev_put(hdev); | 1017 | hci_dev_put(hdev); |
999 | 1018 | ||
1000 | return err; | 1019 | return err; |
@@ -1020,7 +1039,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1020 | if (!hdev) | 1039 | if (!hdev) |
1021 | return cmd_status(sk, index, MGMT_OP_DISCONNECT, ENODEV); | 1040 | return cmd_status(sk, index, MGMT_OP_DISCONNECT, ENODEV); |
1022 | 1041 | ||
1023 | hci_dev_lock(hdev); | 1042 | hci_dev_lock_bh(hdev); |
1024 | 1043 | ||
1025 | if (!test_bit(HCI_UP, &hdev->flags)) { | 1044 | if (!test_bit(HCI_UP, &hdev->flags)) { |
1026 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENETDOWN); | 1045 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENETDOWN); |
@@ -1055,7 +1074,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1055 | mgmt_pending_remove(cmd); | 1074 | mgmt_pending_remove(cmd); |
1056 | 1075 | ||
1057 | failed: | 1076 | failed: |
1058 | hci_dev_unlock(hdev); | 1077 | hci_dev_unlock_bh(hdev); |
1059 | hci_dev_put(hdev); | 1078 | hci_dev_put(hdev); |
1060 | 1079 | ||
1061 | return err; | 1080 | return err; |
@@ -1076,7 +1095,7 @@ static int get_connections(struct sock *sk, u16 index) | |||
1076 | if (!hdev) | 1095 | if (!hdev) |
1077 | return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS, ENODEV); | 1096 | return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS, ENODEV); |
1078 | 1097 | ||
1079 | hci_dev_lock(hdev); | 1098 | hci_dev_lock_bh(hdev); |
1080 | 1099 | ||
1081 | count = 0; | 1100 | count = 0; |
1082 | list_for_each(p, &hdev->conn_hash.list) { | 1101 | list_for_each(p, &hdev->conn_hash.list) { |
@@ -1103,7 +1122,7 @@ static int get_connections(struct sock *sk, u16 index) | |||
1103 | 1122 | ||
1104 | unlock: | 1123 | unlock: |
1105 | kfree(rp); | 1124 | kfree(rp); |
1106 | hci_dev_unlock(hdev); | 1125 | hci_dev_unlock_bh(hdev); |
1107 | hci_dev_put(hdev); | 1126 | hci_dev_put(hdev); |
1108 | return err; | 1127 | return err; |
1109 | } | 1128 | } |
@@ -1149,7 +1168,7 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1149 | if (!hdev) | 1168 | if (!hdev) |
1150 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENODEV); | 1169 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENODEV); |
1151 | 1170 | ||
1152 | hci_dev_lock(hdev); | 1171 | hci_dev_lock_bh(hdev); |
1153 | 1172 | ||
1154 | if (!test_bit(HCI_UP, &hdev->flags)) { | 1173 | if (!test_bit(HCI_UP, &hdev->flags)) { |
1155 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENETDOWN); | 1174 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENETDOWN); |
@@ -1190,7 +1209,7 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1190 | mgmt_pending_remove(cmd); | 1209 | mgmt_pending_remove(cmd); |
1191 | 1210 | ||
1192 | failed: | 1211 | failed: |
1193 | hci_dev_unlock(hdev); | 1212 | hci_dev_unlock_bh(hdev); |
1194 | hci_dev_put(hdev); | 1213 | hci_dev_put(hdev); |
1195 | 1214 | ||
1196 | return err; | 1215 | return err; |
@@ -1216,7 +1235,7 @@ static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1216 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, | 1235 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, |
1217 | ENODEV); | 1236 | ENODEV); |
1218 | 1237 | ||
1219 | hci_dev_lock(hdev); | 1238 | hci_dev_lock_bh(hdev); |
1220 | 1239 | ||
1221 | if (!test_bit(HCI_UP, &hdev->flags)) { | 1240 | if (!test_bit(HCI_UP, &hdev->flags)) { |
1222 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, | 1241 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, |
@@ -1227,7 +1246,7 @@ static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1227 | err = send_pin_code_neg_reply(sk, index, hdev, cp); | 1246 | err = send_pin_code_neg_reply(sk, index, hdev, cp); |
1228 | 1247 | ||
1229 | failed: | 1248 | failed: |
1230 | hci_dev_unlock(hdev); | 1249 | hci_dev_unlock_bh(hdev); |
1231 | hci_dev_put(hdev); | 1250 | hci_dev_put(hdev); |
1232 | 1251 | ||
1233 | return err; | 1252 | return err; |
@@ -1250,14 +1269,14 @@ static int set_io_capability(struct sock *sk, u16 index, unsigned char *data, | |||
1250 | if (!hdev) | 1269 | if (!hdev) |
1251 | return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, ENODEV); | 1270 | return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, ENODEV); |
1252 | 1271 | ||
1253 | hci_dev_lock(hdev); | 1272 | hci_dev_lock_bh(hdev); |
1254 | 1273 | ||
1255 | hdev->io_capability = cp->io_capability; | 1274 | hdev->io_capability = cp->io_capability; |
1256 | 1275 | ||
1257 | BT_DBG("%s IO capability set to 0x%02x", hdev->name, | 1276 | BT_DBG("%s IO capability set to 0x%02x", hdev->name, |
1258 | hdev->io_capability); | 1277 | hdev->io_capability); |
1259 | 1278 | ||
1260 | hci_dev_unlock(hdev); | 1279 | hci_dev_unlock_bh(hdev); |
1261 | hci_dev_put(hdev); | 1280 | hci_dev_put(hdev); |
1262 | 1281 | ||
1263 | return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0); | 1282 | return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0); |
@@ -1343,7 +1362,7 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1343 | if (!hdev) | 1362 | if (!hdev) |
1344 | return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, ENODEV); | 1363 | return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, ENODEV); |
1345 | 1364 | ||
1346 | hci_dev_lock(hdev); | 1365 | hci_dev_lock_bh(hdev); |
1347 | 1366 | ||
1348 | if (cp->io_cap == 0x03) { | 1367 | if (cp->io_cap == 0x03) { |
1349 | sec_level = BT_SECURITY_MEDIUM; | 1368 | sec_level = BT_SECURITY_MEDIUM; |
@@ -1385,7 +1404,7 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1385 | err = 0; | 1404 | err = 0; |
1386 | 1405 | ||
1387 | unlock: | 1406 | unlock: |
1388 | hci_dev_unlock(hdev); | 1407 | hci_dev_unlock_bh(hdev); |
1389 | hci_dev_put(hdev); | 1408 | hci_dev_put(hdev); |
1390 | 1409 | ||
1391 | return err; | 1410 | return err; |
@@ -1417,7 +1436,7 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1417 | if (!hdev) | 1436 | if (!hdev) |
1418 | return cmd_status(sk, index, mgmt_op, ENODEV); | 1437 | return cmd_status(sk, index, mgmt_op, ENODEV); |
1419 | 1438 | ||
1420 | hci_dev_lock(hdev); | 1439 | hci_dev_lock_bh(hdev); |
1421 | 1440 | ||
1422 | if (!test_bit(HCI_UP, &hdev->flags)) { | 1441 | if (!test_bit(HCI_UP, &hdev->flags)) { |
1423 | err = cmd_status(sk, index, mgmt_op, ENETDOWN); | 1442 | err = cmd_status(sk, index, mgmt_op, ENETDOWN); |
@@ -1435,7 +1454,7 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1435 | mgmt_pending_remove(cmd); | 1454 | mgmt_pending_remove(cmd); |
1436 | 1455 | ||
1437 | failed: | 1456 | failed: |
1438 | hci_dev_unlock(hdev); | 1457 | hci_dev_unlock_bh(hdev); |
1439 | hci_dev_put(hdev); | 1458 | hci_dev_put(hdev); |
1440 | 1459 | ||
1441 | return err; | 1460 | return err; |
@@ -1459,7 +1478,7 @@ static int set_local_name(struct sock *sk, u16 index, unsigned char *data, | |||
1459 | if (!hdev) | 1478 | if (!hdev) |
1460 | return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, ENODEV); | 1479 | return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, ENODEV); |
1461 | 1480 | ||
1462 | hci_dev_lock(hdev); | 1481 | hci_dev_lock_bh(hdev); |
1463 | 1482 | ||
1464 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, index, data, len); | 1483 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, index, data, len); |
1465 | if (!cmd) { | 1484 | if (!cmd) { |
@@ -1474,7 +1493,7 @@ static int set_local_name(struct sock *sk, u16 index, unsigned char *data, | |||
1474 | mgmt_pending_remove(cmd); | 1493 | mgmt_pending_remove(cmd); |
1475 | 1494 | ||
1476 | failed: | 1495 | failed: |
1477 | hci_dev_unlock(hdev); | 1496 | hci_dev_unlock_bh(hdev); |
1478 | hci_dev_put(hdev); | 1497 | hci_dev_put(hdev); |
1479 | 1498 | ||
1480 | return err; | 1499 | return err; |
@@ -1493,7 +1512,7 @@ static int read_local_oob_data(struct sock *sk, u16 index) | |||
1493 | return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 1512 | return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, |
1494 | ENODEV); | 1513 | ENODEV); |
1495 | 1514 | ||
1496 | hci_dev_lock(hdev); | 1515 | hci_dev_lock_bh(hdev); |
1497 | 1516 | ||
1498 | if (!test_bit(HCI_UP, &hdev->flags)) { | 1517 | if (!test_bit(HCI_UP, &hdev->flags)) { |
1499 | err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 1518 | err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, |
@@ -1523,7 +1542,7 @@ static int read_local_oob_data(struct sock *sk, u16 index) | |||
1523 | mgmt_pending_remove(cmd); | 1542 | mgmt_pending_remove(cmd); |
1524 | 1543 | ||
1525 | unlock: | 1544 | unlock: |
1526 | hci_dev_unlock(hdev); | 1545 | hci_dev_unlock_bh(hdev); |
1527 | hci_dev_put(hdev); | 1546 | hci_dev_put(hdev); |
1528 | 1547 | ||
1529 | return err; | 1548 | return err; |
@@ -1547,7 +1566,7 @@ static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data, | |||
1547 | return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, | 1566 | return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, |
1548 | ENODEV); | 1567 | ENODEV); |
1549 | 1568 | ||
1550 | hci_dev_lock(hdev); | 1569 | hci_dev_lock_bh(hdev); |
1551 | 1570 | ||
1552 | err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash, | 1571 | err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash, |
1553 | cp->randomizer); | 1572 | cp->randomizer); |
@@ -1557,7 +1576,7 @@ static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data, | |||
1557 | err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL, | 1576 | err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL, |
1558 | 0); | 1577 | 0); |
1559 | 1578 | ||
1560 | hci_dev_unlock(hdev); | 1579 | hci_dev_unlock_bh(hdev); |
1561 | hci_dev_put(hdev); | 1580 | hci_dev_put(hdev); |
1562 | 1581 | ||
1563 | return err; | 1582 | return err; |
@@ -1581,7 +1600,7 @@ static int remove_remote_oob_data(struct sock *sk, u16 index, | |||
1581 | return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, | 1600 | return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, |
1582 | ENODEV); | 1601 | ENODEV); |
1583 | 1602 | ||
1584 | hci_dev_lock(hdev); | 1603 | hci_dev_lock_bh(hdev); |
1585 | 1604 | ||
1586 | err = hci_remove_remote_oob_data(hdev, &cp->bdaddr); | 1605 | err = hci_remove_remote_oob_data(hdev, &cp->bdaddr); |
1587 | if (err < 0) | 1606 | if (err < 0) |
@@ -1591,7 +1610,7 @@ static int remove_remote_oob_data(struct sock *sk, u16 index, | |||
1591 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, | 1610 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, |
1592 | NULL, 0); | 1611 | NULL, 0); |
1593 | 1612 | ||
1594 | hci_dev_unlock(hdev); | 1613 | hci_dev_unlock_bh(hdev); |
1595 | hci_dev_put(hdev); | 1614 | hci_dev_put(hdev); |
1596 | 1615 | ||
1597 | return err; | 1616 | return err; |
@@ -1958,17 +1977,28 @@ int mgmt_connectable(u16 index, u8 connectable) | |||
1958 | 1977 | ||
1959 | int mgmt_new_key(u16 index, struct link_key *key, u8 persistent) | 1978 | int mgmt_new_key(u16 index, struct link_key *key, u8 persistent) |
1960 | { | 1979 | { |
1961 | struct mgmt_ev_new_key ev; | 1980 | struct mgmt_ev_new_key *ev; |
1981 | int err, total; | ||
1962 | 1982 | ||
1963 | memset(&ev, 0, sizeof(ev)); | 1983 | total = sizeof(struct mgmt_ev_new_key) + key->dlen; |
1984 | ev = kzalloc(total, GFP_ATOMIC); | ||
1985 | if (!ev) | ||
1986 | return -ENOMEM; | ||
1964 | 1987 | ||
1965 | ev.store_hint = persistent; | 1988 | bacpy(&ev->key.bdaddr, &key->bdaddr); |
1966 | bacpy(&ev.key.bdaddr, &key->bdaddr); | 1989 | ev->key.type = key->type; |
1967 | ev.key.type = key->type; | 1990 | memcpy(ev->key.val, key->val, 16); |
1968 | memcpy(ev.key.val, key->val, 16); | 1991 | ev->key.pin_len = key->pin_len; |
1969 | ev.key.pin_len = key->pin_len; | 1992 | ev->key.dlen = key->dlen; |
1993 | ev->store_hint = persistent; | ||
1970 | 1994 | ||
1971 | return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL); | 1995 | memcpy(ev->key.data, key->data, key->dlen); |
1996 | |||
1997 | err = mgmt_event(MGMT_EV_NEW_KEY, index, ev, total, NULL); | ||
1998 | |||
1999 | kfree(ev); | ||
2000 | |||
2001 | return err; | ||
1972 | } | 2002 | } |
1973 | 2003 | ||
1974 | int mgmt_connected(u16 index, bdaddr_t *bdaddr) | 2004 | int mgmt_connected(u16 index, bdaddr_t *bdaddr) |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index cb4fb7837e5c..4c3621b5e0aa 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -932,7 +932,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status) | |||
932 | if (conn) | 932 | if (conn) |
933 | sco_conn_ready(conn); | 933 | sco_conn_ready(conn); |
934 | } else | 934 | } else |
935 | sco_conn_del(hcon, bt_err(status)); | 935 | sco_conn_del(hcon, bt_to_errno(status)); |
936 | 936 | ||
937 | return 0; | 937 | return 0; |
938 | } | 938 | } |
@@ -944,7 +944,7 @@ static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) | |||
944 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) | 944 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) |
945 | return -EINVAL; | 945 | return -EINVAL; |
946 | 946 | ||
947 | sco_conn_del(hcon, bt_err(reason)); | 947 | sco_conn_del(hcon, bt_to_errno(reason)); |
948 | 948 | ||
949 | return 0; | 949 | return 0; |
950 | } | 950 | } |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index a36f8707d964..391888b88a92 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -197,14 +197,34 @@ static __u8 seclevel_to_authreq(__u8 level) | |||
197 | } | 197 | } |
198 | 198 | ||
199 | static void build_pairing_cmd(struct l2cap_conn *conn, | 199 | static void build_pairing_cmd(struct l2cap_conn *conn, |
200 | struct smp_cmd_pairing *cmd, __u8 authreq) | 200 | struct smp_cmd_pairing *req, |
201 | struct smp_cmd_pairing *rsp, | ||
202 | __u8 authreq) | ||
201 | { | 203 | { |
202 | cmd->io_capability = conn->hcon->io_capability; | 204 | u8 dist_keys; |
203 | cmd->oob_flag = SMP_OOB_NOT_PRESENT; | 205 | |
204 | cmd->max_key_size = SMP_MAX_ENC_KEY_SIZE; | 206 | dist_keys = 0; |
205 | cmd->init_key_dist = 0x00; | 207 | if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->flags)) { |
206 | cmd->resp_key_dist = 0x00; | 208 | dist_keys = SMP_DIST_ENC_KEY | SMP_DIST_ID_KEY | SMP_DIST_SIGN; |
207 | cmd->auth_req = authreq; | 209 | authreq |= SMP_AUTH_BONDING; |
210 | } | ||
211 | |||
212 | if (rsp == NULL) { | ||
213 | req->io_capability = conn->hcon->io_capability; | ||
214 | req->oob_flag = SMP_OOB_NOT_PRESENT; | ||
215 | req->max_key_size = SMP_MAX_ENC_KEY_SIZE; | ||
216 | req->init_key_dist = dist_keys; | ||
217 | req->resp_key_dist = dist_keys; | ||
218 | req->auth_req = authreq; | ||
219 | return; | ||
220 | } | ||
221 | |||
222 | rsp->io_capability = conn->hcon->io_capability; | ||
223 | rsp->oob_flag = SMP_OOB_NOT_PRESENT; | ||
224 | rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; | ||
225 | rsp->init_key_dist = req->init_key_dist & dist_keys; | ||
226 | rsp->resp_key_dist = req->resp_key_dist & dist_keys; | ||
227 | rsp->auth_req = authreq; | ||
208 | } | 228 | } |
209 | 229 | ||
210 | static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) | 230 | static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) |
@@ -233,7 +253,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
233 | return SMP_OOB_NOT_AVAIL; | 253 | return SMP_OOB_NOT_AVAIL; |
234 | 254 | ||
235 | /* We didn't start the pairing, so no requirements */ | 255 | /* We didn't start the pairing, so no requirements */ |
236 | build_pairing_cmd(conn, &rsp, SMP_AUTH_NONE); | 256 | build_pairing_cmd(conn, req, &rsp, SMP_AUTH_NONE); |
237 | 257 | ||
238 | key_size = min(req->max_key_size, rsp.max_key_size); | 258 | key_size = min(req->max_key_size, rsp.max_key_size); |
239 | if (check_enc_key_size(conn, key_size)) | 259 | if (check_enc_key_size(conn, key_size)) |
@@ -347,8 +367,6 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) | |||
347 | swap128(skb->data, random); | 367 | swap128(skb->data, random); |
348 | skb_pull(skb, sizeof(random)); | 368 | skb_pull(skb, sizeof(random)); |
349 | 369 | ||
350 | memset(hcon->ltk, 0, sizeof(hcon->ltk)); | ||
351 | |||
352 | if (conn->hcon->out) | 370 | if (conn->hcon->out) |
353 | ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0, | 371 | ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0, |
354 | conn->src, conn->hcon->dst_type, conn->dst, | 372 | conn->src, conn->hcon->dst_type, conn->dst, |
@@ -370,29 +388,38 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) | |||
370 | } | 388 | } |
371 | 389 | ||
372 | if (conn->hcon->out) { | 390 | if (conn->hcon->out) { |
391 | u8 stk[16], rand[8]; | ||
373 | __le16 ediv; | 392 | __le16 ediv; |
374 | u8 rand[8]; | 393 | |
394 | memset(rand, 0, sizeof(rand)); | ||
395 | ediv = 0; | ||
375 | 396 | ||
376 | smp_s1(tfm, conn->tk, random, conn->prnd, key); | 397 | smp_s1(tfm, conn->tk, random, conn->prnd, key); |
377 | swap128(key, hcon->ltk); | 398 | swap128(key, stk); |
378 | 399 | ||
379 | memset(hcon->ltk + conn->smp_key_size, 0, | 400 | memset(stk + conn->smp_key_size, 0, |
380 | SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size); | 401 | SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size); |
381 | 402 | ||
403 | hci_le_start_enc(hcon, ediv, rand, stk); | ||
404 | hcon->enc_key_size = conn->smp_key_size; | ||
405 | } else { | ||
406 | u8 stk[16], r[16], rand[8]; | ||
407 | __le16 ediv; | ||
408 | |||
382 | memset(rand, 0, sizeof(rand)); | 409 | memset(rand, 0, sizeof(rand)); |
383 | ediv = 0; | 410 | ediv = 0; |
384 | hci_le_start_enc(hcon, ediv, rand, hcon->ltk); | ||
385 | } else { | ||
386 | u8 r[16]; | ||
387 | 411 | ||
388 | swap128(conn->prnd, r); | 412 | swap128(conn->prnd, r); |
389 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r); | 413 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r); |
390 | 414 | ||
391 | smp_s1(tfm, conn->tk, conn->prnd, random, key); | 415 | smp_s1(tfm, conn->tk, conn->prnd, random, key); |
392 | swap128(key, hcon->ltk); | 416 | swap128(key, stk); |
393 | 417 | ||
394 | memset(hcon->ltk + conn->smp_key_size, 0, | 418 | memset(stk + conn->smp_key_size, 0, |
395 | SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size); | 419 | SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size); |
420 | |||
421 | hci_add_ltk(conn->hcon->hdev, 0, conn->dst, conn->smp_key_size, | ||
422 | ediv, rand, stk); | ||
396 | } | 423 | } |
397 | 424 | ||
398 | return 0; | 425 | return 0; |
@@ -412,7 +439,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
412 | skb_pull(skb, sizeof(*rp)); | 439 | skb_pull(skb, sizeof(*rp)); |
413 | 440 | ||
414 | memset(&cp, 0, sizeof(cp)); | 441 | memset(&cp, 0, sizeof(cp)); |
415 | build_pairing_cmd(conn, &cp, rp->auth_req); | 442 | build_pairing_cmd(conn, &cp, NULL, rp->auth_req); |
416 | 443 | ||
417 | conn->preq[0] = SMP_CMD_PAIRING_REQ; | 444 | conn->preq[0] = SMP_CMD_PAIRING_REQ; |
418 | memcpy(&conn->preq[1], &cp, sizeof(cp)); | 445 | memcpy(&conn->preq[1], &cp, sizeof(cp)); |
@@ -434,6 +461,9 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) | |||
434 | 461 | ||
435 | BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); | 462 | BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); |
436 | 463 | ||
464 | if (!lmp_host_le_capable(hcon->hdev)) | ||
465 | return 1; | ||
466 | |||
437 | if (IS_ERR(hcon->hdev->tfm)) | 467 | if (IS_ERR(hcon->hdev->tfm)) |
438 | return 1; | 468 | return 1; |
439 | 469 | ||
@@ -450,8 +480,21 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) | |||
450 | 480 | ||
451 | if (hcon->link_mode & HCI_LM_MASTER) { | 481 | if (hcon->link_mode & HCI_LM_MASTER) { |
452 | struct smp_cmd_pairing cp; | 482 | struct smp_cmd_pairing cp; |
483 | struct link_key *key; | ||
453 | 484 | ||
454 | build_pairing_cmd(conn, &cp, authreq); | 485 | key = hci_find_link_key_type(hcon->hdev, conn->dst, |
486 | HCI_LK_SMP_LTK); | ||
487 | if (key) { | ||
488 | struct key_master_id *master = (void *) key->data; | ||
489 | |||
490 | hci_le_start_enc(hcon, master->ediv, master->rand, | ||
491 | key->val); | ||
492 | hcon->enc_key_size = key->pin_len; | ||
493 | |||
494 | goto done; | ||
495 | } | ||
496 | |||
497 | build_pairing_cmd(conn, &cp, NULL, authreq); | ||
455 | conn->preq[0] = SMP_CMD_PAIRING_REQ; | 498 | conn->preq[0] = SMP_CMD_PAIRING_REQ; |
456 | memcpy(&conn->preq[1], &cp, sizeof(cp)); | 499 | memcpy(&conn->preq[1], &cp, sizeof(cp)); |
457 | 500 | ||
@@ -465,18 +508,50 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) | |||
465 | smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); | 508 | smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); |
466 | } | 509 | } |
467 | 510 | ||
511 | done: | ||
468 | hcon->pending_sec_level = sec_level; | 512 | hcon->pending_sec_level = sec_level; |
469 | set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend); | 513 | set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend); |
470 | 514 | ||
471 | return 0; | 515 | return 0; |
472 | } | 516 | } |
473 | 517 | ||
518 | static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) | ||
519 | { | ||
520 | struct smp_cmd_encrypt_info *rp = (void *) skb->data; | ||
521 | |||
522 | skb_pull(skb, sizeof(*rp)); | ||
523 | |||
524 | memcpy(conn->tk, rp->ltk, sizeof(conn->tk)); | ||
525 | |||
526 | return 0; | ||
527 | } | ||
528 | |||
529 | static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) | ||
530 | { | ||
531 | struct smp_cmd_master_ident *rp = (void *) skb->data; | ||
532 | |||
533 | skb_pull(skb, sizeof(*rp)); | ||
534 | |||
535 | hci_add_ltk(conn->hcon->hdev, 1, conn->src, conn->smp_key_size, | ||
536 | rp->ediv, rp->rand, conn->tk); | ||
537 | |||
538 | smp_distribute_keys(conn, 1); | ||
539 | |||
540 | return 0; | ||
541 | } | ||
542 | |||
474 | int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) | 543 | int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) |
475 | { | 544 | { |
476 | __u8 code = skb->data[0]; | 545 | __u8 code = skb->data[0]; |
477 | __u8 reason; | 546 | __u8 reason; |
478 | int err = 0; | 547 | int err = 0; |
479 | 548 | ||
549 | if (!lmp_host_le_capable(conn->hcon->hdev)) { | ||
550 | err = -ENOTSUPP; | ||
551 | reason = SMP_PAIRING_NOTSUPP; | ||
552 | goto done; | ||
553 | } | ||
554 | |||
480 | if (IS_ERR(conn->hcon->hdev->tfm)) { | 555 | if (IS_ERR(conn->hcon->hdev->tfm)) { |
481 | err = PTR_ERR(conn->hcon->hdev->tfm); | 556 | err = PTR_ERR(conn->hcon->hdev->tfm); |
482 | reason = SMP_PAIRING_NOTSUPP; | 557 | reason = SMP_PAIRING_NOTSUPP; |
@@ -512,10 +587,20 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) | |||
512 | break; | 587 | break; |
513 | 588 | ||
514 | case SMP_CMD_ENCRYPT_INFO: | 589 | case SMP_CMD_ENCRYPT_INFO: |
590 | reason = smp_cmd_encrypt_info(conn, skb); | ||
591 | break; | ||
592 | |||
515 | case SMP_CMD_MASTER_IDENT: | 593 | case SMP_CMD_MASTER_IDENT: |
594 | reason = smp_cmd_master_ident(conn, skb); | ||
595 | break; | ||
596 | |||
516 | case SMP_CMD_IDENT_INFO: | 597 | case SMP_CMD_IDENT_INFO: |
517 | case SMP_CMD_IDENT_ADDR_INFO: | 598 | case SMP_CMD_IDENT_ADDR_INFO: |
518 | case SMP_CMD_SIGN_INFO: | 599 | case SMP_CMD_SIGN_INFO: |
600 | /* Just ignored */ | ||
601 | reason = 0; | ||
602 | break; | ||
603 | |||
519 | default: | 604 | default: |
520 | BT_DBG("Unknown command code 0x%2.2x", code); | 605 | BT_DBG("Unknown command code 0x%2.2x", code); |
521 | 606 | ||
@@ -532,3 +617,86 @@ done: | |||
532 | kfree_skb(skb); | 617 | kfree_skb(skb); |
533 | return err; | 618 | return err; |
534 | } | 619 | } |
620 | |||
621 | int smp_distribute_keys(struct l2cap_conn *conn, __u8 force) | ||
622 | { | ||
623 | struct smp_cmd_pairing *req, *rsp; | ||
624 | __u8 *keydist; | ||
625 | |||
626 | BT_DBG("conn %p force %d", conn, force); | ||
627 | |||
628 | if (IS_ERR(conn->hcon->hdev->tfm)) | ||
629 | return PTR_ERR(conn->hcon->hdev->tfm); | ||
630 | |||
631 | rsp = (void *) &conn->prsp[1]; | ||
632 | |||
633 | /* The responder sends its keys first */ | ||
634 | if (!force && conn->hcon->out && (rsp->resp_key_dist & 0x07)) | ||
635 | return 0; | ||
636 | |||
637 | req = (void *) &conn->preq[1]; | ||
638 | |||
639 | if (conn->hcon->out) { | ||
640 | keydist = &rsp->init_key_dist; | ||
641 | *keydist &= req->init_key_dist; | ||
642 | } else { | ||
643 | keydist = &rsp->resp_key_dist; | ||
644 | *keydist &= req->resp_key_dist; | ||
645 | } | ||
646 | |||
647 | |||
648 | BT_DBG("keydist 0x%x", *keydist); | ||
649 | |||
650 | if (*keydist & SMP_DIST_ENC_KEY) { | ||
651 | struct smp_cmd_encrypt_info enc; | ||
652 | struct smp_cmd_master_ident ident; | ||
653 | __le16 ediv; | ||
654 | |||
655 | get_random_bytes(enc.ltk, sizeof(enc.ltk)); | ||
656 | get_random_bytes(&ediv, sizeof(ediv)); | ||
657 | get_random_bytes(ident.rand, sizeof(ident.rand)); | ||
658 | |||
659 | smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc); | ||
660 | |||
661 | hci_add_ltk(conn->hcon->hdev, 1, conn->dst, conn->smp_key_size, | ||
662 | ediv, ident.rand, enc.ltk); | ||
663 | |||
664 | ident.ediv = cpu_to_le16(ediv); | ||
665 | |||
666 | smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident); | ||
667 | |||
668 | *keydist &= ~SMP_DIST_ENC_KEY; | ||
669 | } | ||
670 | |||
671 | if (*keydist & SMP_DIST_ID_KEY) { | ||
672 | struct smp_cmd_ident_addr_info addrinfo; | ||
673 | struct smp_cmd_ident_info idinfo; | ||
674 | |||
675 | /* Send a dummy key */ | ||
676 | get_random_bytes(idinfo.irk, sizeof(idinfo.irk)); | ||
677 | |||
678 | smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo); | ||
679 | |||
680 | /* Just public address */ | ||
681 | memset(&addrinfo, 0, sizeof(addrinfo)); | ||
682 | bacpy(&addrinfo.bdaddr, conn->src); | ||
683 | |||
684 | smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo), | ||
685 | &addrinfo); | ||
686 | |||
687 | *keydist &= ~SMP_DIST_ID_KEY; | ||
688 | } | ||
689 | |||
690 | if (*keydist & SMP_DIST_SIGN) { | ||
691 | struct smp_cmd_sign_info sign; | ||
692 | |||
693 | /* Send a dummy key */ | ||
694 | get_random_bytes(sign.csrk, sizeof(sign.csrk)); | ||
695 | |||
696 | smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign); | ||
697 | |||
698 | *keydist &= ~SMP_DIST_SIGN; | ||
699 | } | ||
700 | |||
701 | return 0; | ||
702 | } | ||
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c index b9b595c08112..0785e95c9924 100644 --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <linux/crypto.h> | 12 | #include <linux/crypto.h> |
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <crypto/aes.h> | ||
14 | 15 | ||
15 | #include <net/mac80211.h> | 16 | #include <net/mac80211.h> |
16 | #include "key.h" | 17 | #include "key.h" |
@@ -21,21 +22,21 @@ static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a) | |||
21 | int i; | 22 | int i; |
22 | u8 *b_0, *aad, *b, *s_0; | 23 | u8 *b_0, *aad, *b, *s_0; |
23 | 24 | ||
24 | b_0 = scratch + 3 * AES_BLOCK_LEN; | 25 | b_0 = scratch + 3 * AES_BLOCK_SIZE; |
25 | aad = scratch + 4 * AES_BLOCK_LEN; | 26 | aad = scratch + 4 * AES_BLOCK_SIZE; |
26 | b = scratch; | 27 | b = scratch; |
27 | s_0 = scratch + AES_BLOCK_LEN; | 28 | s_0 = scratch + AES_BLOCK_SIZE; |
28 | 29 | ||
29 | crypto_cipher_encrypt_one(tfm, b, b_0); | 30 | crypto_cipher_encrypt_one(tfm, b, b_0); |
30 | 31 | ||
31 | /* Extra Authenticate-only data (always two AES blocks) */ | 32 | /* Extra Authenticate-only data (always two AES blocks) */ |
32 | for (i = 0; i < AES_BLOCK_LEN; i++) | 33 | for (i = 0; i < AES_BLOCK_SIZE; i++) |
33 | aad[i] ^= b[i]; | 34 | aad[i] ^= b[i]; |
34 | crypto_cipher_encrypt_one(tfm, b, aad); | 35 | crypto_cipher_encrypt_one(tfm, b, aad); |
35 | 36 | ||
36 | aad += AES_BLOCK_LEN; | 37 | aad += AES_BLOCK_SIZE; |
37 | 38 | ||
38 | for (i = 0; i < AES_BLOCK_LEN; i++) | 39 | for (i = 0; i < AES_BLOCK_SIZE; i++) |
39 | aad[i] ^= b[i]; | 40 | aad[i] ^= b[i]; |
40 | crypto_cipher_encrypt_one(tfm, a, aad); | 41 | crypto_cipher_encrypt_one(tfm, a, aad); |
41 | 42 | ||
@@ -57,12 +58,12 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, | |||
57 | u8 *pos, *cpos, *b, *s_0, *e, *b_0; | 58 | u8 *pos, *cpos, *b, *s_0, *e, *b_0; |
58 | 59 | ||
59 | b = scratch; | 60 | b = scratch; |
60 | s_0 = scratch + AES_BLOCK_LEN; | 61 | s_0 = scratch + AES_BLOCK_SIZE; |
61 | e = scratch + 2 * AES_BLOCK_LEN; | 62 | e = scratch + 2 * AES_BLOCK_SIZE; |
62 | b_0 = scratch + 3 * AES_BLOCK_LEN; | 63 | b_0 = scratch + 3 * AES_BLOCK_SIZE; |
63 | 64 | ||
64 | num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); | 65 | num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); |
65 | last_len = data_len % AES_BLOCK_LEN; | 66 | last_len = data_len % AES_BLOCK_SIZE; |
66 | aes_ccm_prepare(tfm, scratch, b); | 67 | aes_ccm_prepare(tfm, scratch, b); |
67 | 68 | ||
68 | /* Process payload blocks */ | 69 | /* Process payload blocks */ |
@@ -70,7 +71,7 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, | |||
70 | cpos = cdata; | 71 | cpos = cdata; |
71 | for (j = 1; j <= num_blocks; j++) { | 72 | for (j = 1; j <= num_blocks; j++) { |
72 | int blen = (j == num_blocks && last_len) ? | 73 | int blen = (j == num_blocks && last_len) ? |
73 | last_len : AES_BLOCK_LEN; | 74 | last_len : AES_BLOCK_SIZE; |
74 | 75 | ||
75 | /* Authentication followed by encryption */ | 76 | /* Authentication followed by encryption */ |
76 | for (i = 0; i < blen; i++) | 77 | for (i = 0; i < blen; i++) |
@@ -96,12 +97,12 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, | |||
96 | u8 *pos, *cpos, *b, *s_0, *a, *b_0; | 97 | u8 *pos, *cpos, *b, *s_0, *a, *b_0; |
97 | 98 | ||
98 | b = scratch; | 99 | b = scratch; |
99 | s_0 = scratch + AES_BLOCK_LEN; | 100 | s_0 = scratch + AES_BLOCK_SIZE; |
100 | a = scratch + 2 * AES_BLOCK_LEN; | 101 | a = scratch + 2 * AES_BLOCK_SIZE; |
101 | b_0 = scratch + 3 * AES_BLOCK_LEN; | 102 | b_0 = scratch + 3 * AES_BLOCK_SIZE; |
102 | 103 | ||
103 | num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); | 104 | num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); |
104 | last_len = data_len % AES_BLOCK_LEN; | 105 | last_len = data_len % AES_BLOCK_SIZE; |
105 | aes_ccm_prepare(tfm, scratch, a); | 106 | aes_ccm_prepare(tfm, scratch, a); |
106 | 107 | ||
107 | /* Process payload blocks */ | 108 | /* Process payload blocks */ |
@@ -109,7 +110,7 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, | |||
109 | pos = data; | 110 | pos = data; |
110 | for (j = 1; j <= num_blocks; j++) { | 111 | for (j = 1; j <= num_blocks; j++) { |
111 | int blen = (j == num_blocks && last_len) ? | 112 | int blen = (j == num_blocks && last_len) ? |
112 | last_len : AES_BLOCK_LEN; | 113 | last_len : AES_BLOCK_SIZE; |
113 | 114 | ||
114 | /* Decryption followed by authentication */ | 115 | /* Decryption followed by authentication */ |
115 | b_0[14] = (j >> 8) & 0xff; | 116 | b_0[14] = (j >> 8) & 0xff; |
diff --git a/net/mac80211/aes_ccm.h b/net/mac80211/aes_ccm.h index 6e7820ef3448..5b7d744e2370 100644 --- a/net/mac80211/aes_ccm.h +++ b/net/mac80211/aes_ccm.h | |||
@@ -12,8 +12,6 @@ | |||
12 | 12 | ||
13 | #include <linux/crypto.h> | 13 | #include <linux/crypto.h> |
14 | 14 | ||
15 | #define AES_BLOCK_LEN 16 | ||
16 | |||
17 | struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]); | 15 | struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]); |
18 | void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, | 16 | void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, |
19 | u8 *data, size_t data_len, | 17 | u8 *data, size_t data_len, |
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c index d502b2684a66..8dfd70d8fcfb 100644 --- a/net/mac80211/aes_cmac.c +++ b/net/mac80211/aes_cmac.c | |||
@@ -11,12 +11,12 @@ | |||
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <linux/crypto.h> | 12 | #include <linux/crypto.h> |
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <crypto/aes.h> | ||
14 | 15 | ||
15 | #include <net/mac80211.h> | 16 | #include <net/mac80211.h> |
16 | #include "key.h" | 17 | #include "key.h" |
17 | #include "aes_cmac.h" | 18 | #include "aes_cmac.h" |
18 | 19 | ||
19 | #define AES_BLOCK_SIZE 16 | ||
20 | #define AES_CMAC_KEY_LEN 16 | 20 | #define AES_CMAC_KEY_LEN 16 |
21 | #define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */ | 21 | #define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */ |
22 | #define AAD_LEN 20 | 22 | #define AAD_LEN 20 |
@@ -35,10 +35,10 @@ static void gf_mulx(u8 *pad) | |||
35 | } | 35 | } |
36 | 36 | ||
37 | 37 | ||
38 | static void aes_128_cmac_vector(struct crypto_cipher *tfm, u8 *scratch, | 38 | static void aes_128_cmac_vector(struct crypto_cipher *tfm, size_t num_elem, |
39 | size_t num_elem, | ||
40 | const u8 *addr[], const size_t *len, u8 *mac) | 39 | const u8 *addr[], const size_t *len, u8 *mac) |
41 | { | 40 | { |
41 | u8 scratch[2 * AES_BLOCK_SIZE]; | ||
42 | u8 *cbc, *pad; | 42 | u8 *cbc, *pad; |
43 | const u8 *pos, *end; | 43 | const u8 *pos, *end; |
44 | size_t i, e, left, total_len; | 44 | size_t i, e, left, total_len; |
@@ -95,7 +95,7 @@ static void aes_128_cmac_vector(struct crypto_cipher *tfm, u8 *scratch, | |||
95 | } | 95 | } |
96 | 96 | ||
97 | 97 | ||
98 | void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad, | 98 | void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, |
99 | const u8 *data, size_t data_len, u8 *mic) | 99 | const u8 *data, size_t data_len, u8 *mic) |
100 | { | 100 | { |
101 | const u8 *addr[3]; | 101 | const u8 *addr[3]; |
@@ -110,7 +110,7 @@ void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad, | |||
110 | addr[2] = zero; | 110 | addr[2] = zero; |
111 | len[2] = CMAC_TLEN; | 111 | len[2] = CMAC_TLEN; |
112 | 112 | ||
113 | aes_128_cmac_vector(tfm, scratch, 3, addr, len, mic); | 113 | aes_128_cmac_vector(tfm, 3, addr, len, mic); |
114 | } | 114 | } |
115 | 115 | ||
116 | 116 | ||
diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h index 0eb9a4831508..20785a647254 100644 --- a/net/mac80211/aes_cmac.h +++ b/net/mac80211/aes_cmac.h | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <linux/crypto.h> | 12 | #include <linux/crypto.h> |
13 | 13 | ||
14 | struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]); | 14 | struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]); |
15 | void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad, | 15 | void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, |
16 | const u8 *data, size_t data_len, u8 *mic); | 16 | const u8 *data, size_t data_len, u8 *mic); |
17 | void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); | 17 | void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); |
18 | 18 | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 295ab747663f..bfc36e904764 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -209,6 +209,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
209 | u8 seq[6] = {0}; | 209 | u8 seq[6] = {0}; |
210 | struct key_params params; | 210 | struct key_params params; |
211 | struct ieee80211_key *key = NULL; | 211 | struct ieee80211_key *key = NULL; |
212 | u64 pn64; | ||
212 | u32 iv32; | 213 | u32 iv32; |
213 | u16 iv16; | 214 | u16 iv16; |
214 | int err = -ENOENT; | 215 | int err = -ENOENT; |
@@ -256,22 +257,24 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
256 | params.seq_len = 6; | 257 | params.seq_len = 6; |
257 | break; | 258 | break; |
258 | case WLAN_CIPHER_SUITE_CCMP: | 259 | case WLAN_CIPHER_SUITE_CCMP: |
259 | seq[0] = key->u.ccmp.tx_pn[5]; | 260 | pn64 = atomic64_read(&key->u.ccmp.tx_pn); |
260 | seq[1] = key->u.ccmp.tx_pn[4]; | 261 | seq[0] = pn64; |
261 | seq[2] = key->u.ccmp.tx_pn[3]; | 262 | seq[1] = pn64 >> 8; |
262 | seq[3] = key->u.ccmp.tx_pn[2]; | 263 | seq[2] = pn64 >> 16; |
263 | seq[4] = key->u.ccmp.tx_pn[1]; | 264 | seq[3] = pn64 >> 24; |
264 | seq[5] = key->u.ccmp.tx_pn[0]; | 265 | seq[4] = pn64 >> 32; |
266 | seq[5] = pn64 >> 40; | ||
265 | params.seq = seq; | 267 | params.seq = seq; |
266 | params.seq_len = 6; | 268 | params.seq_len = 6; |
267 | break; | 269 | break; |
268 | case WLAN_CIPHER_SUITE_AES_CMAC: | 270 | case WLAN_CIPHER_SUITE_AES_CMAC: |
269 | seq[0] = key->u.aes_cmac.tx_pn[5]; | 271 | pn64 = atomic64_read(&key->u.aes_cmac.tx_pn); |
270 | seq[1] = key->u.aes_cmac.tx_pn[4]; | 272 | seq[0] = pn64; |
271 | seq[2] = key->u.aes_cmac.tx_pn[3]; | 273 | seq[1] = pn64 >> 8; |
272 | seq[3] = key->u.aes_cmac.tx_pn[2]; | 274 | seq[2] = pn64 >> 16; |
273 | seq[4] = key->u.aes_cmac.tx_pn[1]; | 275 | seq[3] = pn64 >> 24; |
274 | seq[5] = key->u.aes_cmac.tx_pn[0]; | 276 | seq[4] = pn64 >> 32; |
277 | seq[5] = pn64 >> 40; | ||
275 | params.seq = seq; | 278 | params.seq = seq; |
276 | params.seq_len = 6; | 279 | params.seq_len = 6; |
277 | break; | 280 | break; |
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 33c58b85c911..38e6101190d9 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c | |||
@@ -78,7 +78,7 @@ KEY_OPS(algorithm); | |||
78 | static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, | 78 | static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, |
79 | size_t count, loff_t *ppos) | 79 | size_t count, loff_t *ppos) |
80 | { | 80 | { |
81 | const u8 *tpn; | 81 | u64 pn; |
82 | char buf[20]; | 82 | char buf[20]; |
83 | int len; | 83 | int len; |
84 | struct ieee80211_key *key = file->private_data; | 84 | struct ieee80211_key *key = file->private_data; |
@@ -94,15 +94,16 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, | |||
94 | key->u.tkip.tx.iv16); | 94 | key->u.tkip.tx.iv16); |
95 | break; | 95 | break; |
96 | case WLAN_CIPHER_SUITE_CCMP: | 96 | case WLAN_CIPHER_SUITE_CCMP: |
97 | tpn = key->u.ccmp.tx_pn; | 97 | pn = atomic64_read(&key->u.ccmp.tx_pn); |
98 | len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", | 98 | len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", |
99 | tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]); | 99 | (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24), |
100 | (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn); | ||
100 | break; | 101 | break; |
101 | case WLAN_CIPHER_SUITE_AES_CMAC: | 102 | case WLAN_CIPHER_SUITE_AES_CMAC: |
102 | tpn = key->u.aes_cmac.tx_pn; | 103 | pn = atomic64_read(&key->u.aes_cmac.tx_pn); |
103 | len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", | 104 | len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", |
104 | tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], | 105 | (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24), |
105 | tpn[5]); | 106 | (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn); |
106 | break; | 107 | break; |
107 | default: | 108 | default: |
108 | return 0; | 109 | return 0; |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index edd2dd79c9be..b2d6bba44054 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -657,4 +657,12 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local, | |||
657 | trace_drv_return_void(local); | 657 | trace_drv_return_void(local); |
658 | } | 658 | } |
659 | 659 | ||
660 | static inline void drv_rssi_callback(struct ieee80211_local *local, | ||
661 | const enum ieee80211_rssi_event event) | ||
662 | { | ||
663 | trace_drv_rssi_callback(local, event); | ||
664 | if (local->ops->rssi_callback) | ||
665 | local->ops->rssi_callback(&local->hw, event); | ||
666 | trace_drv_return_void(local); | ||
667 | } | ||
660 | #endif /* __MAC80211_DRIVER_OPS */ | 668 | #endif /* __MAC80211_DRIVER_OPS */ |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 31a9dfa81f65..4470f6e8b845 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -1052,6 +1052,28 @@ TRACE_EVENT(drv_set_rekey_data, | |||
1052 | LOCAL_PR_ARG, VIF_PR_ARG) | 1052 | LOCAL_PR_ARG, VIF_PR_ARG) |
1053 | ); | 1053 | ); |
1054 | 1054 | ||
1055 | TRACE_EVENT(drv_rssi_callback, | ||
1056 | TP_PROTO(struct ieee80211_local *local, | ||
1057 | enum ieee80211_rssi_event rssi_event), | ||
1058 | |||
1059 | TP_ARGS(local, rssi_event), | ||
1060 | |||
1061 | TP_STRUCT__entry( | ||
1062 | LOCAL_ENTRY | ||
1063 | __field(u32, rssi_event) | ||
1064 | ), | ||
1065 | |||
1066 | TP_fast_assign( | ||
1067 | LOCAL_ASSIGN; | ||
1068 | __entry->rssi_event = rssi_event; | ||
1069 | ), | ||
1070 | |||
1071 | TP_printk( | ||
1072 | LOCAL_PR_FMT " rssi_event:%d", | ||
1073 | LOCAL_PR_ARG, __entry->rssi_event | ||
1074 | ) | ||
1075 | ); | ||
1076 | |||
1055 | /* | 1077 | /* |
1056 | * Tracing for API calls that drivers call. | 1078 | * Tracing for API calls that drivers call. |
1057 | */ | 1079 | */ |
@@ -1342,6 +1364,30 @@ TRACE_EVENT(api_gtk_rekey_notify, | |||
1342 | TP_printk(VIF_PR_FMT, VIF_PR_ARG) | 1364 | TP_printk(VIF_PR_FMT, VIF_PR_ARG) |
1343 | ); | 1365 | ); |
1344 | 1366 | ||
1367 | TRACE_EVENT(api_enable_rssi_reports, | ||
1368 | TP_PROTO(struct ieee80211_sub_if_data *sdata, | ||
1369 | int rssi_min_thold, int rssi_max_thold), | ||
1370 | |||
1371 | TP_ARGS(sdata, rssi_min_thold, rssi_max_thold), | ||
1372 | |||
1373 | TP_STRUCT__entry( | ||
1374 | VIF_ENTRY | ||
1375 | __field(int, rssi_min_thold) | ||
1376 | __field(int, rssi_max_thold) | ||
1377 | ), | ||
1378 | |||
1379 | TP_fast_assign( | ||
1380 | VIF_ASSIGN; | ||
1381 | __entry->rssi_min_thold = rssi_min_thold; | ||
1382 | __entry->rssi_max_thold = rssi_max_thold; | ||
1383 | ), | ||
1384 | |||
1385 | TP_printk( | ||
1386 | VIF_PR_FMT " rssi_min_thold =%d, rssi_max_thold = %d", | ||
1387 | VIF_PR_ARG, __entry->rssi_min_thold, __entry->rssi_max_thold | ||
1388 | ) | ||
1389 | ); | ||
1390 | |||
1345 | /* | 1391 | /* |
1346 | * Tracing for internal functions | 1392 | * Tracing for internal functions |
1347 | * (which may also be called in response to driver calls) | 1393 | * (which may also be called in response to driver calls) |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 4f2e424e8b1b..dda0d1ab34f3 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -202,7 +202,22 @@ struct ieee80211_rx_data { | |||
202 | struct ieee80211_key *key; | 202 | struct ieee80211_key *key; |
203 | 203 | ||
204 | unsigned int flags; | 204 | unsigned int flags; |
205 | int queue; | 205 | |
206 | /* | ||
207 | * Index into sequence numbers array, 0..16 | ||
208 | * since the last (16) is used for non-QoS, | ||
209 | * will be 16 on non-QoS frames. | ||
210 | */ | ||
211 | int seqno_idx; | ||
212 | |||
213 | /* | ||
214 | * Index into the security IV/PN arrays, 0..16 | ||
215 | * since the last (16) is used for CCMP-encrypted | ||
216 | * management frames, will be set to 16 on mgmt | ||
217 | * frames and 0 on non-QoS frames. | ||
218 | */ | ||
219 | int security_idx; | ||
220 | |||
206 | u32 tkip_iv32; | 221 | u32 tkip_iv32; |
207 | u16 tkip_iv16; | 222 | u16 tkip_iv16; |
208 | }; | 223 | }; |
@@ -417,6 +432,14 @@ struct ieee80211_if_managed { | |||
417 | * generated for the current association. | 432 | * generated for the current association. |
418 | */ | 433 | */ |
419 | int last_cqm_event_signal; | 434 | int last_cqm_event_signal; |
435 | |||
436 | /* | ||
437 | * State variables for keeping track of RSSI of the AP currently | ||
438 | * connected to and informing driver when RSSI has gone | ||
439 | * below/above a certain threshold. | ||
440 | */ | ||
441 | int rssi_min_thold, rssi_max_thold; | ||
442 | int last_ave_beacon_signal; | ||
420 | }; | 443 | }; |
421 | 444 | ||
422 | struct ieee80211_if_ibss { | 445 | struct ieee80211_if_ibss { |
@@ -515,12 +538,14 @@ struct ieee80211_if_mesh { | |||
515 | * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between | 538 | * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between |
516 | * associated stations and deliver multicast frames both | 539 | * associated stations and deliver multicast frames both |
517 | * back to wireless media and to the local net stack. | 540 | * back to wireless media and to the local net stack. |
541 | * @IEEE80211_SDATA_DISCONNECT_RESUME: Disconnect after resume. | ||
518 | */ | 542 | */ |
519 | enum ieee80211_sub_if_data_flags { | 543 | enum ieee80211_sub_if_data_flags { |
520 | IEEE80211_SDATA_ALLMULTI = BIT(0), | 544 | IEEE80211_SDATA_ALLMULTI = BIT(0), |
521 | IEEE80211_SDATA_PROMISC = BIT(1), | 545 | IEEE80211_SDATA_PROMISC = BIT(1), |
522 | IEEE80211_SDATA_OPERATING_GMODE = BIT(2), | 546 | IEEE80211_SDATA_OPERATING_GMODE = BIT(2), |
523 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), | 547 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), |
548 | IEEE80211_SDATA_DISCONNECT_RESUME = BIT(4), | ||
524 | }; | 549 | }; |
525 | 550 | ||
526 | /** | 551 | /** |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index dee30aea9ab3..cd5fb40d3fd4 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -363,8 +363,7 @@ static int ieee80211_open(struct net_device *dev) | |||
363 | int err; | 363 | int err; |
364 | 364 | ||
365 | /* fail early if user set an invalid address */ | 365 | /* fail early if user set an invalid address */ |
366 | if (!is_zero_ether_addr(dev->dev_addr) && | 366 | if (!is_valid_ether_addr(dev->dev_addr)) |
367 | !is_valid_ether_addr(dev->dev_addr)) | ||
368 | return -EADDRNOTAVAIL; | 367 | return -EADDRNOTAVAIL; |
369 | 368 | ||
370 | err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type); | 369 | err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type); |
@@ -1130,8 +1129,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1130 | 1129 | ||
1131 | ASSERT_RTNL(); | 1130 | ASSERT_RTNL(); |
1132 | 1131 | ||
1133 | ndev = alloc_netdev_mq(sizeof(*sdata) + local->hw.vif_data_size, | 1132 | ndev = alloc_netdev_mqs(sizeof(*sdata) + local->hw.vif_data_size, |
1134 | name, ieee80211_if_setup, local->hw.queues); | 1133 | name, ieee80211_if_setup, local->hw.queues, 1); |
1135 | if (!ndev) | 1134 | if (!ndev) |
1136 | return -ENOMEM; | 1135 | return -ENOMEM; |
1137 | dev_net_set(ndev, wiphy_net(local->hw.wiphy)); | 1136 | dev_net_set(ndev, wiphy_net(local->hw.wiphy)); |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 1208a7878bfd..739bee13e813 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -369,6 +369,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, | |||
369 | get_unaligned_le16(seq); | 369 | get_unaligned_le16(seq); |
370 | } | 370 | } |
371 | } | 371 | } |
372 | spin_lock_init(&key->u.tkip.txlock); | ||
372 | break; | 373 | break; |
373 | case WLAN_CIPHER_SUITE_CCMP: | 374 | case WLAN_CIPHER_SUITE_CCMP: |
374 | key->conf.iv_len = CCMP_HDR_LEN; | 375 | key->conf.iv_len = CCMP_HDR_LEN; |
@@ -625,3 +626,77 @@ void ieee80211_gtk_rekey_notify(struct ieee80211_vif *vif, const u8 *bssid, | |||
625 | cfg80211_gtk_rekey_notify(sdata->dev, bssid, replay_ctr, gfp); | 626 | cfg80211_gtk_rekey_notify(sdata->dev, bssid, replay_ctr, gfp); |
626 | } | 627 | } |
627 | EXPORT_SYMBOL_GPL(ieee80211_gtk_rekey_notify); | 628 | EXPORT_SYMBOL_GPL(ieee80211_gtk_rekey_notify); |
629 | |||
630 | void ieee80211_get_key_tx_seq(struct ieee80211_key_conf *keyconf, | ||
631 | struct ieee80211_key_seq *seq) | ||
632 | { | ||
633 | struct ieee80211_key *key; | ||
634 | u64 pn64; | ||
635 | |||
636 | if (WARN_ON(!(keyconf->flags & IEEE80211_KEY_FLAG_GENERATE_IV))) | ||
637 | return; | ||
638 | |||
639 | key = container_of(keyconf, struct ieee80211_key, conf); | ||
640 | |||
641 | switch (key->conf.cipher) { | ||
642 | case WLAN_CIPHER_SUITE_TKIP: | ||
643 | seq->tkip.iv32 = key->u.tkip.tx.iv32; | ||
644 | seq->tkip.iv16 = key->u.tkip.tx.iv16; | ||
645 | break; | ||
646 | case WLAN_CIPHER_SUITE_CCMP: | ||
647 | pn64 = atomic64_read(&key->u.ccmp.tx_pn); | ||
648 | seq->ccmp.pn[5] = pn64; | ||
649 | seq->ccmp.pn[4] = pn64 >> 8; | ||
650 | seq->ccmp.pn[3] = pn64 >> 16; | ||
651 | seq->ccmp.pn[2] = pn64 >> 24; | ||
652 | seq->ccmp.pn[1] = pn64 >> 32; | ||
653 | seq->ccmp.pn[0] = pn64 >> 40; | ||
654 | break; | ||
655 | case WLAN_CIPHER_SUITE_AES_CMAC: | ||
656 | pn64 = atomic64_read(&key->u.aes_cmac.tx_pn); | ||
657 | seq->ccmp.pn[5] = pn64; | ||
658 | seq->ccmp.pn[4] = pn64 >> 8; | ||
659 | seq->ccmp.pn[3] = pn64 >> 16; | ||
660 | seq->ccmp.pn[2] = pn64 >> 24; | ||
661 | seq->ccmp.pn[1] = pn64 >> 32; | ||
662 | seq->ccmp.pn[0] = pn64 >> 40; | ||
663 | break; | ||
664 | default: | ||
665 | WARN_ON(1); | ||
666 | } | ||
667 | } | ||
668 | EXPORT_SYMBOL(ieee80211_get_key_tx_seq); | ||
669 | |||
670 | void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf, | ||
671 | int tid, struct ieee80211_key_seq *seq) | ||
672 | { | ||
673 | struct ieee80211_key *key; | ||
674 | const u8 *pn; | ||
675 | |||
676 | key = container_of(keyconf, struct ieee80211_key, conf); | ||
677 | |||
678 | switch (key->conf.cipher) { | ||
679 | case WLAN_CIPHER_SUITE_TKIP: | ||
680 | if (WARN_ON(tid < 0 || tid >= NUM_RX_DATA_QUEUES)) | ||
681 | return; | ||
682 | seq->tkip.iv32 = key->u.tkip.rx[tid].iv32; | ||
683 | seq->tkip.iv16 = key->u.tkip.rx[tid].iv16; | ||
684 | break; | ||
685 | case WLAN_CIPHER_SUITE_CCMP: | ||
686 | if (WARN_ON(tid < -1 || tid >= NUM_RX_DATA_QUEUES)) | ||
687 | return; | ||
688 | if (tid < 0) | ||
689 | pn = key->u.ccmp.rx_pn[NUM_RX_DATA_QUEUES]; | ||
690 | else | ||
691 | pn = key->u.ccmp.rx_pn[tid]; | ||
692 | memcpy(seq->ccmp.pn, pn, CCMP_PN_LEN); | ||
693 | break; | ||
694 | case WLAN_CIPHER_SUITE_AES_CMAC: | ||
695 | if (WARN_ON(tid != 0)) | ||
696 | return; | ||
697 | pn = key->u.aes_cmac.rx_pn; | ||
698 | memcpy(seq->aes_cmac.pn, pn, CMAC_PN_LEN); | ||
699 | break; | ||
700 | } | ||
701 | } | ||
702 | EXPORT_SYMBOL(ieee80211_get_key_rx_seq); | ||
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index d801d5351336..7d4e31f037d7 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -28,8 +28,9 @@ | |||
28 | #define CCMP_PN_LEN 6 | 28 | #define CCMP_PN_LEN 6 |
29 | #define TKIP_IV_LEN 8 | 29 | #define TKIP_IV_LEN 8 |
30 | #define TKIP_ICV_LEN 4 | 30 | #define TKIP_ICV_LEN 4 |
31 | #define CMAC_PN_LEN 6 | ||
31 | 32 | ||
32 | #define NUM_RX_DATA_QUEUES 17 | 33 | #define NUM_RX_DATA_QUEUES 16 |
33 | 34 | ||
34 | struct ieee80211_local; | 35 | struct ieee80211_local; |
35 | struct ieee80211_sub_if_data; | 36 | struct ieee80211_sub_if_data; |
@@ -40,9 +41,11 @@ struct sta_info; | |||
40 | * | 41 | * |
41 | * @KEY_FLAG_UPLOADED_TO_HARDWARE: Indicates that this key is present | 42 | * @KEY_FLAG_UPLOADED_TO_HARDWARE: Indicates that this key is present |
42 | * in the hardware for TX crypto hardware acceleration. | 43 | * in the hardware for TX crypto hardware acceleration. |
44 | * @KEY_FLAG_TAINTED: Key is tainted and packets should be dropped. | ||
43 | */ | 45 | */ |
44 | enum ieee80211_internal_key_flags { | 46 | enum ieee80211_internal_key_flags { |
45 | KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0), | 47 | KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0), |
48 | KEY_FLAG_TAINTED = BIT(1), | ||
46 | }; | 49 | }; |
47 | 50 | ||
48 | enum ieee80211_internal_tkip_state { | 51 | enum ieee80211_internal_tkip_state { |
@@ -52,9 +55,10 @@ enum ieee80211_internal_tkip_state { | |||
52 | }; | 55 | }; |
53 | 56 | ||
54 | struct tkip_ctx { | 57 | struct tkip_ctx { |
55 | u32 iv32; | 58 | u32 iv32; /* current iv32 */ |
56 | u16 iv16; | 59 | u16 iv16; /* current iv16 */ |
57 | u16 p1k[5]; | 60 | u16 p1k[5]; /* p1k cache */ |
61 | u32 p1k_iv32; /* iv32 for which p1k computed */ | ||
58 | enum ieee80211_internal_tkip_state state; | 62 | enum ieee80211_internal_tkip_state state; |
59 | }; | 63 | }; |
60 | 64 | ||
@@ -71,6 +75,9 @@ struct ieee80211_key { | |||
71 | 75 | ||
72 | union { | 76 | union { |
73 | struct { | 77 | struct { |
78 | /* protects tx context */ | ||
79 | spinlock_t txlock; | ||
80 | |||
74 | /* last used TSC */ | 81 | /* last used TSC */ |
75 | struct tkip_ctx tx; | 82 | struct tkip_ctx tx; |
76 | 83 | ||
@@ -78,32 +85,23 @@ struct ieee80211_key { | |||
78 | struct tkip_ctx rx[NUM_RX_DATA_QUEUES]; | 85 | struct tkip_ctx rx[NUM_RX_DATA_QUEUES]; |
79 | } tkip; | 86 | } tkip; |
80 | struct { | 87 | struct { |
81 | u8 tx_pn[6]; | 88 | atomic64_t tx_pn; |
82 | /* | 89 | /* |
83 | * Last received packet number. The first | 90 | * Last received packet number. The first |
84 | * NUM_RX_DATA_QUEUES counters are used with Data | 91 | * NUM_RX_DATA_QUEUES counters are used with Data |
85 | * frames and the last counter is used with Robust | 92 | * frames and the last counter is used with Robust |
86 | * Management frames. | 93 | * Management frames. |
87 | */ | 94 | */ |
88 | u8 rx_pn[NUM_RX_DATA_QUEUES + 1][6]; | 95 | u8 rx_pn[NUM_RX_DATA_QUEUES + 1][CCMP_PN_LEN]; |
89 | struct crypto_cipher *tfm; | 96 | struct crypto_cipher *tfm; |
90 | u32 replays; /* dot11RSNAStatsCCMPReplays */ | 97 | u32 replays; /* dot11RSNAStatsCCMPReplays */ |
91 | /* scratch buffers for virt_to_page() (crypto API) */ | ||
92 | #ifndef AES_BLOCK_LEN | ||
93 | #define AES_BLOCK_LEN 16 | ||
94 | #endif | ||
95 | u8 tx_crypto_buf[6 * AES_BLOCK_LEN]; | ||
96 | u8 rx_crypto_buf[6 * AES_BLOCK_LEN]; | ||
97 | } ccmp; | 98 | } ccmp; |
98 | struct { | 99 | struct { |
99 | u8 tx_pn[6]; | 100 | atomic64_t tx_pn; |
100 | u8 rx_pn[6]; | 101 | u8 rx_pn[CMAC_PN_LEN]; |
101 | struct crypto_cipher *tfm; | 102 | struct crypto_cipher *tfm; |
102 | u32 replays; /* dot11RSNAStatsCMACReplays */ | 103 | u32 replays; /* dot11RSNAStatsCMACReplays */ |
103 | u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ | 104 | u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ |
104 | /* scratch buffers for virt_to_page() (crypto API) */ | ||
105 | u8 tx_crypto_buf[2 * AES_BLOCK_LEN]; | ||
106 | u8 rx_crypto_buf[2 * AES_BLOCK_LEN]; | ||
107 | } aes_cmac; | 105 | } aes_cmac; |
108 | } u; | 106 | } u; |
109 | 107 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 182cda66ebef..c99237cd4b98 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1763,6 +1763,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1763 | ifmgd->ave_beacon_signal = rx_status->signal * 16; | 1763 | ifmgd->ave_beacon_signal = rx_status->signal * 16; |
1764 | ifmgd->last_cqm_event_signal = 0; | 1764 | ifmgd->last_cqm_event_signal = 0; |
1765 | ifmgd->count_beacon_signal = 1; | 1765 | ifmgd->count_beacon_signal = 1; |
1766 | ifmgd->last_ave_beacon_signal = 0; | ||
1766 | } else { | 1767 | } else { |
1767 | ifmgd->ave_beacon_signal = | 1768 | ifmgd->ave_beacon_signal = |
1768 | (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 + | 1769 | (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 + |
@@ -1770,6 +1771,28 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1770 | ifmgd->ave_beacon_signal) / 16; | 1771 | ifmgd->ave_beacon_signal) / 16; |
1771 | ifmgd->count_beacon_signal++; | 1772 | ifmgd->count_beacon_signal++; |
1772 | } | 1773 | } |
1774 | |||
1775 | if (ifmgd->rssi_min_thold != ifmgd->rssi_max_thold && | ||
1776 | ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) { | ||
1777 | int sig = ifmgd->ave_beacon_signal; | ||
1778 | int last_sig = ifmgd->last_ave_beacon_signal; | ||
1779 | |||
1780 | /* | ||
1781 | * if signal crosses either of the boundaries, invoke callback | ||
1782 | * with appropriate parameters | ||
1783 | */ | ||
1784 | if (sig > ifmgd->rssi_max_thold && | ||
1785 | (last_sig <= ifmgd->rssi_min_thold || last_sig == 0)) { | ||
1786 | ifmgd->last_ave_beacon_signal = sig; | ||
1787 | drv_rssi_callback(local, RSSI_EVENT_HIGH); | ||
1788 | } else if (sig < ifmgd->rssi_min_thold && | ||
1789 | (last_sig >= ifmgd->rssi_max_thold || | ||
1790 | last_sig == 0)) { | ||
1791 | ifmgd->last_ave_beacon_signal = sig; | ||
1792 | drv_rssi_callback(local, RSSI_EVENT_LOW); | ||
1793 | } | ||
1794 | } | ||
1795 | |||
1773 | if (bss_conf->cqm_rssi_thold && | 1796 | if (bss_conf->cqm_rssi_thold && |
1774 | ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT && | 1797 | ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT && |
1775 | !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { | 1798 | !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { |
@@ -2029,7 +2052,7 @@ static void ieee80211_sta_timer(unsigned long data) | |||
2029 | } | 2052 | } |
2030 | 2053 | ||
2031 | static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | 2054 | static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, |
2032 | u8 *bssid) | 2055 | u8 *bssid, u8 reason) |
2033 | { | 2056 | { |
2034 | struct ieee80211_local *local = sdata->local; | 2057 | struct ieee80211_local *local = sdata->local; |
2035 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2058 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
@@ -2047,8 +2070,7 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | |||
2047 | * but that's not a problem. | 2070 | * but that's not a problem. |
2048 | */ | 2071 | */ |
2049 | ieee80211_send_deauth_disassoc(sdata, bssid, | 2072 | ieee80211_send_deauth_disassoc(sdata, bssid, |
2050 | IEEE80211_STYPE_DEAUTH, | 2073 | IEEE80211_STYPE_DEAUTH, reason, |
2051 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, | ||
2052 | NULL, true); | 2074 | NULL, true); |
2053 | mutex_lock(&ifmgd->mtx); | 2075 | mutex_lock(&ifmgd->mtx); |
2054 | } | 2076 | } |
@@ -2094,7 +2116,8 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
2094 | " AP %pM, disconnecting.\n", | 2116 | " AP %pM, disconnecting.\n", |
2095 | sdata->name, bssid); | 2117 | sdata->name, bssid); |
2096 | #endif | 2118 | #endif |
2097 | ieee80211_sta_connection_lost(sdata, bssid); | 2119 | ieee80211_sta_connection_lost(sdata, bssid, |
2120 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); | ||
2098 | } | 2121 | } |
2099 | } else if (time_is_after_jiffies(ifmgd->probe_timeout)) | 2122 | } else if (time_is_after_jiffies(ifmgd->probe_timeout)) |
2100 | run_again(ifmgd, ifmgd->probe_timeout); | 2123 | run_again(ifmgd, ifmgd->probe_timeout); |
@@ -2106,7 +2129,8 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
2106 | sdata->name, | 2129 | sdata->name, |
2107 | bssid, probe_wait_ms); | 2130 | bssid, probe_wait_ms); |
2108 | #endif | 2131 | #endif |
2109 | ieee80211_sta_connection_lost(sdata, bssid); | 2132 | ieee80211_sta_connection_lost(sdata, bssid, |
2133 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); | ||
2110 | } else if (ifmgd->probe_send_count < max_tries) { | 2134 | } else if (ifmgd->probe_send_count < max_tries) { |
2111 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 2135 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
2112 | wiphy_debug(local->hw.wiphy, | 2136 | wiphy_debug(local->hw.wiphy, |
@@ -2128,7 +2152,8 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
2128 | sdata->name, | 2152 | sdata->name, |
2129 | bssid, probe_wait_ms); | 2153 | bssid, probe_wait_ms); |
2130 | 2154 | ||
2131 | ieee80211_sta_connection_lost(sdata, bssid); | 2155 | ieee80211_sta_connection_lost(sdata, bssid, |
2156 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); | ||
2132 | } | 2157 | } |
2133 | } | 2158 | } |
2134 | 2159 | ||
@@ -2215,6 +2240,27 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) | |||
2215 | { | 2240 | { |
2216 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2241 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2217 | 2242 | ||
2243 | if (!ifmgd->associated) | ||
2244 | return; | ||
2245 | |||
2246 | if (sdata->flags & IEEE80211_SDATA_DISCONNECT_RESUME) { | ||
2247 | sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME; | ||
2248 | mutex_lock(&ifmgd->mtx); | ||
2249 | if (ifmgd->associated) { | ||
2250 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
2251 | wiphy_debug(sdata->local->hw.wiphy, | ||
2252 | "%s: driver requested disconnect after resume.\n", | ||
2253 | sdata->name); | ||
2254 | #endif | ||
2255 | ieee80211_sta_connection_lost(sdata, | ||
2256 | ifmgd->associated->bssid, | ||
2257 | WLAN_REASON_UNSPECIFIED); | ||
2258 | mutex_unlock(&ifmgd->mtx); | ||
2259 | return; | ||
2260 | } | ||
2261 | mutex_unlock(&ifmgd->mtx); | ||
2262 | } | ||
2263 | |||
2218 | if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running)) | 2264 | if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running)) |
2219 | add_timer(&ifmgd->timer); | 2265 | add_timer(&ifmgd->timer); |
2220 | if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) | 2266 | if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index b5493ecd1e93..fe2c2a717793 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -331,7 +331,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) | |||
331 | { | 331 | { |
332 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 332 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
333 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | 333 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); |
334 | int tid; | 334 | int tid, seqno_idx, security_idx; |
335 | 335 | ||
336 | /* does the frame have a qos control field? */ | 336 | /* does the frame have a qos control field? */ |
337 | if (ieee80211_is_data_qos(hdr->frame_control)) { | 337 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
@@ -340,6 +340,9 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) | |||
340 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; | 340 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; |
341 | if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT) | 341 | if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT) |
342 | status->rx_flags |= IEEE80211_RX_AMSDU; | 342 | status->rx_flags |= IEEE80211_RX_AMSDU; |
343 | |||
344 | seqno_idx = tid; | ||
345 | security_idx = tid; | ||
343 | } else { | 346 | } else { |
344 | /* | 347 | /* |
345 | * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): | 348 | * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): |
@@ -352,10 +355,15 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) | |||
352 | * | 355 | * |
353 | * We also use that counter for non-QoS STAs. | 356 | * We also use that counter for non-QoS STAs. |
354 | */ | 357 | */ |
355 | tid = NUM_RX_DATA_QUEUES - 1; | 358 | seqno_idx = NUM_RX_DATA_QUEUES; |
359 | security_idx = 0; | ||
360 | if (ieee80211_is_mgmt(hdr->frame_control)) | ||
361 | security_idx = NUM_RX_DATA_QUEUES; | ||
362 | tid = 0; | ||
356 | } | 363 | } |
357 | 364 | ||
358 | rx->queue = tid; | 365 | rx->seqno_idx = seqno_idx; |
366 | rx->security_idx = security_idx; | ||
359 | /* Set skb->priority to 1d tag if highest order bit of TID is not set. | 367 | /* Set skb->priority to 1d tag if highest order bit of TID is not set. |
360 | * For now, set skb->priority to 0 for other cases. */ | 368 | * For now, set skb->priority to 0 for other cases. */ |
361 | rx->skb->priority = (tid > 7) ? 0 : tid; | 369 | rx->skb->priority = (tid > 7) ? 0 : tid; |
@@ -810,7 +818,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
810 | /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ | 818 | /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ |
811 | if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { | 819 | if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { |
812 | if (unlikely(ieee80211_has_retry(hdr->frame_control) && | 820 | if (unlikely(ieee80211_has_retry(hdr->frame_control) && |
813 | rx->sta->last_seq_ctrl[rx->queue] == | 821 | rx->sta->last_seq_ctrl[rx->seqno_idx] == |
814 | hdr->seq_ctrl)) { | 822 | hdr->seq_ctrl)) { |
815 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { | 823 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { |
816 | rx->local->dot11FrameDuplicateCount++; | 824 | rx->local->dot11FrameDuplicateCount++; |
@@ -818,7 +826,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
818 | } | 826 | } |
819 | return RX_DROP_UNUSABLE; | 827 | return RX_DROP_UNUSABLE; |
820 | } else | 828 | } else |
821 | rx->sta->last_seq_ctrl[rx->queue] = hdr->seq_ctrl; | 829 | rx->sta->last_seq_ctrl[rx->seqno_idx] = hdr->seq_ctrl; |
822 | } | 830 | } |
823 | 831 | ||
824 | if (unlikely(rx->skb->len < 16)) { | 832 | if (unlikely(rx->skb->len < 16)) { |
@@ -1011,6 +1019,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
1011 | } | 1019 | } |
1012 | 1020 | ||
1013 | if (rx->key) { | 1021 | if (rx->key) { |
1022 | if (unlikely(rx->key->flags & KEY_FLAG_TAINTED)) | ||
1023 | return RX_DROP_MONITOR; | ||
1024 | |||
1014 | rx->key->tx_rx_count++; | 1025 | rx->key->tx_rx_count++; |
1015 | /* TODO: add threshold stuff again */ | 1026 | /* TODO: add threshold stuff again */ |
1016 | } else { | 1027 | } else { |
@@ -1374,11 +1385,10 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1374 | if (frag == 0) { | 1385 | if (frag == 0) { |
1375 | /* This is the first fragment of a new frame. */ | 1386 | /* This is the first fragment of a new frame. */ |
1376 | entry = ieee80211_reassemble_add(rx->sdata, frag, seq, | 1387 | entry = ieee80211_reassemble_add(rx->sdata, frag, seq, |
1377 | rx->queue, &(rx->skb)); | 1388 | rx->seqno_idx, &(rx->skb)); |
1378 | if (rx->key && rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP && | 1389 | if (rx->key && rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP && |
1379 | ieee80211_has_protected(fc)) { | 1390 | ieee80211_has_protected(fc)) { |
1380 | int queue = ieee80211_is_mgmt(fc) ? | 1391 | int queue = rx->security_idx; |
1381 | NUM_RX_DATA_QUEUES : rx->queue; | ||
1382 | /* Store CCMP PN so that we can verify that the next | 1392 | /* Store CCMP PN so that we can verify that the next |
1383 | * fragment has a sequential PN value. */ | 1393 | * fragment has a sequential PN value. */ |
1384 | entry->ccmp = 1; | 1394 | entry->ccmp = 1; |
@@ -1392,7 +1402,8 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1392 | /* This is a fragment for a frame that should already be pending in | 1402 | /* This is a fragment for a frame that should already be pending in |
1393 | * fragment cache. Add this fragment to the end of the pending entry. | 1403 | * fragment cache. Add this fragment to the end of the pending entry. |
1394 | */ | 1404 | */ |
1395 | entry = ieee80211_reassemble_find(rx->sdata, frag, seq, rx->queue, hdr); | 1405 | entry = ieee80211_reassemble_find(rx->sdata, frag, seq, |
1406 | rx->seqno_idx, hdr); | ||
1396 | if (!entry) { | 1407 | if (!entry) { |
1397 | I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); | 1408 | I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); |
1398 | return RX_DROP_MONITOR; | 1409 | return RX_DROP_MONITOR; |
@@ -1412,8 +1423,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1412 | if (pn[i]) | 1423 | if (pn[i]) |
1413 | break; | 1424 | break; |
1414 | } | 1425 | } |
1415 | queue = ieee80211_is_mgmt(fc) ? | 1426 | queue = rx->security_idx; |
1416 | NUM_RX_DATA_QUEUES : rx->queue; | ||
1417 | rpn = rx->key->u.ccmp.rx_pn[queue]; | 1427 | rpn = rx->key->u.ccmp.rx_pn[queue]; |
1418 | if (memcmp(pn, rpn, CCMP_PN_LEN)) | 1428 | if (memcmp(pn, rpn, CCMP_PN_LEN)) |
1419 | return RX_DROP_UNUSABLE; | 1429 | return RX_DROP_UNUSABLE; |
@@ -2590,7 +2600,9 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) | |||
2590 | .sta = sta, | 2600 | .sta = sta, |
2591 | .sdata = sta->sdata, | 2601 | .sdata = sta->sdata, |
2592 | .local = sta->local, | 2602 | .local = sta->local, |
2593 | .queue = tid, | 2603 | /* This is OK -- must be QoS data frame */ |
2604 | .security_idx = tid, | ||
2605 | .seqno_idx = tid, | ||
2594 | .flags = 0, | 2606 | .flags = 0, |
2595 | }; | 2607 | }; |
2596 | struct tid_ampdu_rx *tid_agg_rx; | 2608 | struct tid_ampdu_rx *tid_agg_rx; |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index a06d64ebc177..28beb78e601e 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -287,7 +287,8 @@ struct sta_info { | |||
287 | unsigned long rx_dropped; | 287 | unsigned long rx_dropped; |
288 | int last_signal; | 288 | int last_signal; |
289 | struct ewma avg_signal; | 289 | struct ewma avg_signal; |
290 | __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; | 290 | /* Plus 1 for non-QoS frames */ |
291 | __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES + 1]; | ||
291 | 292 | ||
292 | /* Updated from TX status path only, no locking requirements */ | 293 | /* Updated from TX status path only, no locking requirements */ |
293 | unsigned long tx_filtered_count; | 294 | unsigned long tx_filtered_count; |
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 757e4eb2baf7..cc79e697cdb2 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -101,6 +101,7 @@ static void tkip_mixing_phase1(const u8 *tk, struct tkip_ctx *ctx, | |||
101 | p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; | 101 | p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; |
102 | } | 102 | } |
103 | ctx->state = TKIP_STATE_PHASE1_DONE; | 103 | ctx->state = TKIP_STATE_PHASE1_DONE; |
104 | ctx->p1k_iv32 = tsc_IV32; | ||
104 | } | 105 | } |
105 | 106 | ||
106 | static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, | 107 | static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, |
@@ -140,60 +141,69 @@ static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, | |||
140 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets | 141 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets |
141 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of | 142 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of |
142 | * the packet payload). */ | 143 | * the packet payload). */ |
143 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16) | 144 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key) |
144 | { | 145 | { |
145 | pos = write_tkip_iv(pos, iv16); | 146 | lockdep_assert_held(&key->u.tkip.txlock); |
147 | |||
148 | pos = write_tkip_iv(pos, key->u.tkip.tx.iv16); | ||
146 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; | 149 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; |
147 | put_unaligned_le32(key->u.tkip.tx.iv32, pos); | 150 | put_unaligned_le32(key->u.tkip.tx.iv32, pos); |
148 | return pos + 4; | 151 | return pos + 4; |
149 | } | 152 | } |
150 | 153 | ||
151 | void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | 154 | static void ieee80211_compute_tkip_p1k(struct ieee80211_key *key, u32 iv32) |
152 | struct sk_buff *skb, enum ieee80211_tkip_key_type type, | ||
153 | u8 *outkey) | ||
154 | { | 155 | { |
155 | struct ieee80211_key *key = (struct ieee80211_key *) | 156 | struct ieee80211_sub_if_data *sdata = key->sdata; |
156 | container_of(keyconf, struct ieee80211_key, conf); | 157 | struct tkip_ctx *ctx = &key->u.tkip.tx; |
157 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 158 | const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; |
158 | u8 *data; | ||
159 | const u8 *tk; | ||
160 | struct tkip_ctx *ctx; | ||
161 | u16 iv16; | ||
162 | u32 iv32; | ||
163 | |||
164 | data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); | ||
165 | iv16 = data[2] | (data[0] << 8); | ||
166 | iv32 = get_unaligned_le32(&data[4]); | ||
167 | |||
168 | tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | ||
169 | ctx = &key->u.tkip.tx; | ||
170 | 159 | ||
171 | #ifdef CONFIG_MAC80211_TKIP_DEBUG | 160 | lockdep_assert_held(&key->u.tkip.txlock); |
172 | printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", | 161 | |
173 | iv16, iv32); | 162 | /* |
174 | 163 | * Update the P1K when the IV32 is different from the value it | |
175 | if (iv32 != ctx->iv32) { | 164 | * had when we last computed it (or when not initialised yet). |
176 | printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n", | 165 | * This might flip-flop back and forth if packets are processed |
177 | iv32, ctx->iv32); | 166 | * out-of-order due to the different ACs, but then we have to |
178 | printk(KERN_DEBUG "Wrap around of iv16 in the middle of a " | 167 | * just compute the P1K more often. |
179 | "fragmented packet\n"); | 168 | */ |
180 | } | 169 | if (ctx->p1k_iv32 != iv32 || ctx->state == TKIP_STATE_NOT_INIT) |
181 | #endif | 170 | tkip_mixing_phase1(tk, ctx, sdata->vif.addr, iv32); |
171 | } | ||
182 | 172 | ||
183 | /* Update the p1k only when the iv16 in the packet wraps around, this | 173 | void ieee80211_get_tkip_p1k_iv(struct ieee80211_key_conf *keyconf, |
184 | * might occur after the wrap around of iv16 in the key in case of | 174 | u32 iv32, u16 *p1k) |
185 | * fragmented packets. */ | 175 | { |
186 | if (iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT) | 176 | struct ieee80211_key *key = (struct ieee80211_key *) |
187 | tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32); | 177 | container_of(keyconf, struct ieee80211_key, conf); |
178 | struct tkip_ctx *ctx = &key->u.tkip.tx; | ||
179 | unsigned long flags; | ||
188 | 180 | ||
189 | if (type == IEEE80211_TKIP_P1_KEY) { | 181 | spin_lock_irqsave(&key->u.tkip.txlock, flags); |
190 | memcpy(outkey, ctx->p1k, sizeof(u16) * 5); | 182 | ieee80211_compute_tkip_p1k(key, iv32); |
191 | return; | 183 | memcpy(p1k, ctx->p1k, sizeof(ctx->p1k)); |
192 | } | 184 | spin_unlock_irqrestore(&key->u.tkip.txlock, flags); |
185 | } | ||
186 | EXPORT_SYMBOL(ieee80211_get_tkip_p1k_iv); | ||
193 | 187 | ||
194 | tkip_mixing_phase2(tk, ctx, iv16, outkey); | 188 | void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf, |
189 | struct sk_buff *skb, u8 *p2k) | ||
190 | { | ||
191 | struct ieee80211_key *key = (struct ieee80211_key *) | ||
192 | container_of(keyconf, struct ieee80211_key, conf); | ||
193 | const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | ||
194 | struct tkip_ctx *ctx = &key->u.tkip.tx; | ||
195 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
196 | const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); | ||
197 | u32 iv32 = get_unaligned_le32(&data[4]); | ||
198 | u16 iv16 = data[2] | (data[0] << 8); | ||
199 | unsigned long flags; | ||
200 | |||
201 | spin_lock_irqsave(&key->u.tkip.txlock, flags); | ||
202 | ieee80211_compute_tkip_p1k(key, iv32); | ||
203 | tkip_mixing_phase2(tk, ctx, iv16, p2k); | ||
204 | spin_unlock_irqrestore(&key->u.tkip.txlock, flags); | ||
195 | } | 205 | } |
196 | EXPORT_SYMBOL(ieee80211_get_tkip_key); | 206 | EXPORT_SYMBOL(ieee80211_get_tkip_p2k); |
197 | 207 | ||
198 | /* | 208 | /* |
199 | * Encrypt packet payload with TKIP using @key. @pos is a pointer to the | 209 | * Encrypt packet payload with TKIP using @key. @pos is a pointer to the |
@@ -204,19 +214,15 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key); | |||
204 | */ | 214 | */ |
205 | int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, | 215 | int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, |
206 | struct ieee80211_key *key, | 216 | struct ieee80211_key *key, |
207 | u8 *pos, size_t payload_len, u8 *ta) | 217 | struct sk_buff *skb, |
218 | u8 *payload, size_t payload_len) | ||
208 | { | 219 | { |
209 | u8 rc4key[16]; | 220 | u8 rc4key[16]; |
210 | struct tkip_ctx *ctx = &key->u.tkip.tx; | ||
211 | const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | ||
212 | |||
213 | /* Calculate per-packet key */ | ||
214 | if (ctx->iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT) | ||
215 | tkip_mixing_phase1(tk, ctx, ta, ctx->iv32); | ||
216 | 221 | ||
217 | tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key); | 222 | ieee80211_get_tkip_p2k(&key->conf, skb, rc4key); |
218 | 223 | ||
219 | return ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); | 224 | return ieee80211_wep_encrypt_data(tfm, rc4key, 16, |
225 | payload, payload_len); | ||
220 | } | 226 | } |
221 | 227 | ||
222 | /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the | 228 | /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the |
diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h index 1cab9c86978f..e3ecb659b90a 100644 --- a/net/mac80211/tkip.h +++ b/net/mac80211/tkip.h | |||
@@ -13,11 +13,13 @@ | |||
13 | #include <linux/crypto.h> | 13 | #include <linux/crypto.h> |
14 | #include "key.h" | 14 | #include "key.h" |
15 | 15 | ||
16 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16); | 16 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key); |
17 | 17 | ||
18 | int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, | 18 | int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, |
19 | struct ieee80211_key *key, | 19 | struct ieee80211_key *key, |
20 | u8 *pos, size_t payload_len, u8 *ta); | 20 | struct sk_buff *skb, |
21 | u8 *payload, size_t payload_len); | ||
22 | |||
21 | enum { | 23 | enum { |
22 | TKIP_DECRYPT_OK = 0, | 24 | TKIP_DECRYPT_OK = 0, |
23 | TKIP_DECRYPT_NO_EXT_IV = -1, | 25 | TKIP_DECRYPT_NO_EXT_IV = -1, |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index e8d0d2d22665..8cb0d2d0ac69 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -589,6 +589,9 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
589 | break; | 589 | break; |
590 | } | 590 | } |
591 | 591 | ||
592 | if (unlikely(tx->key && tx->key->flags & KEY_FLAG_TAINTED)) | ||
593 | return TX_DROP; | ||
594 | |||
592 | if (!skip_hw && tx->key && | 595 | if (!skip_hw && tx->key && |
593 | tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 596 | tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) |
594 | info->control.hw_key = &tx->key->conf; | 597 | info->control.hw_key = &tx->key->conf; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 652e5695225a..5bfb80cba634 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1334,6 +1334,33 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1334 | return 0; | 1334 | return 0; |
1335 | } | 1335 | } |
1336 | 1336 | ||
1337 | void ieee80211_resume_disconnect(struct ieee80211_vif *vif) | ||
1338 | { | ||
1339 | struct ieee80211_sub_if_data *sdata; | ||
1340 | struct ieee80211_local *local; | ||
1341 | struct ieee80211_key *key; | ||
1342 | |||
1343 | if (WARN_ON(!vif)) | ||
1344 | return; | ||
1345 | |||
1346 | sdata = vif_to_sdata(vif); | ||
1347 | local = sdata->local; | ||
1348 | |||
1349 | if (WARN_ON(!local->resuming)) | ||
1350 | return; | ||
1351 | |||
1352 | if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) | ||
1353 | return; | ||
1354 | |||
1355 | sdata->flags |= IEEE80211_SDATA_DISCONNECT_RESUME; | ||
1356 | |||
1357 | mutex_lock(&local->key_mtx); | ||
1358 | list_for_each_entry(key, &sdata->key_list, list) | ||
1359 | key->flags |= KEY_FLAG_TAINTED; | ||
1360 | mutex_unlock(&local->key_mtx); | ||
1361 | } | ||
1362 | EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect); | ||
1363 | |||
1337 | static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, | 1364 | static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, |
1338 | enum ieee80211_smps_mode *smps_mode) | 1365 | enum ieee80211_smps_mode *smps_mode) |
1339 | { | 1366 | { |
@@ -1450,3 +1477,43 @@ size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset) | |||
1450 | 1477 | ||
1451 | return pos; | 1478 | return pos; |
1452 | } | 1479 | } |
1480 | |||
1481 | static void _ieee80211_enable_rssi_reports(struct ieee80211_sub_if_data *sdata, | ||
1482 | int rssi_min_thold, | ||
1483 | int rssi_max_thold) | ||
1484 | { | ||
1485 | trace_api_enable_rssi_reports(sdata, rssi_min_thold, rssi_max_thold); | ||
1486 | |||
1487 | if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) | ||
1488 | return; | ||
1489 | |||
1490 | /* | ||
1491 | * Scale up threshold values before storing it, as the RSSI averaging | ||
1492 | * algorithm uses a scaled up value as well. Change this scaling | ||
1493 | * factor if the RSSI averaging algorithm changes. | ||
1494 | */ | ||
1495 | sdata->u.mgd.rssi_min_thold = rssi_min_thold*16; | ||
1496 | sdata->u.mgd.rssi_max_thold = rssi_max_thold*16; | ||
1497 | } | ||
1498 | |||
1499 | void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif, | ||
1500 | int rssi_min_thold, | ||
1501 | int rssi_max_thold) | ||
1502 | { | ||
1503 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
1504 | |||
1505 | WARN_ON(rssi_min_thold == rssi_max_thold || | ||
1506 | rssi_min_thold > rssi_max_thold); | ||
1507 | |||
1508 | _ieee80211_enable_rssi_reports(sdata, rssi_min_thold, | ||
1509 | rssi_max_thold); | ||
1510 | } | ||
1511 | EXPORT_SYMBOL(ieee80211_enable_rssi_reports); | ||
1512 | |||
1513 | void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif) | ||
1514 | { | ||
1515 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
1516 | |||
1517 | _ieee80211_enable_rssi_reports(sdata, 0, 0); | ||
1518 | } | ||
1519 | EXPORT_SYMBOL(ieee80211_disable_rssi_reports); | ||
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 8f6a302d2ac3..7bc8702808fa 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/gfp.h> | 15 | #include <linux/gfp.h> |
16 | #include <asm/unaligned.h> | 16 | #include <asm/unaligned.h> |
17 | #include <net/mac80211.h> | 17 | #include <net/mac80211.h> |
18 | #include <crypto/aes.h> | ||
18 | 19 | ||
19 | #include "ieee80211_i.h" | 20 | #include "ieee80211_i.h" |
20 | #include "michael.h" | 21 | #include "michael.h" |
@@ -86,11 +87,6 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
86 | struct sk_buff *skb = rx->skb; | 87 | struct sk_buff *skb = rx->skb; |
87 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 88 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
88 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 89 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
89 | int queue = rx->queue; | ||
90 | |||
91 | /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */ | ||
92 | if (rx->queue == NUM_RX_DATA_QUEUES - 1) | ||
93 | queue = 0; | ||
94 | 90 | ||
95 | /* | 91 | /* |
96 | * it makes no sense to check for MIC errors on anything other | 92 | * it makes no sense to check for MIC errors on anything other |
@@ -153,8 +149,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
153 | 149 | ||
154 | update_iv: | 150 | update_iv: |
155 | /* update IV in key information to be able to detect replays */ | 151 | /* update IV in key information to be able to detect replays */ |
156 | rx->key->u.tkip.rx[queue].iv32 = rx->tkip_iv32; | 152 | rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip_iv32; |
157 | rx->key->u.tkip.rx[queue].iv16 = rx->tkip_iv16; | 153 | rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip_iv16; |
158 | 154 | ||
159 | return RX_CONTINUE; | 155 | return RX_CONTINUE; |
160 | 156 | ||
@@ -176,6 +172,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
176 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 172 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
177 | struct ieee80211_key *key = tx->key; | 173 | struct ieee80211_key *key = tx->key; |
178 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 174 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
175 | unsigned long flags; | ||
179 | unsigned int hdrlen; | 176 | unsigned int hdrlen; |
180 | int len, tail; | 177 | int len, tail; |
181 | u8 *pos; | 178 | u8 *pos; |
@@ -203,11 +200,12 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
203 | pos += hdrlen; | 200 | pos += hdrlen; |
204 | 201 | ||
205 | /* Increase IV for the frame */ | 202 | /* Increase IV for the frame */ |
203 | spin_lock_irqsave(&key->u.tkip.txlock, flags); | ||
206 | key->u.tkip.tx.iv16++; | 204 | key->u.tkip.tx.iv16++; |
207 | if (key->u.tkip.tx.iv16 == 0) | 205 | if (key->u.tkip.tx.iv16 == 0) |
208 | key->u.tkip.tx.iv32++; | 206 | key->u.tkip.tx.iv32++; |
209 | 207 | pos = ieee80211_tkip_add_iv(pos, key); | |
210 | pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); | 208 | spin_unlock_irqrestore(&key->u.tkip.txlock, flags); |
211 | 209 | ||
212 | /* hwaccel - with software IV */ | 210 | /* hwaccel - with software IV */ |
213 | if (info->control.hw_key) | 211 | if (info->control.hw_key) |
@@ -216,9 +214,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
216 | /* Add room for ICV */ | 214 | /* Add room for ICV */ |
217 | skb_put(skb, TKIP_ICV_LEN); | 215 | skb_put(skb, TKIP_ICV_LEN); |
218 | 216 | ||
219 | hdr = (struct ieee80211_hdr *) skb->data; | ||
220 | return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm, | 217 | return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm, |
221 | key, pos, len, hdr->addr2); | 218 | key, skb, pos, len); |
222 | } | 219 | } |
223 | 220 | ||
224 | 221 | ||
@@ -246,11 +243,6 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
246 | struct ieee80211_key *key = rx->key; | 243 | struct ieee80211_key *key = rx->key; |
247 | struct sk_buff *skb = rx->skb; | 244 | struct sk_buff *skb = rx->skb; |
248 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 245 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
249 | int queue = rx->queue; | ||
250 | |||
251 | /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */ | ||
252 | if (rx->queue == NUM_RX_DATA_QUEUES - 1) | ||
253 | queue = 0; | ||
254 | 246 | ||
255 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 247 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
256 | 248 | ||
@@ -271,7 +263,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
271 | res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, | 263 | res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, |
272 | key, skb->data + hdrlen, | 264 | key, skb->data + hdrlen, |
273 | skb->len - hdrlen, rx->sta->sta.addr, | 265 | skb->len - hdrlen, rx->sta->sta.addr, |
274 | hdr->addr1, hwaccel, queue, | 266 | hdr->addr1, hwaccel, rx->security_idx, |
275 | &rx->tkip_iv32, | 267 | &rx->tkip_iv32, |
276 | &rx->tkip_iv16); | 268 | &rx->tkip_iv16); |
277 | if (res != TKIP_DECRYPT_OK) | 269 | if (res != TKIP_DECRYPT_OK) |
@@ -299,8 +291,10 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch, | |||
299 | unsigned int hdrlen; | 291 | unsigned int hdrlen; |
300 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 292 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
301 | 293 | ||
302 | b_0 = scratch + 3 * AES_BLOCK_LEN; | 294 | memset(scratch, 0, 6 * AES_BLOCK_SIZE); |
303 | aad = scratch + 4 * AES_BLOCK_LEN; | 295 | |
296 | b_0 = scratch + 3 * AES_BLOCK_SIZE; | ||
297 | aad = scratch + 4 * AES_BLOCK_SIZE; | ||
304 | 298 | ||
305 | /* | 299 | /* |
306 | * Mask FC: zero subtype b4 b5 b6 (if not mgmt) | 300 | * Mask FC: zero subtype b4 b5 b6 (if not mgmt) |
@@ -389,8 +383,10 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
389 | struct ieee80211_key *key = tx->key; | 383 | struct ieee80211_key *key = tx->key; |
390 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 384 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
391 | int hdrlen, len, tail; | 385 | int hdrlen, len, tail; |
392 | u8 *pos, *pn; | 386 | u8 *pos; |
393 | int i; | 387 | u8 pn[6]; |
388 | u64 pn64; | ||
389 | u8 scratch[6 * AES_BLOCK_SIZE]; | ||
394 | 390 | ||
395 | if (info->control.hw_key && | 391 | if (info->control.hw_key && |
396 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | 392 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
@@ -418,14 +414,14 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
418 | hdr = (struct ieee80211_hdr *) pos; | 414 | hdr = (struct ieee80211_hdr *) pos; |
419 | pos += hdrlen; | 415 | pos += hdrlen; |
420 | 416 | ||
421 | /* PN = PN + 1 */ | 417 | pn64 = atomic64_inc_return(&key->u.ccmp.tx_pn); |
422 | pn = key->u.ccmp.tx_pn; | ||
423 | 418 | ||
424 | for (i = CCMP_PN_LEN - 1; i >= 0; i--) { | 419 | pn[5] = pn64; |
425 | pn[i]++; | 420 | pn[4] = pn64 >> 8; |
426 | if (pn[i]) | 421 | pn[3] = pn64 >> 16; |
427 | break; | 422 | pn[2] = pn64 >> 24; |
428 | } | 423 | pn[1] = pn64 >> 32; |
424 | pn[0] = pn64 >> 40; | ||
429 | 425 | ||
430 | ccmp_pn2hdr(pos, pn, key->conf.keyidx); | 426 | ccmp_pn2hdr(pos, pn, key->conf.keyidx); |
431 | 427 | ||
@@ -434,8 +430,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
434 | return 0; | 430 | return 0; |
435 | 431 | ||
436 | pos += CCMP_HDR_LEN; | 432 | pos += CCMP_HDR_LEN; |
437 | ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0); | 433 | ccmp_special_blocks(skb, pn, scratch, 0); |
438 | ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, key->u.ccmp.tx_crypto_buf, pos, len, | 434 | ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len, |
439 | pos, skb_put(skb, CCMP_MIC_LEN)); | 435 | pos, skb_put(skb, CCMP_MIC_LEN)); |
440 | 436 | ||
441 | return 0; | 437 | return 0; |
@@ -482,8 +478,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
482 | 478 | ||
483 | ccmp_hdr2pn(pn, skb->data + hdrlen); | 479 | ccmp_hdr2pn(pn, skb->data + hdrlen); |
484 | 480 | ||
485 | queue = ieee80211_is_mgmt(hdr->frame_control) ? | 481 | queue = rx->security_idx; |
486 | NUM_RX_DATA_QUEUES : rx->queue; | ||
487 | 482 | ||
488 | if (memcmp(pn, key->u.ccmp.rx_pn[queue], CCMP_PN_LEN) <= 0) { | 483 | if (memcmp(pn, key->u.ccmp.rx_pn[queue], CCMP_PN_LEN) <= 0) { |
489 | key->u.ccmp.replays++; | 484 | key->u.ccmp.replays++; |
@@ -491,11 +486,12 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
491 | } | 486 | } |
492 | 487 | ||
493 | if (!(status->flag & RX_FLAG_DECRYPTED)) { | 488 | if (!(status->flag & RX_FLAG_DECRYPTED)) { |
489 | u8 scratch[6 * AES_BLOCK_SIZE]; | ||
494 | /* hardware didn't decrypt/verify MIC */ | 490 | /* hardware didn't decrypt/verify MIC */ |
495 | ccmp_special_blocks(skb, pn, key->u.ccmp.rx_crypto_buf, 1); | 491 | ccmp_special_blocks(skb, pn, scratch, 1); |
496 | 492 | ||
497 | if (ieee80211_aes_ccm_decrypt( | 493 | if (ieee80211_aes_ccm_decrypt( |
498 | key->u.ccmp.tfm, key->u.ccmp.rx_crypto_buf, | 494 | key->u.ccmp.tfm, scratch, |
499 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, | 495 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, |
500 | skb->data + skb->len - CCMP_MIC_LEN, | 496 | skb->data + skb->len - CCMP_MIC_LEN, |
501 | skb->data + hdrlen + CCMP_HDR_LEN)) | 497 | skb->data + hdrlen + CCMP_HDR_LEN)) |
@@ -526,6 +522,16 @@ static void bip_aad(struct sk_buff *skb, u8 *aad) | |||
526 | } | 522 | } |
527 | 523 | ||
528 | 524 | ||
525 | static inline void bip_ipn_set64(u8 *d, u64 pn) | ||
526 | { | ||
527 | *d++ = pn; | ||
528 | *d++ = pn >> 8; | ||
529 | *d++ = pn >> 16; | ||
530 | *d++ = pn >> 24; | ||
531 | *d++ = pn >> 32; | ||
532 | *d = pn >> 40; | ||
533 | } | ||
534 | |||
529 | static inline void bip_ipn_swap(u8 *d, const u8 *s) | 535 | static inline void bip_ipn_swap(u8 *d, const u8 *s) |
530 | { | 536 | { |
531 | *d++ = s[5]; | 537 | *d++ = s[5]; |
@@ -544,8 +550,8 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx) | |||
544 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 550 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
545 | struct ieee80211_key *key = tx->key; | 551 | struct ieee80211_key *key = tx->key; |
546 | struct ieee80211_mmie *mmie; | 552 | struct ieee80211_mmie *mmie; |
547 | u8 *pn, aad[20]; | 553 | u8 aad[20]; |
548 | int i; | 554 | u64 pn64; |
549 | 555 | ||
550 | if (info->control.hw_key) | 556 | if (info->control.hw_key) |
551 | return 0; | 557 | return 0; |
@@ -559,22 +565,17 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx) | |||
559 | mmie->key_id = cpu_to_le16(key->conf.keyidx); | 565 | mmie->key_id = cpu_to_le16(key->conf.keyidx); |
560 | 566 | ||
561 | /* PN = PN + 1 */ | 567 | /* PN = PN + 1 */ |
562 | pn = key->u.aes_cmac.tx_pn; | 568 | pn64 = atomic64_inc_return(&key->u.aes_cmac.tx_pn); |
563 | 569 | ||
564 | for (i = sizeof(key->u.aes_cmac.tx_pn) - 1; i >= 0; i--) { | 570 | bip_ipn_set64(mmie->sequence_number, pn64); |
565 | pn[i]++; | ||
566 | if (pn[i]) | ||
567 | break; | ||
568 | } | ||
569 | bip_ipn_swap(mmie->sequence_number, pn); | ||
570 | 571 | ||
571 | bip_aad(skb, aad); | 572 | bip_aad(skb, aad); |
572 | 573 | ||
573 | /* | 574 | /* |
574 | * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) | 575 | * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) |
575 | */ | 576 | */ |
576 | ieee80211_aes_cmac(key->u.aes_cmac.tfm, key->u.aes_cmac.tx_crypto_buf, | 577 | ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, |
577 | aad, skb->data + 24, skb->len - 24, mmie->mic); | 578 | skb->data + 24, skb->len - 24, mmie->mic); |
578 | 579 | ||
579 | return TX_CONTINUE; | 580 | return TX_CONTINUE; |
580 | } | 581 | } |
@@ -612,8 +613,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) | |||
612 | if (!(status->flag & RX_FLAG_DECRYPTED)) { | 613 | if (!(status->flag & RX_FLAG_DECRYPTED)) { |
613 | /* hardware didn't decrypt/verify MIC */ | 614 | /* hardware didn't decrypt/verify MIC */ |
614 | bip_aad(skb, aad); | 615 | bip_aad(skb, aad); |
615 | ieee80211_aes_cmac(key->u.aes_cmac.tfm, | 616 | ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, |
616 | key->u.aes_cmac.rx_crypto_buf, aad, | ||
617 | skb->data + 24, skb->len - 24, mic); | 617 | skb->data + 24, skb->len - 24, mic); |
618 | if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { | 618 | if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { |
619 | key->u.aes_cmac.icverrors++; | 619 | key->u.aes_cmac.icverrors++; |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 2cc9d4ab5578..1c4672e35144 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -137,7 +137,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, | |||
137 | lockdep_assert_held(&rdev->sched_scan_mtx); | 137 | lockdep_assert_held(&rdev->sched_scan_mtx); |
138 | 138 | ||
139 | if (!rdev->sched_scan_req) | 139 | if (!rdev->sched_scan_req) |
140 | return 0; | 140 | return -ENOENT; |
141 | 141 | ||
142 | dev = rdev->sched_scan_req->dev; | 142 | dev = rdev->sched_scan_req->dev; |
143 | 143 | ||