summaryrefslogtreecommitdiff
path: root/net/mac80211
diff options
context:
space:
mode:
authorLiad Kaufman <liad.kaufman@intel.com>2014-09-04 09:28:40 +0400
committerJohannes Berg <johannes.berg@intel.com>2014-09-11 14:18:47 +0400
commit9d58f25b12f70f52581a5a1fdb1e59d322c4c729 (patch)
tree28740298c051b41408729bd456c6347efdb23da8 /net/mac80211
parent5935839ad73583781b8bbe8d91412f6826e218a4 (diff)
downloadlinux-9d58f25b12f70f52581a5a1fdb1e59d322c4c729.tar.xz
mac80211: add TDLS connection timeout
Adding a timeout for tearing down a TDLS connection that hasn't had ACKed traffic sent through it for a certain amount of time. Since we have no other monitoring facility to indicate the existance (or non-existance) of a peer, this patch will cause a peer to be considered as unavailable if for some X time at least some Y packets have all not been ACKed. Signed-off-by: Liad Kaufman <liad.kaufman@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/sta_info.h3
-rw-r--r--net/mac80211/status.c21
2 files changed, 23 insertions, 1 deletions
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 9dc7a9d6b0d2..42f68cb8957e 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -450,6 +450,9 @@ struct sta_info {
enum ieee80211_smps_mode known_smps_mode;
const struct ieee80211_cipher_scheme *cipher_scheme;
+ /* TDLS timeout data */
+ unsigned long last_tdls_pkt_time;
+
/* keep last! */
struct ieee80211_sta sta;
};
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 2800e1c65519..89290e33dafe 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -538,6 +538,8 @@ static void ieee80211_tx_latency_end_msrmnt(struct ieee80211_local *local,
* - current throughput (higher value for higher tpt)?
*/
#define STA_LOST_PKT_THRESHOLD 50
+#define STA_LOST_TDLS_PKT_THRESHOLD 10
+#define STA_LOST_TDLS_PKT_TIME (10*HZ) /* 10secs since last ACK */
static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb)
{
@@ -548,7 +550,20 @@ static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb)
!(info->flags & IEEE80211_TX_STAT_AMPDU))
return;
- if (++sta->lost_packets < STA_LOST_PKT_THRESHOLD)
+ sta->lost_packets++;
+ if (!sta->sta.tdls && sta->lost_packets < STA_LOST_PKT_THRESHOLD)
+ return;
+
+ /*
+ * If we're in TDLS mode, make sure that all STA_LOST_TDLS_PKT_THRESHOLD
+ * of the last packets were lost, and that no ACK was received in the
+ * last STA_LOST_TDLS_PKT_TIME ms, before triggering the CQM packet-loss
+ * mechanism.
+ */
+ if (sta->sta.tdls &&
+ (sta->lost_packets < STA_LOST_TDLS_PKT_THRESHOLD ||
+ time_before(jiffies,
+ sta->last_tdls_pkt_time + STA_LOST_TDLS_PKT_TIME)))
return;
cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr,
@@ -695,6 +710,10 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
if (info->flags & IEEE80211_TX_STAT_ACK) {
if (sta->lost_packets)
sta->lost_packets = 0;
+
+ /* Track when last TDLS packet was ACKed */
+ if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
+ sta->last_tdls_pkt_time = jiffies;
} else {
ieee80211_lost_packet(sta, skb);
}