Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 2589b38..2b0bfb8 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -46,7 +46,7 @@
* @chan:
*
* This is the function to change channel on single-chip devices, that is
- * all devices after ar9280.
+ * for AR9300 family of chipsets.
*
* This function takes the channel value in MHz and sets
* hardware channel value. Assumes writes have been enabled to analog bus.
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index b30e9fc..171ccf7 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -679,7 +679,6 @@
void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
void ath9k_reload_chainmask_settings(struct ath_softc *sc);
-void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
bool ath9k_uses_beacons(int type);
#ifdef CONFIG_ATH9K_PCI
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 172e33d..2f4b48e 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -400,6 +400,7 @@
ah->noise = ath9k_hw_getchan_noise(ah, chan);
return true;
}
+EXPORT_SYMBOL(ath9k_hw_getnf);
void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
struct ath9k_channel *chan)
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 05b9dbf..3b33996 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -19,7 +19,6 @@
#include "hw.h"
-#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3
#define AR_PHY_CCA_FILTERWINDOW_LENGTH 5
#define NUM_NF_READINGS 6
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index e267c92..4a00806 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1629,7 +1629,6 @@
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
struct ieee80211_channel *curchan = hw->conf.channel;
- struct ath9k_channel old_chan;
int pos = curchan->hw_value;
int old_pos = -1;
unsigned long flags;
@@ -1654,11 +1653,8 @@
* Preserve the current channel values, before updating
* the same channel
*/
- if (old_pos == pos) {
- memcpy(&old_chan, &sc->sc_ah->channels[pos],
- sizeof(struct ath9k_channel));
- ah->curchan = &old_chan;
- }
+ if (ah->curchan && (old_pos == pos))
+ ath9k_hw_getnf(ah, ah->curchan);
ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
curchan, conf->channel_type);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 5a002a2..f7eeee1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -3119,8 +3119,10 @@
/* Verify NVRAM bytes */
brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize);
nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
- if (!nvram_ularray)
+ if (!nvram_ularray) {
+ kfree(vbuffer);
return -ENOMEM;
+ }
/* Upload image to verify downloaded contents. */
memset(nvram_ularray, 0xaa, varsize);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
index 6f91a14..3fda6b1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
@@ -196,6 +196,8 @@
/* Allocate skb buffer to contain firmware */
/* info and tx descriptor info. */
skb = dev_alloc_skb(frag_length);
+ if (!skb)
+ return false;
skb_reserve(skb, extra_descoffset);
seg_ptr = (u8 *)skb_put(skb, (u32)(frag_length -
extra_descoffset));
@@ -573,6 +575,8 @@
len = _rtl92s_get_h2c_cmdlen(MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len);
skb = dev_alloc_skb(len);
+ if (!skb)
+ return false;
cb_desc = (struct rtl_tcb_desc *)(skb->cb);
cb_desc->queue_index = TXCMD_QUEUE;
cb_desc->cmd_or_init = DESC_PACKET_TYPE_NORMAL;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 5e2e984..ea9231f 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -127,7 +127,7 @@
__u8 major_class;
__u8 minor_class;
__u8 features[8];
- __u8 extfeatures[8];
+ __u8 host_features[8];
__u8 commands[64];
__u8 ssp_mode;
__u8 hci_ver;
@@ -676,7 +676,7 @@
#define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE)
/* ----- Extended LMP capabilities ----- */
-#define lmp_host_le_capable(dev) ((dev)->extfeatures[0] & LMP_HOST_LE)
+#define lmp_host_le_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE)
/* ----- HCI protocols ----- */
static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index cdcfcab..ef92864 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -156,17 +156,17 @@
void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
{
- write_lock_bh(&l->lock);
+ write_lock(&l->lock);
sk_add_node(sk, &l->head);
- write_unlock_bh(&l->lock);
+ write_unlock(&l->lock);
}
EXPORT_SYMBOL(bt_sock_link);
void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
{
- write_lock_bh(&l->lock);
+ write_lock(&l->lock);
sk_del_node_init(sk);
- write_unlock_bh(&l->lock);
+ write_unlock(&l->lock);
}
EXPORT_SYMBOL(bt_sock_unlink);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 4221bd2..001307f 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -711,7 +711,14 @@
if (rp->status)
return;
- memcpy(hdev->extfeatures, rp->features, 8);
+ switch (rp->page) {
+ case 0:
+ memcpy(hdev->features, rp->features, 8);
+ break;
+ case 1:
+ memcpy(hdev->host_features, rp->features, 8);
+ break;
+ }
hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
}
@@ -1047,9 +1054,7 @@
case LE_SCANNING_DISABLED:
clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
- cancel_delayed_work_sync(&hdev->adv_work);
- queue_delayed_work(hdev->workqueue, &hdev->adv_work,
- jiffies + ADV_CLEAR_TIMEOUT);
+ schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
break;
default:
@@ -2266,20 +2271,19 @@
struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
int i;
- skb_pull(skb, sizeof(*ev));
-
- BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
-
if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
return;
}
- if (skb->len < ev->num_hndl * 4) {
+ if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
+ ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
BT_DBG("%s bad parameters", hdev->name);
return;
}
+ BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
+
for (i = 0; i < ev->num_hndl; i++) {
struct hci_comp_pkts_info *info = &ev->handles[i];
struct hci_conn *conn;
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 6d94616..0dcc962 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -767,7 +767,6 @@
/* Detach sockets from device */
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
- local_bh_disable();
bh_lock_sock_nested(sk);
if (hci_pi(sk)->hdev == hdev) {
hci_pi(sk)->hdev = NULL;
@@ -778,7 +777,6 @@
hci_dev_put(hdev);
}
bh_unlock_sock(sk);
- local_bh_enable();
}
read_unlock(&hci_sk_list.lock);
}
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index aa78d8c..faf0b11 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -165,7 +165,7 @@
{
int err;
- write_lock_bh(&chan_list_lock);
+ write_lock(&chan_list_lock);
if (psm && __l2cap_global_chan_by_addr(psm, src)) {
err = -EADDRINUSE;
@@ -190,17 +190,17 @@
}
done:
- write_unlock_bh(&chan_list_lock);
+ write_unlock(&chan_list_lock);
return err;
}
int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
{
- write_lock_bh(&chan_list_lock);
+ write_lock(&chan_list_lock);
chan->scid = scid;
- write_unlock_bh(&chan_list_lock);
+ write_unlock(&chan_list_lock);
return 0;
}
@@ -289,9 +289,9 @@
chan->sk = sk;
- write_lock_bh(&chan_list_lock);
+ write_lock(&chan_list_lock);
list_add(&chan->global_l, &chan_list);
- write_unlock_bh(&chan_list_lock);
+ write_unlock(&chan_list_lock);
INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
@@ -306,9 +306,9 @@
void l2cap_chan_destroy(struct l2cap_chan *chan)
{
- write_lock_bh(&chan_list_lock);
+ write_lock(&chan_list_lock);
list_del(&chan->global_l);
- write_unlock_bh(&chan_list_lock);
+ write_unlock(&chan_list_lock);
l2cap_chan_put(chan);
}
@@ -543,14 +543,14 @@
* 200 - 254 are used by utilities like l2ping, etc.
*/
- spin_lock_bh(&conn->lock);
+ spin_lock(&conn->lock);
if (++conn->tx_ident > 128)
conn->tx_ident = 1;
id = conn->tx_ident;
- spin_unlock_bh(&conn->lock);
+ spin_unlock(&conn->lock);
return id;
}
@@ -1190,7 +1190,7 @@
}
/* Set destination address and psm */
- bacpy(&bt_sk(sk)->dst, src);
+ bacpy(&bt_sk(sk)->dst, dst);
chan->psm = psm;
chan->dcid = cid;
@@ -4702,7 +4702,7 @@
{
struct l2cap_chan *c;
- read_lock_bh(&chan_list_lock);
+ read_lock(&chan_list_lock);
list_for_each_entry(c, &chan_list, global_l) {
struct sock *sk = c->sk;
@@ -4715,7 +4715,7 @@
c->sec_level, c->mode);
}
- read_unlock_bh(&chan_list_lock);
+ read_unlock(&chan_list_lock);
return 0;
}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 9ca5616..c61d967 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -587,6 +587,7 @@
if (smp_conn_security(conn, sec.level))
break;
sk->sk_state = BT_CONFIG;
+ chan->state = BT_CONFIG;
/* or for ACL link, under defer_setup time */
} else if (sk->sk_state == BT_CONNECT2 &&
@@ -731,6 +732,7 @@
if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
sk->sk_state = BT_CONFIG;
+ pi->chan->state = BT_CONFIG;
__l2cap_connect_rsp_defer(pi->chan);
release_sock(sk);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 2540944..bc8e59d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -291,7 +291,7 @@
if (!(hdev->features[4] & LMP_NO_BREDR))
settings |= MGMT_SETTING_BREDR;
- if (hdev->extfeatures[0] & LMP_HOST_LE)
+ if (hdev->host_features[0] & LMP_HOST_LE)
settings |= MGMT_SETTING_LE;
if (test_bit(HCI_AUTH, &hdev->flags))
@@ -2756,7 +2756,7 @@
if (!cmd)
return -ENOENT;
- err = cmd_status(cmd->sk, hdev->id, cmd->opcode, status);
+ err = cmd_status(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status));
mgmt_pending_remove(cmd);
return err;
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index aea2bdd..f066678 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -370,7 +370,7 @@
goto done;
}
- write_lock_bh(&rfcomm_sk_list.lock);
+ write_lock(&rfcomm_sk_list.lock);
if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
err = -EADDRINUSE;
@@ -381,7 +381,7 @@
sk->sk_state = BT_BOUND;
}
- write_unlock_bh(&rfcomm_sk_list.lock);
+ write_unlock(&rfcomm_sk_list.lock);
done:
release_sock(sk);
@@ -455,7 +455,7 @@
err = -EINVAL;
- write_lock_bh(&rfcomm_sk_list.lock);
+ write_lock(&rfcomm_sk_list.lock);
for (channel = 1; channel < 31; channel++)
if (!__rfcomm_get_sock_by_addr(channel, src)) {
@@ -464,7 +464,7 @@
break;
}
- write_unlock_bh(&rfcomm_sk_list.lock);
+ write_unlock(&rfcomm_sk_list.lock);
if (err < 0)
goto done;
@@ -982,7 +982,7 @@
struct sock *sk;
struct hlist_node *node;
- read_lock_bh(&rfcomm_sk_list.lock);
+ read_lock(&rfcomm_sk_list.lock);
sk_for_each(sk, node, &rfcomm_sk_list.head) {
seq_printf(f, "%s %s %d %d\n",
@@ -991,7 +991,7 @@
sk->sk_state, rfcomm_pi(sk)->channel);
}
- read_unlock_bh(&rfcomm_sk_list.lock);
+ read_unlock(&rfcomm_sk_list.lock);
return 0;
}
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index fa8f4de5..a2d4f51 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -76,7 +76,7 @@
};
static LIST_HEAD(rfcomm_dev_list);
-static DEFINE_RWLOCK(rfcomm_dev_lock);
+static DEFINE_SPINLOCK(rfcomm_dev_lock);
static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
@@ -146,7 +146,7 @@
{
struct rfcomm_dev *dev;
- read_lock(&rfcomm_dev_lock);
+ spin_lock(&rfcomm_dev_lock);
dev = __rfcomm_dev_get(id);
@@ -157,7 +157,7 @@
rfcomm_dev_hold(dev);
}
- read_unlock(&rfcomm_dev_lock);
+ spin_unlock(&rfcomm_dev_lock);
return dev;
}
@@ -205,7 +205,7 @@
if (!dev)
return -ENOMEM;
- write_lock_bh(&rfcomm_dev_lock);
+ spin_lock(&rfcomm_dev_lock);
if (req->dev_id < 0) {
dev->id = 0;
@@ -290,7 +290,7 @@
__module_get(THIS_MODULE);
out:
- write_unlock_bh(&rfcomm_dev_lock);
+ spin_unlock(&rfcomm_dev_lock);
if (err < 0)
goto free;
@@ -327,9 +327,9 @@
if (atomic_read(&dev->opened) > 0)
return;
- write_lock_bh(&rfcomm_dev_lock);
+ spin_lock(&rfcomm_dev_lock);
list_del_init(&dev->list);
- write_unlock_bh(&rfcomm_dev_lock);
+ spin_unlock(&rfcomm_dev_lock);
rfcomm_dev_put(dev);
}
@@ -473,7 +473,7 @@
di = dl->dev_info;
- read_lock_bh(&rfcomm_dev_lock);
+ spin_lock(&rfcomm_dev_lock);
list_for_each_entry(dev, &rfcomm_dev_list, list) {
if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
@@ -488,7 +488,7 @@
break;
}
- read_unlock_bh(&rfcomm_dev_lock);
+ spin_unlock(&rfcomm_dev_lock);
dl->dev_num = n;
size = sizeof(*dl) + n * sizeof(*di);
@@ -766,9 +766,9 @@
rfcomm_dlc_unlock(dev->dlc);
if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) {
- write_lock_bh(&rfcomm_dev_lock);
+ spin_lock(&rfcomm_dev_lock);
list_del_init(&dev->list);
- write_unlock_bh(&rfcomm_dev_lock);
+ spin_unlock(&rfcomm_dev_lock);
rfcomm_dev_put(dev);
}
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 5dc2f21..8bf26d1 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -482,7 +482,7 @@
goto done;
}
- write_lock_bh(&sco_sk_list.lock);
+ write_lock(&sco_sk_list.lock);
if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) {
err = -EADDRINUSE;
@@ -492,7 +492,7 @@
sk->sk_state = BT_BOUND;
}
- write_unlock_bh(&sco_sk_list.lock);
+ write_unlock(&sco_sk_list.lock);
done:
release_sock(sk);
@@ -965,14 +965,14 @@
struct sock *sk;
struct hlist_node *node;
- read_lock_bh(&sco_sk_list.lock);
+ read_lock(&sco_sk_list.lock);
sk_for_each(sk, node, &sco_sk_list.head) {
seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src),
batostr(&bt_sk(sk)->dst), sk->sk_state);
}
- read_unlock_bh(&sco_sk_list.lock);
+ read_unlock(&sco_sk_list.lock);
return 0;
}
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 93aab07..422b798 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -106,7 +106,7 @@
if (status->flag & RX_FLAG_MMIC_ERROR)
goto mic_fail;
- if (!(status->flag & RX_FLAG_IV_STRIPPED))
+ if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key)
goto update_iv;
return RX_CONTINUE;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b3d3cf8..afeea32 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2250,6 +2250,7 @@
};
static int parse_station_flags(struct genl_info *info,
+ enum nl80211_iftype iftype,
struct station_parameters *params)
{
struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
@@ -2283,8 +2284,33 @@
nla, sta_flags_policy))
return -EINVAL;
- params->sta_flags_mask = (1 << __NL80211_STA_FLAG_AFTER_LAST) - 1;
- params->sta_flags_mask &= ~1;
+ /*
+ * Only allow certain flags for interface types so that
+ * other attributes are silently ignored. Remember that
+ * this is backward compatibility code with old userspace
+ * and shouldn't be hit in other cases anyway.
+ */
+ switch (iftype) {
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_AP_VLAN:
+ case NL80211_IFTYPE_P2P_GO:
+ params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
+ BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
+ BIT(NL80211_STA_FLAG_WME) |
+ BIT(NL80211_STA_FLAG_MFP);
+ break;
+ case NL80211_IFTYPE_P2P_CLIENT:
+ case NL80211_IFTYPE_STATION:
+ params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
+ BIT(NL80211_STA_FLAG_TDLS_PEER);
+ break;
+ case NL80211_IFTYPE_MESH_POINT:
+ params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
+ BIT(NL80211_STA_FLAG_MFP) |
+ BIT(NL80211_STA_FLAG_AUTHORIZED);
+ default:
+ return -EINVAL;
+ }
for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
if (flags[flag])
@@ -2585,7 +2611,7 @@
if (!rdev->ops->change_station)
return -EOPNOTSUPP;
- if (parse_station_flags(info, ¶ms))
+ if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms))
return -EINVAL;
if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
@@ -2731,7 +2757,7 @@
if (!rdev->ops->add_station)
return -EOPNOTSUPP;
- if (parse_station_flags(info, ¶ms))
+ if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms))
return -EINVAL;
switch (dev->ieee80211_ptr->iftype) {