Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorJohn W. Linville <linville@tuxdriver.com>
Fri, 6 Jun 2014 15:59:11 +0000 (11:59 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 6 Jun 2014 15:59:11 +0000 (11:59 -0400)
drivers/bluetooth/ath3k.c
drivers/net/wireless/at76c50x-usb.c
drivers/net/wireless/at76c50x-usb.h
net/bluetooth/6lowpan.c
net/bluetooth/hci_event.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/bluetooth/mgmt.c
net/bluetooth/smp.c

index a83b57e57b6370572d53325638355a0d94ce24bf..f98380648cb3513fe47ac19213ce0b105a0d1873 100644 (file)
@@ -193,9 +193,10 @@ static int ath3k_load_firmware(struct usb_device *udev,
        sent += 20;
        count -= 20;
 
+       pipe = usb_sndbulkpipe(udev, 0x02);
+
        while (count) {
                size = min_t(uint, count, BULK_SIZE);
-               pipe = usb_sndbulkpipe(udev, 0x02);
                memcpy(send_buf, firmware->data + sent, size);
 
                err = usb_bulk_msg(udev, pipe, send_buf, size,
index 10fd12ec85be909501bd831ba8174f03f1b5cd2e..d48776e4f343e050787510923bc01e689a2bd9cc 100644 (file)
@@ -1429,6 +1429,8 @@ static int at76_startup_device(struct at76_priv *priv)
        /* remove BSSID from previous run */
        memset(priv->bssid, 0, ETH_ALEN);
 
+       priv->scanning = false;
+
        if (at76_set_radio(priv, 1) == 1)
                at76_wait_completion(priv, CMD_RADIO_ON);
 
@@ -1502,6 +1504,52 @@ static void at76_work_submit_rx(struct work_struct *work)
        mutex_unlock(&priv->mtx);
 }
 
+/* This is a workaround to make scan working:
+ * currently mac80211 does not process frames with no frequency
+ * information.
+ * However during scan the HW performs a sweep by itself, and we
+ * are unable to know where the radio is actually tuned.
+ * This function tries to do its best to guess this information..
+ * During scan, If the current frame is a beacon or a probe response,
+ * the channel information is extracted from it.
+ * When not scanning, for other frames, or if it happens that for
+ * whatever reason we fail to parse beacons and probe responses, this
+ * function returns the priv->channel information, that should be correct
+ * at least when we are not scanning.
+ */
+static inline int at76_guess_freq(struct at76_priv *priv)
+{
+       size_t el_off;
+       const u8 *el;
+       int channel = priv->channel;
+       int len = priv->rx_skb->len;
+       struct ieee80211_hdr *hdr = (void *)priv->rx_skb->data;
+
+       if (!priv->scanning)
+               goto exit;
+
+       if (len < 24)
+               goto exit;
+
+       if (ieee80211_is_probe_resp(hdr->frame_control)) {
+               el_off = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
+               el = ((struct ieee80211_mgmt *)hdr)->u.probe_resp.variable;
+       } else if (ieee80211_is_beacon(hdr->frame_control)) {
+               el_off = offsetof(struct ieee80211_mgmt, u.beacon.variable);
+               el = ((struct ieee80211_mgmt *)hdr)->u.beacon.variable;
+       } else {
+               goto exit;
+       }
+       len -= el_off;
+
+       el = cfg80211_find_ie(WLAN_EID_DS_PARAMS, el, len);
+       if (el && el[1] > 0)
+               channel = el[2];
+
+exit:
+       return ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
+}
+
 static void at76_rx_tasklet(unsigned long param)
 {
        struct urb *urb = (struct urb *)param;
@@ -1542,6 +1590,8 @@ static void at76_rx_tasklet(unsigned long param)
        rx_status.signal = buf->rssi;
        rx_status.flag |= RX_FLAG_DECRYPTED;
        rx_status.flag |= RX_FLAG_IV_STRIPPED;
+       rx_status.band = IEEE80211_BAND_2GHZ;
+       rx_status.freq = at76_guess_freq(priv);
 
        at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d",
                 priv->rx_skb->len, priv->rx_skb->data_len);
@@ -1894,6 +1944,8 @@ static void at76_dwork_hw_scan(struct work_struct *work)
        if (is_valid_ether_addr(priv->bssid))
                at76_join(priv);
 
+       priv->scanning = false;
+
        mutex_unlock(&priv->mtx);
 
        ieee80211_scan_completed(priv->hw, false);
@@ -1948,6 +2000,7 @@ static int at76_hw_scan(struct ieee80211_hw *hw,
                goto exit;
        }
 
+       priv->scanning = true;
        ieee80211_queue_delayed_work(priv->hw, &priv->dwork_hw_scan,
                                     SCAN_POLL_INTERVAL);
 
index 4718aa59f0510ba04ae07cbffd73ff4e1f4f0b7e..55090a38ac9549eb546a747144b9f274ae1b2faf 100644 (file)
@@ -418,6 +418,7 @@ struct at76_priv {
        int scan_max_time;      /* scan max channel time */
        int scan_mode;          /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */
        int scan_need_any;      /* if set, need to scan for any ESSID */
+       bool scanning;          /* if set, the scan is running */
 
        u16 assoc_id;           /* current association ID, if associated */
 
index 73492b91105ac0aba10aec738415128d0582bfc5..8796ffa08b43b4f57ae1485f4a5867c0f532807c 100644 (file)
@@ -420,12 +420,18 @@ static int conn_send(struct l2cap_conn *conn,
        return 0;
 }
 
-static void get_dest_bdaddr(struct in6_addr *ip6_daddr,
-                           bdaddr_t *addr, u8 *addr_type)
+static u8 get_addr_type_from_eui64(u8 byte)
 {
-       u8 *eui64;
+       /* Is universal(0) or local(1) bit,  */
+       if (byte & 0x02)
+               return ADDR_LE_DEV_RANDOM;
 
-       eui64 = ip6_daddr->s6_addr + 8;
+       return ADDR_LE_DEV_PUBLIC;
+}
+
+static void copy_to_bdaddr(struct in6_addr *ip6_daddr, bdaddr_t *addr)
+{
+       u8 *eui64 = ip6_daddr->s6_addr + 8;
 
        addr->b[0] = eui64[7];
        addr->b[1] = eui64[6];
@@ -433,16 +439,19 @@ static void get_dest_bdaddr(struct in6_addr *ip6_daddr,
        addr->b[3] = eui64[2];
        addr->b[4] = eui64[1];
        addr->b[5] = eui64[0];
+}
 
-       addr->b[5] ^= 2;
+static void convert_dest_bdaddr(struct in6_addr *ip6_daddr,
+                               bdaddr_t *addr, u8 *addr_type)
+{
+       copy_to_bdaddr(ip6_daddr, addr);
 
-       /* Set universal/local bit to 0 */
-       if (addr->b[5] & 1) {
-               addr->b[5] &= ~1;
-               *addr_type = ADDR_LE_DEV_PUBLIC;
-       } else {
-               *addr_type = ADDR_LE_DEV_RANDOM;
-       }
+       /* We need to toggle the U/L bit that we got from IPv6 address
+        * so that we get the proper address and type of the BD address.
+        */
+       addr->b[5] ^= 0x02;
+
+       *addr_type = get_addr_type_from_eui64(addr->b[5]);
 }
 
 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,
                /* Get destination BT device from skb.
                 * If there is no such peer then discard the packet.
                 */
-               get_dest_bdaddr(&hdr->daddr, &addr, &addr_type);
+               convert_dest_bdaddr(&hdr->daddr, &addr, &addr_type);
 
-               BT_DBG("dest addr %pMR type %d", &addr, addr_type);
+               BT_DBG("dest addr %pMR type %s IP %pI6c", &addr,
+                      addr_type == ADDR_LE_DEV_PUBLIC ? "PUBLIC" : "RANDOM",
+                      &hdr->daddr);
 
                read_lock_irqsave(&devices_lock, flags);
                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)
        } else {
                unsigned long flags;
 
-               get_dest_bdaddr(&lowpan_cb(skb)->addr, &addr, &addr_type);
+               convert_dest_bdaddr(&lowpan_cb(skb)->addr, &addr, &addr_type);
                eui64_addr = lowpan_cb(skb)->addr.s6_addr + 8;
                dev = lowpan_dev(netdev);
 
@@ -564,8 +575,10 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
                peer = peer_lookup_ba(dev, &addr, addr_type);
                read_unlock_irqrestore(&devices_lock, flags);
 
-               BT_DBG("xmit from %s to %pMR (%pI6c) peer %p", netdev->name,
-                      &addr, &lowpan_cb(skb)->addr, peer);
+               BT_DBG("xmit %s to %pMR type %s IP %pI6c peer %p",
+                      netdev->name, &addr,
+                      addr_type == ADDR_LE_DEV_PUBLIC ? "PUBLIC" : "RANDOM",
+                      &lowpan_cb(skb)->addr, peer);
 
                if (peer && peer->conn)
                        err = send_pkt(peer->conn, netdev->dev_addr,
@@ -620,13 +633,13 @@ static void set_addr(u8 *eui, u8 *addr, u8 addr_type)
        eui[6] = addr[1];
        eui[7] = addr[0];
 
-       eui[0] ^= 2;
-
-       /* Universal/local bit set, RFC 4291 */
+       /* Universal/local bit set, BT 6lowpan draft ch. 3.2.1 */
        if (addr_type == ADDR_LE_DEV_PUBLIC)
-               eui[0] |= 1;
+               eui[0] &= ~0x02;
        else
-               eui[0] &= ~1;
+               eui[0] |= 0x02;
+
+       BT_DBG("type %d addr %*phC", addr_type, 8, eui);
 }
 
 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,
 {
        netdev->addr_assign_type = NET_ADDR_PERM;
        set_addr(netdev->dev_addr, addr->b, addr_type);
-       netdev->dev_addr[0] ^= 2;
 }
 
 static void ifup(struct net_device *netdev)
@@ -684,13 +696,6 @@ static int add_peer_conn(struct l2cap_conn *conn, struct lowpan_dev *dev)
 
        memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8,
               EUI64_ADDR_LEN);
-       peer->eui64_addr[0] ^= 2; /* second bit-flip (Universe/Local)
-                                  * is done according RFC2464
-                                  */
-
-       raw_dump_inline(__func__, "peer IPv6 address",
-                       (unsigned char *)&peer->peer_addr, 16);
-       raw_dump_inline(__func__, "peer EUI64 address", peer->eui64_addr, 8);
 
        write_lock_irqsave(&devices_lock, flags);
        INIT_LIST_HEAD(&peer->list);
index 3454807a40c53df7e720543e90ab4208d9e0afc2..1096e4cd12833387313c7b5da3dd7698b3faad32 100644 (file)
@@ -1453,6 +1453,7 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev,
         * is requested.
         */
        if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
+           conn->pending_sec_level != BT_SECURITY_FIPS &&
            conn->pending_sec_level != BT_SECURITY_HIGH &&
            conn->pending_sec_level != BT_SECURITY_MEDIUM)
                return 0;
@@ -3076,7 +3077,8 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
                }
 
                if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
-                   conn->pending_sec_level == BT_SECURITY_HIGH) {
+                   (conn->pending_sec_level == BT_SECURITY_HIGH ||
+                    conn->pending_sec_level == BT_SECURITY_FIPS)) {
                        BT_DBG("%s ignoring key unauthenticated for high security",
                               hdev->name);
                        goto not_found;
index dc4d301d3a728ccd0af8efe4e9648b843d598406..6eabbe05fe54fe8ecc39707a05350439d99ce830 100644 (file)
@@ -471,8 +471,14 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan)
        chan->max_tx = L2CAP_DEFAULT_MAX_TX;
        chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
        chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
+       chan->remote_max_tx = chan->max_tx;
+       chan->remote_tx_win = chan->tx_win;
        chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
        chan->sec_level = BT_SECURITY_LOW;
+       chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
+       chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
+       chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
+       chan->conf_state = 0;
 
        set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
 }
index ef5e5b04f34fbd3c130c74dc2a41ffe775870b3b..ade3fb4c23bce81aa054e2bdd064f74019767dae 100644 (file)
@@ -1180,13 +1180,16 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
        /* Check for backlog size */
        if (sk_acceptq_is_full(parent)) {
                BT_DBG("backlog full %d", parent->sk_ack_backlog);
+               release_sock(parent);
                return NULL;
        }
 
        sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
                              GFP_ATOMIC);
-       if (!sk)
+       if (!sk) {
+               release_sock(parent);
                return NULL;
+        }
 
        bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
 
index 5e9c21a5525f445ae7c513a9a175e6337aed3a41..0fce54412ffdc077f6d337eadc4cfbe20b51ed26 100644 (file)
@@ -4546,10 +4546,16 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
                else
                        type = HCI_SMP_LTK_SLAVE;
 
-               if (key->type == MGMT_LTK_UNAUTHENTICATED)
+               switch (key->type) {
+               case MGMT_LTK_UNAUTHENTICATED:
                        authenticated = 0x00;
-               else
+                       break;
+               case MGMT_LTK_AUTHENTICATED:
                        authenticated = 0x01;
+                       break;
+               default:
+                       continue;
+               }
 
                hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, type,
                            authenticated, key->val, key->enc_size, key->ediv,
index 4f9662d0fd812f47ddc11e2d738de84e7360092c..3d1cc164557de1750e4768f229aaede55b03e80c 100644 (file)
@@ -909,10 +909,11 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
 
        authreq = seclevel_to_authreq(sec_level);
 
-       /* hcon->auth_type is set by pair_device in mgmt.c. If the MITM
-        * flag is set we should also set it for the SMP request.
+       /* Require MITM if IO Capability allows or the security level
+        * requires it.
         */
-       if ((hcon->auth_type & 0x01))
+       if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
+           sec_level > BT_SECURITY_MEDIUM)
                authreq |= SMP_AUTH_MITM;
 
        if (hcon->link_mode & HCI_LM_MASTER) {