summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-11-24 08:10:06 +0100
committerJohn W. Linville <linville@tuxdriver.com>2010-11-24 16:19:36 -0500
commit99ba2a14283be96a682e04455061c08a46bbf4ec (patch)
tree120520c075528d7ef5a32bb8782c82b7c7e972eb
parentc063dbf52b998b852122dff07a8b8dd430b38437 (diff)
mac80211: implement packet loss notification
For drivers that have accurate TX status reporting we can report the number of consecutive lost packets to userspace using the new cfg80211 CQM event. The threshold is fixed right now, this may need to be improved in the future. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/sta_info.h3
-rw-r--r--net/mac80211/status.c22
2 files changed, 25 insertions, 0 deletions
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 9265acadef32..b562d9b6a702 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -248,6 +248,7 @@ enum plink_state {
* @sta: station information we share with the driver
* @dead: set to true when sta is unlinked
* @uploaded: set to true when sta is uploaded to the driver
+ * @lost_packets: number of consecutive lost packets
*/
struct sta_info {
/* General information, mostly static */
@@ -335,6 +336,8 @@ struct sta_info {
} debugfs;
#endif
+ unsigned int lost_packets;
+
/* keep last! */
struct ieee80211_sta sta;
};
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 8695cd11dfd9..bed7e32ed908 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -161,6 +161,15 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
ieee80211_sta_tx_notify(sdata, (void *) skb->data);
}
+/*
+ * Use a static threshold for now, best value to be determined
+ * by testing ...
+ * Should it depend on:
+ * - on # of retransmissions
+ * - current throughput (higher value for higher tpt)?
+ */
+#define STA_LOST_PKT_THRESHOLD 50
+
void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct sk_buff *skb2;
@@ -247,6 +256,19 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
if (!(info->flags & IEEE80211_TX_CTL_INJECTED) &&
(info->flags & IEEE80211_TX_STAT_ACK))
ieee80211_frame_acked(sta, skb);
+
+ if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
+ if (info->flags & IEEE80211_TX_STAT_ACK) {
+ if (sta->lost_packets)
+ sta->lost_packets = 0;
+ } else if (++sta->lost_packets >= STA_LOST_PKT_THRESHOLD) {
+ cfg80211_cqm_pktloss_notify(sta->sdata->dev,
+ sta->sta.addr,
+ sta->lost_packets,
+ GFP_ATOMIC);
+ sta->lost_packets = 0;
+ }
+ }
}
rcu_read_unlock();