Commit b78370c0 authored by David S. Miller's avatar David S. Miller

Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next

John W. Linville says:

====================
pull request: wireless-next 2014-06-06

Please accept this batch of fixes intended for the 3.16 stream.

For the bluetooth bits, Gustavo says:

"Here some more patches for 3.16. We know that Linus already opened the merge
window, but this is fix only pull request, and most of the patches here are
also tagged for stable."

Along with that, Andrea Merello provides a fix for the broken scanning
in the venerable at76c50x driver...
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8063968a c6ac68a6
...@@ -193,9 +193,10 @@ static int ath3k_load_firmware(struct usb_device *udev, ...@@ -193,9 +193,10 @@ static int ath3k_load_firmware(struct usb_device *udev,
sent += 20; sent += 20;
count -= 20; count -= 20;
pipe = usb_sndbulkpipe(udev, 0x02);
while (count) { while (count) {
size = min_t(uint, count, BULK_SIZE); size = min_t(uint, count, BULK_SIZE);
pipe = usb_sndbulkpipe(udev, 0x02);
memcpy(send_buf, firmware->data + sent, size); memcpy(send_buf, firmware->data + sent, size);
err = usb_bulk_msg(udev, pipe, send_buf, size, err = usb_bulk_msg(udev, pipe, send_buf, size,
......
...@@ -1429,6 +1429,8 @@ static int at76_startup_device(struct at76_priv *priv) ...@@ -1429,6 +1429,8 @@ static int at76_startup_device(struct at76_priv *priv)
/* remove BSSID from previous run */ /* remove BSSID from previous run */
memset(priv->bssid, 0, ETH_ALEN); memset(priv->bssid, 0, ETH_ALEN);
priv->scanning = false;
if (at76_set_radio(priv, 1) == 1) if (at76_set_radio(priv, 1) == 1)
at76_wait_completion(priv, CMD_RADIO_ON); at76_wait_completion(priv, CMD_RADIO_ON);
...@@ -1502,6 +1504,52 @@ static void at76_work_submit_rx(struct work_struct *work) ...@@ -1502,6 +1504,52 @@ static void at76_work_submit_rx(struct work_struct *work)
mutex_unlock(&priv->mtx); 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) static void at76_rx_tasklet(unsigned long param)
{ {
struct urb *urb = (struct urb *)param; struct urb *urb = (struct urb *)param;
...@@ -1542,6 +1590,8 @@ static void at76_rx_tasklet(unsigned long param) ...@@ -1542,6 +1590,8 @@ static void at76_rx_tasklet(unsigned long param)
rx_status.signal = buf->rssi; rx_status.signal = buf->rssi;
rx_status.flag |= RX_FLAG_DECRYPTED; rx_status.flag |= RX_FLAG_DECRYPTED;
rx_status.flag |= RX_FLAG_IV_STRIPPED; 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", at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d",
priv->rx_skb->len, priv->rx_skb->data_len); priv->rx_skb->len, priv->rx_skb->data_len);
...@@ -1894,6 +1944,8 @@ static void at76_dwork_hw_scan(struct work_struct *work) ...@@ -1894,6 +1944,8 @@ static void at76_dwork_hw_scan(struct work_struct *work)
if (is_valid_ether_addr(priv->bssid)) if (is_valid_ether_addr(priv->bssid))
at76_join(priv); at76_join(priv);
priv->scanning = false;
mutex_unlock(&priv->mtx); mutex_unlock(&priv->mtx);
ieee80211_scan_completed(priv->hw, false); ieee80211_scan_completed(priv->hw, false);
...@@ -1948,6 +2000,7 @@ static int at76_hw_scan(struct ieee80211_hw *hw, ...@@ -1948,6 +2000,7 @@ static int at76_hw_scan(struct ieee80211_hw *hw,
goto exit; goto exit;
} }
priv->scanning = true;
ieee80211_queue_delayed_work(priv->hw, &priv->dwork_hw_scan, ieee80211_queue_delayed_work(priv->hw, &priv->dwork_hw_scan,
SCAN_POLL_INTERVAL); SCAN_POLL_INTERVAL);
......
...@@ -418,6 +418,7 @@ struct at76_priv { ...@@ -418,6 +418,7 @@ struct at76_priv {
int scan_max_time; /* scan max channel time */ int scan_max_time; /* scan max channel time */
int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */ int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */
int scan_need_any; /* if set, need to scan for any ESSID */ 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 */ u16 assoc_id; /* current association ID, if associated */
......
...@@ -420,12 +420,18 @@ static int conn_send(struct l2cap_conn *conn, ...@@ -420,12 +420,18 @@ static int conn_send(struct l2cap_conn *conn,
return 0; return 0;
} }
static void get_dest_bdaddr(struct in6_addr *ip6_daddr, static u8 get_addr_type_from_eui64(u8 byte)
bdaddr_t *addr, u8 *addr_type)
{ {
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[0] = eui64[7];
addr->b[1] = eui64[6]; addr->b[1] = eui64[6];
...@@ -433,16 +439,19 @@ static void get_dest_bdaddr(struct in6_addr *ip6_daddr, ...@@ -433,16 +439,19 @@ static void get_dest_bdaddr(struct in6_addr *ip6_daddr,
addr->b[3] = eui64[2]; addr->b[3] = eui64[2];
addr->b[4] = eui64[1]; addr->b[4] = eui64[1];
addr->b[5] = eui64[0]; 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 */ /* We need to toggle the U/L bit that we got from IPv6 address
if (addr->b[5] & 1) { * so that we get the proper address and type of the BD address.
addr->b[5] &= ~1; */
*addr_type = ADDR_LE_DEV_PUBLIC; addr->b[5] ^= 0x02;
} else {
*addr_type = ADDR_LE_DEV_RANDOM; *addr_type = get_addr_type_from_eui64(addr->b[5]);
}
} }
static int header_create(struct sk_buff *skb, struct net_device *netdev, 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,9 +482,11 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev,
/* Get destination BT device from skb. /* Get destination BT device from skb.
* If there is no such peer then discard the packet. * 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); read_lock_irqsave(&devices_lock, flags);
peer = peer_lookup_ba(dev, &addr, addr_type); 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,7 +567,7 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
} else { } else {
unsigned long flags; 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; eui64_addr = lowpan_cb(skb)->addr.s6_addr + 8;
dev = lowpan_dev(netdev); dev = lowpan_dev(netdev);
...@@ -564,8 +575,10 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *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); peer = peer_lookup_ba(dev, &addr, addr_type);
read_unlock_irqrestore(&devices_lock, flags); read_unlock_irqrestore(&devices_lock, flags);
BT_DBG("xmit from %s to %pMR (%pI6c) peer %p", netdev->name, BT_DBG("xmit %s to %pMR type %s IP %pI6c peer %p",
&addr, &lowpan_cb(skb)->addr, peer); netdev->name, &addr,
addr_type == ADDR_LE_DEV_PUBLIC ? "PUBLIC" : "RANDOM",
&lowpan_cb(skb)->addr, peer);
if (peer && peer->conn) if (peer && peer->conn)
err = send_pkt(peer->conn, netdev->dev_addr, err = send_pkt(peer->conn, netdev->dev_addr,
...@@ -620,13 +633,13 @@ static void set_addr(u8 *eui, u8 *addr, u8 addr_type) ...@@ -620,13 +633,13 @@ static void set_addr(u8 *eui, u8 *addr, u8 addr_type)
eui[6] = addr[1]; eui[6] = addr[1];
eui[7] = addr[0]; eui[7] = addr[0];
eui[0] ^= 2; /* Universal/local bit set, BT 6lowpan draft ch. 3.2.1 */
/* Universal/local bit set, RFC 4291 */
if (addr_type == ADDR_LE_DEV_PUBLIC) if (addr_type == ADDR_LE_DEV_PUBLIC)
eui[0] |= 1; eui[0] &= ~0x02;
else 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, 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,7 +647,6 @@ static void set_dev_addr(struct net_device *netdev, bdaddr_t *addr,
{ {
netdev->addr_assign_type = NET_ADDR_PERM; netdev->addr_assign_type = NET_ADDR_PERM;
set_addr(netdev->dev_addr, addr->b, addr_type); set_addr(netdev->dev_addr, addr->b, addr_type);
netdev->dev_addr[0] ^= 2;
} }
static void ifup(struct net_device *netdev) 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,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, memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8,
EUI64_ADDR_LEN); 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); write_lock_irqsave(&devices_lock, flags);
INIT_LIST_HEAD(&peer->list); INIT_LIST_HEAD(&peer->list);
......
...@@ -1453,6 +1453,7 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, ...@@ -1453,6 +1453,7 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev,
* is requested. * is requested.
*/ */
if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) && 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_HIGH &&
conn->pending_sec_level != BT_SECURITY_MEDIUM) conn->pending_sec_level != BT_SECURITY_MEDIUM)
return 0; return 0;
...@@ -3076,7 +3077,8 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -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 && 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", BT_DBG("%s ignoring key unauthenticated for high security",
hdev->name); hdev->name);
goto not_found; goto not_found;
......
...@@ -471,8 +471,14 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan) ...@@ -471,8 +471,14 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan)
chan->max_tx = L2CAP_DEFAULT_MAX_TX; chan->max_tx = L2CAP_DEFAULT_MAX_TX;
chan->tx_win = L2CAP_DEFAULT_TX_WINDOW; chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
chan->tx_win_max = 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->ack_win = L2CAP_DEFAULT_TX_WINDOW;
chan->sec_level = BT_SECURITY_LOW; 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); set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
} }
......
...@@ -1180,13 +1180,16 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) ...@@ -1180,13 +1180,16 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
/* Check for backlog size */ /* Check for backlog size */
if (sk_acceptq_is_full(parent)) { if (sk_acceptq_is_full(parent)) {
BT_DBG("backlog full %d", parent->sk_ack_backlog); BT_DBG("backlog full %d", parent->sk_ack_backlog);
release_sock(parent);
return NULL; return NULL;
} }
sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
GFP_ATOMIC); GFP_ATOMIC);
if (!sk) if (!sk) {
release_sock(parent);
return NULL; return NULL;
}
bt_sock_reclassify_lock(sk, BTPROTO_L2CAP); bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
......
...@@ -4546,10 +4546,16 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, ...@@ -4546,10 +4546,16 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
else else
type = HCI_SMP_LTK_SLAVE; type = HCI_SMP_LTK_SLAVE;
if (key->type == MGMT_LTK_UNAUTHENTICATED) switch (key->type) {
case MGMT_LTK_UNAUTHENTICATED:
authenticated = 0x00; authenticated = 0x00;
else break;
case MGMT_LTK_AUTHENTICATED:
authenticated = 0x01; authenticated = 0x01;
break;
default:
continue;
}
hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, type, hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, type,
authenticated, key->val, key->enc_size, key->ediv, authenticated, key->val, key->enc_size, key->ediv,
......
...@@ -909,10 +909,11 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) ...@@ -909,10 +909,11 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
authreq = seclevel_to_authreq(sec_level); authreq = seclevel_to_authreq(sec_level);
/* hcon->auth_type is set by pair_device in mgmt.c. If the MITM /* Require MITM if IO Capability allows or the security level
* flag is set we should also set it for the SMP request. * 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; authreq |= SMP_AUTH_MITM;
if (hcon->link_mode & HCI_LM_MASTER) { if (hcon->link_mode & HCI_LM_MASTER) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment