1 --- a/net/mac80211/sta_info.h
2 +++ b/net/mac80211/sta_info.h
3 @@ -99,6 +99,7 @@ enum ieee80211_sta_info_flags {
4 * @dialog_token: dialog token for aggregation session
5 * @timeout: session timeout value to be filled in ADDBA requests
6 * @state: session state (see above)
7 + * @last_tx: jiffies of last tx activity
8 * @stop_initiator: initiator of a session stop
9 * @tx_stop: TX DelBA frame when stopping
10 * @buf_size: reorder buffer size at receiver
11 @@ -120,6 +121,7 @@ struct tid_ampdu_tx {
12 struct timer_list addba_resp_timer;
13 struct sk_buff_head pending;
15 + unsigned long last_tx;
19 @@ -137,6 +139,7 @@ struct tid_ampdu_tx {
20 * @reorder_time: jiffies when skb was added
21 * @session_timer: check if peer keeps Tx-ing on the TID (by timeout value)
22 * @reorder_timer: releases expired frames from the reorder buffer.
23 + * @last_rx: jiffies of last rx activity
24 * @head_seq_num: head sequence number in reordering buffer.
25 * @stored_mpdu_num: number of MPDUs in reordering buffer
26 * @ssn: Starting Sequence Number expected to be aggregated.
27 @@ -161,6 +164,7 @@ struct tid_ampdu_rx {
28 unsigned long *reorder_time;
29 struct timer_list session_timer;
30 struct timer_list reorder_timer;
31 + unsigned long last_rx;
35 --- a/net/mac80211/tx.c
36 +++ b/net/mac80211/tx.c
37 @@ -1120,8 +1120,7 @@ static bool ieee80211_tx_prep_agg(struct
39 /* reset session timer */
40 if (reset_agg_timer && tid_tx->timeout)
41 - mod_timer(&tid_tx->session_timer,
42 - TU_TO_EXP_TIME(tid_tx->timeout));
43 + tid_tx->last_tx = jiffies;
47 --- a/net/mac80211/ieee80211_i.h
48 +++ b/net/mac80211/ieee80211_i.h
49 @@ -52,7 +52,8 @@ struct ieee80211_local;
50 * increased memory use (about 2 kB of RAM per entry). */
51 #define IEEE80211_FRAGMENT_MAX 4
53 -#define TU_TO_EXP_TIME(x) (jiffies + usecs_to_jiffies((x) * 1024))
54 +#define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024))
55 +#define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x))
57 #define IEEE80211_DEFAULT_UAPSD_QUEUES \
58 (IEEE80211_WMM_IE_STA_QOSINFO_AC_BK | \
59 --- a/net/mac80211/agg-tx.c
60 +++ b/net/mac80211/agg-tx.c
61 @@ -436,6 +436,18 @@ static void sta_tx_agg_session_timer_exp
62 u8 *timer_to_id = ptid - *ptid;
63 struct sta_info *sta = container_of(timer_to_id, struct sta_info,
65 + struct tid_ampdu_tx *tid_tx;
66 + unsigned long timeout;
68 + tid_tx = rcu_dereference_protected_tid_tx(sta, *ptid);
72 + timeout = tid_tx->last_tx + TU_TO_JIFFIES(tid_tx->timeout);
73 + if (time_is_after_jiffies(timeout)) {
74 + mod_timer(&tid_tx->session_timer, timeout);
78 #ifdef CONFIG_MAC80211_HT_DEBUG
79 printk(KERN_DEBUG "tx session timer expired on tid %d\n", (u16)*ptid);
80 @@ -908,9 +920,11 @@ void ieee80211_process_addba_resp(struct
82 sta->ampdu_mlme.addba_req_num[tid] = 0;
84 - if (tid_tx->timeout)
85 + if (tid_tx->timeout) {
86 mod_timer(&tid_tx->session_timer,
87 TU_TO_EXP_TIME(tid_tx->timeout));
88 + tid_tx->last_tx = jiffies;
92 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR,
93 --- a/net/mac80211/agg-rx.c
94 +++ b/net/mac80211/agg-rx.c
95 @@ -141,6 +141,18 @@ static void sta_rx_agg_session_timer_exp
96 u8 *timer_to_id = ptid - *ptid;
97 struct sta_info *sta = container_of(timer_to_id, struct sta_info,
99 + struct tid_ampdu_rx *tid_rx;
100 + unsigned long timeout;
102 + tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[*ptid]);
106 + timeout = tid_rx->last_rx + TU_TO_JIFFIES(tid_rx->timeout);
107 + if (time_is_after_jiffies(timeout)) {
108 + mod_timer(&tid_rx->session_timer, timeout);
112 #ifdef CONFIG_MAC80211_HT_DEBUG
113 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
114 @@ -336,8 +348,10 @@ void ieee80211_process_addba_request(str
115 /* activate it for RX */
116 rcu_assign_pointer(sta->ampdu_mlme.tid_rx[tid], tid_agg_rx);
120 mod_timer(&tid_agg_rx->session_timer, TU_TO_EXP_TIME(timeout));
121 + tid_agg_rx->last_rx = jiffies;
125 mutex_unlock(&sta->ampdu_mlme.mtx);
126 --- a/net/mac80211/rx.c
127 +++ b/net/mac80211/rx.c
128 @@ -793,8 +793,7 @@ static void ieee80211_rx_reorder_ampdu(s
130 /* reset session timer */
131 if (tid_agg_rx->timeout)
132 - mod_timer(&tid_agg_rx->session_timer,
133 - TU_TO_EXP_TIME(tid_agg_rx->timeout));
134 + tid_agg_rx->last_rx = jiffies;
136 /* if this mpdu is fragmented - terminate rx aggregation session */
137 sc = le16_to_cpu(hdr->seq_ctrl);