Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index b97a40e..3876c7e 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -31,6 +31,12 @@
depends on B43 && BCMA
default y
+config B43_BCMA_EXTRA
+ bool "Hardware support that overlaps with the brcmsmac driver"
+ depends on B43_BCMA
+ default n if BRCMSMAC || BRCMSMAC_MODULE
+ default y
+
config B43_SSB
bool
depends on B43 && SSB
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index b91f28e..23ffb1b 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -116,8 +116,10 @@
#ifdef CONFIG_B43_BCMA
static const struct bcma_device_id b43_bcma_tbl[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
+#ifdef CONFIG_B43_BCMA_EXTRA
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
+#endif
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
BCMA_CORETABLE_END
};
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index f7ed340..f6affc6 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -7981,13 +7981,21 @@
void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
{
+ int timeout = 20;
+
/* flush packet queue when requested */
if (drop)
brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
/* wait for queue and DMA fifos to run dry */
- while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0)
+ while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) {
brcms_msleep(wlc->wl, 1);
+
+ if (--timeout == 0)
+ break;
+ }
+
+ WARN_ON_ONCE(timeout == 0);
}
void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 38e6101..59edcd9 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -225,9 +225,9 @@
key, &key_##name##_ops);
void ieee80211_debugfs_key_add(struct ieee80211_key *key)
- {
+{
static int keycount;
- char buf[50];
+ char buf[100];
struct sta_info *sta;
if (!key->local->debugfs.keys)
@@ -244,7 +244,8 @@
sta = key->sta;
if (sta) {
- sprintf(buf, "../../stations/%pM", sta->sta.addr);
+ sprintf(buf, "../../netdev:%s/stations/%pM",
+ sta->sdata->name, sta->sta.addr);
key->debugfs.stalink =
debugfs_create_symlink("station", key->debugfs.dir, buf);
}
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 73abb75..54df1b2b 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -119,12 +119,12 @@
int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) +
sizeof(mgmt->u.action.u.mesh_action);
- skb = dev_alloc_skb(local->hw.extra_tx_headroom +
+ skb = dev_alloc_skb(local->tx_headroom +
hdr_len +
2 + 37); /* max HWMP IE */
if (!skb)
return -1;
- skb_reserve(skb, local->hw.extra_tx_headroom);
+ skb_reserve(skb, local->tx_headroom);
mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
memset(mgmt, 0, hdr_len);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
@@ -250,12 +250,12 @@
if (time_before(jiffies, ifmsh->next_perr))
return -EAGAIN;
- skb = dev_alloc_skb(local->hw.extra_tx_headroom +
+ skb = dev_alloc_skb(local->tx_headroom +
hdr_len +
2 + 15 /* PERR IE */);
if (!skb)
return -1;
- skb_reserve(skb, local->tx_headroom + local->hw.extra_tx_headroom);
+ skb_reserve(skb, local->tx_headroom);
mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
memset(mgmt, 0, hdr_len);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 41ef1b4..a172517 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -172,7 +172,7 @@
int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) +
sizeof(mgmt->u.action.u.self_prot);
- skb = dev_alloc_skb(local->hw.extra_tx_headroom +
+ skb = dev_alloc_skb(local->tx_headroom +
hdr_len +
2 + /* capability info */
2 + /* AID */
@@ -186,7 +186,7 @@
sdata->u.mesh.ie_len);
if (!skb)
return -1;
- skb_reserve(skb, local->hw.extra_tx_headroom);
+ skb_reserve(skb, local->tx_headroom);
mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
memset(mgmt, 0, hdr_len);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index ecb4c84..295be92 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2750,7 +2750,6 @@
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
- struct ieee80211_work *wk;
u8 bssid[ETH_ALEN];
bool assoc_bss = false;
@@ -2763,30 +2762,47 @@
assoc_bss = true;
} else {
bool not_auth_yet = false;
+ struct ieee80211_work *tmp, *wk = NULL;
mutex_unlock(&ifmgd->mtx);
mutex_lock(&local->mtx);
- list_for_each_entry(wk, &local->work_list, list) {
- if (wk->sdata != sdata)
+ list_for_each_entry(tmp, &local->work_list, list) {
+ if (tmp->sdata != sdata)
continue;
- if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
- wk->type != IEEE80211_WORK_AUTH &&
- wk->type != IEEE80211_WORK_ASSOC &&
- wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
+ if (tmp->type != IEEE80211_WORK_DIRECT_PROBE &&
+ tmp->type != IEEE80211_WORK_AUTH &&
+ tmp->type != IEEE80211_WORK_ASSOC &&
+ tmp->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
continue;
- if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
+ if (memcmp(req->bss->bssid, tmp->filter_ta, ETH_ALEN))
continue;
- not_auth_yet = wk->type == IEEE80211_WORK_DIRECT_PROBE;
- list_del_rcu(&wk->list);
- free_work(wk);
+ not_auth_yet = tmp->type == IEEE80211_WORK_DIRECT_PROBE;
+ list_del_rcu(&tmp->list);
+ synchronize_rcu();
+ wk = tmp;
break;
}
mutex_unlock(&local->mtx);
+ if (wk && wk->type == IEEE80211_WORK_ASSOC) {
+ /* clean up dummy sta & TX sync */
+ sta_info_destroy_addr(wk->sdata, wk->filter_ta);
+ if (wk->assoc.synced)
+ drv_finish_tx_sync(local, wk->sdata,
+ wk->filter_ta,
+ IEEE80211_TX_SYNC_ASSOC);
+ } else if (wk && wk->type == IEEE80211_WORK_AUTH) {
+ if (wk->probe_auth.synced)
+ drv_finish_tx_sync(local, wk->sdata,
+ wk->filter_ta,
+ IEEE80211_TX_SYNC_AUTH);
+ }
+ kfree(wk);
+
/*
* If somebody requests authentication and we haven't
* sent out an auth frame yet there's no need to send