diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-06-06 11:59:11 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-06-06 11:59:11 -0400 |
commit | c6ac68a612783aab0aad62b8edd36791b251aadb (patch) | |
tree | 348e65496111cd7b40365ffd78fcbe7bd2f9a58d | |
parent | 9e89fd8b7db71038fd9f70f34e210963fa8fc980 (diff) | |
parent | c678de55361aa5b72b1aaa495380a395b8cc1bd2 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
-rw-r--r-- | drivers/bluetooth/ath3k.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/at76c50x-usb.c | 53 | ||||
-rw-r--r-- | drivers/net/wireless/at76c50x-usb.h | 1 | ||||
-rw-r--r-- | net/bluetooth/6lowpan.c | 65 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 4 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 6 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 5 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 10 | ||||
-rw-r--r-- | net/bluetooth/smp.c | 7 |
9 files changed, 116 insertions, 38 deletions
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index a83b57e57b63..f98380648cb3 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -193,9 +193,10 @@ static int ath3k_load_firmware(struct usb_device *udev, | |||
193 | sent += 20; | 193 | sent += 20; |
194 | count -= 20; | 194 | count -= 20; |
195 | 195 | ||
196 | pipe = usb_sndbulkpipe(udev, 0x02); | ||
197 | |||
196 | while (count) { | 198 | while (count) { |
197 | size = min_t(uint, count, BULK_SIZE); | 199 | size = min_t(uint, count, BULK_SIZE); |
198 | pipe = usb_sndbulkpipe(udev, 0x02); | ||
199 | memcpy(send_buf, firmware->data + sent, size); | 200 | memcpy(send_buf, firmware->data + sent, size); |
200 | 201 | ||
201 | err = usb_bulk_msg(udev, pipe, send_buf, size, | 202 | err = usb_bulk_msg(udev, pipe, send_buf, size, |
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 10fd12ec85be..d48776e4f343 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
@@ -1429,6 +1429,8 @@ static int at76_startup_device(struct at76_priv *priv) | |||
1429 | /* remove BSSID from previous run */ | 1429 | /* remove BSSID from previous run */ |
1430 | memset(priv->bssid, 0, ETH_ALEN); | 1430 | memset(priv->bssid, 0, ETH_ALEN); |
1431 | 1431 | ||
1432 | priv->scanning = false; | ||
1433 | |||
1432 | if (at76_set_radio(priv, 1) == 1) | 1434 | if (at76_set_radio(priv, 1) == 1) |
1433 | at76_wait_completion(priv, CMD_RADIO_ON); | 1435 | at76_wait_completion(priv, CMD_RADIO_ON); |
1434 | 1436 | ||
@@ -1502,6 +1504,52 @@ static void at76_work_submit_rx(struct work_struct *work) | |||
1502 | mutex_unlock(&priv->mtx); | 1504 | mutex_unlock(&priv->mtx); |
1503 | } | 1505 | } |
1504 | 1506 | ||
1507 | /* This is a workaround to make scan working: | ||
1508 | * currently mac80211 does not process frames with no frequency | ||
1509 | * information. | ||
1510 | * However during scan the HW performs a sweep by itself, and we | ||
1511 | * are unable to know where the radio is actually tuned. | ||
1512 | * This function tries to do its best to guess this information.. | ||
1513 | * During scan, If the current frame is a beacon or a probe response, | ||
1514 | * the channel information is extracted from it. | ||
1515 | * When not scanning, for other frames, or if it happens that for | ||
1516 | * whatever reason we fail to parse beacons and probe responses, this | ||
1517 | * function returns the priv->channel information, that should be correct | ||
1518 | * at least when we are not scanning. | ||
1519 | */ | ||
1520 | static inline int at76_guess_freq(struct at76_priv *priv) | ||
1521 | { | ||
1522 | size_t el_off; | ||
1523 | const u8 *el; | ||
1524 | int channel = priv->channel; | ||
1525 | int len = priv->rx_skb->len; | ||
1526 | struct ieee80211_hdr *hdr = (void *)priv->rx_skb->data; | ||
1527 | |||
1528 | if (!priv->scanning) | ||
1529 | goto exit; | ||
1530 | |||
1531 | if (len < 24) | ||
1532 | goto exit; | ||
1533 | |||
1534 | if (ieee80211_is_probe_resp(hdr->frame_control)) { | ||
1535 | el_off = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); | ||
1536 | el = ((struct ieee80211_mgmt *)hdr)->u.probe_resp.variable; | ||
1537 | } else if (ieee80211_is_beacon(hdr->frame_control)) { | ||
1538 | el_off = offsetof(struct ieee80211_mgmt, u.beacon.variable); | ||
1539 | el = ((struct ieee80211_mgmt *)hdr)->u.beacon.variable; | ||
1540 | } else { | ||
1541 | goto exit; | ||
1542 | } | ||
1543 | len -= el_off; | ||
1544 | |||
1545 | el = cfg80211_find_ie(WLAN_EID_DS_PARAMS, el, len); | ||
1546 | if (el && el[1] > 0) | ||
1547 | channel = el[2]; | ||
1548 | |||
1549 | exit: | ||
1550 | return ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ); | ||
1551 | } | ||
1552 | |||
1505 | static void at76_rx_tasklet(unsigned long param) | 1553 | static void at76_rx_tasklet(unsigned long param) |
1506 | { | 1554 | { |
1507 | struct urb *urb = (struct urb *)param; | 1555 | struct urb *urb = (struct urb *)param; |
@@ -1542,6 +1590,8 @@ static void at76_rx_tasklet(unsigned long param) | |||
1542 | rx_status.signal = buf->rssi; | 1590 | rx_status.signal = buf->rssi; |
1543 | rx_status.flag |= RX_FLAG_DECRYPTED; | 1591 | rx_status.flag |= RX_FLAG_DECRYPTED; |
1544 | rx_status.flag |= RX_FLAG_IV_STRIPPED; | 1592 | rx_status.flag |= RX_FLAG_IV_STRIPPED; |
1593 | rx_status.band = IEEE80211_BAND_2GHZ; | ||
1594 | rx_status.freq = at76_guess_freq(priv); | ||
1545 | 1595 | ||
1546 | at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d", | 1596 | at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d", |
1547 | priv->rx_skb->len, priv->rx_skb->data_len); | 1597 | priv->rx_skb->len, priv->rx_skb->data_len); |
@@ -1894,6 +1944,8 @@ static void at76_dwork_hw_scan(struct work_struct *work) | |||
1894 | if (is_valid_ether_addr(priv->bssid)) | 1944 | if (is_valid_ether_addr(priv->bssid)) |
1895 | at76_join(priv); | 1945 | at76_join(priv); |
1896 | 1946 | ||
1947 | priv->scanning = false; | ||
1948 | |||
1897 | mutex_unlock(&priv->mtx); | 1949 | mutex_unlock(&priv->mtx); |
1898 | 1950 | ||
1899 | ieee80211_scan_completed(priv->hw, false); | 1951 | ieee80211_scan_completed(priv->hw, false); |
@@ -1948,6 +2000,7 @@ static int at76_hw_scan(struct ieee80211_hw *hw, | |||
1948 | goto exit; | 2000 | goto exit; |
1949 | } | 2001 | } |
1950 | 2002 | ||
2003 | priv->scanning = true; | ||
1951 | ieee80211_queue_delayed_work(priv->hw, &priv->dwork_hw_scan, | 2004 | ieee80211_queue_delayed_work(priv->hw, &priv->dwork_hw_scan, |
1952 | SCAN_POLL_INTERVAL); | 2005 | SCAN_POLL_INTERVAL); |
1953 | 2006 | ||
diff --git a/drivers/net/wireless/at76c50x-usb.h b/drivers/net/wireless/at76c50x-usb.h index 4718aa59f051..55090a38ac95 100644 --- a/drivers/net/wireless/at76c50x-usb.h +++ b/drivers/net/wireless/at76c50x-usb.h | |||
@@ -418,6 +418,7 @@ struct at76_priv { | |||
418 | int scan_max_time; /* scan max channel time */ | 418 | int scan_max_time; /* scan max channel time */ |
419 | int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */ | 419 | int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */ |
420 | int scan_need_any; /* if set, need to scan for any ESSID */ | 420 | int scan_need_any; /* if set, need to scan for any ESSID */ |
421 | bool scanning; /* if set, the scan is running */ | ||
421 | 422 | ||
422 | u16 assoc_id; /* current association ID, if associated */ | 423 | u16 assoc_id; /* current association ID, if associated */ |
423 | 424 | ||
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 73492b91105a..8796ffa08b43 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c | |||
@@ -420,12 +420,18 @@ static int conn_send(struct l2cap_conn *conn, | |||
420 | return 0; | 420 | return 0; |
421 | } | 421 | } |
422 | 422 | ||
423 | static void get_dest_bdaddr(struct in6_addr *ip6_daddr, | 423 | static u8 get_addr_type_from_eui64(u8 byte) |
424 | bdaddr_t *addr, u8 *addr_type) | ||
425 | { | 424 | { |
426 | u8 *eui64; | 425 | /* Is universal(0) or local(1) bit, */ |
426 | if (byte & 0x02) | ||
427 | return ADDR_LE_DEV_RANDOM; | ||
427 | 428 | ||
428 | eui64 = ip6_daddr->s6_addr + 8; | 429 | return ADDR_LE_DEV_PUBLIC; |
430 | } | ||
431 | |||
432 | static void copy_to_bdaddr(struct in6_addr *ip6_daddr, bdaddr_t *addr) | ||
433 | { | ||
434 | u8 *eui64 = ip6_daddr->s6_addr + 8; | ||
429 | 435 | ||
430 | addr->b[0] = eui64[7]; | 436 | addr->b[0] = eui64[7]; |
431 | addr->b[1] = eui64[6]; | 437 | addr->b[1] = eui64[6]; |
@@ -433,16 +439,19 @@ static void get_dest_bdaddr(struct in6_addr *ip6_daddr, | |||
433 | addr->b[3] = eui64[2]; | 439 | addr->b[3] = eui64[2]; |
434 | addr->b[4] = eui64[1]; | 440 | addr->b[4] = eui64[1]; |
435 | addr->b[5] = eui64[0]; | 441 | addr->b[5] = eui64[0]; |
442 | } | ||
436 | 443 | ||
437 | addr->b[5] ^= 2; | 444 | static void convert_dest_bdaddr(struct in6_addr *ip6_daddr, |
445 | bdaddr_t *addr, u8 *addr_type) | ||
446 | { | ||
447 | copy_to_bdaddr(ip6_daddr, addr); | ||
438 | 448 | ||
439 | /* Set universal/local bit to 0 */ | 449 | /* We need to toggle the U/L bit that we got from IPv6 address |
440 | if (addr->b[5] & 1) { | 450 | * so that we get the proper address and type of the BD address. |
441 | addr->b[5] &= ~1; | 451 | */ |
442 | *addr_type = ADDR_LE_DEV_PUBLIC; | 452 | addr->b[5] ^= 0x02; |
443 | } else { | 453 | |
444 | *addr_type = ADDR_LE_DEV_RANDOM; | 454 | *addr_type = get_addr_type_from_eui64(addr->b[5]); |
445 | } | ||
446 | } | 455 | } |
447 | 456 | ||
448 | static int header_create(struct sk_buff *skb, struct net_device *netdev, | 457 | static int header_create(struct sk_buff *skb, struct net_device *netdev, |
@@ -473,9 +482,11 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev, | |||
473 | /* Get destination BT device from skb. | 482 | /* Get destination BT device from skb. |
474 | * If there is no such peer then discard the packet. | 483 | * If there is no such peer then discard the packet. |
475 | */ | 484 | */ |
476 | get_dest_bdaddr(&hdr->daddr, &addr, &addr_type); | 485 | convert_dest_bdaddr(&hdr->daddr, &addr, &addr_type); |
477 | 486 | ||
478 | BT_DBG("dest addr %pMR type %d", &addr, addr_type); | 487 | BT_DBG("dest addr %pMR type %s IP %pI6c", &addr, |
488 | addr_type == ADDR_LE_DEV_PUBLIC ? "PUBLIC" : "RANDOM", | ||
489 | &hdr->daddr); | ||
479 | 490 | ||
480 | read_lock_irqsave(&devices_lock, flags); | 491 | read_lock_irqsave(&devices_lock, flags); |
481 | peer = peer_lookup_ba(dev, &addr, addr_type); | 492 | peer = peer_lookup_ba(dev, &addr, addr_type); |
@@ -556,7 +567,7 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
556 | } else { | 567 | } else { |
557 | unsigned long flags; | 568 | unsigned long flags; |
558 | 569 | ||
559 | get_dest_bdaddr(&lowpan_cb(skb)->addr, &addr, &addr_type); | 570 | convert_dest_bdaddr(&lowpan_cb(skb)->addr, &addr, &addr_type); |
560 | eui64_addr = lowpan_cb(skb)->addr.s6_addr + 8; | 571 | eui64_addr = lowpan_cb(skb)->addr.s6_addr + 8; |
561 | dev = lowpan_dev(netdev); | 572 | dev = lowpan_dev(netdev); |
562 | 573 | ||
@@ -564,8 +575,10 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
564 | peer = peer_lookup_ba(dev, &addr, addr_type); | 575 | peer = peer_lookup_ba(dev, &addr, addr_type); |
565 | read_unlock_irqrestore(&devices_lock, flags); | 576 | read_unlock_irqrestore(&devices_lock, flags); |
566 | 577 | ||
567 | BT_DBG("xmit from %s to %pMR (%pI6c) peer %p", netdev->name, | 578 | BT_DBG("xmit %s to %pMR type %s IP %pI6c peer %p", |
568 | &addr, &lowpan_cb(skb)->addr, peer); | 579 | netdev->name, &addr, |
580 | addr_type == ADDR_LE_DEV_PUBLIC ? "PUBLIC" : "RANDOM", | ||
581 | &lowpan_cb(skb)->addr, peer); | ||
569 | 582 | ||
570 | if (peer && peer->conn) | 583 | if (peer && peer->conn) |
571 | err = send_pkt(peer->conn, netdev->dev_addr, | 584 | err = send_pkt(peer->conn, netdev->dev_addr, |
@@ -620,13 +633,13 @@ static void set_addr(u8 *eui, u8 *addr, u8 addr_type) | |||
620 | eui[6] = addr[1]; | 633 | eui[6] = addr[1]; |
621 | eui[7] = addr[0]; | 634 | eui[7] = addr[0]; |
622 | 635 | ||
623 | eui[0] ^= 2; | 636 | /* Universal/local bit set, BT 6lowpan draft ch. 3.2.1 */ |
624 | |||
625 | /* Universal/local bit set, RFC 4291 */ | ||
626 | if (addr_type == ADDR_LE_DEV_PUBLIC) | 637 | if (addr_type == ADDR_LE_DEV_PUBLIC) |
627 | eui[0] |= 1; | 638 | eui[0] &= ~0x02; |
628 | else | 639 | else |
629 | eui[0] &= ~1; | 640 | eui[0] |= 0x02; |
641 | |||
642 | BT_DBG("type %d addr %*phC", addr_type, 8, eui); | ||
630 | } | 643 | } |
631 | 644 | ||
632 | static void set_dev_addr(struct net_device *netdev, bdaddr_t *addr, | 645 | static void set_dev_addr(struct net_device *netdev, bdaddr_t *addr, |
@@ -634,7 +647,6 @@ static void set_dev_addr(struct net_device *netdev, bdaddr_t *addr, | |||
634 | { | 647 | { |
635 | netdev->addr_assign_type = NET_ADDR_PERM; | 648 | netdev->addr_assign_type = NET_ADDR_PERM; |
636 | set_addr(netdev->dev_addr, addr->b, addr_type); | 649 | set_addr(netdev->dev_addr, addr->b, addr_type); |
637 | netdev->dev_addr[0] ^= 2; | ||
638 | } | 650 | } |
639 | 651 | ||
640 | static void ifup(struct net_device *netdev) | 652 | static void ifup(struct net_device *netdev) |
@@ -684,13 +696,6 @@ static int add_peer_conn(struct l2cap_conn *conn, struct lowpan_dev *dev) | |||
684 | 696 | ||
685 | memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8, | 697 | memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8, |
686 | EUI64_ADDR_LEN); | 698 | EUI64_ADDR_LEN); |
687 | peer->eui64_addr[0] ^= 2; /* second bit-flip (Universe/Local) | ||
688 | * is done according RFC2464 | ||
689 | */ | ||
690 | |||
691 | raw_dump_inline(__func__, "peer IPv6 address", | ||
692 | (unsigned char *)&peer->peer_addr, 16); | ||
693 | raw_dump_inline(__func__, "peer EUI64 address", peer->eui64_addr, 8); | ||
694 | 699 | ||
695 | write_lock_irqsave(&devices_lock, flags); | 700 | write_lock_irqsave(&devices_lock, flags); |
696 | INIT_LIST_HEAD(&peer->list); | 701 | INIT_LIST_HEAD(&peer->list); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 3454807a40c5..1096e4cd1283 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -1453,6 +1453,7 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, | |||
1453 | * is requested. | 1453 | * is requested. |
1454 | */ | 1454 | */ |
1455 | if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) && | 1455 | if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) && |
1456 | conn->pending_sec_level != BT_SECURITY_FIPS && | ||
1456 | conn->pending_sec_level != BT_SECURITY_HIGH && | 1457 | conn->pending_sec_level != BT_SECURITY_HIGH && |
1457 | conn->pending_sec_level != BT_SECURITY_MEDIUM) | 1458 | conn->pending_sec_level != BT_SECURITY_MEDIUM) |
1458 | return 0; | 1459 | return 0; |
@@ -3076,7 +3077,8 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
3076 | } | 3077 | } |
3077 | 3078 | ||
3078 | if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && | 3079 | if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && |
3079 | conn->pending_sec_level == BT_SECURITY_HIGH) { | 3080 | (conn->pending_sec_level == BT_SECURITY_HIGH || |
3081 | conn->pending_sec_level == BT_SECURITY_FIPS)) { | ||
3080 | BT_DBG("%s ignoring key unauthenticated for high security", | 3082 | BT_DBG("%s ignoring key unauthenticated for high security", |
3081 | hdev->name); | 3083 | hdev->name); |
3082 | goto not_found; | 3084 | goto not_found; |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index dc4d301d3a72..6eabbe05fe54 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -471,8 +471,14 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan) | |||
471 | chan->max_tx = L2CAP_DEFAULT_MAX_TX; | 471 | chan->max_tx = L2CAP_DEFAULT_MAX_TX; |
472 | chan->tx_win = L2CAP_DEFAULT_TX_WINDOW; | 472 | chan->tx_win = L2CAP_DEFAULT_TX_WINDOW; |
473 | chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW; | 473 | chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW; |
474 | chan->remote_max_tx = chan->max_tx; | ||
475 | chan->remote_tx_win = chan->tx_win; | ||
474 | chan->ack_win = L2CAP_DEFAULT_TX_WINDOW; | 476 | chan->ack_win = L2CAP_DEFAULT_TX_WINDOW; |
475 | chan->sec_level = BT_SECURITY_LOW; | 477 | chan->sec_level = BT_SECURITY_LOW; |
478 | chan->flush_to = L2CAP_DEFAULT_FLUSH_TO; | ||
479 | chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO; | ||
480 | chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO; | ||
481 | chan->conf_state = 0; | ||
476 | 482 | ||
477 | set_bit(FLAG_FORCE_ACTIVE, &chan->flags); | 483 | set_bit(FLAG_FORCE_ACTIVE, &chan->flags); |
478 | } | 484 | } |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index ef5e5b04f34f..ade3fb4c23bc 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -1180,13 +1180,16 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) | |||
1180 | /* Check for backlog size */ | 1180 | /* Check for backlog size */ |
1181 | if (sk_acceptq_is_full(parent)) { | 1181 | if (sk_acceptq_is_full(parent)) { |
1182 | BT_DBG("backlog full %d", parent->sk_ack_backlog); | 1182 | BT_DBG("backlog full %d", parent->sk_ack_backlog); |
1183 | release_sock(parent); | ||
1183 | return NULL; | 1184 | return NULL; |
1184 | } | 1185 | } |
1185 | 1186 | ||
1186 | sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, | 1187 | sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, |
1187 | GFP_ATOMIC); | 1188 | GFP_ATOMIC); |
1188 | if (!sk) | 1189 | if (!sk) { |
1190 | release_sock(parent); | ||
1189 | return NULL; | 1191 | return NULL; |
1192 | } | ||
1190 | 1193 | ||
1191 | bt_sock_reclassify_lock(sk, BTPROTO_L2CAP); | 1194 | bt_sock_reclassify_lock(sk, BTPROTO_L2CAP); |
1192 | 1195 | ||
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 5e9c21a5525f..0fce54412ffd 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -4546,10 +4546,16 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, | |||
4546 | else | 4546 | else |
4547 | type = HCI_SMP_LTK_SLAVE; | 4547 | type = HCI_SMP_LTK_SLAVE; |
4548 | 4548 | ||
4549 | if (key->type == MGMT_LTK_UNAUTHENTICATED) | 4549 | switch (key->type) { |
4550 | case MGMT_LTK_UNAUTHENTICATED: | ||
4550 | authenticated = 0x00; | 4551 | authenticated = 0x00; |
4551 | else | 4552 | break; |
4553 | case MGMT_LTK_AUTHENTICATED: | ||
4552 | authenticated = 0x01; | 4554 | authenticated = 0x01; |
4555 | break; | ||
4556 | default: | ||
4557 | continue; | ||
4558 | } | ||
4553 | 4559 | ||
4554 | hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, type, | 4560 | hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, type, |
4555 | authenticated, key->val, key->enc_size, key->ediv, | 4561 | authenticated, key->val, key->enc_size, key->ediv, |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 4f9662d0fd81..3d1cc164557d 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -909,10 +909,11 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) | |||
909 | 909 | ||
910 | authreq = seclevel_to_authreq(sec_level); | 910 | authreq = seclevel_to_authreq(sec_level); |
911 | 911 | ||
912 | /* hcon->auth_type is set by pair_device in mgmt.c. If the MITM | 912 | /* Require MITM if IO Capability allows or the security level |
913 | * flag is set we should also set it for the SMP request. | 913 | * requires it. |
914 | */ | 914 | */ |
915 | if ((hcon->auth_type & 0x01)) | 915 | if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT || |
916 | sec_level > BT_SECURITY_MEDIUM) | ||
916 | authreq |= SMP_AUTH_MITM; | 917 | authreq |= SMP_AUTH_MITM; |
917 | 918 | ||
918 | if (hcon->link_mode & HCI_LM_MASTER) { | 919 | if (hcon->link_mode & HCI_LM_MASTER) { |