Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6ac68a6 authored by John W. Linville's avatar John W. Linville
Browse files

Merge branch 'master' of...

parents 9e89fd8b c678de55
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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,
+53 −0
Original line number Diff line number Diff line
@@ -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);

+1 −0
Original line number Diff line number Diff line
@@ -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 */

+35 −30
Original line number Diff line number Diff line
@@ -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];
@@ -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);
+3 −1
Original line number Diff line number Diff line
@@ -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;
Loading