summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2011-03-31 10:35:45 +1100
committerStephen Rothwell <sfr@canb.auug.org.au>2011-03-31 10:35:45 +1100
commit8681cc2a668bbe70acb659e8e0672fce799d8518 (patch)
treea81c12b62773d8abbe20b34f70f2096e96421c1a /net
parent4e8e57d6f86f7a6382a81eb37549ed3af9165742 (diff)
parent83860c594f65945b1a2c99e84338e1145cd34890 (diff)
Merge remote-tracking branch 'wireless/master'
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/mac80211/sta_info.c2
-rw-r--r--net/mac80211/status.c11
-rw-r--r--net/wireless/mlme.c9
-rw-r--r--net/wireless/nl80211.c34
-rw-r--r--net/wireless/nl80211.h3
6 files changed, 57 insertions, 4 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index aa5cc37b4921..d456fa35762b 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -707,6 +707,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
/*
* If the current MPDU is in the right order and nothing else
* is stored we can process it directly, no need to buffer it.
+ * If it is first but there's something stored, we may be able
+ * to release frames after this one.
*/
if (mpdu_seq_num == tid_agg_rx->head_seq_num &&
tid_agg_rx->stored_mpdu_num == 0) {
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index d0311a322ddd..5ec0a7c51b6d 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -698,6 +698,8 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
cancel_work_sync(&sta->drv_unblock_wk);
+ cfg80211_del_sta(sdata->dev, sta->sta.addr, GFP_KERNEL);
+
rate_control_remove_sta_debugfs(sta);
ieee80211_sta_debugfs_remove(sta);
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index b936dd29e92b..3ed3c835fbbf 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -189,16 +189,19 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
bool acked;
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
- /* the HW cannot have attempted that rate */
- if (i >= hw->max_report_rates) {
+ if (info->status.rates[i].idx < 0) {
+ break;
+ } else if (i >= hw->max_report_rates) {
+ /* the HW cannot have attempted that rate */
info->status.rates[i].idx = -1;
info->status.rates[i].count = 0;
- } else if (info->status.rates[i].idx >= 0) {
- rates_idx = i;
+ break;
}
retry_count += info->status.rates[i].count;
}
+ rates_idx = i - 1;
+
if (retry_count < 0)
retry_count = 0;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index aa5df8865ff7..16881fea4ce6 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -770,6 +770,15 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
}
EXPORT_SYMBOL(cfg80211_new_sta);
+void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp)
+{
+ struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+ nl80211_send_sta_del_event(rdev, dev, mac_addr, gfp);
+}
+EXPORT_SYMBOL(cfg80211_del_sta);
+
struct cfg80211_mgmt_registration {
struct list_head list;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4ebce4284e9d..40c90fb461c4 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5966,6 +5966,40 @@ void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
nl80211_mlme_mcgrp.id, gfp);
}
+void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, const u8 *mac_addr,
+ gfp_t gfp)
+{
+ struct sk_buff *msg;
+ void *hdr;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_STATION);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
+
+ if (genlmsg_end(msg, hdr) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+ nl80211_mlme_mcgrp.id, gfp);
+ return;
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+
int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u32 nlpid,
int freq, const u8 *buf, size_t len, gfp_t gfp)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index e3f7fa886966..dcac5cd6f017 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -79,6 +79,9 @@ void nl80211_send_remain_on_channel_cancel(
void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *mac_addr,
struct station_info *sinfo, gfp_t gfp);
+void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, const u8 *mac_addr,
+ gfp_t gfp);
int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u32 nlpid, int freq,