Loading drivers/bluetooth/ath3k.c +2 −1 Original line number Diff line number Diff line Loading @@ -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, Loading drivers/net/wireless/at76c50x-usb.c +53 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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); Loading drivers/net/wireless/at76c50x-usb.h +1 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading net/bluetooth/6lowpan.c +35 −30 Original line number Diff line number Diff line Loading @@ -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; return ADDR_LE_DEV_PUBLIC; } eui64 = ip6_daddr->s6_addr + 8; 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]; Loading @@ -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, Loading Loading @@ -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); Loading Loading @@ -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); Loading @@ -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, Loading Loading @@ -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, Loading @@ -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) Loading Loading @@ -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); Loading net/bluetooth/hci_event.c +3 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading
drivers/bluetooth/ath3k.c +2 −1 Original line number Diff line number Diff line Loading @@ -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, Loading
drivers/net/wireless/at76c50x-usb.c +53 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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); Loading
drivers/net/wireless/at76c50x-usb.h +1 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading
net/bluetooth/6lowpan.c +35 −30 Original line number Diff line number Diff line Loading @@ -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; return ADDR_LE_DEV_PUBLIC; } eui64 = ip6_daddr->s6_addr + 8; 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]; Loading @@ -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, Loading Loading @@ -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); Loading Loading @@ -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); Loading @@ -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, Loading Loading @@ -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, Loading @@ -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) Loading Loading @@ -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); Loading
net/bluetooth/hci_event.c +3 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading